Beispiel #1
0
    def __init__(self, torrent_id, parent=None):
        self.torrent_id = torrent_id
        self.builder = Gtk.Builder()
        self.gtkui_config = ConfigManager('gtk3ui.conf')

        # Main dialog
        self.builder.add_from_file(
            resource_filename(__package__, os.path.join('glade', 'edit_trackers.ui'))
        )
        # add tracker dialog
        self.builder.add_from_file(
            resource_filename(
                __package__, os.path.join('glade', 'edit_trackers.add.ui')
            )
        )
        # edit tracker dialog
        self.builder.add_from_file(
            resource_filename(
                __package__, os.path.join('glade', 'edit_trackers.edit.ui')
            )
        )

        self.dialog = self.builder.get_object('edit_trackers_dialog')
        self.treeview = self.builder.get_object('tracker_treeview')
        self.add_tracker_dialog = self.builder.get_object('add_tracker_dialog')
        self.add_tracker_dialog.set_transient_for(self.dialog)
        self.edit_tracker_entry = self.builder.get_object('edit_tracker_entry')
        self.edit_tracker_entry.set_transient_for(self.dialog)
        self.dialog.set_icon(get_deluge_icon())

        self.load_edit_trackers_dialog_state()

        if parent is not None:
            self.dialog.set_transient_for(parent)

        # Connect the signals
        self.builder.connect_signals(self)

        # Create a liststore for tier, url
        self.liststore = Gtk.ListStore(int, str)

        # Create the columns
        self.treeview.append_column(
            Gtk.TreeViewColumn(_('Tier'), Gtk.CellRendererText(), text=0)
        )
        self.treeview.append_column(
            Gtk.TreeViewColumn(_('Tracker'), Gtk.CellRendererText(), text=1)
        )

        self.treeview.set_model(self.liststore)
        self.liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)

        self.dialog.connect('delete-event', self._on_delete_event)
        self.dialog.connect('response', self._on_response)
        self.treeview.connect('button_press_event', self.on_button_press_event)
    def __init__(self, torrent_id, parent=None):
        self.torrent_id = torrent_id
        self.builder = gtk.Builder()
        self.gtkui_config = ConfigManager('gtkui.conf')

        # Main dialog
        self.builder.add_from_file(resource_filename(
            'deluge.ui.gtkui', os.path.join('glade', 'edit_trackers.ui')
        ))
        # add tracker dialog
        self.builder.add_from_file(resource_filename(
            'deluge.ui.gtkui', os.path.join('glade', 'edit_trackers.add.ui')
        ))
        # edit tracker dialog
        self.builder.add_from_file(resource_filename(
            'deluge.ui.gtkui', os.path.join('glade', 'edit_trackers.edit.ui')
        ))

        self.dialog = self.builder.get_object('edit_trackers_dialog')
        self.treeview = self.builder.get_object('tracker_treeview')
        self.add_tracker_dialog = self.builder.get_object('add_tracker_dialog')
        self.add_tracker_dialog.set_transient_for(self.dialog)
        self.edit_tracker_entry = self.builder.get_object('edit_tracker_entry')
        self.edit_tracker_entry.set_transient_for(self.dialog)
        self.dialog.set_icon(get_deluge_icon())

        self.load_edit_trackers_dialog_state()

        if parent is not None:
            self.dialog.set_transient_for(parent)

        # Connect the signals
        self.builder.connect_signals(self)

        # Create a liststore for tier, url
        self.liststore = gtk.ListStore(int, str)

        # Create the columns
        self.treeview.append_column(
            gtk.TreeViewColumn(_('Tier'), gtk.CellRendererText(), text=0))
        self.treeview.append_column(
            gtk.TreeViewColumn(_('Tracker'), gtk.CellRendererText(), text=1))

        self.treeview.set_model(self.liststore)
        self.liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)

        self.dialog.connect('delete-event', self._on_delete_event)
        self.dialog.connect('response', self._on_response)
Beispiel #3
0
    def on_button_add_clicked(self, widget):
        log.debug('on_button_add_clicked')
        builder = gtk.Builder()
        builder.add_from_file(
            resource_filename('deluge.ui.gtkui',
                              os.path.join('glade', 'edit_trackers.add.ui')))
        dialog = builder.get_object('add_tracker_dialog')
        dialog.set_transient_for(self.dialog)
        textview = builder.get_object('textview_trackers')
        if self.config['createtorrent.trackers']:
            textview.get_buffer().set_text('\n'.join(
                self.config['createtorrent.trackers']))
        else:
            textview.get_buffer().set_text('')
        textview.grab_focus()
        response = dialog.run()

        if response == gtk.RESPONSE_OK:
            # Create a list of trackers from the textview buffer
            textview_buf = textview.get_buffer()
            trackers_text = textview_buf.get_text(*textview_buf.get_bounds())
            log.debug('Create torrent tracker lines: %s', trackers_text)
            self.config['createtorrent.trackers'] = trackers_text.split('/n')

            # Append trackers liststore with unique trackers and tiers starting from last tier number.
            last_tier, orig_trackers = last_tier_trackers_from_liststore(
                self.trackers_liststore)
            for tracker, tier in trackers_tiers_from_text(
                    trackers_text).items():
                if tracker not in orig_trackers:
                    self.trackers_liststore.append([tier + last_tier, tracker])

        dialog.destroy()
Beispiel #4
0
    def enable(self):
        """Enables the system tray icon."""
        self.builder = Builder()
        self.builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
            'glade', 'tray_menu.ui')))

        self.builder.connect_signals(self)

        self.tray_menu = self.builder.get_object('tray_menu')

        if appindicator and self.config['enable_appindicator']:
            log.debug('Enabling the Application Indicator...')
            self.indicator = appindicator.Indicator('deluge', 'deluge',
                                                    appindicator.CATEGORY_APPLICATION_STATUS)
            try:
                self.indicator.set_property('title', _('Deluge'))
            except TypeError:
                # Catch 'title' property error for previous appindicator versions
                pass
            # Pass the menu to the Application Indicator
            self.indicator.set_menu(self.tray_menu)

            # Make sure the status of the Show Window MenuItem is correct
            self._sig_win_hide = self.mainwindow.window.connect('hide', self._on_window_hide)
            self._sig_win_show = self.mainwindow.window.connect('show', self._on_window_show)
            if self.mainwindow.visible():
                self.builder.get_object('menuitem_show_deluge').set_active(True)
            else:
                self.builder.get_object('menuitem_show_deluge').set_active(False)

            # Show the Application Indicator
            self.indicator.set_status(appindicator.STATUS_ACTIVE)

        else:
            log.debug('Enabling the system tray icon..')
            if windows_check():
                self.tray = status_icon_new_from_pixbuf(get_logo(32))
            else:
                self.tray = status_icon_new_from_icon_name('deluge')

            self.tray.connect('activate', self.on_tray_clicked)
            self.tray.connect('popup-menu', self.on_tray_popup)

        self.builder.get_object('download-limit-image').set_from_file(get_pixmap('downloading16.png'))
        self.builder.get_object('upload-limit-image').set_from_file(get_pixmap('seeding16.png'))

        client.register_event_handler('ConfigValueChangedEvent', self.config_value_changed)
        if client.connected():
            # We're connected so we need to get some values from the core
            self.__start()
        else:
            # Hide menu widgets because we're not connected to a host.
            for widget in self.hide_widget_list:
                self.builder.get_object(widget).hide()
Beispiel #5
0
    def __init__(self):
        if wnck:
            self.screen = wnck.screen_get_default()
        component.Component.__init__(self, 'MainWindow', interval=2)
        self.config = ConfigManager('gtkui.conf')
        self.main_builder = gtk.Builder()

        # Patch this GtkBuilder to avoid connecting signals from elsewhere
        #
        # Think about splitting up  mainwindow gtkbuilder file into the necessary parts
        # to avoid GtkBuilder monkey patch. Those parts would then need adding to mainwindow 'by hand'.
        self.gtk_builder_signals_holder = _GtkBuilderSignalsHolder()
        self.main_builder.prev_connect_signals = copy.deepcopy(self.main_builder.connect_signals)

        def patched_connect_signals(*a, **k):
            raise RuntimeError('In order to connect signals to this GtkBuilder instance please use '
                               '"component.get(\'MainWindow\').connect_signals()"')
        self.main_builder.connect_signals = patched_connect_signals

        # Get Gtk Builder files Main Window, New release dialog, and Tabs.
        for filename in ('main_window.ui', 'main_window.new_release.ui', 'main_window.tabs.ui',
                         'main_window.tabs.menu_file.ui', 'main_window.tabs.menu_peer.ui'):
            self.main_builder.add_from_file(
                resource_filename('deluge.ui.gtkui', os.path.join('glade', filename)))

        self.window = self.main_builder.get_object('main_window')
        self.window.set_icon(deluge.ui.gtkui.common.get_deluge_icon())
        self.vpaned = self.main_builder.get_object('vpaned')
        self.initial_vpaned_position = self.config['window_pane_position']

        # Keep a list of components to pause and resume when changing window state.
        self.child_components = ['TorrentView', 'StatusBar', 'TorrentDetails']

        # Load the window state
        self.load_window_state()

        # Keep track of window minimization state so we don't update UI when it is minimized.
        self.is_minimized = False
        self.restart = False

        self.window.drag_dest_set(gtk.DEST_DEFAULT_ALL, [('text/uri-list', 0, 80)], ACTION_COPY)

        # Connect events
        self.window.connect('window-state-event', self.on_window_state_event)
        self.window.connect('configure-event', self.on_window_configure_event)
        self.window.connect('delete-event', self.on_window_delete_event)
        self.window.connect('drag-data-received', self.on_drag_data_received_event)
        self.vpaned.connect('notify::position', self.on_vpaned_position_event)
        self.window.connect('expose-event', self.on_expose_event)

        self.config.register_set_function('show_rate_in_title', self._on_set_show_rate_in_title, apply_now=False)

        client.register_event_handler('NewVersionAvailableEvent', self.on_newversionavailable_event)
Beispiel #6
0
 def render(self, request):
     headers = {}
     path = ("data", "pixmaps", "flags", request.country.lower() + ".png")
     filename = common.resource_filename("deluge", os.path.join(*path))
     if os.path.exists(filename):
         request.setHeader("cache-control",
                           "public, must-revalidate, max-age=86400")
         request.setHeader("content-type", "image/png")
         data = open(filename, "rb")
         request.setResponseCode(http.OK)
         return data.read()
     else:
         request.setResponseCode(http.NOT_FOUND)
         return ""
Beispiel #7
0
 def render(self, request):
     headers = {}
     path = ("data", "pixmaps", "flags", request.country.lower() + ".png")
     filename = common.resource_filename("deluge", os.path.join(*path))
     if os.path.exists(filename):
         request.setHeader("cache-control",
                           "public, must-revalidate, max-age=86400")
         request.setHeader("content-type", "image/png")
         data = open(filename, "rb")
         request.setResponseCode(http.OK)
         return data.read()
     else:
         request.setResponseCode(http.NOT_FOUND)
         return ""
Beispiel #8
0
 def render(self, request):
     path = ('ui', 'data', 'pixmaps', 'flags', request.country.lower() + '.png')
     filename = common.resource_filename('deluge', os.path.join(*path))
     if os.path.exists(filename):
         request.setHeader('cache-control',
                           'public, must-revalidate, max-age=86400')
         request.setHeader('content-type', 'image/png')
         with open(filename, 'rb') as _file:
             data = _file.read()
         request.setResponseCode(http.OK)
         return data
     else:
         request.setResponseCode(http.NOT_FOUND)
         return ''
Beispiel #9
0
 def render(self, request):
     path = ('ui', 'data', 'pixmaps', 'flags',
             request.country.lower() + '.png')
     filename = common.resource_filename('deluge', os.path.join(*path))
     if os.path.exists(filename):
         request.setHeader(b'cache-control',
                           b'public, must-revalidate, max-age=86400')
         request.setHeader(b'content-type', b'image/png')
         with open(filename, 'rb') as _file:
             data = _file.read()
         request.setResponseCode(http.OK)
         return data
     else:
         request.setResponseCode(http.NOT_FOUND)
         return ''
Beispiel #10
0
    def _run_addhost_dialog(self, edit_host_info=None):
        """Create and runs the add host dialog.

        Supplying edit_host_info changes the dialog to an edit dialog.

        Args:
            edit_host_info (list): A list of (host, port, user, pass) to edit.

        Returns:
            list: The new host info values (host, port, user, pass).

        """
        self.builder.add_from_file(
            resource_filename(
                'deluge.ui.gtkui',
                os.path.join('glade', 'connection_manager.addhost.ui'),
            ))
        dialog = self.builder.get_object('addhost_dialog')
        dialog.set_transient_for(self.connection_manager)
        hostname_entry = self.builder.get_object('entry_hostname')
        port_spinbutton = self.builder.get_object('spinbutton_port')
        username_entry = self.builder.get_object('entry_username')
        password_entry = self.builder.get_object('entry_password')

        if edit_host_info:
            dialog.set_title(_('Edit Host'))
            hostname_entry.set_text(edit_host_info[0])
            port_spinbutton.set_value(edit_host_info[1])
            username_entry.set_text(edit_host_info[2])
            password_entry.set_text(edit_host_info[3])

        response = dialog.run()
        new_host_info = []
        if response:
            new_host_info.append(hostname_entry.get_text())
            new_host_info.append(port_spinbutton.get_value_as_int())
            new_host_info.append(username_entry.get_text())
            new_host_info.append(password_entry.get_text())

        dialog.destroy()
        return new_host_info
    def _run_addhost_dialog(self, edit_host_info=None):
        """Create and runs the add host dialog.

        Supplying edit_host_info changes the dialog to an edit dialog.

        Args:
            edit_host_info (list): A list of (host, port, user, pass) to edit.

        Returns:
            list: The new host info values (host, port, user, pass).

        """
        self.builder.add_from_file(resource_filename(
            'deluge.ui.gtkui', os.path.join('glade', 'connection_manager.addhost.ui')))
        dialog = self.builder.get_object('addhost_dialog')
        dialog.set_transient_for(self.connection_manager)
        hostname_entry = self.builder.get_object('entry_hostname')
        port_spinbutton = self.builder.get_object('spinbutton_port')
        username_entry = self.builder.get_object('entry_username')
        password_entry = self.builder.get_object('entry_password')

        if edit_host_info:
            dialog.set_title(_('Edit Host'))
            hostname_entry.set_text(edit_host_info[0])
            port_spinbutton.set_value(edit_host_info[1])
            username_entry.set_text(edit_host_info[2])
            password_entry.set_text(edit_host_info[3])

        response = dialog.run()
        new_host_info = []
        if response:
            new_host_info.append(hostname_entry.get_text())
            new_host_info.append(port_spinbutton.get_value_as_int())
            new_host_info.append(username_entry.get_text())
            new_host_info.append(password_entry.get_text())

        dialog.destroy()
        return new_host_info
Beispiel #12
0
    def __init__(self):
        component.Component.__init__(self, 'FilterTreeView', interval=2)
        self.config = ConfigManager('gtkui.conf')

        self.tracker_icons = component.get('TrackerIcons')

        self.sidebar = component.get('SideBar')
        self.treeview = gtk.TreeView()
        self.sidebar.add_tab(self.treeview, 'filters', 'Filters')

        # set filter to all when hidden:
        self.sidebar.notebook.connect('hide', self._on_hide)

        # Create the treestore
        # cat, value, label, count, pixmap, visible
        self.treestore = gtk.TreeStore(str, str, str, int, Pixbuf, bool)

        # Create the column and cells
        column = gtk.TreeViewColumn('Filters')
        column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
        # icon cell
        self.cell_pix = gtk.CellRendererPixbuf()
        column.pack_start(self.cell_pix, expand=False)
        column.add_attribute(self.cell_pix, 'pixbuf', 4)
        # label cell
        cell_label = gtk.CellRendererText()
        cell_label.set_property('ellipsize', ELLIPSIZE_END)
        column.pack_start(cell_label, expand=True)
        column.set_cell_data_func(cell_label, self.render_cell_data, None)
        # count cell
        self.cell_count = gtk.CellRendererText()
        self.cell_count.set_property('xalign', 1.0)
        self.cell_count.set_padding(3, 0)
        column.pack_start(self.cell_count, expand=False)

        self.treeview.append_column(column)

        # Style
        self.treeview.set_show_expanders(True)
        self.treeview.set_headers_visible(False)
        self.treeview.set_level_indentation(-21)
        # Force theme to use expander-size so we don't cut out entries due to indentation hack.
        gtk.rc_parse_string("""style "treeview-style" {GtkTreeView::expander-size = 7}
                            class "GtkTreeView" style "treeview-style" """)

        self.treeview.set_model(self.treestore)
        self.treeview.get_selection().connect('changed', self.on_selection_changed)
        self.create_model_filter()

        self.treeview.connect('button-press-event', self.on_button_press_event)

        # colors using current theme.
        style = component.get('MainWindow').window.get_style()
        self.colour_background = style.bg[gtk.STATE_NORMAL]
        self.colour_foreground = style.fg[gtk.STATE_NORMAL]

        # filtertree menu
        builder = gtk.Builder()
        builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join('glade', 'filtertree_menu.ui')))
        self.menu = builder.get_object('filtertree_menu')
        builder.connect_signals(self)

        self.default_menu_items = self.menu.get_children()
Beispiel #13
0
    def show(self):
        self.builder = gtk.Builder()

        # The main dialog
        self.builder.add_from_file(
            resource_filename(
                'deluge.ui.gtkui',
                os.path.join('glade', 'create_torrent_dialog.ui')))
        # The remote path dialog
        self.builder.add_from_file(
            resource_filename(
                'deluge.ui.gtkui',
                os.path.join('glade', 'create_torrent_dialog.remote_path.ui')))
        # The remote save dialog
        self.builder.add_from_file(
            resource_filename(
                'deluge.ui.gtkui',
                os.path.join('glade', 'create_torrent_dialog.remote_save.ui')))
        # The progress dialog
        self.builder.add_from_file(
            resource_filename(
                'deluge.ui.gtkui',
                os.path.join('glade', 'create_torrent_dialog.progress.ui')))

        self.config = ConfigManager('gtkui.conf')

        self.dialog = self.builder.get_object('create_torrent_dialog')
        self.dialog.set_transient_for(component.get('MainWindow').window)

        self.builder.connect_signals(self)

        # path, icon, size
        self.files_treestore = gtk.TreeStore(str, str, TYPE_UINT64)

        column = gtk.TreeViewColumn(_('Filename'))
        render = gtk.CellRendererPixbuf()
        column.pack_start(render, False)
        column.add_attribute(render, 'stock-id', 1)
        render = gtk.CellRendererText()
        column.pack_start(render, True)
        column.add_attribute(render, 'text', 0)
        column.set_expand(True)
        self.builder.get_object('treeview_files').append_column(column)

        column = gtk.TreeViewColumn(_('Size'))
        render = gtk.CellRendererText()
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data_size, 2)
        self.builder.get_object('treeview_files').append_column(column)

        self.builder.get_object('treeview_files').set_model(
            self.files_treestore)
        self.builder.get_object('treeview_files').set_show_expanders(False)

        # tier, url
        self.trackers_liststore = gtk.ListStore(int, str)

        self.builder.get_object('tracker_treeview').append_column(
            gtk.TreeViewColumn(_('Tier'), gtk.CellRendererText(), text=0))
        self.builder.get_object('tracker_treeview').append_column(
            gtk.TreeViewColumn(_('Tracker'), gtk.CellRendererText(), text=1))

        self.builder.get_object('tracker_treeview').set_model(
            self.trackers_liststore)
        self.trackers_liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)

        if not client.is_localhost() and client.connected():
            self.builder.get_object('button_remote_path').show()
        else:
            self.builder.get_object('button_remote_path').hide()

        self.dialog.show()
    def show(self):
        """Show the ConnectionManager dialog."""
        self.builder = gtk.Builder()
        self.builder.add_from_file(resource_filename(
            'deluge.ui.gtkui', os.path.join('glade', 'connection_manager.ui')))
        self.connection_manager = self.builder.get_object('connection_manager')
        self.connection_manager.set_transient_for(component.get('MainWindow').window)

        # Create status pixbufs
        if not HOSTLIST_PIXBUFS:
            for stock_id in (gtk.STOCK_NO, gtk.STOCK_YES, gtk.STOCK_CONNECT):
                HOSTLIST_PIXBUFS.append(
                    self.connection_manager.render_icon(stock_id, gtk.ICON_SIZE_MENU))

        # Setup the hostlist liststore and treeview
        self.treeview = self.builder.get_object('treeview_hostlist')
        self.liststore = self.builder.get_object('liststore_hostlist')

        render = gtk.CellRendererPixbuf()
        column = gtk.TreeViewColumn(_('Status'), render)
        column.set_cell_data_func(render, cell_render_status, HOSTLIST_COL_STATUS)
        self.treeview.append_column(column)

        render = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_('Host'), render, text=HOSTLIST_COL_HOST)
        host_data = (HOSTLIST_COL_HOST, HOSTLIST_COL_PORT, HOSTLIST_COL_USER)
        column.set_cell_data_func(render, cell_render_host, host_data)
        column.set_expand(True)
        self.treeview.append_column(column)

        column = gtk.TreeViewColumn(_('Version'), gtk.CellRendererText(), text=HOSTLIST_COL_VERSION)
        self.treeview.append_column(column)

        # Load any saved host entries
        self._load_liststore()
        # Set widgets to values from gtkui config.
        self._load_widget_config()
        self._update_widget_buttons()

        # Connect the signals to the handlers
        self.builder.connect_signals(self)
        self.treeview.get_selection().connect('changed', self.on_hostlist_selection_changed)

        # Set running True before update status call.
        self.running = True

        if windows_check():
            # Call to simulate() required to workaround showing daemon status (see #2813)
            reactor.simulate()
        self._update_host_status()

        # Trigger the on_selection_changed code and select the first host if possible
        self.treeview.get_selection().unselect_all()
        if len(self.liststore):
            self.treeview.get_selection().select_path(0)

        # Run the dialog
        self.connection_manager.run()

        # Dialog closed so cleanup.
        self.running = False
        self.connection_manager.destroy()
        del self.builder
        del self.connection_manager
        del self.liststore
        del self.treeview
Beispiel #15
0
    def __init__(self):
        resource.Resource.__init__(self)

        self.putChild(b'css', LookupResource('Css', rpath('css')))
        if os.path.isfile(rpath('js', 'gettext.js')):
            self.putChild(
                b'gettext.js',
                EncodingResourceWrapper(GetText(), [server.GzipEncoderFactory()]),
            )
        else:
            log.warning(
                'Cannot find "gettext.js" translation file!'
                ' Text will only be available in English.'
            )
            self.putChild(b'gettext.js', MockGetText())
        self.putChild(b'flag', Flag())
        self.putChild(b'icons', LookupResource('Icons', rpath('icons')))
        self.putChild(b'images', LookupResource('Images', rpath('images')))
        self.putChild(
            b'ui_images',
            LookupResource(
                'UI_Images', common.resource_filename('deluge.ui.data', 'pixmaps')
            ),
        )

        js = ScriptResource()

        # configure the dev scripts
        js.add_script(
            'ext-base-debug.js', rpath('js', 'extjs', 'ext-base-debug.js'), 'dev'
        )
        js.add_script(
            'ext-all-debug.js', rpath('js', 'extjs', 'ext-all-debug.js'), 'dev'
        )
        js.add_script_folder(
            'ext-extensions', rpath('js', 'extjs', 'ext-extensions'), 'dev'
        )
        js.add_script_folder('deluge-all', rpath('js', 'deluge-all'), 'dev')

        # configure the debug scripts
        js.add_script(
            'ext-base-debug.js', rpath('js', 'extjs', 'ext-base-debug.js'), 'debug'
        )
        js.add_script(
            'ext-all-debug.js', rpath('js', 'extjs', 'ext-all-debug.js'), 'debug'
        )
        js.add_script(
            'ext-extensions-debug.js',
            rpath('js', 'extjs', 'ext-extensions-debug.js'),
            'debug',
        )
        js.add_script(
            'deluge-all-debug.js', rpath('js', 'deluge-all-debug.js'), 'debug'
        )

        # configure the normal scripts
        js.add_script('ext-base.js', rpath('js', 'extjs', 'ext-base.js'))
        js.add_script('ext-all.js', rpath('js', 'extjs', 'ext-all.js'))
        js.add_script('ext-extensions.js', rpath('js', 'extjs', 'ext-extensions.js'))
        js.add_script('deluge-all.js', rpath('js', 'deluge-all.js'))

        self.js = js
        self.putChild(b'js', js)
        self.putChild(
            b'json', EncodingResourceWrapper(JSON(), [server.GzipEncoderFactory()])
        )
        self.putChild(
            b'upload', EncodingResourceWrapper(Upload(), [server.GzipEncoderFactory()])
        )
        self.putChild(b'render', Render())
        self.putChild(b'themes', Themes(rpath('themes')))
        self.putChild(b'tracker', Tracker())

        theme = component.get('DelugeWeb').config['theme']
        if not os.path.isfile(rpath('themes', 'css', 'xtheme-%s.css' % theme)):
            theme = CONFIG_DEFAULTS.get('theme')
        self.__stylesheets.insert(1, 'themes/css/xtheme-%s.css' % theme)
Beispiel #16
0
    def enable(self):
        """Enables the system tray icon."""
        self.builder = Builder()
        self.builder.add_from_file(
            resource_filename(__package__,
                              os.path.join('glade', 'tray_menu.ui')))

        self.builder.connect_signals(self)

        self.tray_menu = self.builder.get_object('tray_menu')

        if AppIndicator3 and self.config['enable_appindicator']:
            log.debug('Enabling the Application Indicator...')
            self.indicator = AppIndicator3.Indicator.new(
                'deluge',
                'deluge-panel',
                AppIndicator3.IndicatorCategory.APPLICATION_STATUS,
            )
            self.indicator.set_property('title', _('Deluge'))

            # Pass the menu to the Application Indicator
            self.indicator.set_menu(self.tray_menu)

            # Make sure the status of the Show Window MenuItem is correct
            self._sig_win_hide = self.mainwindow.window.connect(
                'hide', self._on_window_hide)
            self._sig_win_show = self.mainwindow.window.connect(
                'show', self._on_window_show)
            if self.mainwindow.visible():
                self.builder.get_object('menuitem_show_deluge').set_active(
                    True)
            else:
                self.builder.get_object('menuitem_show_deluge').set_active(
                    False)

            # Show the Application Indicator
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        else:
            log.debug('Enabling the system tray icon..')
            if windows_check() or osx_check():
                self.tray = StatusIcon.new_from_pixbuf(get_logo(32))
            else:
                self.tray = StatusIcon.new_from_icon_name('deluge-panel')

            self.tray.connect('activate', self.on_tray_clicked)
            self.tray.connect('popup-menu', self.on_tray_popup)

        self.builder.get_object('download-limit-image').set_from_file(
            get_pixmap('downloading16.png'))
        self.builder.get_object('upload-limit-image').set_from_file(
            get_pixmap('seeding16.png'))

        client.register_event_handler('ConfigValueChangedEvent',
                                      self.config_value_changed)
        if client.connected():
            # We're connected so we need to get some values from the core
            self.__start()
        else:
            # Hide menu widgets because we're not connected to a host.
            for widget in self.hide_widget_list:
                self.builder.get_object(widget).hide()
Beispiel #17
0
    def __init__(self):
        if Wnck:
            self.screen = Wnck.Screen.get_default()
        component.Component.__init__(self, 'MainWindow', interval=2)
        self.config = ConfigManager('gtk3ui.conf')
        self.main_builder = Gtk.Builder()

        # Patch this GtkBuilder to avoid connecting signals from elsewhere
        #
        # Think about splitting up  mainwindow gtkbuilder file into the necessary parts
        # to avoid GtkBuilder monkey patch. Those parts would then need adding to mainwindow 'by hand'.
        self.gtk_builder_signals_holder = _GtkBuilderSignalsHolder()
        # FIXME: The deepcopy has been removed: copy.deepcopy(self.main_builder.connect_signals)
        self.main_builder.prev_connect_signals = self.main_builder.connect_signals

        def patched_connect_signals(*a, **k):
            raise RuntimeError(
                'In order to connect signals to this GtkBuilder instance please use '
                '"component.get(\'MainWindow\').connect_signals()"'
            )

        self.main_builder.connect_signals = patched_connect_signals

        # Get Gtk Builder files Main Window, New release dialog, and Tabs.
        ui_filenames = [
            'main_window.ui',
            'main_window.new_release.ui',
            'main_window.tabs.ui',
            'main_window.tabs.menu_file.ui',
            'main_window.tabs.menu_peer.ui',
        ]
        for filename in ui_filenames:
            self.main_builder.add_from_file(
                resource_filename(__package__, os.path.join('glade', filename))
            )

        self.window = self.main_builder.get_object('main_window')
        self.window.set_icon(get_deluge_icon())
        self.tabsbar_pane = self.main_builder.get_object('tabsbar_pane')
        self.sidebar_pane = self.main_builder.get_object('sidebar_pane')

        # Keep a list of components to pause and resume when changing window state.
        self.child_components = ['TorrentView', 'StatusBar', 'TorrentDetails']

        # Load the window state
        self.load_window_state()

        # Keep track of window minimization state so we don't update UI when it is minimized.
        self.is_minimized = False
        self.restart = False

        self.window.drag_dest_set(
            Gtk.DestDefaults.ALL,
            [Gtk.TargetEntry.new(target='text/uri-list', flags=0, info=80)],
            DragAction.COPY,
        )

        # Connect events
        self.window.connect('window-state-event', self.on_window_state_event)
        self.window.connect('configure-event', self.on_window_configure_event)
        self.window.connect('delete-event', self.on_window_delete_event)
        self.window.connect('drag-data-received', self.on_drag_data_received_event)
        self.tabsbar_pane.connect(
            'notify::position', self.on_tabsbar_pane_position_event
        )
        self.sidebar_pane.connect(
            'notify::position', self.on_sidebar_pane_position_event
        )
        self.window.connect('draw', self.on_expose_event)

        self.config.register_set_function(
            'show_rate_in_title', self._on_set_show_rate_in_title, apply_now=False
        )

        client.register_event_handler(
            'NewVersionAvailableEvent', self.on_newversionavailable_event
        )
Beispiel #18
0
    def show(self):
        """Show the ConnectionManager dialog."""
        self.builder = gtk.Builder()
        self.builder.add_from_file(
            resource_filename('deluge.ui.gtkui',
                              os.path.join('glade', 'connection_manager.ui')))
        self.connection_manager = self.builder.get_object('connection_manager')
        self.connection_manager.set_transient_for(
            component.get('MainWindow').window)

        # Create status pixbufs
        if not HOSTLIST_PIXBUFS:
            for stock_id in (gtk.STOCK_NO, gtk.STOCK_YES, gtk.STOCK_CONNECT):
                HOSTLIST_PIXBUFS.append(
                    self.connection_manager.render_icon(
                        stock_id, gtk.ICON_SIZE_MENU))

        # Setup the hostlist liststore and treeview
        self.treeview = self.builder.get_object('treeview_hostlist')
        self.liststore = self.builder.get_object('liststore_hostlist')

        render = gtk.CellRendererPixbuf()
        column = gtk.TreeViewColumn(_('Status'), render)
        column.set_cell_data_func(render, cell_render_status,
                                  HOSTLIST_COL_STATUS)
        self.treeview.append_column(column)

        render = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_('Host'), render, text=HOSTLIST_COL_HOST)
        host_data = (HOSTLIST_COL_HOST, HOSTLIST_COL_PORT, HOSTLIST_COL_USER)
        column.set_cell_data_func(render, cell_render_host, host_data)
        column.set_expand(True)
        self.treeview.append_column(column)

        column = gtk.TreeViewColumn(_('Version'),
                                    gtk.CellRendererText(),
                                    text=HOSTLIST_COL_VERSION)
        self.treeview.append_column(column)

        # Load any saved host entries
        self._load_liststore()
        # Set widgets to values from gtkui config.
        self._load_widget_config()
        self._update_widget_buttons()

        # Connect the signals to the handlers
        self.builder.connect_signals(self)
        self.treeview.get_selection().connect(
            'changed', self.on_hostlist_selection_changed)

        # Set running True before update status call.
        self.running = True

        if windows_check():
            # Call to simulate() required to workaround showing daemon status (see #2813)
            reactor.simulate()
        self._update_host_status()

        # Trigger the on_selection_changed code and select the first host if possible
        self.treeview.get_selection().unselect_all()
        if len(self.liststore):
            self.treeview.get_selection().select_path(0)

        # Run the dialog
        self.connection_manager.run()

        # Dialog closed so cleanup.
        self.running = False
        self.connection_manager.destroy()
        del self.builder
        del self.connection_manager
        del self.liststore
        del self.treeview
Beispiel #19
0
def rpath(*paths):
    """Convert a relative path into an absolute path relative to the location
    of this script.
    """
    return common.resource_filename("deluge.ui.web", os.path.join(*paths))
Beispiel #20
0
    def __init__(self):
        component.Component.__init__(self, 'FilterTreeView', interval=2)
        self.config = ConfigManager('gtkui.conf')

        self.tracker_icons = component.get('TrackerIcons')

        self.sidebar = component.get('SideBar')
        self.treeview = gtk.TreeView()
        self.sidebar.add_tab(self.treeview, 'filters', 'Filters')

        # set filter to all when hidden:
        self.sidebar.notebook.connect('hide', self._on_hide)

        # Create the treestore
        # cat, value, label, count, pixmap, visible
        self.treestore = gtk.TreeStore(str, str, str, int, Pixbuf, bool)

        # Create the column and cells
        column = gtk.TreeViewColumn('Filters')
        column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
        # icon cell
        self.cell_pix = gtk.CellRendererPixbuf()
        column.pack_start(self.cell_pix, expand=False)
        column.add_attribute(self.cell_pix, 'pixbuf', 4)
        # label cell
        cell_label = gtk.CellRendererText()
        cell_label.set_property('ellipsize', ELLIPSIZE_END)
        column.pack_start(cell_label, expand=True)
        column.set_cell_data_func(cell_label, self.render_cell_data, None)
        # count cell
        self.cell_count = gtk.CellRendererText()
        self.cell_count.set_property('xalign', 1.0)
        self.cell_count.set_padding(3, 0)
        column.pack_start(self.cell_count, expand=False)

        self.treeview.append_column(column)

        # Style
        self.treeview.set_show_expanders(True)
        self.treeview.set_headers_visible(False)
        self.treeview.set_level_indentation(-21)
        # Force theme to use expander-size so we don't cut out entries due to indentation hack.
        gtk.rc_parse_string(
            """style "treeview-style" {GtkTreeView::expander-size = 7}
                            class "GtkTreeView" style "treeview-style" """)

        self.treeview.set_model(self.treestore)
        self.treeview.get_selection().connect('changed',
                                              self.on_selection_changed)
        self.create_model_filter()

        self.treeview.connect('button-press-event', self.on_button_press_event)

        # colors using current theme.
        style = component.get('MainWindow').window.get_style()
        self.colour_background = style.bg[gtk.STATE_NORMAL]
        self.colour_foreground = style.fg[gtk.STATE_NORMAL]

        # filtertree menu
        builder = gtk.Builder()
        builder.add_from_file(
            resource_filename('deluge.ui.gtkui',
                              os.path.join('glade', 'filtertree_menu.ui')))
        self.menu = builder.get_object('filtertree_menu')
        builder.connect_signals(self)

        self.default_menu_items = self.menu.get_children()
Beispiel #21
0
    def __init__(self):
        component.Component.__init__(self, 'AddTorrentDialog')
        self.builder = Gtk.Builder()
        # The base dialog
        self.builder.add_from_file(
            resource_filename(__package__,
                              os.path.join('glade', 'add_torrent_dialog.ui')))
        # The infohash dialog
        self.builder.add_from_file(
            resource_filename(
                __package__,
                os.path.join('glade', 'add_torrent_dialog.infohash.ui')))
        # The url dialog
        self.builder.add_from_file(
            resource_filename(
                __package__, os.path.join('glade',
                                          'add_torrent_dialog.url.ui')))

        self.dialog = self.builder.get_object('dialog_add_torrent')

        self.dialog.connect('delete-event', self._on_delete_event)

        self.builder.connect_signals(self)

        # download?, path, filesize, sequence number, inconsistent?
        self.files_treestore = Gtk.TreeStore(bool, str, TYPE_UINT64,
                                             TYPE_INT64, bool, str)
        self.files_treestore.set_sort_column_id(1, Gtk.SortType.ASCENDING)

        # Holds the files info
        self.files = {}
        self.infos = {}
        self.core_config = {}
        self.options = {}

        self.previous_selected_torrent = None

        self.listview_torrents = self.builder.get_object('listview_torrents')
        self.listview_files = self.builder.get_object('listview_files')

        self.prefetching_magnets = []

        render = Gtk.CellRendererText()
        render.connect('edited', self._on_torrent_name_edit)
        render.set_property('editable', True)
        column = Gtk.TreeViewColumn(_('Torrent'), render, text=1)
        self.listview_torrents.append_column(column)

        render = Gtk.CellRendererToggle()
        render.connect('toggled', self._on_file_toggled)
        column = Gtk.TreeViewColumn(None, render, active=0, inconsistent=4)
        self.listview_files.append_column(column)

        column = Gtk.TreeViewColumn(_('Filename'))
        render = Gtk.CellRendererPixbuf()
        column.pack_start(render, False)
        column.add_attribute(render, 'icon-name', 5)
        render = Gtk.CellRendererText()
        render.set_property('editable', True)
        render.connect('edited', self._on_filename_edited)
        column.pack_start(render, True)
        column.add_attribute(render, 'text', 1)
        column.set_expand(True)
        self.listview_files.append_column(column)

        render = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_('Size'))
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data_size, 2)
        self.listview_files.append_column(column)

        self.torrent_liststore = Gtk.ListStore(str, str, str)
        self.listview_torrents.set_model(self.torrent_liststore)
        self.listview_torrents.set_tooltip_column(2)
        self.listview_files.set_model(self.files_treestore)

        self.listview_files.get_selection().set_mode(
            Gtk.SelectionMode.MULTIPLE)
        self.listview_torrents.get_selection().connect(
            'changed', self._on_torrent_changed)
        self.torrent_liststore.connect('row-inserted',
                                       self.update_dialog_title_count)
        self.torrent_liststore.connect('row-deleted',
                                       self.update_dialog_title_count)

        self.setup_move_completed_path_chooser()
        self.setup_download_location_path_chooser()

        # Get default config values from the core
        self.core_keys = [
            'pre_allocate_storage',
            'max_connections_per_torrent',
            'max_upload_slots_per_torrent',
            'max_upload_speed_per_torrent',
            'max_download_speed_per_torrent',
            'prioritize_first_last_pieces',
            'sequential_download',
            'add_paused',
            'download_location',
            'download_location_paths_list',
            'move_completed',
            'move_completed_path',
            'move_completed_paths_list',
            'super_seeding',
        ]
        # self.core_keys += self.move_completed_path_chooser.get_config_keys()
        self.builder.get_object('notebook1').connect('switch-page',
                                                     self._on_switch_page)
Beispiel #22
0
def rpath(*paths):
    """Convert a relative path into an absolute path relative to the location
    of this script.
    """
    return common.resource_filename("deluge.ui.web", os.path.join(*paths))
Beispiel #23
0
    def __init__(self):
        component.Component.__init__(self, 'FilterTreeView', interval=2)
        self.config = ConfigManager('gtk3ui.conf')

        self.tracker_icons = component.get('TrackerIcons')

        self.sidebar = component.get('SideBar')
        self.treeview = Gtk.TreeView()
        self.sidebar.add_tab(self.treeview, 'filters', 'Filters')

        # set filter to all when hidden:
        self.sidebar.notebook.connect('hide', self._on_hide)

        # Create the treestore
        # cat, value, label, count, pixmap, visible
        self.treestore = Gtk.TreeStore(str, str, str, int, Pixbuf, bool)

        # Create the column and cells
        column = Gtk.TreeViewColumn('Filters')
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        # icon cell
        self.cell_pix = Gtk.CellRendererPixbuf()
        column.pack_start(self.cell_pix, expand=False)
        column.add_attribute(self.cell_pix, 'pixbuf', 4)
        # label cell
        cell_label = Gtk.CellRendererText()
        cell_label.set_property('ellipsize', EllipsizeMode.END)
        column.pack_start(cell_label, expand=True)
        column.set_cell_data_func(cell_label, self.render_cell_data, None)
        # count cell
        self.cell_count = Gtk.CellRendererText()
        self.cell_count.set_property('xalign', 1.0)
        self.cell_count.set_padding(3, 0)
        column.pack_start(self.cell_count, expand=False)

        self.treeview.append_column(column)

        # Style
        self.treeview.set_show_expanders(True)
        self.treeview.set_headers_visible(False)
        self.treeview.set_level_indentation(-21)
        # Force theme to use expander-size so we don't cut out entries due to indentation hack.
        provider = Gtk.CssProvider()
        provider.load_from_data('* {-GtkTreeView-expander-size: 9;}'.encode())
        context = self.treeview.get_style_context()
        context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

        self.treeview.set_model(self.treestore)
        self.treeview.get_selection().connect('changed', self.on_selection_changed)
        self.create_model_filter()

        self.treeview.connect('button-press-event', self.on_button_press_event)

        # filtertree menu
        builder = Gtk.Builder()
        builder.add_from_file(
            resource_filename(__package__, os.path.join('glade', 'filtertree_menu.ui'))
        )
        self.menu = builder.get_object('filtertree_menu')
        builder.connect_signals(self)

        self.default_menu_items = self.menu.get_children()

        # add Cat nodes:
        self.cat_nodes = {}
        self.filters = {}