Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
6e7f53df
by Philipp Hörist at 2019-04-20T06:37:48Z
-
cc375071
by Philipp Hörist at 2019-04-20T07:47:34Z
6 changed files:
- gajim/app_actions.py
- gajim/application.py
- − gajim/data/gui/progress_dialog.ui
- gajim/dialogs.py
- gajim/gtk/search.py
- gajim/gui_menu_builder.py
Changes:
| ... | ... | @@ -355,7 +355,7 @@ def open_link(_action, param): |
| 355 | 355 |
helpers.launch_browser_mailer(kind, link)
|
| 356 | 356 |
|
| 357 | 357 |
|
| 358 |
-def copy_link(_action, param):
|
|
| 358 |
+def copy_text(_action, param):
|
|
| 359 | 359 |
text = param.get_string()
|
| 360 | 360 |
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
| 361 | 361 |
clip.set_text(text, -1)
|
| ... | ... | @@ -416,8 +416,8 @@ class GajimApplication(Gtk.Application): |
| 416 | 416 |
act.connect("activate", app_actions.on_add_contact_jid)
|
| 417 | 417 |
self.add_action(act)
|
| 418 | 418 |
|
| 419 |
- act = Gio.SimpleAction.new('copy-link', GLib.VariantType.new('s'))
|
|
| 420 |
- act.connect("activate", app_actions.copy_link)
|
|
| 419 |
+ act = Gio.SimpleAction.new('copy-text', GLib.VariantType.new('s'))
|
|
| 420 |
+ act.connect("activate", app_actions.copy_text)
|
|
| 421 | 421 |
self.add_action(act)
|
| 422 | 422 |
|
| 423 | 423 |
act = Gio.SimpleAction.new('open-link', GLib.VariantType.new('as'))
|
| 1 |
-<?xml version="1.0" encoding="UTF-8"?>
|
|
| 2 |
-<!-- Generated with glade 3.18.3 -->
|
|
| 3 |
-<interface>
|
|
| 4 |
- <requires lib="gtk+" version="3.12"/>
|
|
| 5 |
- <object class="GtkDialog" id="progress_dialog">
|
|
| 6 |
- <property name="can_focus">False</property>
|
|
| 7 |
- <property name="type_hint">dialog</property>
|
|
| 8 |
- <signal name="delete-event" handler="on_progress_dialog_delete_event" swapped="no"/>
|
|
| 9 |
- <child internal-child="vbox">
|
|
| 10 |
- <object class="GtkBox" id="dialog-vbox">
|
|
| 11 |
- <property name="visible">True</property>
|
|
| 12 |
- <property name="can_focus">False</property>
|
|
| 13 |
- <property name="orientation">vertical</property>
|
|
| 14 |
- <property name="spacing">6</property>
|
|
| 15 |
- <child internal-child="action_area">
|
|
| 16 |
- <object class="GtkButtonBox" id="dialog-action_area11">
|
|
| 17 |
- <property name="visible">True</property>
|
|
| 18 |
- <property name="can_focus">False</property>
|
|
| 19 |
- <property name="layout_style">end</property>
|
|
| 20 |
- <child>
|
|
| 21 |
- <object class="GtkButton" id="close_button">
|
|
| 22 |
- <property name="label">gtk-close</property>
|
|
| 23 |
- <property name="visible">True</property>
|
|
| 24 |
- <property name="sensitive">False</property>
|
|
| 25 |
- <property name="can_focus">True</property>
|
|
| 26 |
- <property name="can_default">True</property>
|
|
| 27 |
- <property name="receives_default">False</property>
|
|
| 28 |
- <property name="use_stock">True</property>
|
|
| 29 |
- </object>
|
|
| 30 |
- <packing>
|
|
| 31 |
- <property name="expand">False</property>
|
|
| 32 |
- <property name="fill">False</property>
|
|
| 33 |
- <property name="position">0</property>
|
|
| 34 |
- </packing>
|
|
| 35 |
- </child>
|
|
| 36 |
- </object>
|
|
| 37 |
- <packing>
|
|
| 38 |
- <property name="expand">False</property>
|
|
| 39 |
- <property name="fill">False</property>
|
|
| 40 |
- <property name="pack_type">end</property>
|
|
| 41 |
- <property name="position">0</property>
|
|
| 42 |
- </packing>
|
|
| 43 |
- </child>
|
|
| 44 |
- <child>
|
|
| 45 |
- <object class="GtkLabel" id="label">
|
|
| 46 |
- <property name="visible">True</property>
|
|
| 47 |
- <property name="can_focus">False</property>
|
|
| 48 |
- <property name="use_markup">True</property>
|
|
| 49 |
- </object>
|
|
| 50 |
- <packing>
|
|
| 51 |
- <property name="expand">False</property>
|
|
| 52 |
- <property name="fill">False</property>
|
|
| 53 |
- <property name="position">2</property>
|
|
| 54 |
- </packing>
|
|
| 55 |
- </child>
|
|
| 56 |
- <child>
|
|
| 57 |
- <object class="GtkProgressBar" id="progressbar">
|
|
| 58 |
- <property name="visible">True</property>
|
|
| 59 |
- <property name="can_focus">False</property>
|
|
| 60 |
- <property name="pulse_step">0.10000000149</property>
|
|
| 61 |
- </object>
|
|
| 62 |
- <packing>
|
|
| 63 |
- <property name="expand">False</property>
|
|
| 64 |
- <property name="fill">False</property>
|
|
| 65 |
- <property name="position">3</property>
|
|
| 66 |
- </packing>
|
|
| 67 |
- </child>
|
|
| 68 |
- </object>
|
|
| 69 |
- </child>
|
|
| 70 |
- <action-widgets>
|
|
| 71 |
- <action-widget response="-7">close_button</action-widget>
|
|
| 72 |
- </action-widgets>
|
|
| 73 |
- </object>
|
|
| 74 |
-</interface>
|
| ... | ... | @@ -1159,35 +1159,6 @@ class RosterItemExchangeWindow: |
| 1159 | 1159 |
self.window.destroy()
|
| 1160 | 1160 |
|
| 1161 | 1161 |
|
| 1162 |
-class ProgressDialog:
|
|
| 1163 |
- def __init__(self, title_text, during_text, messages_queue):
|
|
| 1164 |
- """
|
|
| 1165 |
- During text is what to show during the procedure, messages_queue has the
|
|
| 1166 |
- message to show in the textview
|
|
| 1167 |
- """
|
|
| 1168 |
- self.xml = get_builder('progress_dialog.ui')
|
|
| 1169 |
- self.dialog = self.xml.get_object('progress_dialog')
|
|
| 1170 |
- self.label = self.xml.get_object('label')
|
|
| 1171 |
- self.label.set_markup('<big>' + during_text + '</big>')
|
|
| 1172 |
- self.progressbar = self.xml.get_object('progressbar')
|
|
| 1173 |
- self.dialog.set_title(title_text)
|
|
| 1174 |
- self.dialog.set_default_size(450, 250)
|
|
| 1175 |
- self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
|
|
| 1176 |
- self.dialog.show_all()
|
|
| 1177 |
- self.xml.connect_signals(self)
|
|
| 1178 |
- |
|
| 1179 |
- self.update_progressbar_timeout_id = GLib.timeout_add(100,
|
|
| 1180 |
- self.update_progressbar)
|
|
| 1181 |
- |
|
| 1182 |
- def update_progressbar(self):
|
|
| 1183 |
- if self.dialog:
|
|
| 1184 |
- self.progressbar.pulse()
|
|
| 1185 |
- return True # loop forever
|
|
| 1186 |
- return False
|
|
| 1187 |
- |
|
| 1188 |
- def on_progress_dialog_delete_event(self, widget, event):
|
|
| 1189 |
- return True # WM's X button or Escape key should not destroy the window
|
|
| 1190 |
- |
|
| 1191 | 1162 |
class TransformChatToMUC:
|
| 1192 | 1163 |
# Keep a reference on windows so garbage collector don't restroy them
|
| 1193 | 1164 |
instances = [] # type: List[TransformChatToMUC]
|
| ... | ... | @@ -26,6 +26,8 @@ from gajim.common.i18n import _ |
| 26 | 26 |
|
| 27 | 27 |
from gajim.common.modules import dataforms
|
| 28 | 28 |
|
| 29 |
+from gajim.gui_menu_builder import SearchMenu
|
|
| 30 |
+ |
|
| 29 | 31 |
from gajim.gtk.dataform import DataFormWidget
|
| 30 | 32 |
from gajim.gtk.util import ensure_not_destroyed
|
| 31 | 33 |
from gajim.gtk.util import find_widget
|
| ... | ... | @@ -259,6 +261,7 @@ class Completed(Gtk.Box): |
| 259 | 261 |
self._scrolled.get_style_context().add_class('search-scrolled')
|
| 260 | 262 |
self._scrolled.set_no_show_all(True)
|
| 261 | 263 |
self._treeview = None
|
| 264 |
+ self._menu = None
|
|
| 262 | 265 |
self.add(self._label)
|
| 263 | 266 |
self.add(self._scrolled)
|
| 264 | 267 |
self.show_all()
|
| ... | ... | @@ -268,6 +271,7 @@ class Completed(Gtk.Box): |
| 268 | 271 |
self._scrolled.remove(self._treeview)
|
| 269 | 272 |
self._treeview.destroy()
|
| 270 | 273 |
self._treeview = None
|
| 274 |
+ self._menu = None
|
|
| 271 | 275 |
self._label.hide()
|
| 272 | 276 |
self._scrolled.hide()
|
| 273 | 277 |
|
| ... | ... | @@ -303,6 +307,8 @@ class Completed(Gtk.Box): |
| 303 | 307 |
self._treeview.set_hexpand(True)
|
| 304 | 308 |
self._treeview.set_vexpand(True)
|
| 305 | 309 |
self._treeview.get_style_context().add_class('search-treeview')
|
| 310 |
+ self._treeview.connect('button-press-event', self._on_button_press)
|
|
| 311 |
+ self._menu = SearchMenu(self._treeview)
|
|
| 306 | 312 |
|
| 307 | 313 |
for field, counter in zip(form.reported.iter_fields(),
|
| 308 | 314 |
itertools.count()):
|
| ... | ... | @@ -316,6 +322,19 @@ class Completed(Gtk.Box): |
| 316 | 322 |
self._scrolled.add(self._treeview)
|
| 317 | 323 |
self._scrolled.show()
|
| 318 | 324 |
|
| 325 |
+ def _on_button_press(self, treeview, event):
|
|
| 326 |
+ if event.button != 3:
|
|
| 327 |
+ return
|
|
| 328 |
+ path, _column, _x, _y = treeview.get_path_at_pos(event.x, event.y)
|
|
| 329 |
+ if path is None:
|
|
| 330 |
+ return
|
|
| 331 |
+ store = treeview.get_model()
|
|
| 332 |
+ iter_ = store.get_iter(path)
|
|
| 333 |
+ column_values = store[iter_]
|
|
| 334 |
+ text = ' '.join(column_values)
|
|
| 335 |
+ self._menu.set_copy_text(text)
|
|
| 336 |
+ self._menu.popup_at_pointer()
|
|
| 337 |
+ |
|
| 319 | 338 |
|
| 320 | 339 |
class Error(Gtk.Box):
|
| 321 | 340 |
|
| ... | ... | @@ -905,31 +905,31 @@ def get_conv_context_menu(account, kind, text): |
| 905 | 905 |
if kind == 'xmpp':
|
| 906 | 906 |
if '?join' in text:
|
| 907 | 907 |
context_menu = [
|
| 908 |
- ('copy-link', _('Copy JID')),
|
|
| 908 |
+ ('copy-text', _('Copy JID')),
|
|
| 909 | 909 |
('-join-groupchat', _('Join Groupchat')),
|
| 910 | 910 |
]
|
| 911 | 911 |
else:
|
| 912 | 912 |
context_menu = [
|
| 913 |
- ('copy-link', _('Copy JID')),
|
|
| 913 |
+ ('copy-text', _('Copy JID')),
|
|
| 914 | 914 |
('-start-chat', _('Start Chat')),
|
| 915 | 915 |
('-add-contact', _('Add to Roster…')),
|
| 916 | 916 |
]
|
| 917 | 917 |
|
| 918 | 918 |
elif kind == 'url':
|
| 919 | 919 |
context_menu = [
|
| 920 |
- ('copy-link', _('Copy Link Location')),
|
|
| 920 |
+ ('copy-text', _('Copy Link Location')),
|
|
| 921 | 921 |
('open-link', _('Open Link in Browser')),
|
| 922 | 922 |
]
|
| 923 | 923 |
|
| 924 | 924 |
elif kind == 'mail':
|
| 925 | 925 |
context_menu = [
|
| 926 |
- ('copy-link', _('Copy Email Address')),
|
|
| 926 |
+ ('copy-text', _('Copy Email Address')),
|
|
| 927 | 927 |
('open-link', _('Open Email Composer')),
|
| 928 | 928 |
]
|
| 929 | 929 |
|
| 930 | 930 |
elif kind == 'sth_at_sth':
|
| 931 | 931 |
context_menu = [
|
| 932 |
- ('copy-link', _('Copy JID/Email')),
|
|
| 932 |
+ ('copy-text', _('Copy JID/Email')),
|
|
| 933 | 933 |
('open-link', _('Open Email Composer')),
|
| 934 | 934 |
('-start-chat', _('Start Chat')),
|
| 935 | 935 |
('-join-groupchat', _('Join Groupchat')),
|
| ... | ... | @@ -954,7 +954,7 @@ def get_conv_context_menu(account, kind, text): |
| 954 | 954 |
|
| 955 | 955 |
if action == 'app.open-link':
|
| 956 | 956 |
value = GLib.Variant.new_strv([kind, text])
|
| 957 |
- elif action == 'app.copy-link':
|
|
| 957 |
+ elif action == 'app.copy-text':
|
|
| 958 | 958 |
value = GLib.Variant.new_string(text)
|
| 959 | 959 |
else:
|
| 960 | 960 |
value = GLib.Variant.new_strv([account, text])
|
| ... | ... | @@ -964,6 +964,20 @@ def get_conv_context_menu(account, kind, text): |
| 964 | 964 |
return menu
|
| 965 | 965 |
|
| 966 | 966 |
|
| 967 |
+class SearchMenu(Gtk.Menu):
|
|
| 968 |
+ def __init__(self, treeview):
|
|
| 969 |
+ Gtk.Menu.__init__(self)
|
|
| 970 |
+ self._copy_item = Gtk.MenuItem(label=_('Copy'))
|
|
| 971 |
+ self._copy_item.set_action_name('app.copy-text')
|
|
| 972 |
+ self.set_copy_text('')
|
|
| 973 |
+ self._copy_item.show()
|
|
| 974 |
+ self.append(self._copy_item)
|
|
| 975 |
+ self.attach_to_widget(treeview, None)
|
|
| 976 |
+ |
|
| 977 |
+ def set_copy_text(self, text):
|
|
| 978 |
+ self._copy_item.set_action_target_value(GLib.Variant('s', text))
|
|
| 979 |
+ |
|
| 980 |
+ |
|
| 967 | 981 |
def escape_mnemonic(label):
|
| 968 | 982 |
if label is None:
|
| 969 | 983 |
return
|