diff options
Diffstat (limited to 'src/actionGroups/clipboardGroup.vala')
-rw-r--r-- | src/actionGroups/clipboardGroup.vala | 124 |
1 files changed, 99 insertions, 25 deletions
diff --git a/src/actionGroups/clipboardGroup.vala b/src/actionGroups/clipboardGroup.vala index ad18740..58409de 100644 --- a/src/actionGroups/clipboardGroup.vala +++ b/src/actionGroups/clipboardGroup.vala @@ -25,34 +25,78 @@ namespace GnomePie { public class ClipboardGroup : ActionGroup { ///////////////////////////////////////////////////////////////////// - /// - ///////////////////////////////////////////////////////////////////// private class ClipboardItem : GLib.Object { - public string name { get; private set; } - public string icon { get; private set; } + public string name { get; protected set; } + public string icon { get; protected set; } + + protected Gtk.Clipboard clipboard { get; set; } + protected static Key paste_key = new Key.from_string("<Control>v"); + + public virtual void paste() {} + } - private Gtk.SelectionData contents; + ///////////////////////////////////////////////////////////////////// - public ClipboardItem(Gtk.SelectionData contents) { - this.contents = contents.copy(); - this.name = this.contents.get_text() ?? ""; - this.icon = "edit-paste"; + private class TextClipboardItem : ClipboardItem { + + public TextClipboardItem(Gtk.Clipboard clipboard) { + GLib.Object(clipboard : clipboard, + name : clipboard.wait_for_text(), + icon : "edit-paste"); + + // check whether a file has been copied and search for a cool icon + var first_line = this.name.substring(0, this.name.index_of("\n")); + var file = GLib.File.new_for_path(first_line); + + if (file.query_exists()) { + try { + var info = file.query_info("standard::icon", 0); + this.icon = Icon.get_icon_name(info.get_icon()); + } catch (Error e) { + warning("Failed to generate icon for ClipboardGroupItem."); + } + } } - public void paste() { - debug(name); + public override void paste() { + clipboard.set_text(name, name.length); + paste_key.press(); } } - public ClipboardGroup(string parent_id) { - GLib.Object(parent_id : parent_id); + ///////////////////////////////////////////////////////////////////// + + private class ImageClipboardItem : ClipboardItem { + + private Gdk.Pixbuf image { get; set; } + + public ImageClipboardItem(Gtk.Clipboard clipboard) { + GLib.Object(clipboard : clipboard, + name : _("Image data"), + icon : "image-viewer"); + this.image = clipboard.wait_for_image(); + } + + public override void paste() { + clipboard.set_image(image); + paste_key.press(); + } } ///////////////////////////////////////////////////////////////////// + /// The maximum remembered items of the clipboard. + ///////////////////////////////////////////////////////////////////// + + public int max_items {get; set; default=8; } + ///////////////////////////////////////////////////////////////////// + public ClipboardGroup(string parent_id) { + GLib.Object(parent_id : parent_id); + } + ///////////////////////////////////////////////////////////////////// /// Used to register this type of ActionGroup. It sets the display /// name for this ActionGroup, it's icon name and the string used in @@ -74,12 +118,7 @@ public class ClipboardGroup : ActionGroup { private Gtk.Clipboard clipboard; - - ///////////////////////////////////////////////////////////////////// - /// The maximum remembered items of the clipboard. - ///////////////////////////////////////////////////////////////////// - - private static const int max_items = 6; + private bool ignore_next_change = false; private Gee.ArrayList<ClipboardItem?> items; @@ -89,26 +128,61 @@ public class ClipboardGroup : ActionGroup { this.clipboard.owner_change.connect(this.on_change); } + ///////////////////////////////////////////////////////////////////// + /// This one is called, when the ActionGroup is saved. + ///////////////////////////////////////////////////////////////////// + + public override void on_save(Xml.TextWriter writer) { + base.on_save(writer); + writer.write_attribute("max_items", this.max_items.to_string()); + } + + ///////////////////////////////////////////////////////////////////// + /// This one is called, when the ActionGroup is loaded. + ///////////////////////////////////////////////////////////////////// + + public override void on_load(Xml.Node* data) { + for (Xml.Attr* attribute = data->properties; attribute != null; attribute = attribute->next) { + string attr_name = attribute->name.down(); + string attr_content = attribute->children->content; + + if (attr_name == "max_items") { + this.max_items = int.parse(attr_content); + } + } + } + private void on_change() { + if (ignore_next_change) { + ignore_next_change = false; + return; + } + if (this.clipboard.wait_is_text_available()) { - this.clipboard.request_contents(Gdk.Atom.intern("text/plain", false), this.add_item); + if (clipboard.wait_for_text() != null) { + add_item(new TextClipboardItem(this.clipboard)); + } + } else if (this.clipboard.wait_is_image_available()) { + add_item(new ImageClipboardItem(this.clipboard)); } } - private void add_item(Gtk.Clipboard c, Gtk.SelectionData contents) { - var new_item = new ClipboardItem(contents); + private void add_item(ClipboardItem item) { - if (this.items.size == ClipboardGroup.max_items) + // remove one item if there are too many + if (this.items.size == this.max_items) { this.items.remove_at(0); + } - this.items.add(new_item); + this.items.add(item); // update slices this.delete_all(); - for (int i=0; i<this.items.size; ++i) { + for (int i=this.items.size-1; i>=0; --i) { var action = new SigAction(items[i].name, items[i].icon, i.to_string()); action.activated.connect(() => { + ignore_next_change = true; this.items[int.parse(action.real_command)].paste(); }); this.add_action(action); |