summaryrefslogtreecommitdiff
path: root/src/gui/pieList.vala
diff options
context:
space:
mode:
authorAlessandro Ghedini <al3xbio@gmail.com>2012-01-21 19:14:06 +0100
committerAlessandro Ghedini <al3xbio@gmail.com>2012-01-21 19:19:46 +0100
commitc05883f47c498be4e11893e5178c5bc37ffd9f4a (patch)
treedbd3cd7ad3d7771405ad63af2f1e9d14d4ae5a35 /src/gui/pieList.vala
parent31539042f11bc210a29e923f45586779c3ad46b2 (diff)
parent60560a030fda3c539ff9dc1563b9926414a193da (diff)
Merge commit 'upstream/0.4.0'
Diffstat (limited to 'src/gui/pieList.vala')
-rw-r--r--src/gui/pieList.vala1105
1 files changed, 151 insertions, 954 deletions
diff --git a/src/gui/pieList.vala b/src/gui/pieList.vala
index 46970d5..bfcb832 100644
--- a/src/gui/pieList.vala
+++ b/src/gui/pieList.vala
@@ -17,1029 +17,226 @@ this program. If not, see <http://www.gnu.org/licenses/>.
namespace GnomePie {
-// A very complex Widget. This is by far the most ugly file of this project
-// but well, this list *is* complex... sorry ;)
+/////////////////////////////////////////////////////////////////////////
+/// A list, containing one entry for each existing Pie.
+/////////////////////////////////////////////////////////////////////////
class PieList : Gtk.TreeView {
- private Gtk.ListStore groups;
- private Gtk.ListStore pies;
- private Gtk.ListStore actions;
- private Gtk.TreeStore data;
+ /////////////////////////////////////////////////////////////////////
+ /// This signal gets emitted when the user selects a new Pie.
+ /////////////////////////////////////////////////////////////////////
- private const int small_icon = 24;
- private const int large_icon = 36;
+ public signal void on_select(string id);
- // data positions in the data ListStore
- private enum DataPos {IS_QUICKACTION, ICON, NAME, TYPE_ID, ACTION_TYPE,
- ICON_PIXBUF, FONT_WEIGHT, ICON_NAME_EDITABLE, QUICKACTION_VISIBLE, QUICKACTION_ACTIVATABLE,
- TYPE_VISIBLE, GROUP_VISIBLE, APP_VISIBLE, KEY_VISIBLE, PIE_VISIBLE,
- URI_VISIBLE, TRIGGER_VISIBLE, DISPLAY_COMMAND_GROUP, DISPLAY_COMMAND_APP,
- DISPLAY_COMMAND_KEY, DISPLAY_COMMAND_PIE, DISPLAY_COMMAND_URI,
- REAL_COMMAND_GROUP, REAL_COMMAND_PIE, REAL_COMMAND_KEY}
+ /////////////////////////////////////////////////////////////////////
+ /// Stores the data internally.
+ /////////////////////////////////////////////////////////////////////
- // data positions in the actions ListStore
- private enum ActionPos {NAME, TYPE, CAN_QUICKACTION, ICON_NAME_EDITABLE}
+ private Gtk.ListStore data;
+ private enum DataPos {ICON, ICON_NAME, NAME, ID}
- // data positions in the pies ListStore
- private enum PiePos {NAME, ID}
+ /////////////////////////////////////////////////////////////////////
+ /// Stores where a drag startet.
+ /////////////////////////////////////////////////////////////////////
- // data positions in the groups ListStore
- private enum GroupPos {NAME, TYPE, ICON}
+ private Gtk.TreeIter? drag_start = null;
+
+ /////////////////////////////////////////////////////////////////////
+ /// Rembers the time when a last drag move event was reported. Used
+ /// to avoid frequent changes of selected Pie when a Pie is dragged
+ /// over this widget.
+ /////////////////////////////////////////////////////////////////////
+
+ private uint last_hover = 0;
+
+ /////////////////////////////////////////////////////////////////////
+ /// C'tor, constructs the Widget.
+ /////////////////////////////////////////////////////////////////////
public PieList() {
GLib.Object();
- Gtk.TreeIter last;
-
- // group choices
- this.groups = new Gtk.ListStore(3, typeof(string), // group name
- typeof(string), // group type
- typeof(string)); // group icon
-
- // add all registered group types
- foreach (var type in GroupRegistry.types) {
- this.groups.append(out last);
- this.groups.set(last, GroupPos.NAME, GroupRegistry.names[type],
- GroupPos.TYPE, type.name(),
- GroupPos.ICON, GroupRegistry.icons[type]);
- }
-
- // pie choices
- this.pies = new Gtk.ListStore(2, typeof(string), // pie name
- typeof(string)); // pie id
-
- // action type choices
- this.actions = new Gtk.ListStore(4, typeof(string), // type name
- typeof(string), // action type
- typeof(bool), // can be quickaction
- typeof(bool)); // icon/name editable
-
- // add all registered action types
- foreach (var type in ActionRegistry.types) {
- this.actions.append(out last);
- this.actions.set(last, ActionPos.NAME, ActionRegistry.names[type],
- ActionPos.TYPE, type.name(),
- ActionPos.CAN_QUICKACTION, true,
- ActionPos.ICON_NAME_EDITABLE, ActionRegistry.icon_name_editables[type]);
- }
- // and one type for groups
- this.actions.append(out last);
- this.actions.set(last, ActionPos.NAME, _("Slice group"),
- ActionPos.TYPE, typeof(ActionGroup).name(),
- ActionPos.CAN_QUICKACTION, false,
- ActionPos.ICON_NAME_EDITABLE, false);
+ this.data = new Gtk.ListStore(4, typeof(Gdk.Pixbuf),
+ typeof(string),
+ typeof(string),
+ typeof(string));
+
+ this.data.set_sort_column_id(DataPos.NAME, Gtk.SortType.ASCENDING);
- // main data model
- this.data = new Gtk.TreeStore(25, typeof(bool), // is quickaction
- typeof(string), // icon
- typeof(string), // name
- typeof(string), // slice: type label, pie: "ID: %id"
- typeof(string), // typeof(action), typeof(ActionGroup).name() if group action, pie_id if Pie
-
- typeof(Gdk.Pixbuf), // icon pixbuf
- typeof(int), // font weight
-
- typeof(bool), // icon/name editable
-
- typeof(bool), // quickaction visible
- typeof(bool), // quickaction activatable
- typeof(bool), // type visible
- typeof(bool), // group renderer visible
- typeof(bool), // app renderer visible
- typeof(bool), // key renderer visible
- typeof(bool), // pie renderer visible
- typeof(bool), // uri renderer visible
- typeof(bool), // trigger renderer visible
-
- typeof(string), // display command group
- typeof(string), // display command app
- typeof(string), // display command key
- typeof(string), // display command pie
- typeof(string), // display command uri
-
- typeof(string), // real command group
- typeof(string), // real command pie
- typeof(string)); // real command key
-
-
this.set_model(this.data);
+ this.set_headers_visible(false);
this.set_grid_lines(Gtk.TreeViewGridLines.NONE);
- this.set_enable_tree_lines(false);
- this.set_reorderable(false);
- this.set_level_indentation(-10);
+ this.width_request = 170;
+ this.set_enable_search(false);
- // create the gui
- // icon column
- var icon_column = new Gtk.TreeViewColumn();
- icon_column.title = _("Icon");
- icon_column.expand = false;
-
- // quickaction checkbox
- var check_render = new Gtk.CellRendererToggle();
- check_render.activatable = true;
- check_render.radio = true;
- check_render.width = 15;
-
- check_render.toggled.connect((path) => {
- Gtk.TreeIter toggled;
- this.data.get_iter_from_string(out toggled, path);
-
- bool current = false;
- this.data.get(toggled, DataPos.IS_QUICKACTION, out current);
-
- // set all others off
- Gtk.TreeIter parent;
- this.data.iter_parent(out parent, toggled);
- string parent_pos = this.data.get_string_from_iter(parent);
- int child_count = this.data.iter_n_children(parent);
-
- for (int i=0; i<child_count; ++i) {
- Gtk.TreeIter child;
- this.data.get_iter_from_string(out child, "%s:%d".printf(parent_pos, i));
- this.data.set(child, DataPos.IS_QUICKACTION, false);
- }
-
- // toggle selected
- this.data.set(toggled, DataPos.IS_QUICKACTION, !current);
-
- this.update_pie(toggled);
- });
-
- icon_column.pack_start(check_render, false);
- icon_column.add_attribute(check_render, "activatable", DataPos.QUICKACTION_ACTIVATABLE);
- icon_column.add_attribute(check_render, "sensitive", DataPos.QUICKACTION_ACTIVATABLE);
- icon_column.add_attribute(check_render, "visible", DataPos.QUICKACTION_VISIBLE);
- icon_column.add_attribute(check_render, "active", DataPos.IS_QUICKACTION);
-
+ this.set_events(Gdk.EventMask.POINTER_MOTION_MASK);
- // icon
- var icon_render = new GnomePie.CellRendererIcon();
- icon_render.editable = true;
-
- icon_render.on_select.connect((path, icon_name) => {
- Gtk.TreeIter iter;
- this.data.get_iter_from_string(out iter, path);
- int icon_size = this.data.iter_depth(iter) == 0 ? this.large_icon : this.small_icon;
-
- this.data.set(iter, DataPos.ICON, icon_name);
- this.data.set(iter, DataPos.ICON_PIXBUF, this.load_icon(icon_name, icon_size));
-
- this.update_pie(iter);
- this.update_linked();
- });
-
- icon_column.pack_start(icon_render, false);
- icon_column.add_attribute(icon_render, "icon_name", DataPos.ICON);
- icon_column.add_attribute(icon_render, "pixbuf", DataPos.ICON_PIXBUF);
- icon_column.add_attribute(icon_render, "editable", DataPos.ICON_NAME_EDITABLE);
- icon_column.add_attribute(icon_render, "icon_sensitive", DataPos.ICON_NAME_EDITABLE);
-
- // command column
- var command_column = new Gtk.TreeViewColumn();
- command_column.title = _("Command");
- command_column.resizable = true;
- command_column.expand = true;
-
- // trigger
- var command_renderer_trigger = new CellRendererTrigger();
- command_renderer_trigger.editable = true;
- command_renderer_trigger.ellipsize = Pango.EllipsizeMode.END;
-
- command_renderer_trigger.on_select.connect((path, trigger) => {
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_KEY, trigger.label_with_specials);
- this.data.set(data_iter, DataPos.REAL_COMMAND_KEY, trigger.name);
-
- this.update_pie(data_iter);
- });
-
- command_column.pack_end(command_renderer_trigger, true);
- command_column.add_attribute(command_renderer_trigger, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_trigger, "markup", DataPos.DISPLAY_COMMAND_KEY);
- command_column.add_attribute(command_renderer_trigger, "visible", DataPos.TRIGGER_VISIBLE);
- command_column.add_attribute(command_renderer_trigger, "trigger", DataPos.REAL_COMMAND_KEY);
-
- // slice group
- var command_renderer_group = new Gtk.CellRendererCombo();
- command_renderer_group.editable = true;
- command_renderer_group.has_entry = false;
- command_renderer_group.text_column = 0;
- command_renderer_group.ellipsize = Pango.EllipsizeMode.END;
- command_renderer_group.model = this.groups;
-
- command_renderer_group.changed.connect((path, iter) => {
- string display_name;
- string type;
- string icon;
-
- this.groups.get(iter, GroupPos.NAME, out display_name);
- this.groups.get(iter, GroupPos.TYPE, out type);
- this.groups.get(iter, GroupPos.ICON, out icon);
-
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_GROUP, display_name);
- this.data.set(data_iter, DataPos.REAL_COMMAND_GROUP, type);
- this.data.set(data_iter, DataPos.NAME, display_name);
- this.data.set(data_iter, DataPos.ICON, icon);
-
- this.update_pie(data_iter);
- });
-
- command_column.pack_end(command_renderer_group, true);
- command_column.add_attribute(command_renderer_group, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_group, "text", DataPos.DISPLAY_COMMAND_GROUP);
- command_column.add_attribute(command_renderer_group, "visible", DataPos.GROUP_VISIBLE);
-
-
- // app action
- var command_renderer_app = new Gtk.CellRendererText();
- command_renderer_app.editable = true;
- command_renderer_app.ellipsize = Pango.EllipsizeMode.END;
-
- command_renderer_app.edited.connect((path, command) => {
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_APP, command);
-
- this.update_pie(data_iter);
- });
-
- command_column.pack_end(command_renderer_app, true);
- command_column.add_attribute(command_renderer_app, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_app, "text", DataPos.DISPLAY_COMMAND_APP);
- command_column.add_attribute(command_renderer_app, "visible", DataPos.APP_VISIBLE);
-
-
- // key action
- var command_renderer_key = new Gtk.CellRendererAccel();
- command_renderer_key.editable = true;
- command_renderer_key.ellipsize = Pango.EllipsizeMode.END;
-
- command_renderer_key.accel_edited.connect((path, key, mods) => {
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- string label = Gtk.accelerator_get_label(key, mods);
- string accelerator = Gtk.accelerator_name(key, mods);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_KEY, label);
- this.data.set(data_iter, DataPos.REAL_COMMAND_KEY, accelerator);
-
- this.update_pie(data_iter);
- });
-
- command_renderer_key.accel_cleared.connect((path) => {
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_KEY, _("Not bound"));
- this.data.set(data_iter, DataPos.REAL_COMMAND_KEY, "");
-
- this.update_pie(data_iter);
- });
-
- command_column.pack_end(command_renderer_key, true);
- command_column.add_attribute(command_renderer_key, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_key, "text", DataPos.DISPLAY_COMMAND_KEY);
- command_column.add_attribute(command_renderer_key, "visible", DataPos.KEY_VISIBLE);
-
-
- // pie action
- var command_renderer_pie = new Gtk.CellRendererCombo();
- command_renderer_pie.editable = true;
- command_renderer_pie.has_entry = false;
- command_renderer_pie.text_column = 0;
- command_renderer_pie.ellipsize = Pango.EllipsizeMode.END;
- command_renderer_pie.model = this.pies;
-
- command_renderer_pie.changed.connect((path, iter) => {
- string name;
- string id;
-
- this.pies.get(iter, PiePos.NAME, out name);
- this.pies.get(iter, PiePos.ID, out id);
-
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_PIE, name);
- this.data.set(data_iter, DataPos.REAL_COMMAND_PIE, id);
-
- this.update_pie(data_iter);
- this.update_linked();
- });
-
- command_column.pack_end(command_renderer_pie, true);
- command_column.add_attribute(command_renderer_pie, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_pie, "text", DataPos.DISPLAY_COMMAND_PIE);
- command_column.add_attribute(command_renderer_pie, "visible", DataPos.PIE_VISIBLE);
-
-
- // uri action
- var command_renderer_uri = new Gtk.CellRendererText();
- command_renderer_uri.editable = true;
- command_renderer_uri.ellipsize = Pango.EllipsizeMode.END;
-
- command_renderer_uri.edited.connect((path, uri) => {
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.DISPLAY_COMMAND_URI, uri);
-
- this.update_pie(data_iter);
- });
-
- command_column.pack_end(command_renderer_uri, true);
- command_column.add_attribute(command_renderer_uri, "weight", DataPos.FONT_WEIGHT);
- command_column.add_attribute(command_renderer_uri, "text", DataPos.DISPLAY_COMMAND_URI);
- command_column.add_attribute(command_renderer_uri, "visible", DataPos.URI_VISIBLE);
-
-
- // type column
- var type_column = new Gtk.TreeViewColumn();
- type_column.title = _("Pie-ID / Action type");
- type_column.resizable = true;
- type_column.expand = false;
-
- var type_render = new Gtk.CellRendererCombo();
- type_render.editable = true;
- type_render.has_entry = false;
- type_render.model = actions;
- type_render.text_column = 0;
- type_render.ellipsize = Pango.EllipsizeMode.END;
-
- // change command_render's visibility accordingly
- type_render.changed.connect((path, iter) => {
- string text = "";
- string type;
- bool can_quickaction;
- bool icon_name_editable;
-
- this.actions.get(iter, ActionPos.NAME, out text);
- this.actions.get(iter, ActionPos.TYPE, out type);
- this.actions.get(iter, ActionPos.CAN_QUICKACTION, out can_quickaction);
- this.actions.get(iter, ActionPos.ICON_NAME_EDITABLE, out icon_name_editable);
-
- Gtk.TreeIter data_iter;
- this.data.get_iter_from_string(out data_iter, path);
-
- this.data.set(data_iter, DataPos.TYPE_ID, text);
- this.data.set(data_iter, DataPos.ACTION_TYPE, type);
- this.data.set(data_iter, DataPos.QUICKACTION_ACTIVATABLE, can_quickaction);
- this.data.set(data_iter, DataPos.ICON_NAME_EDITABLE, icon_name_editable);
-
- // set all command renderes invisible
- this.data.set(data_iter, DataPos.GROUP_VISIBLE, false);
- this.data.set(data_iter, DataPos.APP_VISIBLE, false);
- this.data.set(data_iter, DataPos.KEY_VISIBLE, false);
- this.data.set(data_iter, DataPos.PIE_VISIBLE, false);
- this.data.set(data_iter, DataPos.URI_VISIBLE, false);
-
- // set one visible
- int type_id = 0;
- if(type == typeof(AppAction).name()) type_id = 1;
- else if(type == typeof(KeyAction).name()) type_id = 2;
- else if(type == typeof(PieAction).name()) type_id = 3;
- else if(type == typeof(UriAction).name()) type_id = 4;
- else type_id = 0;
-
- this.data.set(data_iter, DataPos.GROUP_VISIBLE + type_id, true);
-
- this.update_linked();
- this.update_pie(data_iter);
-
- //this.set_cursor(new Gtk.TreePath.from_string(path), command_column, true);
- });
-
- type_column.pack_start(type_render, true);
- type_column.add_attribute(type_render, "sensitive", DataPos.TYPE_VISIBLE);
- type_column.add_attribute(type_render, "editable", DataPos.TYPE_VISIBLE);
- type_column.add_attribute(type_render, "text", DataPos.TYPE_ID);
-
- // name column
- var name_column = new Gtk.TreeViewColumn();
- name_column.title = _("Name");
- name_column.expand = true;
- name_column.resizable = true;
+ var main_column = new Gtk.TreeViewColumn();
+ var icon_render = new Gtk.CellRendererPixbuf();
+ icon_render.xpad = 4;
+ icon_render.ypad = 4;
+ main_column.pack_start(icon_render, false);
var name_render = new Gtk.CellRendererText();
- name_render.editable = true;
name_render.ellipsize = Pango.EllipsizeMode.END;
-
- name_render.edited.connect((path, text) => {
- Gtk.TreeIter iter;
- this.data.get_iter_from_string(out iter, path);
-
- this.data.set(iter, DataPos.NAME, text);
-
- // try to change icon to a fitting one
- string icon;
- this.data.get(iter, DataPos.ICON, out icon);
- if (icon == "application-default-icon" && Gtk.IconTheme.get_default().has_icon(text.down())) {
- this.data.set(iter, DataPos.ICON, text.down());
- }
-
- this.update_pie(iter);
- this.update_linked();
-
- //this.set_cursor(new Gtk.TreePath.from_string(path), type_column, true);
- });
-
- name_column.pack_start(name_render, true);
- name_column.add_attribute(name_render, "weight", DataPos.FONT_WEIGHT);
- name_column.add_attribute(name_render, "text", DataPos.NAME);
- name_column.add_attribute(name_render, "sensitive", DataPos.ICON_NAME_EDITABLE);
- name_column.add_attribute(name_render, "editable", DataPos.ICON_NAME_EDITABLE);
-
- this.append_column(icon_column);
- this.append_column(name_column);
- this.append_column(type_column);
- this.append_column(command_column);
+ name_render.ellipsize_set = true;
+ main_column.pack_start(name_render, true);
- this.realize.connect(this.load);
-
- // context menu
- var menu = new Gtk.Menu();
-
- var item = new Gtk.ImageMenuItem.with_label(_("Add new Pie"));
- item.set_image(new Gtk.Image.from_stock(Gtk.Stock.ADD, Gtk.IconSize.MENU));
- item.activate.connect(this.add_empty_pie);
- menu.append(item);
-
- item = new Gtk.ImageMenuItem.with_label(_("Add new Slice"));
- item.set_image(new Gtk.Image.from_stock(Gtk.Stock.ADD, Gtk.IconSize.MENU));
- item.activate.connect(this.add_empty_slice);
- menu.append(item);
-
- var sepa = new Gtk.SeparatorMenuItem();
- menu.append(sepa);
-
- item = new Gtk.ImageMenuItem.with_label(_("Delete"));
- item.set_image(new Gtk.Image.from_stock(Gtk.Stock.DELETE, Gtk.IconSize.MENU));
- item.activate.connect(this.delete_selection);
- menu.append(item);
+ base.append_column(main_column);
- menu.show_all();
-
- this.button_press_event.connect((event) => {
- if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) {
- menu.popup(null, null, null, event.button, event.time);
- }
- return false;
- });
+ main_column.add_attribute(icon_render, "pixbuf", DataPos.ICON);
+ main_column.add_attribute(name_render, "markup", DataPos.NAME);
// setup drag'n'drop
Gtk.TargetEntry uri_source = {"text/uri-list", 0, 0};
Gtk.TargetEntry[] entries = { uri_source };
-
- this.drag_data_received.connect(this.on_dnd_received);
- this.drag_data_get.connect(this.on_dnd_source);
+ this.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, entries, Gdk.DragAction.LINK);
this.enable_model_drag_dest(entries, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK);
+ this.drag_data_get.connect(this.on_dnd_source);
+ this.drag_begin.connect_after(this.on_start_drag);
+ this.drag_motion.connect(this.on_drag_move);
+ this.drag_leave.connect(() => {
+ this.last_hover = 0;
+ });
this.get_selection().changed.connect(() => {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- if (this.data.iter_depth(selected) == 0) {
- this.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, entries, Gdk.DragAction.LINK);
- } else {
- this.unset_rows_drag_source();
- }
+ Gtk.TreeIter active;
+ if (this.get_selection().get_selected(null, out active)) {
+ string id = "";
+ this.data.get(active, DataPos.ID, out id);
+ this.on_select(id);
}
});
- this.drag_begin.connect(() => {
- this.unset_rows_drag_dest();
- });
-
- this.drag_end.connect(() => {
- this.enable_model_drag_dest(entries, Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK);
- });
+ reload_all();
}
- // moves the selected slice up
- public void selection_up() {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- Gtk.TreePath path = this.data.get_path(selected);
- Gtk.TreeIter? before = null;;
- if (path.prev() && this.data.get_iter(out before, path)) {
- this.data.swap(selected, before);
- this.get_selection().changed();
- this.update_pie(selected);
- }
- }
- }
+ /////////////////////////////////////////////////////////////////////
+ /// Loads all existing Pies to the list.
+ /////////////////////////////////////////////////////////////////////
- // moves the selected slice down
- public void selection_down() {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- Gtk.TreePath path = this.data.get_path(selected);
- Gtk.TreeIter? after = null;
- path.next();
- if (this.data.get_iter(out after, path)) {
- this.data.swap(selected, after);
- this.get_selection().changed();
- this.update_pie(selected);
- }
- }
- }
+ public void reload_all() {
+ Gtk.TreeIter active;
+ string id = "";
+ if (this.get_selection().get_selected(null, out active))
+ this.data.get(active, DataPos.ID, out id);
- // updates the entire list, checking for changed cross-references via PieActions
- // updates their names and icons if needed
- private void update_linked() {
- this.data.foreach((model, path, iter) => {
- string action_type;
- this.data.get(iter, DataPos.ACTION_TYPE, out action_type);
-
- if (action_type == typeof(PieAction).name()) {
- string command;
- this.data.get(iter, DataPos.REAL_COMMAND_PIE, out command);
-
- var referee = PieManager.all_pies[command];
-
- if (referee != null) {
- this.data.set(iter, DataPos.ICON, referee.icon);
- this.data.set(iter, DataPos.NAME, referee.name);
- this.data.set(iter, DataPos.ICON_PIXBUF, this.load_icon(referee.icon, this.small_icon));
- this.data.set(iter, DataPos.DISPLAY_COMMAND_PIE, referee.name);
- } else {
- // referenced Pie does not exist anymore or no is selected;
- // select the first one...
- Gtk.TreeIter first_pie;
- this.pies.get_iter_first(out first_pie);
-
- string name;
- string id;
-
- this.pies.get(first_pie, PiePos.NAME, out name);
- this.pies.get(first_pie, PiePos.ID, out id);
-
- this.data.set(iter, DataPos.DISPLAY_COMMAND_PIE, name);
- this.data.set(iter, DataPos.REAL_COMMAND_PIE, id);
-
- update_linked();
- }
- } else if (action_type == typeof(ActionGroup).name()) {
- string command;
- this.data.get(iter, DataPos.REAL_COMMAND_GROUP, out command);
-
- if (command == "") {
- // no group is selected, select the first one...
- Gtk.TreeIter first_group;
- this.groups.get_iter_first(out first_group);
-
- string name;
- string type;
- string icon;
-
- this.groups.get(first_group, GroupPos.NAME, out name);
- this.groups.get(first_group, GroupPos.TYPE, out type);
- this.groups.get(first_group, GroupPos.ICON, out icon);
-
- this.data.set(iter, DataPos.DISPLAY_COMMAND_GROUP, name);
- this.data.set(iter, DataPos.NAME, name);
- this.data.set(iter, DataPos.REAL_COMMAND_GROUP, type);
- this.data.set(iter, DataPos.ICON, icon);
- }
- }
-
- return false;
- });
+ data.clear();
+ foreach (var pie in PieManager.all_pies.entries) {
+ this.load_pie(pie.value);
+ }
+
+ select(id);
}
- // adds a new, empty pie to the list
- private void add_empty_pie() {
- var new_one = PieManager.create_persistent_pie(_("New Pie"), "application-default-icon", null);
-
- Gtk.TreeIter last;
- this.pies.append(out last); this.pies.set(last, 0, new_one.name, 1, new_one.id);
+ /////////////////////////////////////////////////////////////////////
+ /// Selects the first Pie.
+ /////////////////////////////////////////////////////////////////////
- Gtk.TreeIter parent;
- this.data.append(out parent, null);
- this.data.set(parent, DataPos.IS_QUICKACTION, false,
- DataPos.ICON, new_one.icon,
- DataPos.NAME, new_one.name,
- DataPos.TYPE_ID, "ID: " + new_one.id,
- DataPos.ACTION_TYPE, new_one.id,
- DataPos.ICON_PIXBUF, this.load_icon(new_one.icon, this.large_icon),
- DataPos.FONT_WEIGHT, 800,
- DataPos.ICON_NAME_EDITABLE, true,
- DataPos.QUICKACTION_VISIBLE, false,
- DataPos.QUICKACTION_ACTIVATABLE, false,
- DataPos.TYPE_VISIBLE, false,
- DataPos.GROUP_VISIBLE, false,
- DataPos.APP_VISIBLE, false,
- DataPos.KEY_VISIBLE, false,
- DataPos.PIE_VISIBLE, false,
- DataPos.URI_VISIBLE, false,
- DataPos.TRIGGER_VISIBLE, true,
- DataPos.DISPLAY_COMMAND_GROUP, "",
- DataPos.DISPLAY_COMMAND_APP, "",
- DataPos.DISPLAY_COMMAND_KEY, PieManager.get_accelerator_label_of(new_one.id),
- DataPos.DISPLAY_COMMAND_PIE, "",
- DataPos.DISPLAY_COMMAND_URI, "",
- DataPos.REAL_COMMAND_GROUP, "",
- DataPos.REAL_COMMAND_PIE, "",
- DataPos.REAL_COMMAND_KEY, PieManager.get_accelerator_of(new_one.id));
-
+ public void select_first() {
+ Gtk.TreeIter active;
- this.get_selection().select_iter(parent);
- this.scroll_to_cell(this.data.get_path(parent), null, true, 0.5f, 0.0f);
- }
-
- // adds a new empty slice to the list
- private void add_empty_slice() {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- var path = this.data.get_path(selected);
- if (path != null) {
- if (path.get_depth() == 2)
- this.data.iter_parent(out selected, selected);
-
- this.load_action(selected, new AppAction(_("New Action"), "application-default-icon", ""));
-
- Gtk.TreeIter new_one;
- this.data.iter_nth_child(out new_one, selected, this.data.iter_n_children(selected)-1);
- this.expand_to_path(this.data.get_path(new_one));
- this.get_selection().select_iter(new_one);
- this.scroll_to_cell(this.data.get_path(new_one), null, true, 0.5f, 0.0f);
-
- this.update_pie(selected);
- }
+ if(this.data.get_iter_first(out active) ) {
+ this.get_selection().select_iter(active);
+ string id = "";
+ this.data.get(active, DataPos.ID, out id);
+ this.on_select(id);
} else {
- var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
- Gtk.MessageType.INFO,
- Gtk.ButtonsType.CLOSE,
- _("You have to select a Pie to add a Slice to!"));
- dialog.run();
- dialog.destroy();
+ this.on_select("");
}
}
- // writes the contents of action to the position pointed by slice
- private void write_action(Action action, Gtk.TreeIter slice) {
- this.data.set(slice, DataPos.IS_QUICKACTION, action.is_quick_action,
- DataPos.ICON, action.icon,
- DataPos.NAME, action.name,
- DataPos.TYPE_ID, ActionRegistry.names[action.get_type()],
- DataPos.ACTION_TYPE, action.get_type().name(),
- DataPos.ICON_PIXBUF, this.load_icon(action.icon, this.small_icon),
- DataPos.FONT_WEIGHT, 400,
- DataPos.ICON_NAME_EDITABLE, !(action is PieAction),
- DataPos.QUICKACTION_VISIBLE, true,
- DataPos.QUICKACTION_ACTIVATABLE, true,
- DataPos.TYPE_VISIBLE, true,
- DataPos.GROUP_VISIBLE, false,
- DataPos.TRIGGER_VISIBLE, false,
- DataPos.APP_VISIBLE, action is AppAction,
- DataPos.KEY_VISIBLE, action is KeyAction,
- DataPos.PIE_VISIBLE, action is PieAction,
- DataPos.URI_VISIBLE, action is UriAction,
- DataPos.DISPLAY_COMMAND_GROUP, "",
- DataPos.DISPLAY_COMMAND_APP, (action is AppAction) ? action.display_command : "",
- DataPos.DISPLAY_COMMAND_KEY, (action is KeyAction) ? action.display_command : _("Not bound"),
- DataPos.DISPLAY_COMMAND_PIE, (action is PieAction) ? action.display_command : "",
- DataPos.DISPLAY_COMMAND_URI, (action is UriAction) ? action.display_command : "",
- DataPos.REAL_COMMAND_GROUP, "",
- DataPos.REAL_COMMAND_PIE, (action is PieAction) ? action.real_command : "",
- DataPos.REAL_COMMAND_KEY, (action is KeyAction) ? action.real_command : "");
- }
+ /////////////////////////////////////////////////////////////////////
+ /// Selects the Pie with the given ID.
+ /////////////////////////////////////////////////////////////////////
- // deletes the currently selected pie or slice
- private void delete_selection() {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- var path = this.data.get_path(selected);
- if (path != null) {
- if (path.get_depth() == 1)
- this.delete_pie(selected);
- else
- this.delete_slice(selected);
- }
- } else {
- var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
- Gtk.MessageType.INFO,
- Gtk.ButtonsType.CLOSE,
- _("You have to select a Pie or a Slice to delete!"));
- dialog.run();
- dialog.destroy();
- }
- }
-
- // deletes the given pie
- private void delete_pie(Gtk.TreeIter pie) {
- var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
- Gtk.MessageType.QUESTION,
- Gtk.ButtonsType.YES_NO,
- _("Do you really want to delete the selected Pie with all contained Slices?"));
-
- dialog.response.connect((response) => {
- if (response == Gtk.ResponseType.YES) {
- string id;
- this.data.get(pie, DataPos.ACTION_TYPE, out id);
- this.data.remove(pie);
- PieManager.remove_pie(id);
-
- this.pies.foreach((model, path, iter) => {
- string pies_id;
- this.pies.get(iter, PiePos.ID, out pies_id);
-
- if (id == pies_id) {
- this.pies.remove(iter);
- return true;
- }
-
- return false;
- });
-
- this.update_linked();
- }
- });
-
- dialog.run();
- dialog.destroy();
- }
-
- // deletes the given slice
- private void delete_slice(Gtk.TreeIter slice) {
- var dialog = new Gtk.MessageDialog((Gtk.Window)this.get_toplevel(), Gtk.DialogFlags.MODAL,
- Gtk.MessageType.QUESTION,
- Gtk.ButtonsType.YES_NO,
- _("Do you really want to delete the selected Slice?"));
-
- dialog.response.connect((response) => {
- if (response == Gtk.ResponseType.YES) {
- Gtk.TreeIter parent;
- this.data.iter_parent(out parent, slice);
- this.data.remove(slice);
- this.update_pie(parent);
+ public void select(string id) {
+ this.data.foreach((model, path, iter) => {
+ string pie_id;
+ this.data.get(iter, DataPos.ID, out pie_id);
+
+ if (id == pie_id) {
+ this.get_selection().select_iter(iter);
+ return true;
}
+
+ return false;
});
-
- dialog.run();
- dialog.destroy();
}
- // loads all pies to the list
- private void load() {
- foreach (var pie in PieManager.all_pies.entries) {
- this.load_pie(pie.value);
- }
- }
+ /////////////////////////////////////////////////////////////////////
+ /// Loads one given pie to the list.
+ /////////////////////////////////////////////////////////////////////
- // loads one given pie to the list
private void load_pie(Pie pie) {
if (pie.id.length == 3) {
-
Gtk.TreeIter last;
- this.pies.append(out last); this.pies.set(last, PiePos.NAME, pie.name,
- PiePos.ID, pie.id);
-
- Gtk.TreeIter parent;
- this.data.append(out parent, null);
- this.data.set(parent, DataPos.IS_QUICKACTION, false,
- DataPos.ICON, pie.icon,
- DataPos.NAME, pie.name,
- DataPos.TYPE_ID, "ID: " + pie.id,
- DataPos.ACTION_TYPE, pie.id,
- DataPos.ICON_PIXBUF, this.load_icon(pie.icon, this.large_icon),
- DataPos.FONT_WEIGHT, 800,
- DataPos.ICON_NAME_EDITABLE, true,
- DataPos.QUICKACTION_VISIBLE, false,
- DataPos.QUICKACTION_ACTIVATABLE, false,
- DataPos.TYPE_VISIBLE, false,
- DataPos.GROUP_VISIBLE, false,
- DataPos.APP_VISIBLE, false,
- DataPos.KEY_VISIBLE, false,
- DataPos.PIE_VISIBLE, false,
- DataPos.URI_VISIBLE, false,
- DataPos.TRIGGER_VISIBLE, true,
- DataPos.DISPLAY_COMMAND_GROUP, "",
- DataPos.DISPLAY_COMMAND_APP, "",
- DataPos.DISPLAY_COMMAND_KEY, PieManager.get_accelerator_label_of(pie.id),
- DataPos.DISPLAY_COMMAND_PIE, "",
- DataPos.DISPLAY_COMMAND_URI, "",
- DataPos.REAL_COMMAND_GROUP, "",
- DataPos.REAL_COMMAND_PIE, "",
- DataPos.REAL_COMMAND_KEY, PieManager.get_accelerator_of(pie.id));
-
- foreach (var group in pie.action_groups) {
- this.load_group(parent, group);
- }
+ this.data.append(out last);
+ var icon = new Icon(pie.icon, 24);
+ this.data.set(last, DataPos.ICON, icon.to_pixbuf(),
+ DataPos.ICON_NAME, pie.icon,
+ DataPos.NAME, pie.name,
+ DataPos.ID, pie.id);
}
}
- // loads a given group
- private void load_group(Gtk.TreeIter parent, ActionGroup group) {
- if (group.get_type() == typeof(ActionGroup)) {
- foreach (var action in group.actions) {
- this.load_action(parent, action);
- }
- } else {
- Gtk.TreeIter child;
- this.data.append(out child, parent);
- this.data.set(child, DataPos.IS_QUICKACTION, false,
- DataPos.ICON, GroupRegistry.icons[group.get_type()],
- DataPos.NAME, GroupRegistry.names[group.get_type()],
- DataPos.TYPE_ID, _("Slice group"),
- DataPos.ACTION_TYPE, typeof(ActionGroup).name(),
- DataPos.ICON_PIXBUF, this.load_icon(GroupRegistry.icons[group.get_type()], this.small_icon),
- DataPos.FONT_WEIGHT, 400,
- DataPos.ICON_NAME_EDITABLE, false,
- DataPos.QUICKACTION_VISIBLE, true,
- DataPos.QUICKACTION_ACTIVATABLE, false,
- DataPos.TYPE_VISIBLE, true,
- DataPos.GROUP_VISIBLE, true,
- DataPos.APP_VISIBLE, false,
- DataPos.KEY_VISIBLE, false,
- DataPos.PIE_VISIBLE, false,
- DataPos.URI_VISIBLE, false,
- DataPos.TRIGGER_VISIBLE, false,
- DataPos.DISPLAY_COMMAND_GROUP, GroupRegistry.names[group.get_type()],
- DataPos.DISPLAY_COMMAND_APP, "",
- DataPos.DISPLAY_COMMAND_KEY, _("Not bound"),
- DataPos.DISPLAY_COMMAND_PIE, "",
- DataPos.DISPLAY_COMMAND_URI, "",
- DataPos.REAL_COMMAND_GROUP, group.get_type().name(),
- DataPos.REAL_COMMAND_PIE, "",
- DataPos.REAL_COMMAND_KEY, "");
+ /////////////////////////////////////////////////////////////////////
+ /// Called when a drag which started on this Widget was successfull.
+ /////////////////////////////////////////////////////////////////////
+
+ private void on_dnd_source(Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_) {
+ if (this.drag_start != null) {
+ string id = "";
+ this.data.get(this.drag_start, DataPos.ID, out id);
+ selection_data.set_uris({"file://" + Paths.launchers + "/" + id + ".desktop"});
}
}
- // loads a given slice
- private void load_action(Gtk.TreeIter parent, Action action) {
- Gtk.TreeIter child;
- this.data.append(out child, parent);
- this.write_action(action, child);
- }
+ /////////////////////////////////////////////////////////////////////
+ /// Called when a drag operation is started on this Widget.
+ /////////////////////////////////////////////////////////////////////
- // applies all changes done to the given pie
- private void update_pie(Gtk.TreeIter slice_or_pie) {
- // get pie iter
- var path = this.data.get_path(slice_or_pie);
- if (path != null) {
- var pie = slice_or_pie;
- if (path.get_depth() == 2)
- this.data.iter_parent(out pie, slice_or_pie);
+ private void on_start_drag(Gdk.DragContext ctx) {
+ if (this.get_selection().get_selected(null, out this.drag_start)) {
+ string icon_name = "";
+ this.data.get(this.drag_start, DataPos.ICON_NAME, out icon_name);
- // get information on pie
- string id;
- string icon;
- string name;
- string hotkey;
-
- this.data.get(pie, DataPos.ICON, out icon);
- this.data.get(pie, DataPos.NAME, out name);
- this.data.get(pie, DataPos.ACTION_TYPE, out id);
- this.data.get(pie, DataPos.REAL_COMMAND_KEY, out hotkey);
-
- // remove pie
- PieManager.remove_pie(id);
-
- this.pies.foreach((model, path, iter) => {
- string pies_id;
- this.pies.get(iter, PiePos.ID, out pies_id);
-
- if (id == pies_id) {
- this.pies.set(iter, PiePos.NAME, name);
- return true;
- }
-
- return false;
- });
-
- // create new pie
- var new_pie = PieManager.create_persistent_pie(name, icon, new Trigger.from_string(hotkey), id);
-
- // add actions accordingly
- if (this.data.iter_has_child(pie)) {
- Gtk.TreeIter child;
- this.data.iter_children(out child, pie);
-
- do {
- // get slice information
- string slice_type;
- string slice_icon;
- string slice_name;
- bool is_quick_action;
-
- this.data.get(child, DataPos.ICON, out slice_icon);
- this.data.get(child, DataPos.NAME, out slice_name);
- this.data.get(child, DataPos.ACTION_TYPE, out slice_type);
- this.data.get(child, DataPos.IS_QUICKACTION, out is_quick_action);
-
- if (slice_type == typeof(AppAction).name()) {
- string slice_command;
- this.data.get(child, DataPos.DISPLAY_COMMAND_APP, out slice_command);
- var group = new ActionGroup(new_pie.id);
- group.add_action(new AppAction(slice_name, slice_icon, slice_command, is_quick_action));
- new_pie.add_group(group);
- } else if (slice_type == typeof(KeyAction).name()) {
- string slice_command;
- this.data.get(child, DataPos.REAL_COMMAND_KEY, out slice_command);
- var group = new ActionGroup(new_pie.id);
- group.add_action(new KeyAction(slice_name, slice_icon, slice_command, is_quick_action));
- new_pie.add_group(group);
- } else if (slice_type == typeof(PieAction).name()) {
- string slice_command;
- this.data.get(child, DataPos.REAL_COMMAND_PIE, out slice_command);
- var group = new ActionGroup(new_pie.id);
- group.add_action(new PieAction(slice_command, is_quick_action));
- new_pie.add_group(group);
- } else if (slice_type == typeof(UriAction).name()) {
- string slice_command;
- this.data.get(child, DataPos.DISPLAY_COMMAND_URI, out slice_command);
- var group = new ActionGroup(new_pie.id);
- group.add_action(new UriAction(slice_name, slice_icon, slice_command, is_quick_action));
- new_pie.add_group(group);
- } else if (slice_type == typeof(ActionGroup).name()) {
- string slice_command;
- this.data.get(child, DataPos.REAL_COMMAND_GROUP, out slice_command);
-
- var group = GLib.Object.new(GLib.Type.from_name(slice_command), "parent_id", new_pie.id);
- new_pie.add_group(group as ActionGroup);
- }
-
- } while (this.data.iter_next(ref child));
- }
- }
+ var icon = new Icon(icon_name, 48);
+ var pixbuf = icon.to_pixbuf();
+ Gtk.drag_set_icon_pixbuf(ctx, pixbuf, icon.size()/2, icon.size()/2);
+ }
}
- // creates new action when the list receives a drag'n'drop event
- private void on_dnd_received(Gdk.DragContext context, int x, int y, Gtk.SelectionData selection_data, uint info, uint time_) {
- string[] uris = selection_data.get_uris();
-
+ /////////////////////////////////////////////////////////////////////
+ /// Called when something is dragged over this Widget.
+ /////////////////////////////////////////////////////////////////////
+
+ private bool on_drag_move(Gdk.DragContext context, int x, int y, uint time) {
+
+ Gtk.TreeViewDropPosition position;
Gtk.TreePath path;
- Gtk.TreeViewDropPosition pos;
- // check for valid position
- if (!this.get_dest_row_at_pos(x, y, out path, out pos)
- || (path.to_string() == "0" && pos == Gtk.TreeViewDropPosition.BEFORE)) {
-
- warning("Failed to insert Slice: Invalid location!");
- return;
- }
-
- // get position to insert (when child: after, when parent: as first child)
- Gtk.TreeIter parent;
- int insert_pos = 0;
- if (path.get_depth() == 1) {
- if (pos == Gtk.TreeViewDropPosition.BEFORE) {
- path.prev();
- this.data.get_iter(out parent, path);
- insert_pos = this.data.iter_n_children(parent);
- } else {
- this.data.get_iter(out parent, path);
- }
- } else {
- if (pos == Gtk.TreeViewDropPosition.BEFORE) {
- insert_pos = path.get_indices()[1];
- } else {
- insert_pos = path.get_indices()[1]+1;
- }
-
- path.up();
- this.data.get_iter(out parent, path);
- }
+ if (!this.get_dest_row_at_pos(x, y, out path, out position))
+ return false;
- foreach (var uri in uris) {
- Gtk.TreeIter new_child;
- this.data.insert(out new_child, parent, insert_pos);
- this.write_action(ActionRegistry.new_for_uri(uri), new_child);
- }
+ if (position == Gtk.TreeViewDropPosition.BEFORE)
+ this.set_drag_dest_row(path, Gtk.TreeViewDropPosition.INTO_OR_BEFORE);
+ else if (position == Gtk.TreeViewDropPosition.AFTER)
+ this.set_drag_dest_row(path, Gtk.TreeViewDropPosition.INTO_OR_AFTER);
+
+ Gdk.drag_status(context, context.get_suggested_action(), time);
- this.update_pie(parent);
- }
-
- private void on_dnd_source(Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_) {
- Gtk.TreeIter selected;
- if (this.get_selection().get_selected(null, out selected)) {
- string id = "";
- this.data.get(selected, DataPos.ACTION_TYPE, out id);
- selection_data.set_uris({"file://" + Paths.launchers + "/" + id + ".desktop"});
- }
- }
-
- private Gdk.Pixbuf load_icon(string name, int size) {
- Gdk.Pixbuf pixbuf = null;
+ // avoid too frequent selection...
+ this.last_hover = time;
- try {
- if (name.contains("/"))
- pixbuf = new Gdk.Pixbuf.from_file_at_size(name, size, size);
- else
- pixbuf = new Gdk.Pixbuf.from_file_at_size(Icon.get_icon_file(name, size), size, size);
- } catch (GLib.Error e) {
- warning(e.message);
- }
+ GLib.Timeout.add(150, () => {
+ if (this.last_hover == time)
+ this.get_selection().select_path(path);
+ return false;
+ });
- return pixbuf;
+ return true;
}
}