def run_dialog(channel): """Displays the feed settings panel dialog.""" pref_window = MainDialog(_("Feed Settings")) try: try: v = widgetset.VBox(spacing=10) v.pack_start(widgetutil.align_left(_build_header(channel), left_pad=20, right_pad=20)) v.pack_start(separator.HThinSeparator((0.6, 0.6, 0.6)), padding=18) grid = dialogwidgets.ControlGrid() _build_auto_download(channel, grid) grid.end_line(spacing=20) _build_video_expires(channel, grid) grid.end_line(spacing=20) _build_remember_items(channel, grid) v.pack_start(widgetutil.align_left(grid.make_table(), left_pad=20, right_pad=20)) v.pack_end(separator.HThinSeparator((0.6, 0.6, 0.6)), padding=6) pref_window.set_extra_widget(v) pref_window.add_button(BUTTON_DONE.text) pref_window.run() except StandardError: logging.exception("feed settings panel threw exception.") finally: pref_window.destroy()
def run_dialog(channel): """Displays the feed settings panel dialog.""" pref_window = MainDialog(_("Podcast Settings")) try: try: v = widgetset.VBox(spacing=10) v.pack_start( widgetutil.align_left(_build_header(channel), left_pad=20, right_pad=20)) v.pack_start(separator.HThinSeparator((0.6, 0.6, 0.6)), padding=18) grid = dialogwidgets.ControlGrid() _build_auto_download(channel, grid) grid.end_line(spacing=20) _build_video_expires(channel, grid) grid.end_line(spacing=20) _build_remember_items(channel, grid) v.pack_start( widgetutil.align_left(grid.make_table(), left_pad=20, right_pad=20)) v.pack_end(separator.HThinSeparator((0.6, 0.6, 0.6)), padding=6) pref_window.set_extra_widget(v) pref_window.add_button(BUTTON_DONE.text) pref_window.run() except StandardError: logging.exception("feed settings panel threw exception.") finally: pref_window.destroy()
def _run_dialog(title, description, default_type): """Creates and launches the New Folder dialog. This dialog waits for the user to press "Create Folder" or "Cancel". Returns a tuple of the (name, section). """ window = MainDialog(title, description) try: try: window.add_button(BUTTON_CREATE_FOLDER.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() lab = widgetset.Label(_('Folder name:')) name_entry = widgetset.TextEntry() name_entry.set_activates_default(True) h = widgetset.HBox() h.pack_start(lab, padding=5) h.pack_start(name_entry, expand=True) extra.pack_start(h, padding=5) lab = widgetset.Label(_('Folder should go in this section:')) rbg = widgetset.RadioButtonGroup() video_rb = widgetset.RadioButton(_("video"), rbg) audio_rb = widgetset.RadioButton(_("audio"), rbg) if default_type == 'feed': video_rb.set_selected() else: audio_rb.set_selected() extra.pack_start(widgetutil.build_hbox((lab, video_rb, audio_rb))) window.set_extra_widget(extra) response = window.run() if response == 0: if rbg.get_selected() == video_rb: section = u"video" else: section = u"audio" name = name_entry.get_text() if name: return (name, section) return (None, None) except StandardError: logging.exception("newfeed threw exception.") finally: window.destroy()
def _run_dialog(iteminfo): """Creates and launches the item edit dialog. This dialog waits for the user to press "Apply" or "Cancel". Returns a dict of new name -> value. """ window = MainDialog(_("Edit Item"), "") try: try: window.add_button(BUTTON_APPLY.text) window.add_button(BUTTON_CANCEL.text) sections = [] sections.append(build_text_entry("name", _("Title:"), iteminfo.name)) sections.append(build_multiline_text_entry("description", _("Description:"), iteminfo.description)) sections.append( build_radio( "file_type", _("Media type:"), iteminfo.file_type, [(_("Video"), u"video"), (_("Audio"), u"audio"), (_("Other"), u"other")], ) ) # we do this to force wrapping at 50 characters sections.append(build_info(_("Path:"), "\n".join(textwrap.wrap(iteminfo.video_path, 50)))) grid = dialogwidgets.ControlGrid() for lab, sec, handler in sections: vbox = widgetset.VBox() vbox.pack_start(lab, expand=True, padding=2) grid.pack(vbox, grid.ALIGN_RIGHT) grid.pack(sec, grid.FILL) grid.end_line(spacing=8) window.set_extra_widget(grid.make_table()) response = window.run() response_dict = {} if response == 0: for lab, sec, handler in sections: handler(response_dict) return response_dict except StandardError: logging.exception("itemedit threw exception.") finally: window.destroy()
def run_dialog(report): window = MainDialog(_("Internal Error")) try: try: vbox = widgetset.VBox(spacing=5) lab = widgetset.Label(_( "%(appname)s has encountered an internal error. You can " "help us track down this problem and fix it by submitting " "an error report.", {"appname": app.config.get(prefs.SHORT_APP_NAME)} )) lab.set_wrap(True) lab.set_size_request(600, -1) vbox.pack_start(widgetutil.align_left(lab)) cbx = widgetset.Checkbox(_( "Include entire program database including all video and " "feed metadata with crash report" )) vbox.pack_start(widgetutil.align_left(cbx)) lab2 = widgetset.Label(_("Describe what you were doing when you got this error:")) vbox.pack_start(widgetutil.align_left(lab2)) text = widgetset.MultilineTextEntry() text.set_size_request(600, 100) vbox.pack_start(widgetutil.align_left(text)) window.set_extra_widget(vbox) window.add_button(BUTTON_SUBMIT_REPORT.text) window.add_button(BUTTON_IGNORE.text) ret = window.run() if ret == 0: messages.ReportCrash(report, text.get_text(), cbx.get_checked()).send_to_backend() else: return IGNORE_ERRORS except StandardError: logging.exception("crashdialog threw exception.") finally: window.destroy()
def _run_dialog(title, description, initial_text): """Creates and launches the New Feed dialog. This dialog waits for the user to press "Create Podcast" or "Cancel". Returns the URL, or None. """ window = MainDialog(title, description) try: try: window.add_button(BUTTON_CREATE_FEED.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() lab = widgetset.Label(_('URL:')) url_entry = widgetset.TextEntry() url_entry.set_text(initial_text) url_entry.set_activates_default(True) h = widgetset.HBox() h.pack_start(lab, padding=5) h.pack_start(url_entry, expand=True) extra.pack_start(h, padding=5) window.set_extra_widget(extra) response = window.run() if response == 0: text = url_entry.get_text() return text return None except StandardError: logging.exception("newfeed threw exception.") finally: window.destroy()
def _run_dialog(title, description, default_type): """Creates and launches the New Folder dialog. This dialog waits for the user to press "Create Folder" or "Cancel". Returns a the name, or None. """ window = MainDialog(title, description) try: try: window.add_button(BUTTON_CREATE_FOLDER.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() lab = widgetset.Label(_('Folder name:')) name_entry = widgetset.TextEntry() name_entry.set_activates_default(True) h = widgetset.HBox() h.pack_start(lab, padding=5) h.pack_start(name_entry, expand=True) extra.pack_start(h, padding=5) window.set_extra_widget(extra) response = window.run() if response == 0: name = name_entry.get_text() if name: return name return None except StandardError: logging.exception("newfeed threw exception.") finally: window.destroy()
def run_dialog(): """Creates and launches the Add to Playlist dialog. This dialog waits for the user to press "Add" or "Cancel". In the case of "Add", returns a tuple of: * ("new", playlist_name) * ("existing", playlist id) In the case of "Cancel", returns None. """ title = _('Add a Playlist') description = _('Add items to an existing playlist or a new one.') playlists = app.tabs['playlist'].get_playlists() playlists = [pi for pi in playlists if not pi.is_folder] playlists.sort(key=lambda x: name_sort_key(x.name)) window = MainDialog(title, description) try: try: window.add_button(BUTTON_ADD.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() choice_table = widgetset.Table(columns=2, rows=2) choice_table.set_column_spacing(5) choice_table.set_row_spacing(5) rbg = widgetset.RadioButtonGroup() existing_rb = widgetset.RadioButton(_("Existing playlist:"), rbg) existing_option = widgetset.OptionMenu( [clamp_text(pi.name) for pi in playlists]) choice_table.pack(existing_rb, 0, 0) choice_table.pack(existing_option, 1, 0) new_rb = widgetset.RadioButton(_("New playlist:"), rbg) new_text = widgetset.TextEntry() new_text.set_activates_default(True) choice_table.pack(new_rb, 0, 1) choice_table.pack(new_text, 1, 1) # only the existing row is enabled choice_table.disable(row=1, column=1) def handle_clicked(widget): # this enables and disables the fields in the table # based on which radio button is selected if widget is existing_rb: choice_table.enable(row=0, column=1) choice_table.disable(row=1, column=1) else: choice_table.disable(row=0, column=1) choice_table.enable(row=1, column=1) if new_rb.get_selected(): new_text.focus() existing_rb.connect('clicked', handle_clicked) new_rb.connect('clicked', handle_clicked) existing_rb.set_selected() extra.pack_start(widgetutil.align_top(choice_table, top_pad=6)) window.set_extra_widget(extra) response = window.run() if response == 0: selected_option = rbg.get_selected() if selected_option is existing_rb and len(playlists) > 0: return ("existing", playlists[existing_option.get_selected()]) elif new_text.get_text(): return ("new", new_text.get_text()) except StandardError: logging.exception("addtoplaylistdialog threw exception.") finally: window.destroy()
class NewSearchFeedDialogRunner(object): """Helper class that runs the new search feed dialog. This class basically splits up the work needed to create the dialog. """ def __init__(self, title, description): self.window = MainDialog(title, description) self.get_channel_info() self.get_search_engine_info() self.build_widgets() self.set_initial_search_text() self.set_initial_source() def get_channel_info(self): self.channels = [ci for ci in app.tabs['feed'].get_feeds() if not (ci.is_folder or ci.is_directory_feed)] self.channels.sort(key=lambda x: util.name_sort_key(x.name)) def get_search_engine_info(self): self.search_engines = searchengines.get_search_engines() def build_widgets(self): self.window.add_button(BUTTON_CREATE_FEED.text) self.window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() hb1 = widgetset.HBox() hb1.pack_start(widgetset.Label(_('Search for:')), padding=5) self.searchterm = widgetset.TextEntry() self.searchterm.set_activates_default(True) hb1.pack_start(self.searchterm, expand=True) extra.pack_start(hb1) hb2 = widgetset.HBox() hb2.pack_start(widgetutil.align_top( widgetset.Label(_('In this:')), top_pad=3), padding=5) self.choice_table = widgetset.Table(columns=2, rows=3) self.choice_table.set_column_spacing(5) self.choice_table.set_row_spacing(5) self.rbg = widgetset.RadioButtonGroup() self.channel_rb = widgetset.RadioButton(_("Podcast:"), self.rbg) self.channel_option = widgetset.OptionMenu( [ci.name + u" - " + ci.url for ci in self.channels]) self.channel_option.set_size_request(250, -1) self.choice_table.pack(self.channel_rb, 0, 0) self.choice_table.pack(self.channel_option, 1, 0) self.search_engine_rb = widgetset.RadioButton(_("Search engine:"), self.rbg) self.search_engine_option = widgetset.OptionMenu( [se.title for se in self.search_engines]) self.choice_table.pack(self.search_engine_rb, 0, 1) self.choice_table.pack(self.search_engine_option, 1, 1) url_rb = widgetset.RadioButton(_("URL:"), self.rbg) self.url_text = widgetset.TextEntry() self.choice_table.pack(url_rb, 0, 2) self.choice_table.pack(self.url_text, 1, 2) hb2.pack_start(self.choice_table, expand=True) # by default only the channel row is enabled self.enable_choice_table_row(0) def handle_clicked(widget): # this enables and disables the fields in the table # based on which radio button is selected if widget is self.channel_rb: self.enable_choice_table_row(0) elif widget is self.search_engine_rb: self.enable_choice_table_row(1) else: self.enable_choice_table_row(2) self.channel_rb.connect('clicked', handle_clicked) self.search_engine_rb.connect('clicked', handle_clicked) url_rb.connect('clicked', handle_clicked) extra.pack_start(widgetutil.align_top(hb2, top_pad=6)) self.window.set_extra_widget(extra) def enable_choice_table_row(self, row_index): for i in range(3): if i == row_index: self.choice_table.enable(row=i, column=1) else: self.choice_table.disable(row=i, column=1) def run_dialog(self): response = self.window.run() if response == 0 and self.searchterm.get_text(): term = self.searchterm.get_text() selected_option = self.rbg.get_selected() if selected_option is self.channel_rb: return ("feed", self.channels[self.channel_option.get_selected()], term) elif selected_option is self.search_engine_rb: index = self.search_engine_option.get_selected() return ("search_engine", self.search_engines[index], term) else: return ("url", self.url_text.get_text(), term) return None def set_initial_search_text(self): """Setup the initial search text """ initial = app.item_list_controller_manager.get_saved_search_text() if initial: self.searchterm.set_text(initial) def set_initial_source(self): source = app.item_list_controller_manager.get_saved_search_source() if source is not None: typ, id_ = source if typ == 'channel': self.channel_rb.set_selected() for i, info in enumerate(self.channels): if info.id == id_: self.channel_option.set_selected(i) break else: # bz:17818 # Watched folders are not listed in this dialog, but is # in the feed/channel category. So we could come here # with a watched folder selected, and fall into else # path. There used to be a soft failure here, now # I think it is okay if we just print a debug message. logging.debug(("didn't find channel with id: %r " "(possibly watched folder selected)"), id_) elif typ == 'search': self.search_engine_rb.set_selected() self.enable_choice_table_row(1) for i, info in enumerate(self.search_engines): if info.name == id_: self.search_engine_option.set_selected(i) break else: app.widgetapp.handle_soft_failure("New search feed dialog", "didn't find search engine with id: %r" % id_, with_exception=False) else: app.widgetapp.handle_soft_failure("New search feed dialog", "unknown source type %r" % typ, with_exception=False)
def run_dialog(channel_infos, downloaded_items, downloading_items, has_watched_feeds): """Displays the remove feeds dialog.""" title = ngettext('Remove Feed', 'Remove Feeds', len(channel_infos)) rc_window = MainDialog(title) try: try: v = widgetset.VBox(spacing=5) lab = widgetset.Label(ngettext( "Are you sure you want to remove this feed:", "Are you sure you want to remove these feeds:", len(channel_infos) )) lab.set_wrap(True) v.pack_start(widgetutil.align_left(lab)) v2 = widgetset.VBox() lab_height = None for mem in channel_infos: lab_mem = widgetset.Label(util.clamp_text(mem.name, 40)) if lab_height is None: dummy, lab_height = lab_mem.get_size_request() v2.pack_start(widgetutil.align_left(lab_mem, left_pad=15)) if len(channel_infos) > 5: scroller = widgetset.Scroller(False, True) scroller.set_has_borders(True) scroller.add(v2) scroller_width, scroller_height = scroller.get_size_request() if scroller_height == 0: scroller.set_size_request(scroller_width, 5 * (lab_height + 1)) v2 = scroller v.pack_start(v2, padding=10) cbx_downloaded = None if downloaded_items: cbx_downloaded = widgetset.Checkbox(_("Keep items that have been downloaded in my library.")) v.pack_start(widgetutil.align_left(cbx_downloaded, bottom_pad=5)) if has_watched_feeds: lab = widgetset.Label(_( "Watched folders will be removed from the sidebar but their contents will " "still appear in your library. You can stop watching watched folders completely " "in the %(appname)s preference panel.", {"appname": app.config.get(prefs.SHORT_APP_NAME)} )) lab.set_wrap(True) lab.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab, bottom_pad=5)) if downloading_items: lab_downloading = widgetset.Label(ngettext( "Are you sure you want to remove this feed? " "The downloads currently in progress will be canceled.", "Are you sure you want to remove these feeds? " "The downloads currently in progress will be canceled.", len(channel_infos) )) lab_downloading.set_wrap(True) lab_downloading.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab_downloading)) rc_window.set_extra_widget(v) rc_window.add_button(BUTTON_REMOVE.text) rc_window.add_button(BUTTON_CANCEL.text) ret = rc_window.run() if ret == 0: # this is silly, but it sets us up for adding additional # bits later. ret = {KEEP_ITEMS: False} if downloaded_items: ret[KEEP_ITEMS] = cbx_downloaded.get_checked() return ret except StandardError: logging.exception("removefeeds threw exception.") finally: rc_window.destroy()
def run_dialog(): """Displays a diagnostics windows that tells a user how Miro is set up on their machine. """ window = MainDialog(_("Diagnostics")) try: items = [{ "label": _("Movies location:"), "data": app.config.get(prefs.MOVIES_DIRECTORY), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.MOVIES_DIRECTORY)) }, { "label": _("Icon cache location:"), "data": app.config.get(prefs.ICON_CACHE_DIRECTORY), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.ICON_CACHE_DIRECTORY)) }, { "label": _("Log file location:"), "data": app.config.get(prefs.LOG_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.LOG_PATHNAME)) }, { "label": _("Downloader log file location:"), "data": app.config.get(prefs.DOWNLOADER_LOG_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.DOWNLOADER_LOG_PATHNAME)) }, { "label": _("Database file location:"), "data": app.config.get(prefs.SQLITE_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.SQLITE_PATHNAME)) }, { "label": _("Crash reports location:"), "data": app.config.get(prefs.CRASH_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.CRASH_PATHNAME)) }, SEPARATOR, { "label": _("Space free on disk:"), "data": lambda: util.format_size_for_user(get_available_bytes_for_movies(), "0B", False) }, { "label": _("Database size:"), "data": lambda: util.format_size_for_user(get_database_size(), "0B", False) }, { "label": _("Total db objects in memory:"), "data": lambda: "%d" % get_database_object_count() }, SEPARATOR, { "label": _("Total db backups:"), "data": "", "button_face": _("%(databasecount)s: Delete", {"databasecount": len(app.db.get_backup_databases())}), "button_fun": delete_backups }] t = widgetset.Table(3, len(items)) t.set_column_spacing(10) for row_num, item in enumerate(items): if item is SEPARATOR: t.pack(widgetset.Label(""), 0, row_num) continue label = item.get("label") lab = widgetset.Label(label) lab.set_bold(True) t.pack(widgetutil.align_left(lab), 0, row_num) data = item.get("data") if callable(data): data = data() if not isinstance(data, basestring): data = repr(data) datalab = widgetset.Label(data) t.pack(widgetutil.align_left(datalab), 1, row_num) if item.get("button_face"): b = widgetset.Button(item["button_face"]) b.set_size(widgetconst.SIZE_SMALL) b.connect('clicked', item["button_fun"]) t.pack(widgetutil.align_left(b), 2, row_num) window.set_extra_widget(t) window.add_button(BUTTON_OK.text) window.run() finally: window.destroy()
def run_dialog(): """Creates and launches the Add to Playlist dialog. This dialog waits for the user to press "Add" or "Cancel". In the case of "Add", returns a tuple of: * ("new", playlist_name) * ("existing", playlist id) In the case of "Cancel", returns None. """ title = _('Add a Playlist') description = _('Add items to an existing playlist or a new one.') playlists = app.tab_list_manager.playlist_list.get_playlists() playlists = [pi for pi in playlists if not pi.is_folder] playlists.sort(key=lambda x: name_sort_key(x.name)) window = MainDialog(title, description) try: try: window.add_button(BUTTON_ADD.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() choice_table = widgetset.Table(columns=2, rows=2) choice_table.set_column_spacing(5) choice_table.set_row_spacing(5) rbg = widgetset.RadioButtonGroup() existing_rb = widgetset.RadioButton(_("Existing playlist:"), rbg) existing_option = widgetset.OptionMenu([clamp_text(pi.name) for pi in playlists]) choice_table.pack(existing_rb, 0, 0) choice_table.pack(existing_option, 1, 0) new_rb = widgetset.RadioButton(_("New playlist:"), rbg) new_text = widgetset.TextEntry() new_text.set_activates_default(True) choice_table.pack(new_rb, 0, 1) choice_table.pack(new_text, 1, 1) # only the existing row is enabled choice_table.disable(row=1, column=1) def handle_clicked(widget): # this enables and disables the fields in the table # based on which radio button is selected if widget is existing_rb: choice_table.enable(row=0, column=1) choice_table.disable(row=1, column=1) else: choice_table.disable(row=0, column=1) choice_table.enable(row=1, column=1) if new_rb.get_selected(): new_text.focus() existing_rb.connect('clicked', handle_clicked) new_rb.connect('clicked', handle_clicked) extra.pack_start(widgetutil.align_top(choice_table, top_pad=6)) window.set_extra_widget(extra) response = window.run() if response == 0: selected_option = rbg.get_selected() if selected_option is existing_rb and len(playlists) > 0: return ("existing", playlists[existing_option.get_selected()]) elif new_text.get_text(): return ("new", new_text.get_text()) except StandardError: logging.exception("addtoplaylistdialog threw exception.") finally: window.destroy()
def run_dialog(): """Displays a diagnostics windows that tells a user how Miro is set up on their machine. """ window = MainDialog(_("Diagnostics")) try: items = [ {"label": _("Movies location:"), "data": app.config.get(prefs.MOVIES_DIRECTORY), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.MOVIES_DIRECTORY))}, {"label": _("Icon cache location:"), "data": app.config.get(prefs.ICON_CACHE_DIRECTORY), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.ICON_CACHE_DIRECTORY))}, {"label": _("Log file location:"), "data": app.config.get(prefs.LOG_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.LOG_PATHNAME))}, {"label": _("Downloader log file location:"), "data": app.config.get(prefs.DOWNLOADER_LOG_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.DOWNLOADER_LOG_PATHNAME))}, {"label": _("Database file location:"), "data": app.config.get(prefs.SQLITE_PATHNAME), "button_face": SHOW, "button_fun": open_helper(app.config.get(prefs.SQLITE_PATHNAME))}, SEPARATOR, {"label": _("Space free on disk:"), "data": lambda: util.format_size_for_user(get_available_bytes_for_movies(), "0B", False)}, {"label": _("Database size:"), "data": lambda: util.format_size_for_user(get_database_size(), "0B", False)}, {"label": _("Total db objects in memory:"), "data": lambda: "%d" % get_database_object_count()}, SEPARATOR, {"label": _("Total db backups:"), "data": "", "button_face": _("%(databasecount)s: Delete", {"databasecount": len(app.db.get_backup_databases())}), "button_fun": delete_backups} ] t = widgetset.Table(3, len(items)) t.set_column_spacing(10) for row_num, item in enumerate(items): if item is SEPARATOR: t.pack(widgetset.Label(""), 0, row_num) continue label = item.get("label") lab = widgetset.Label(label) lab.set_bold(True) t.pack(widgetutil.align_left(lab), 0, row_num) data = item.get("data") if callable(data): data = data() if not isinstance(data, basestring): data = repr(data) datalab = widgetset.Label(data) t.pack(widgetutil.align_left(datalab), 1, row_num) if item.get("button_face"): b = widgetset.Button(item["button_face"]) b.set_size(widgetconst.SIZE_SMALL) b.connect('clicked', item["button_fun"]) t.pack(widgetutil.align_left(b), 2, row_num) window.set_extra_widget(t) window.add_button(BUTTON_OK.text) window.run() finally: window.destroy()
def run_dialog(): """Creates and launches the New Search Feed dialog. This dialog waits for the user to press "Create Feed" or "Cancel". In the case of "Create Feed", returns a tuple of: * ("feed", ChannelInfo, search_term str, section str) * ("search_engine", SearchEngineInfo, search_term str, section str) * ("url", url str, search_term str, section str) In the case of "Cancel", returns None. """ title = _('New Search Feed') description = _('A search feed contains items that match a search term.') channels = app.tab_list_manager.feed_list.get_feeds() channels += app.tab_list_manager.audio_feed_list.get_feeds() channels = [ci for ci in channels if not ci.is_folder] channels.sort(key=lambda x: util.name_sort_key(x.name)) window = MainDialog(title, description) try: try: window.add_button(BUTTON_CREATE_FEED.text) window.add_button(BUTTON_CANCEL.text) extra = widgetset.VBox() hb1 = widgetset.HBox() hb1.pack_start(widgetset.Label(_('Search for:')), padding=5) searchterm = widgetset.TextEntry() searchterm.set_activates_default(True) hb1.pack_start(searchterm, expand=True) extra.pack_start(hb1) hb2 = widgetset.HBox() hb2.pack_start(widgetutil.align_top(widgetset.Label(_('In this:')), top_pad=3), padding=5) choice_table = widgetset.Table(columns=2, rows=3) choice_table.set_column_spacing(5) choice_table.set_row_spacing(5) rbg = widgetset.RadioButtonGroup() channel_rb = widgetset.RadioButton(_("Feed:"), rbg) channel_option = widgetset.OptionMenu( [ci.name + u" - " + ci.url for ci in channels]) channel_option.set_size_request(250, -1) choice_table.pack(channel_rb, 0, 0) choice_table.pack(channel_option, 1, 0) search_engine_rb = widgetset.RadioButton(_("Search engine:"), rbg) search_engines = searchengines.get_search_engines() search_engine_option = widgetset.OptionMenu([se.title for se in search_engines]) choice_table.pack(search_engine_rb, 0, 1) choice_table.pack(search_engine_option, 1, 1) url_rb = widgetset.RadioButton(_("URL:"), rbg) url_text = widgetset.TextEntry() choice_table.pack(url_rb, 0, 2) choice_table.pack(url_text, 1, 2) hb2.pack_start(choice_table, expand=True) # only the channel row is enabled choice_table.disable(row=1, column=1) choice_table.disable(row=2, column=1) def handle_clicked(widget): # this enables and disables the fields in the table # based on which radio button is selected if widget is channel_rb: choice_table.enable(row=0, column=1) choice_table.disable(row=1, column=1) choice_table.disable(row=2, column=1) elif widget is search_engine_rb: choice_table.disable(row=0, column=1) choice_table.enable(row=1, column=1) choice_table.disable(row=2, column=1) else: choice_table.disable(row=0, column=1) choice_table.disable(row=1, column=1) choice_table.enable(row=2, column=1) channel_rb.connect('clicked', handle_clicked) search_engine_rb.connect('clicked', handle_clicked) url_rb.connect('clicked', handle_clicked) extra.pack_start(widgetutil.align_top(hb2, top_pad=6)) hb3 = widgetset.HBox() hb3.pack_start(widgetutil.align_top(widgetset.Label(_('Add new feed to this section:')), top_pad=3), padding=5) rbg_section = widgetset.RadioButtonGroup() video_rb = widgetset.RadioButton(_("video"), rbg_section) audio_rb = widgetset.RadioButton(_("audio"), rbg_section) hb3.pack_start(video_rb) hb3.pack_start(audio_rb) extra.pack_start(widgetutil.align_top(hb3, top_pad=6)) window.set_extra_widget(extra) response = window.run() if response == 0 and searchterm.get_text(): term = searchterm.get_text() selected_option = rbg.get_selected() if rbg_section.get_selected() == video_rb: section = u"video" else: section = u"audio" if selected_option is channel_rb: return ("feed", channels[channel_option.get_selected()], term, section) elif selected_option is search_engine_rb: return ("search_engine", search_engines[search_engine_option.get_selected()], term, section) else: return ("url", url_text.get_text(), term, section) except StandardError: logging.exception("newsearchfeed threw exception.") finally: window.destroy()
def run_dialog(channel_infos, downloaded_items, downloading_items, has_watched_feeds): """Displays the remove feeds dialog. """ title = ngettext('Remove Podcast', 'Remove Podcasts', len(channel_infos)) rc_window = MainDialog(title) try: try: v = widgetset.VBox(spacing=5) lab = widgetset.Label( ngettext("Are you sure you want to remove this podcast:", "Are you sure you want to remove these podcasts:", len(channel_infos))) lab.set_wrap(True) v.pack_start(widgetutil.align_left(lab)) v2 = widgetset.VBox() lab_height = None for mem in channel_infos: lab_mem = widgetset.Label(util.clamp_text(mem.name, 40)) if lab_height is None: dummy, lab_height = lab_mem.get_size_request() v2.pack_start(widgetutil.align_left(lab_mem, left_pad=15)) if len(channel_infos) > 5: scroller = widgetset.Scroller(False, True) scroller.set_has_borders(True) scroller.add(v2) scroller_width, scroller_height = scroller.get_size_request() if scroller_height == 0: scroller.set_size_request(scroller_width, 5 * (lab_height + 1)) v2 = scroller v.pack_start(v2, padding=10) cbx_downloaded = None if downloaded_items: cbx_downloaded = widgetset.Checkbox( _("Keep items that have been downloaded in my library.")) v.pack_start( widgetutil.align_left(cbx_downloaded, bottom_pad=5)) if has_watched_feeds: lab = widgetset.Label( _( "Watched folders will be removed from the sidebar but " "their contents will still appear in your library. " "You can stop watching watched folders completely " "in the %(appname)s preference panel.", {"appname": app.config.get(prefs.SHORT_APP_NAME)})) lab.set_wrap(True) lab.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab, bottom_pad=5)) if downloading_items: lab_downloading = widgetset.Label( ngettext( "Are you sure you want to remove this podcast? " "The downloads currently in progress will be canceled.", "Are you sure you want to remove these podcasts? " "The downloads currently in progress will be canceled.", len(channel_infos))) lab_downloading.set_wrap(True) lab_downloading.set_size_request(390, -1) v.pack_start(widgetutil.align_left(lab_downloading)) rc_window.set_extra_widget(v) rc_window.add_button(BUTTON_REMOVE.text) rc_window.add_button(BUTTON_CANCEL.text) ret = rc_window.run() if ret == 0: # this is silly, but it sets us up for adding additional # bits later. ret = {KEEP_ITEMS: False} if downloaded_items: ret[KEEP_ITEMS] = cbx_downloaded.get_checked() return ret except StandardError: logging.exception("removefeeds threw exception.") finally: rc_window.destroy()