diff --git a/deluge/ui/gtk3/dialogs.py b/deluge/ui/gtk3/dialogs.py index 6a2ae8629..cf72a376c 100644 --- a/deluge/ui/gtk3/dialogs.py +++ b/deluge/ui/gtk3/dialogs.py @@ -452,3 +452,44 @@ class PasswordDialog(BaseDialog): def on_password_activate(self, widget): self.response(Gtk.ResponseType.OK) + + +class CopyMagnetDialog(BaseDialog): + """ + Displays a dialog with a magnet URI + """ + + def __init__(self, torrent_magnet='', parent=None): + super().__init__( + header=_('Copy Magnet URI'), + text='', + icon='magnet_copy.svg', + buttons=(_('_Close'), Gtk.ResponseType.CLOSE), + parent=parent, + ) + self.copied = False + + table = Gtk.Table(1, 2, False) + self.magnet_entry = Gtk.Entry() + self.magnet_entry.set_text(torrent_magnet) + self.magnet_entry.set_editable(False) + self.magnet_entry.connect('copy-clipboard', self.on_copy_emitted) + table.attach(self.magnet_entry, 0, 1, 0, 1) + + copy_button = Gtk.Button.new_with_label(_('Copy')) + copy_button.connect('clicked', self.on_copy_clicked) + table.attach(copy_button, 1, 2, 0, 1) + + self.vbox.pack_start(table, False, False, padding=5) + self.set_focus(self.magnet_entry) + + self.show_all() + + def on_copy_clicked(self, widget): + self.magnet_entry.select_region(0, -1) + self.magnet_entry.copy_clipboard() + self.magnet_entry.set_position(0) + self.copied = True + + def on_copy_emitted(self, widget): + self.copied = True diff --git a/deluge/ui/gtk3/glade/torrent_menu.ui b/deluge/ui/gtk3/glade/torrent_menu.ui index c1b77b4ad..c9ee289c1 100644 --- a/deluge/ui/gtk3/glade/torrent_menu.ui +++ b/deluge/ui/gtk3/glade/torrent_menu.ui @@ -31,6 +31,11 @@ media-playback-pause-symbolic 1 + + False + edit-copy-symbolic + 1 + True False @@ -154,6 +159,17 @@ False + + + _Copy Magnet URI + True + False + True + menu-item-image15 + False + + + _Update Tracker diff --git a/deluge/ui/gtk3/mainwindow.py b/deluge/ui/gtk3/mainwindow.py index 3da81c509..d11ff317a 100644 --- a/deluge/ui/gtk3/mainwindow.py +++ b/deluge/ui/gtk3/mainwindow.py @@ -338,7 +338,9 @@ class MainWindow(component.Component): return self.previous_clipboard_text = text if text and ( - (is_url(text) and text.endswith('.torrent')) or is_magnet(text) + (is_url(text) and text.endswith('.torrent')) + or is_magnet(text) + and not component.get('MenuBar').magnet_copied() ): component.get('AddTorrentDialog').show() component.get('AddTorrentDialog').on_button_url_clicked(window) diff --git a/deluge/ui/gtk3/menubar.py b/deluge/ui/gtk3/menubar.py index 53d46ea97..a78a2472f 100644 --- a/deluge/ui/gtk3/menubar.py +++ b/deluge/ui/gtk3/menubar.py @@ -18,7 +18,7 @@ import deluge.component as component from deluge.configmanager import ConfigManager from deluge.ui.client import client -from .dialogs import ErrorDialog, OtherDialog +from .dialogs import CopyMagnetDialog, ErrorDialog, OtherDialog from .path_chooser import PathChooser log = logging.getLogger(__name__) @@ -31,6 +31,7 @@ class MenuBar(component.Component): self.mainwindow = component.get('MainWindow') self.main_builder = self.mainwindow.get_builder() self.config = ConfigManager('gtk3ui.conf') + self._magnet_copied = False self.builder = Gtk.Builder() # Get the torrent menu from the gtk builder file @@ -139,6 +140,19 @@ class MenuBar(component.Component): self.change_sensitivity = ['menuitem_addtorrent'] + def magnet_copied(self): + """ + lets the caller know whether a magnet was copied internally + + the `mainwindow` checks every time the data in the clipboard, + so it will automatically open the AddTorrentURL dialog in case it + contains a valid link (URL to a torrent or a magnet URI). + + """ + val = self._magnet_copied + self._magnet_copied = False + return val + def start(self): for widget in self.change_sensitivity: self.main_builder.get_object(widget).set_sensitive(True) @@ -279,6 +293,21 @@ class MenuBar(component.Component): component.get('TorrentView').get_selected_torrents() ) + def on_menuitem_copymagnet_activate(self, data=None): + log.debug('on_menuitem_copymagnet_activate') + torrent_ids = component.get('TorrentView').get_selected_torrents() + if torrent_ids: + + def _on_magnet_uri(magnet_uri): + def update_copied(response_id): + if dialog.copied: + self._magnet_copied = True + + dialog = CopyMagnetDialog(magnet_uri) + dialog.run().addCallback(update_copied) + + client.core.get_magnet_uri(torrent_ids[0]).addCallback(_on_magnet_uri) + def on_menuitem_updatetracker_activate(self, data=None): log.debug('on_menuitem_updatetracker_activate') client.core.force_reannounce(