class QueuedTorrents(component.Component): def __init__(self): component.Component.__init__(self, 'QueuedTorrents', depend=['StatusBar', 'AddTorrentDialog']) self.queue = [] self.status_item = None self.config = ConfigManager('gtkui.conf') self.builder = Builder() self.builder.add_from_file(deluge.common.resource_filename( 'deluge.ui.gtkui', os.path.join('glade', 'queuedtorrents.ui'))) self.builder.get_object('chk_autoadd').set_active(self.config['autoadd_queued']) self.dialog = self.builder.get_object('queued_torrents_dialog') self.dialog.set_icon(get_logo(32)) self.builder.connect_signals(self) self.treeview = self.builder.get_object('treeview') self.treeview.append_column(TreeViewColumn(_('Torrent'), CellRendererText(), text=0)) self.liststore = ListStore(str, str) self.treeview.set_model(self.liststore) self.treeview.set_tooltip_column(1) def run(self): self.dialog.set_transient_for(component.get('MainWindow').window) self.dialog.show() def start(self): if len(self.queue) == 0: return # Make sure status bar info is showing self.update_status_bar() # We only want the add button sensitive if we're connected to a host self.builder.get_object('button_add').set_sensitive(True) if self.config['autoadd_queued'] or self.config['standalone']: self.on_button_add_clicked(None) else: self.run() def stop(self): # We only want the add button sensitive if we're connected to a host self.builder.get_object('button_add').set_sensitive(False) self.update_status_bar() def add_to_queue(self, torrents): """Adds the list of torrents to the queue""" # Add to the queue while removing duplicates self.queue = list(set(self.queue + torrents)) # Update the liststore self.liststore.clear() for torrent in self.queue: if deluge.common.is_magnet(torrent): magnet = deluge.common.get_magnet_info(torrent) self.liststore.append([magnet['name'], torrent]) else: self.liststore.append([os.path.split(torrent)[1], torrent]) # Update the status bar self.update_status_bar() def update_status_bar(self): """Attempts to update status bar""" # If there are no queued torrents.. remove statusbar widgets and return if len(self.queue) == 0: if self.status_item is not None: component.get('StatusBar').remove_item(self.status_item) self.status_item = None return False try: component.get('StatusBar') except Exception: # The statusbar hasn't been loaded yet, so we'll add a timer to # update it later. timeout_add(100, self.update_status_bar) return False # Set the label text for statusbar if len(self.queue) > 1: label = str(len(self.queue)) + _(' Torrents Queued') else: label = str(len(self.queue)) + _(' Torrent Queued') # Add the statusbar items if needed, or just modify the label if they # have already been added. if self.status_item is None: self.status_item = component.get('StatusBar').add_item( stock=STOCK_SORT_DESCENDING, text=label, callback=self.on_statusbar_click) else: self.status_item.set_text(label) # We return False so the timer stops return False def on_statusbar_click(self, widget, event): log.debug('on_statusbar_click') self.run() def on_button_remove_clicked(self, widget): selected = self.treeview.get_selection().get_selected()[1] if selected is not None: path = self.liststore.get_value(selected, 1) self.liststore.remove(selected) self.queue.remove(path) self.update_status_bar() def on_button_clear_clicked(self, widget): self.liststore.clear() del self.queue[:] self.update_status_bar() def on_button_close_clicked(self, widget): self.dialog.hide() def on_button_add_clicked(self, widget): # Add all the torrents in the liststore def add_torrent(model, path, _iter, data): torrent_path = model.get_value(_iter, 1).decode('utf-8') process_args([torrent_path]) self.liststore.foreach(add_torrent, None) del self.queue[:] self.dialog.hide() self.update_status_bar() def on_chk_autoadd_toggled(self, widget): self.config['autoadd_queued'] = widget.get_active()
class Requeriment(Expander): def __init__(self, objectives, new): Expander.__init__(self) self.connect("enter-notify-event", self.onEnterNotifyEvent) self.connect("leave-notify-event", self.onLeaveNotifyEvent) vBox = VBox() self.add(vBox) # Data model self.model = ListStore(str, float) # Title bar hBox = HBox() self.set_property("label-widget", hBox) self.title = Label() hBox.pack_start(self.title) # Alternatives treeView = TreeView(self.model) # treeView.set_headers_visible(False) vBox.pack_start(treeView) listStore_objectives = ListStore(str) for name in objectives: listStore_objectives.append((name, )) def combo_changed(_, path, text, model): model[path][0] = text cellRenderer = CellRendererCombo() cellRenderer.connect("edited", combo_changed, self.model) cellRenderer.set_property("text-column", 0) cellRenderer.set_property("editable", True) cellRenderer.set_property("has-entry", True) cellRenderer.set_property("model", listStore_objectives) treeViewColumn = TreeViewColumn("Alternative", cellRenderer, text=0) # treeViewColumn = TreeViewColumn(None,cellRenderer,text=0) treeView.append_column(treeViewColumn) def spin_changed(_, path, value, model): model[path][1] = float(value.replace(",", ".")) cellRenderer = CellRendererSpin() cellRenderer.connect("edited", spin_changed, self.model) cellRenderer.set_property("adjustment", Adjustment(1, 0, 100, 1, 10, 0)) cellRenderer.set_property("editable", True) cellRenderer.set_property("digits", 2) treeViewColumn = TreeViewColumn(None, cellRenderer, text=1) treeView.append_column(treeViewColumn) # Add/remove alternative button box # hButtonBox = HButtonBox() # vBox.pack_start(hButtonBox, False) # Add alternative button = Button("gtk-add") button.connect("clicked", self.on_btnAdd_Alternative_clicked) button.set_use_stock(True) # hButtonBox.pack_start(button) vBox.pack_start(button, False) # # Remove alternative # button = Button("gtk-remove") # button.connect("clicked",self.on_btnDel_Alternative_clicked) # button.set_use_stock(True) # hButtonBox.pack_start(button) # Expand the requeriment and add an alternative if it's new if new: self.set_expanded(True) self.model.append((None, 1.0)) # Show requeriment self.show_all() # Delete requeriment button (default is hidden) self.imgRemove = Image() self.imgRemove.connect("button-press-event", self.onDelRequeriment) self.imgRemove.set_from_stock("gtk-cancel", ICON_SIZE_MENU) hBox.pack_start(self.imgRemove) def Add(self, alternative): self.model.append(alternative) names = [] iter = self.model.get_iter_first() while iter: alt = self.model.get_value(iter, 0) if alt: names.append(alt) iter = self.model.iter_next(iter) self.title.set_text(','.join(names)) def GetData(self): result = OrderedDict() iter = self.model.get_iter_first() while iter: alt = self.model.get_value(iter, 0) if alt: result[alt] = self.model.get_value(iter, 1) iter = self.model.iter_next(iter) return result def onDelRequeriment(self, widget): self.get_parent().remove(self) def onEnterNotifyEvent(self, widget, event): self.imgRemove.show() def onLeaveNotifyEvent(self, widget, event): self.imgRemove.hide() def __btnDel_Alternative_Sensitivity(self): pass # self.__btnDel.set_sensitive(len(self.__model.)) def on_btnAdd_Alternative_clicked(self, widget): self.model.append((None, 1.0)) self.__btnDel_Alternative_Sensitivity() def on_btnDel_Alternative_clicked(self, widget): self.__btnDel_Alternative_Sensitivity()
class InputWidget(Component): """Input mode widget for Rainbow theme.""" def __init__(self, component_manager): Component.__init__(self, component_manager) self.w_tree = self.main_widget().w_tree self.get_widget = get_widget = self.w_tree.get_widget self.conf = self.config() self.connections = [] self.connect_signals([\ ("input_mode_toolbar_button_back_w", "clicked", \ self.input_to_main_menu_cb), ("front_to_back_mode_selector_w", "released", \ self.change_card_type_cb), ("both_way_mode_selector_w", "released", self.change_card_type_cb), ("three_side_mode_selector_w", "released", \ self.change_card_type_cb), ("cloze_mode_selector_w", "released", self.change_card_type_cb), ("picture_content_button", "clicked", self.add_picture_cb), ("image_selection_dialog_button_select", "clicked", \ self.select_item_cb), ("image_selection_dialog_button_close", "clicked", self.close_media_selection_dialog_cb), ("input_mode_prev_category_w", "clicked", self.change_category_cb), ("input_mode_next_category_w", "clicked", self.change_category_cb), ("input_mode_add_new_category_w", "clicked", \ self.create_new_category_cb), ("sound_content_button", "clicked", self.add_sound_cb), ("category_name_container", "clicked", \ self.show_add_category_block_cb), ("input_mode_close_add_category_block_w", "clicked", self.hide_add_category_block_cb), ("input_mode_snd_button", "released", \ self.preview_sound_in_input_cb)]) self.fact = None self.sounddir = None self.imagedir = None self.card_type = None self.categories_list = [] self.added_new_cards = False #liststore = [text, type, filename, dirname, pixbuf] self.liststore = ListStore(str, str, str, str, gtk.gdk.Pixbuf) iconview_widget = get_widget("iconview_widget") iconview_widget.set_model(self.liststore) iconview_widget.set_pixbuf_column(4) iconview_widget.set_text_column(0) get_widget = self.get_widget # Widgets as attributes self.areas = {# Text areas "cloze": get_widget("cloze_text_w"), "answer": get_widget("answer_text_w"), "foreign": get_widget("foreign_text_w"), "question": get_widget("question_text_w"), "translation": get_widget("translation_text_w"), "pronunciation": get_widget("pronun_text_w") } # Mandatory color setup fot GtkTextView for area in self.areas.values(): area.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) area.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000")) # Change default font font = pango.FontDescription("Nokia Sans %s" % \ (self.conf['font_size'] - FONT_DISTINCTION)) for area in self.areas.values(): area.modify_font(font) self.widgets = {# Other widgets "CurrentCategory": get_widget("category_name_w"), "SoundButton": get_widget("sound_content_button"), "PictureButton": get_widget("picture_content_button"), "SoundIndicator": get_widget("input_mode_snd_button"), "CardTypeSwithcer": get_widget("card_type_switcher_w"), "MediaDialog": get_widget("media_selection_dialog"), "SoundContainer": get_widget("input_mode_snd_container"), "QuestionContainer": get_widget("input_mode_question_container"), "NewCategory": get_widget("input_mode_new_category_entry"), "ChangeCategoryBlock": get_widget(\ "input_mode_change_category_block"), "AddCategoryBlock": get_widget("input_mode_add_category_block") } # Mandatory color setup fot GtkEntry self.widgets["NewCategory"].modify_base(gtk.STATE_NORMAL, \ gtk.gdk.color_parse("#FFFFFF")) self.widgets["NewCategory"].modify_text(gtk.STATE_NORMAL, \ gtk.gdk.color_parse("#000000")) # card_id: {"page": page_id, "selector": selector_widget, # "widgets": [(field_name:text_area_widget)...]} self.selectors = { FrontToBack.id: { "page": 0, "selector": get_widget("front_to_back_mode_selector_w"), "widgets": [('q', self.areas["question"]), ('a', self.areas["answer"])] }, BothWays.id: { "page": 0, "selector": get_widget("both_way_mode_selector_w"), "widgets": [('q', self.areas["question"]), ('a', self.areas["answer"])] }, ThreeSided.id: { "page": 1, "selector": get_widget("three_side_mode_selector_w"), "widgets": [('f', self.areas["foreign"]), ('t', self.areas["translation"]), ('p', self.areas["pronunciation"])] }, Cloze.id: { "page": 2, "selector": get_widget("cloze_mode_selector_w"), "widgets": [('text', self.areas["cloze"])] } } # add card_type to selectors subdict for card_type in self.card_types(): self.selectors[card_type.id]["card_type"] = card_type # create {selector_widget:card_type.id} dict self.widget_card_id = dict((self.selectors[id]["selector"], id) \ for id in self.selectors.keys()) self.set_card_type(get_widget("front_to_back_mode_selector_w")) self.compose_widgets() # Turn off hildon autocapitalization try: for widget in self.areas.values(): widget.set_property("hildon-input-mode", 'full') # stock gtk doesn't have hildon properties except (TypeError, AttributeError): pass # so, skip silently def connect_signals(self, control): """Connect signals to widgets and save connection info.""" for wname, signal, callback in control: widget = self.get_widget(wname) cid = widget.connect(signal, callback) self.connections.append((widget, cid)) def disconnect_signals(self): """Disconnect previously connected signals.""" for widget, cid in self.connections: widget.disconnect(cid) self.connections = [] def show_snd_container(self): """Show or hide snd container. """ start, end = self.areas["question"].get_buffer().get_bounds() text = self.areas["question"].get_buffer().get_text(start, end) if "sound src=" in text: self.widgets["QuestionContainer"].hide() self.widgets["SoundContainer"].show() else: self.widgets["QuestionContainer"].show() self.widgets["SoundContainer"].hide() def compose_widgets (self): """Switch to neccessary input page. It depends on card_type.""" self.widgets["CardTypeSwithcer"].set_current_page( \ self.selectors[self.card_type.id]["page"]) self.selectors[self.card_type.id]["selector"].set_active(True) state = self.card_type.id in (FrontToBack.id) self.widgets["PictureButton"].set_sensitive(state) self.widgets["SoundButton"].set_sensitive(state) def set_card_type(self, widget): """Set current card type.""" card_type_id = self.widget_card_id[widget] self.card_type = self.selectors[card_type_id]["card_type"] def update_categories(self): """Update categories list content.""" if not self.categories_list: categories = dict([(i, name) for (i, name) in \ enumerate(self.database().tag_names())]) if categories.values(): for category in sorted(categories.values()): self.categories_list.append(category) self.widgets["CurrentCategory"].set_text( \ sorted(categories.values())[0]) else: self.categories_list.append("default category") self.widgets["CurrentCategory"].set_text("default category") def check_complete_input(self): """Check for non empty fields.""" pattern_list = ["Type %s here..." % item for item in ["ANSWER", \ "QUESTION", "FOREIGN", "PRONUNCIATION", "TRANSLATION", "TEXT"]] pattern_list.append("") for selector in self.selectors[self.card_type.id]["widgets"]: buf = selector[1].get_buffer() start, end = buf.get_bounds() if buf.get_text(start, end) in pattern_list: return False return True def change_category_cb(self, widget): """Change current category.""" if widget.name == "prev_category_w": direction = -1 direction = 1 category_index = self.categories_list.index( \ self.widgets["CurrentCategory"].get_text()) try: new_category = self.categories_list[category_index + direction] except IndexError: if direction: new_category = self.categories_list[0] else: new_category = self.categories_list[len(self.categories_list)-1] self.widgets["CurrentCategory"].set_text(new_category) def create_new_category_cb(self, widget): """Create new category.""" new_category = self.widgets["NewCategory"].get_text() if new_category: self.categories_list.append(new_category) self.widgets["NewCategory"].set_text("") self.widgets["CurrentCategory"].set_text(new_category) self.hide_add_category_block_cb(None) def add_picture_cb(self, widget): """Show image selection dialog.""" self.main_widget().soundplayer.stop() self.liststore.clear() self.imagedir = self.conf['imagedir'] if not os.path.exists(self.imagedir): self.imagedir = "./images" # on Desktop if not os.path.exists(self.imagedir): self.main_widget().information_box(\ _("'Images' directory does not exist!")) return if os.listdir(self.imagedir): self.widgets["MediaDialog"].show() for fname in os.listdir(self.imagedir): if os.path.isfile(os.path.join(self.imagedir, fname)): pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(\ os.path.join(self.imagedir, fname), 100, 100) self.liststore.append(["", "img", fname, \ self.imagedir, pixbuf]) else: self.main_widget().information_box(\ _("There are no files in 'Images' directory!")) def select_item_cb(self, widget): """ Set html-text with media path and type when user select media filefrom media selection dialog. """ self.widgets["MediaDialog"].hide() item_index = self.w_tree.get_widget("iconview_widget"). \ get_selected_items()[0] item_type = self.liststore.get_value( \ self.liststore.get_iter(item_index), 1) item_fname = self.liststore.get_value( \ self.liststore.get_iter(item_index), 2) item_dirname = self.liststore.get_value( \ self.liststore.get_iter(item_index), 3) question_text = """<%s src="%s">""" % \ (item_type, os.path.abspath(os.path.join(item_dirname, item_fname))) self.areas["question"].get_buffer().set_text(question_text) self.show_snd_container() def add_sound_cb(self, widget): """Show sound selection dialog.""" self.main_widget().soundplayer.stop() self.liststore.clear() self.sounddir = self.conf['sounddir'] if not os.path.exists(self.sounddir): self.sounddir = "./sounds" # on Desktop if not os.path.exists(self.sounddir): self.main_widget().information_box(\ _("'Sounds' directory does not exist!")) return if os.listdir(self.sounddir): self.widgets["MediaDialog"].show() for fname in os.listdir(self.sounddir): if os.path.isfile(os.path.join(self.sounddir, fname)): sound_logo_file = os.path.join( \ self.conf["theme_path"], "soundlogo.png") pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(\ sound_logo_file, 100, 100) self.liststore.append([fname, "sound", fname, \ self.sounddir, pixbuf]) else: self.main_widget().information_box(\ _("There are no files in 'Sounds' directory!")) def get_widgets_data(self, check_for_required=True): """ Get data from widgets. """ fact = {} for fact_key, widget in self.selectors[self.card_type.id]["widgets"]: start, end = widget.get_buffer().get_bounds() fact[fact_key] = widget.get_buffer().get_text(start, end) if check_for_required: for required in self.card_type.required_fields: if not fact[required]: raise ValueError return fact def set_widgets_data(self, fact): """Set widgets data from fact.""" for fact_key, widget in self.selectors[self.card_type.id]["widgets"]: widget.get_buffer().set_text(fact[fact_key]) def clear_widgets(self): """Clear data in widgets.""" for caption in self.areas.keys(): self.areas[caption].get_buffer().set_text( \ "Type %s here..." % caption.upper()) def change_card_type_cb(self, widget): """Change cardtype when user choose it from cardtype column.""" self.main_widget().soundplayer.stop() self.clear_widgets() self.show_snd_container() self.set_card_type(widget) self.compose_widgets() def preview_sound_in_input_cb(self, widget): """Preview sound in input mode.""" if widget.get_active(): start, end = self.areas["question"].get_buffer().get_bounds() text = self.areas["question"].get_buffer().get_text(start, end) self.main_widget().soundplayer.play(text, self) else: self.main_widget().soundplayer.stop() def update_indicator(self): """Set non active state for widget.""" self.widgets["SoundIndicator"].set_active(False) def close_media_selection_dialog_cb(self, widget): """Close image selection dialog.""" self.widgets["MediaDialog"].hide() def show_add_category_block_cb(self, widget): """Show add category block.""" self.widgets["ChangeCategoryBlock"].hide() self.widgets["AddCategoryBlock"].show() self.widgets["NewCategory"].grab_focus() def hide_add_category_block_cb(self, widget): """Hide add category block.""" self.widgets["ChangeCategoryBlock"].show() self.widgets["AddCategoryBlock"].hide() def input_to_main_menu_cb(self, widget): """Return to main menu.""" #if self.added_new_cards: #self.review_controller().reset() #self.added_new_cards = False self.disconnect_signals() self.main_widget().soundplayer.stop() self.main_widget().menu_()