~artem-anufrij/scratch/improve-split-view

« back to all changes in this revision

Viewing changes to plugins/clipboard-history/ClipboardHistory.vala

  • Committer: artem-anufrij
  • Date: 2014-12-07 16:37:18 UTC
  • mfrom: (1421.2.5 scratch)
  • Revision ID: artem-anufrij-20141207163718-iiky9875sfdiyph3
dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
/***
 
3
  BEGIN LICENSE
 
4
    
 
5
  Copyright (C) 2014 Artem Anufrij <artem.anufrij@live.de>
 
6
  This program is free software: you can redistribute it and/or modify it   
 
7
  under the terms of the GNU Lesser General Public License version 3, as published  
 
8
  by the Free Software Foundation.
 
9
    
 
10
  This program is distributed in the hope that it will be useful, but   
 
11
  WITHOUT ANY WARRANTY; without even the implied warranties of  
 
12
  MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR    
 
13
  PURPOSE.  See the GNU General Public License for more details.
 
14
    
 
15
  You should have received a copy of the GNU General Public License along   
 
16
  with this program.  If not, see <http://www.gnu.org/licenses/>    
 
17
  
 
18
  END LICENSE   
 
19
***/
 
20
 
 
21
public const string NAME = N_("Clipboard History");
 
22
public const string DESCRIPTION = N_("Clipboard to view history");
 
23
 
 
24
public class Scratch.Plugins.ClipboardHistory : Peas.ExtensionBase,  Peas.Activatable {
 
25
 
 
26
    const int MAX_SIZE = 32;
 
27
    const int MAX_LINE_LENGTH = 24;
 
28
    const string DOTS = _("...");
 
29
    MainWindow window = null;
 
30
    Gtk.Notebook? contextbar = null;
 
31
 
 
32
    Gtk.ScrolledWindow scrolled;
 
33
    Gtk.ListStore list_store;
 
34
    Gtk.TreeIter iter;
 
35
    Gtk.TreeView view;
 
36
 
 
37
    Gtk.Menu menu;
 
38
    Gtk.MenuItem menu_paste;
 
39
    Gtk.MenuItem menu_delete;
 
40
 
 
41
    Scratch.Services.Interface plugins;
 
42
    public Object object { owned get; construct; }
 
43
 
 
44
    public void update_state () {
 
45
    }
 
46
 
 
47
    public void activate () {
 
48
        debug ("-- %s avtivate", NAME);
 
49
 
 
50
        plugins = (Scratch.Services.Interface) object;
 
51
        
 
52
        plugins.hook_window.connect ((w) => {
 
53
            if(window != null)
 
54
                return;
 
55
 
 
56
            window = w;
 
57
            window.clipboard.owner_change.connect (clipboard_action);
 
58
        });
 
59
 
 
60
        plugins.hook_notebook_context.connect ((n) => { 
 
61
            if (contextbar == null) {
 
62
                this.contextbar = n;
 
63
 
 
64
                build_plugin_ui ();
 
65
            }
 
66
        });
 
67
    }
 
68
 
 
69
    public void deactivate () {
 
70
        debug ("-- %s deavtivate", NAME);
 
71
 
 
72
        contextbar.remove_page (contextbar.page_num (scrolled));
 
73
 
 
74
        window.clipboard.owner_change.disconnect (clipboard_action);
 
75
    }
 
76
 
 
77
    void clipboard_action(Gdk.Event event) {
 
78
        string? clipboard_content = window.clipboard.wait_for_text ();
 
79
        if (clipboard_content != null)
 
80
            add_clipboard_item (clipboard_content);
 
81
    }
 
82
 
 
83
    void add_clipboard_item (string clipboard_content) {
 
84
        if(clipboard_content == "")
 
85
            return;
 
86
        
 
87
        // Set the plugin visible
 
88
        if (contextbar.page_num (scrolled) == -1)
 
89
            contextbar.append_page (scrolled, new Gtk.Label (_("Clipboard History")));
 
90
        
 
91
        // Delete last item, if the size of the list store > MAX_SIZE
 
92
        if (list_store.get_iter_from_string (out iter, (MAX_SIZE - 1).to_string ()))
 
93
            list_store.remove (iter);
 
94
 
 
95
        // Delete dupplicates from list store, if exists
 
96
        delete_dupplicates (clipboard_content);
 
97
 
 
98
        // Create a short title
 
99
        string title = create_clipboard_item_title (clipboard_content);
 
100
 
 
101
        if (title == "")
 
102
            return;
 
103
 
 
104
        // Add a new item
 
105
        list_store.insert (out iter, 0);
 
106
        list_store.set (iter, 0, "edit-paste", 1, title, 2, clipboard_content);
 
107
    }
 
108
 
 
109
    string create_clipboard_item_title (string clipboard_content) {
 
110
 
 
111
        string [] lines = clipboard_content.split ("\n");
 
112
 
 
113
        string title = "";
 
114
        
 
115
        for (int i = 0; i < lines.length; i++ ){
 
116
            if (lines [i].strip () != "") {
 
117
                title = lines [i];
 
118
                if (i > 0)
 
119
                    title = DOTS + title;                                   // ...Code
 
120
                if (title.length > MAX_LINE_LENGTH)
 
121
                    title = title.substring (0, MAX_LINE_LENGTH) + DOTS;    // Code...
 
122
                else if (i + 1 < lines.length)
 
123
                    title += DOTS;                                          // Code...
 
124
                break;
 
125
            }
 
126
        }
 
127
 
 
128
        return title;
 
129
    }
 
130
 
 
131
    void delete_dupplicates (string new_clipboard_string) {
 
132
        Gtk.TreeIter? to_delete = null;
 
133
        list_store.foreach ((model, path, it) => {
 
134
            Value content;
 
135
            list_store.get_value (it, 2, out content);
 
136
            string clipboard_string = content.get_string ();
 
137
            if (clipboard_string == new_clipboard_string) {
 
138
                to_delete = it;
 
139
                return true;
 
140
            }
 
141
 
 
142
            return false;
 
143
        });
 
144
 
 
145
        if (to_delete != null)
 
146
            list_store.remove (to_delete);
 
147
    }
 
148
 
 
149
    void build_plugin_ui () {
 
150
        scrolled = new Gtk.ScrolledWindow (null, null);
 
151
        list_store = new Gtk.ListStore (3, typeof (string), typeof (string), typeof (string));
 
152
 
 
153
        // Context Menu
 
154
        menu = new Gtk.Menu ();
 
155
 
 
156
        menu_delete = new Gtk.MenuItem.with_label (_("Delete"));
 
157
        menu_delete.activate.connect (delete_selected);
 
158
 
 
159
        menu_paste = new Gtk.MenuItem.with_label (_("Paste"));
 
160
        menu_paste.activate.connect (paste_selected);
 
161
 
 
162
        menu.append (menu_paste);
 
163
        menu.append (menu_delete);
 
164
 
 
165
        menu.show_all ();
 
166
 
 
167
        // The View
 
168
        view = new Gtk.TreeView.with_model (list_store);
 
169
        view.headers_visible = false;
 
170
        view.set_tooltip_column (2);
 
171
 
 
172
        view.insert_column_with_attributes (-1, "icon-name", new Gtk.CellRendererPixbuf (), "icon_name", 0);
 
173
        view.insert_column_with_attributes (-1, "clipboard", new Gtk.CellRendererText (), "text", 1);
 
174
        view.button_press_event.connect (show_context_menu);
 
175
 
 
176
        scrolled.add (view);
 
177
        scrolled.show_all ();
 
178
    }
 
179
 
 
180
    public bool show_context_menu (Gtk.Widget sender, Gdk.EventButton evt) {
 
181
        if (evt.type == Gdk.EventType.BUTTON_PRESS && evt.button == 3)
 
182
            menu.popup (null, null, null, evt.button, evt.time);
 
183
            
 
184
        return false;
 
185
    }
 
186
 
 
187
    public void paste_selected () {
 
188
        var selection = view.get_selection();
 
189
        selection.set_mode(Gtk.SelectionMode.SINGLE);
 
190
        Gtk.TreeModel model;
 
191
        Gtk.TreeIter iter;
 
192
        if (!selection.get_selected(out model, out iter)) {
 
193
            return;
 
194
        }
 
195
        Value content;
 
196
        model.get_value(iter, 2, out content);
 
197
        string clipboard_string = content.get_string ();
 
198
 
 
199
        Scratch.Services.Document? current_document = window.get_current_document ();
 
200
 
 
201
        if (current_document == null)
 
202
            return;
 
203
        // Set focus on active document, delete selected text and paste the value from selected item.
 
204
        current_document.focus();
 
205
        current_document.source_view.delete_from_cursor (Gtk.DeleteType.CHARS, current_document.source_view.get_selected_text ().length);
 
206
        current_document.source_view.insert_at_cursor (clipboard_string);
 
207
    }
 
208
 
 
209
    public void delete_selected () {
 
210
        var selection = view.get_selection();
 
211
        selection.set_mode(Gtk.SelectionMode.SINGLE);
 
212
        Gtk.TreeModel model;
 
213
        Gtk.TreeIter iter;
 
214
        if (!selection.get_selected(out model, out iter)) {
 
215
            return;
 
216
        }
 
217
        list_store.remove (iter);
 
218
 
 
219
        // Hiding PlugIn, if no more items exist in the list store.
 
220
        if (!list_store.get_iter_first (out iter))
 
221
            contextbar.remove_page (contextbar.page_num (scrolled));
 
222
    }
 
223
}
 
224
 
 
225
[ModuleInit]
 
226
public void peas_register_types (GLib.TypeModule module) {
 
227
    var objmodule = module as Peas.ObjectModule;
 
228
    objmodule.register_extension_type (typeof (Peas.Activatable),
 
229
                                     typeof (Scratch.Plugins.ClipboardHistory));
 
230
}
 
 
b'\\ No newline at end of file'