1
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 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.
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.
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/>
21
public const string NAME = N_("Clipboard History");
22
public const string DESCRIPTION = N_("Clipboard to view history");
24
public class Scratch.Plugins.ClipboardHistory : Peas.ExtensionBase, Peas.Activatable {
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;
32
Gtk.ScrolledWindow scrolled;
33
Gtk.ListStore list_store;
38
Gtk.MenuItem menu_paste;
39
Gtk.MenuItem menu_delete;
41
Scratch.Services.Interface plugins;
42
public Object object { owned get; construct; }
44
public void update_state () {
47
public void activate () {
48
debug ("-- %s avtivate", NAME);
50
plugins = (Scratch.Services.Interface) object;
52
plugins.hook_window.connect ((w) => {
57
window.clipboard.owner_change.connect (clipboard_action);
60
plugins.hook_notebook_context.connect ((n) => {
61
if (contextbar == null) {
69
public void deactivate () {
70
debug ("-- %s deavtivate", NAME);
72
contextbar.remove_page (contextbar.page_num (scrolled));
74
window.clipboard.owner_change.disconnect (clipboard_action);
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);
83
void add_clipboard_item (string clipboard_content) {
84
if(clipboard_content == "")
87
// Set the plugin visible
88
if (contextbar.page_num (scrolled) == -1)
89
contextbar.append_page (scrolled, new Gtk.Label (_("Clipboard History")));
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);
95
// Delete dupplicates from list store, if exists
96
delete_dupplicates (clipboard_content);
98
// Create a short title
99
string title = create_clipboard_item_title (clipboard_content);
105
list_store.insert (out iter, 0);
106
list_store.set (iter, 0, "edit-paste", 1, title, 2, clipboard_content);
109
string create_clipboard_item_title (string clipboard_content) {
111
string [] lines = clipboard_content.split ("\n");
115
for (int i = 0; i < lines.length; i++ ){
116
if (lines [i].strip () != "") {
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...
131
void delete_dupplicates (string new_clipboard_string) {
132
Gtk.TreeIter? to_delete = null;
133
list_store.foreach ((model, path, it) => {
135
list_store.get_value (it, 2, out content);
136
string clipboard_string = content.get_string ();
137
if (clipboard_string == new_clipboard_string) {
145
if (to_delete != null)
146
list_store.remove (to_delete);
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));
154
menu = new Gtk.Menu ();
156
menu_delete = new Gtk.MenuItem.with_label (_("Delete"));
157
menu_delete.activate.connect (delete_selected);
159
menu_paste = new Gtk.MenuItem.with_label (_("Paste"));
160
menu_paste.activate.connect (paste_selected);
162
menu.append (menu_paste);
163
menu.append (menu_delete);
168
view = new Gtk.TreeView.with_model (list_store);
169
view.headers_visible = false;
170
view.set_tooltip_column (2);
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);
177
scrolled.show_all ();
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);
187
public void paste_selected () {
188
var selection = view.get_selection();
189
selection.set_mode(Gtk.SelectionMode.SINGLE);
192
if (!selection.get_selected(out model, out iter)) {
196
model.get_value(iter, 2, out content);
197
string clipboard_string = content.get_string ();
199
Scratch.Services.Document? current_document = window.get_current_document ();
201
if (current_document == null)
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);
209
public void delete_selected () {
210
var selection = view.get_selection();
211
selection.set_mode(Gtk.SelectionMode.SINGLE);
214
if (!selection.get_selected(out model, out iter)) {
217
list_store.remove (iter);
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));
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));
b'\\ No newline at end of file'