def __init__(self, parent, bandwidth_rules): ClientGUICommon.StaticBox.__init__(self, parent, 'bandwidth rules') listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel(self) columns = [('max allowed', 14), ('every', 16)] self._listctrl = ClientGUIListCtrl.BetterListCtrl( listctrl_panel, 'bandwidth_rules', 8, 10, columns, self._ConvertRuleToListCtrlTuples, use_simple_delete=True, activation_callback=self._Edit) listctrl_panel.SetListCtrl(self._listctrl) listctrl_panel.AddButton('add', self._Add) listctrl_panel.AddButton('edit', self._Edit, enabled_only_on_selection=True) listctrl_panel.AddDeleteButton() # self._listctrl.AddDatas(bandwidth_rules.GetRules()) self._listctrl.Sort(0) # self.Add(listctrl_panel, CC.FLAGS_EXPAND_BOTH_WAYS)
def __init__( self, parent, initial_dict: typing.Dict[ str, ClientParsing.StringMatch ], min_height = 10, key_name = 'key' ): QW.QWidget.__init__( self, parent ) self._key_name = key_name listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel( self ) columns = [ ( self._key_name, 20 ), ( 'matching', -1 ) ] self._listctrl = ClientGUIListCtrl.BetterListCtrl( listctrl_panel, 'key_to_string_match', min_height, 36, columns, self._ConvertDataToListCtrlTuples, use_simple_delete = True, activation_callback = self._Edit ) listctrl_panel.SetListCtrl( self._listctrl ) listctrl_panel.AddButton( 'add', self._Add ) listctrl_panel.AddButton( 'edit', self._Edit, enabled_only_on_selection = True ) listctrl_panel.AddDeleteButton() # self._listctrl.AddDatas( initial_dict.items() ) self._listctrl.Sort( 0 ) # vbox = QP.VBoxLayout() QP.AddToLayout( vbox, listctrl_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.setLayout( vbox )
def __init__(self, parent, favourite_searches_rows, initial_search_row_to_edit=None): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._favourite_searches_panel = ClientGUIListCtrl.BetterListCtrlPanel( self) columns = [('folder', 24), ('name', 24), ('search', -1), ('sort', 24), ('collect', 24)] self._favourite_searches = ClientGUIListCtrl.BetterListCtrl( self._favourite_searches_panel, 'favourite_searches', 20, 72, columns, self._ConvertRowToListCtrlTuples, use_simple_delete=True, activation_callback=self._EditFavouriteSearch) self._favourite_searches_panel.SetListCtrl(self._favourite_searches) self._favourite_searches_panel.AddButton('add', self._AddNewFavouriteSearch) self._favourite_searches_panel.AddButton( 'edit', self._EditFavouriteSearch, enabled_only_on_selection=True) self._favourite_searches_panel.AddDeleteButton() # self._favourite_searches.AddDatas(favourite_searches_rows) self._favourite_searches.Sort(0) # vbox = QP.VBoxLayout() QP.AddToLayout(vbox, self._favourite_searches_panel, CC.FLAGS_EXPAND_BOTH_WAYS) self.widget().setLayout(vbox) if initial_search_row_to_edit is not None: HG.client_controller.CallLaterQtSafe(self, 0.5, self._AddNewFavouriteSearch, initial_search_row_to_edit)
def __init__( self, parent ): title = 'manage local upnp' ClientGUIDialogs.Dialog.__init__( self, parent, title ) self._status_st = ClientGUICommon.BetterStaticText( self ) listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel( self ) columns = [ ( 'description', -1 ), ( 'internal ip', 17 ), ( 'internal port', 7 ), ( 'external port', 7 ), ( 'prototcol', 5 ), ( 'lease', 12 ) ] self._mappings_list_ctrl = ClientGUIListCtrl.BetterListCtrl( listctrl_panel, 'manage_upnp_mappings', 12, 36, columns, self._ConvertDataToListCtrlTuples, delete_key_callback = self._Remove, activation_callback = self._Edit ) listctrl_panel.SetListCtrl( self._mappings_list_ctrl ) listctrl_panel.AddButton( 'add custom mapping', self._Add ) listctrl_panel.AddButton( 'edit mapping', self._Edit, enabled_only_on_selection = True ) listctrl_panel.AddButton( 'remove mapping', self._Remove, enabled_only_on_selection = True ) self._ok = QW.QPushButton( 'ok', self ) self._ok.clicked.connect( self.EventOK ) self._ok.setObjectName( 'HydrusAccept' ) # vbox = QP.VBoxLayout() QP.AddToLayout( vbox, self._status_st, CC.FLAGS_EXPAND_PERPENDICULAR ) QP.AddToLayout( vbox, listctrl_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) QP.AddToLayout( vbox, self._ok, CC.FLAGS_LONE_BUTTON ) self.setLayout( vbox ) size_hint = self.sizeHint() size_hint.setWidth( max( size_hint.width(), 760 ) ) QP.SetInitialSize( self, size_hint ) # self._mappings = [] self._mappings_list_ctrl.Sort( 0 ) self._started_external_ip_fetch = False self._RefreshMappings()
def __init__( self, parent, initial_dict: typing.Dict[ str, str ], min_height = 10, key_name = 'key', value_name = 'value', allow_add_delete = True, edit_keys = True ): QW.QWidget.__init__( self, parent ) self._key_name = key_name self._value_name = value_name self._edit_keys = edit_keys listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel( self ) columns = [ ( self._key_name, 20 ), ( self._value_name, -1 ) ] use_simple_delete = allow_add_delete self._listctrl = ClientGUIListCtrl.BetterListCtrl( listctrl_panel, 'key_to_value', min_height, 36, columns, self._ConvertDataToListCtrlTuples, use_simple_delete = use_simple_delete, activation_callback = self._Edit ) self._listctrl.listCtrlChanged.connect( self.listCtrlChanged ) listctrl_panel.SetListCtrl( self._listctrl ) if allow_add_delete: listctrl_panel.AddButton( 'add', self._Add ) listctrl_panel.AddButton( 'edit', self._Edit, enabled_only_on_selection = True ) if allow_add_delete: listctrl_panel.AddDeleteButton() # self._listctrl.AddDatas( list(initial_dict.items()) ) self._listctrl.Sort( 0 ) # vbox = QP.VBoxLayout() QP.AddToLayout( vbox, listctrl_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.setLayout( vbox )
def __init__(self, parent, export_folders): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._export_folders_panel = ClientGUIListCtrl.BetterListCtrlPanel( self) columns = [('name', 20), ('path', -1), ('type', 12), ('query', 16), ('paused', 8), ('period', 16), ('phrase', 20)] self._export_folders = ClientGUIListCtrl.BetterListCtrl( self._export_folders_panel, 'export_folders', 6, 40, columns, self._ConvertExportFolderToListCtrlTuples, use_simple_delete=True, activation_callback=self._Edit) self._export_folders_panel.SetListCtrl(self._export_folders) self._export_folders_panel.AddButton('add', self._AddFolder) self._export_folders_panel.AddButton('edit', self._Edit, enabled_only_on_selection=True) self._export_folders_panel.AddDeleteButton() # self._export_folders.AddDatas(export_folders) self._export_folders.Sort(0) vbox = QP.VBoxLayout() intro = 'Here you can set the client to regularly export a certain query to a particular location.' QP.AddToLayout(vbox, ClientGUICommon.BetterStaticText(self, intro), CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._export_folders_panel, CC.FLAGS_EXPAND_BOTH_WAYS) self.widget().setLayout(vbox)
def _ConvertFileSeedToListCtrlTuples(self, file_seed): try: file_seed_index = self._file_seed_cache.GetFileSeedIndex(file_seed) pretty_file_seed_index = HydrusData.ToHumanInt(file_seed_index) except: file_seed_index = '--' pretty_file_seed_index = '--' file_seed_data = file_seed.file_seed_data status = file_seed.status added = file_seed.created modified = file_seed.modified source_time = file_seed.source_time note = file_seed.note pretty_file_seed_data = str(file_seed_data) pretty_status = CC.status_string_lookup[status] pretty_added = HydrusData.TimestampToPrettyTimeDelta(added) pretty_modified = HydrusData.TimestampToPrettyTimeDelta(modified) if source_time is None: pretty_source_time = 'unknown' else: pretty_source_time = HydrusData.TimestampToPrettyTimeDelta( source_time) sort_source_time = ClientGUIListCtrl.SafeNoneInt(source_time) pretty_note = note.split(os.linesep)[0] display_tuple = (pretty_file_seed_index, pretty_file_seed_data, pretty_status, pretty_added, pretty_modified, pretty_source_time, pretty_note) sort_tuple = (file_seed_index, file_seed_data, status, added, modified, sort_source_time, note) return (display_tuple, sort_tuple)
def __init__(self, parent, controller, file_seed_cache): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._controller = controller self._file_seed_cache = file_seed_cache self._text = ClientGUICommon.BetterStaticText(self, 'initialising') # add index control row here, hide it if needed and hook into showing/hiding and postsizechangedevent on file_seed add/remove columns = [('#', 3), ('source', -1), ('status', 12), ('added', 23), ('last modified', 23), ('source time', 23), ('note', 20)] self._list_ctrl = ClientGUIListCtrl.BetterListCtrl( self, 'file_seed_cache', 30, 30, columns, self._ConvertFileSeedToListCtrlTuples, activation_callback=self._ShowSelectionInNewPage, delete_key_callback=self._DeleteSelected) # self._list_ctrl.AddDatas(self._file_seed_cache.GetFileSeeds()) self._list_ctrl.Sort(0) # vbox = QP.VBoxLayout() QP.AddToLayout(vbox, self._text, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._list_ctrl, CC.FLAGS_EXPAND_BOTH_WAYS) self.widget().setLayout(vbox) self._list_ctrl.AddMenuCallable(self._GetListCtrlMenu) self._controller.sub(self, 'NotifyFileSeedsUpdated', 'file_seed_cache_file_seeds_updated') QP.CallAfter(self._UpdateText)
def _ConvertRuleToListCtrlTuples(self, rule): (bandwidth_type, time_delta, max_allowed) = rule pretty_time_delta = HydrusData.TimeDeltaToPrettyTimeDelta(time_delta) if bandwidth_type == HC.BANDWIDTH_TYPE_DATA: pretty_max_allowed = HydrusData.ToHumanBytes(max_allowed) elif bandwidth_type == HC.BANDWIDTH_TYPE_REQUESTS: pretty_max_allowed = HydrusData.ToHumanInt( max_allowed) + ' requests' sort_time_delta = ClientGUIListCtrl.SafeNoneInt(time_delta) sort_tuple = (max_allowed, sort_time_delta) display_tuple = (pretty_max_allowed, pretty_time_delta) return (display_tuple, sort_tuple)
def __init__( self, parent, controller, read_only, can_generate_more_pages, gallery_seed_log ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) self._controller = controller self._read_only = read_only self._can_generate_more_pages = can_generate_more_pages self._gallery_seed_log = gallery_seed_log self._text = ClientGUICommon.BetterStaticText( self, 'initialising' ) # add index control row here, hide it if needed and hook into showing/hiding and postsizechangedevent on gallery_seed add/remove columns = [ ( '#', 3 ), ( 'url', -1 ), ( 'status', 12 ), ( 'added', 23 ), ( 'last modified', 23 ), ( 'note', 20 ) ] self._list_ctrl = ClientGUIListCtrl.BetterListCtrl( self, 'gallery_seed_log', 30, 30, columns, self._ConvertGallerySeedToListCtrlTuples ) # self._list_ctrl.AddDatas( self._gallery_seed_log.GetGallerySeeds() ) self._list_ctrl.Sort( 0 ) # vbox = QP.VBoxLayout() QP.AddToLayout( vbox, self._text, CC.FLAGS_EXPAND_PERPENDICULAR ) QP.AddToLayout( vbox, self._list_ctrl, CC.FLAGS_EXPAND_BOTH_WAYS ) self.widget().setLayout( vbox ) self._list_ctrl.AddMenuCallable( self._GetListCtrlMenu ) self._controller.sub( self, 'NotifyGallerySeedsUpdated', 'gallery_seed_log_gallery_seeds_updated' ) QP.CallAfter( self._UpdateText )
def __init__(self, parent, all_shortcuts): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) help_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().help, self._ShowHelp) help_button.setToolTip('Show help regarding editing shortcuts.') reserved_panel = ClientGUICommon.StaticBox( self, 'built-in hydrus shortcut sets') self._reserved_shortcuts = ClientGUIListCtrl.BetterListCtrl( reserved_panel, 'reserved_shortcuts', 6, 30, [('name', -1), ('number of shortcuts', 20)], data_to_tuples_func=self._GetTuples, activation_callback=self._EditReserved) self._reserved_shortcuts.setMinimumSize(QC.QSize(320, 200)) self._edit_reserved_button = ClientGUICommon.BetterButton( reserved_panel, 'edit', self._EditReserved) self._restore_defaults_button = ClientGUICommon.BetterButton( reserved_panel, 'restore defaults', self._RestoreDefaults) # custom_panel = ClientGUICommon.StaticBox(self, 'custom user sets') self._custom_shortcuts = ClientGUIListCtrl.BetterListCtrl( custom_panel, 'custom_shortcuts', 6, 30, [('name', -1), ('number of shortcuts', 20)], data_to_tuples_func=self._GetTuples, delete_key_callback=self._Delete, activation_callback=self._EditCustom) self._add_button = ClientGUICommon.BetterButton( custom_panel, 'add', self._Add) self._edit_custom_button = ClientGUICommon.BetterButton( custom_panel, 'edit', self._EditCustom) self._delete_button = ClientGUICommon.BetterButton( custom_panel, 'delete', self._Delete) if not HG.client_controller.new_options.GetBoolean('advanced_mode'): custom_panel.hide() # reserved_shortcuts = [ shortcuts for shortcuts in all_shortcuts if shortcuts.GetName() in ClientGUIShortcuts.SHORTCUTS_RESERVED_NAMES ] custom_shortcuts = [ shortcuts for shortcuts in all_shortcuts if shortcuts.GetName() not in ClientGUIShortcuts.SHORTCUTS_RESERVED_NAMES ] self._reserved_shortcuts.AddDatas(reserved_shortcuts) self._reserved_shortcuts.Sort(0) self._original_custom_names = set() for shortcuts in custom_shortcuts: self._custom_shortcuts.AddDatas((shortcuts, )) self._original_custom_names.add(shortcuts.GetName()) self._custom_shortcuts.Sort(0) # button_hbox = QP.HBoxLayout() QP.AddToLayout(button_hbox, self._edit_reserved_button, CC.FLAGS_VCENTER) QP.AddToLayout(button_hbox, self._restore_defaults_button, CC.FLAGS_VCENTER) reserved_panel.Add(self._reserved_shortcuts, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS) reserved_panel.Add(button_hbox, CC.FLAGS_BUTTON_SIZER) # button_hbox = QP.HBoxLayout() QP.AddToLayout(button_hbox, self._add_button, CC.FLAGS_VCENTER) QP.AddToLayout(button_hbox, self._edit_custom_button, CC.FLAGS_VCENTER) QP.AddToLayout(button_hbox, self._delete_button, CC.FLAGS_VCENTER) custom_panel_message = 'Custom shortcuts are advanced. They apply to the media viewer and must be turned on to take effect.' st = ClientGUICommon.BetterStaticText(custom_panel, custom_panel_message) st.setWordWrap(True) custom_panel.Add(st, CC.FLAGS_EXPAND_PERPENDICULAR) custom_panel.Add(self._custom_shortcuts, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS) custom_panel.Add(button_hbox, CC.FLAGS_BUTTON_SIZER) # vbox = QP.VBoxLayout() QP.AddToLayout(vbox, help_button, CC.FLAGS_LONE_BUTTON) QP.AddToLayout(vbox, reserved_panel, CC.FLAGS_EXPAND_BOTH_WAYS) QP.AddToLayout(vbox, custom_panel, CC.FLAGS_EXPAND_BOTH_WAYS) self.widget().setLayout(vbox)
def __init__(self, parent, shortcuts: ClientGUIShortcuts.ShortcutSet): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._name = QW.QLineEdit(self) self._shortcuts_panel = ClientGUIListCtrl.BetterListCtrlPanel(self) self._shortcuts = ClientGUIListCtrl.BetterListCtrl( self._shortcuts_panel, 'shortcuts', 20, 20, [('shortcut', 20), ('command', -1)], data_to_tuples_func=self._ConvertSortTupleToPrettyTuple, delete_key_callback=self.RemoveShortcuts, activation_callback=self.EditShortcuts) self._shortcuts_panel.SetListCtrl(self._shortcuts) self._shortcuts_panel.AddImportExportButtons( (ClientGUIShortcuts.ShortcutSet, ), self._AddShortcutSet, custom_get_callable=self._GetSelectedShortcutSet) self._shortcuts.setMinimumSize(QC.QSize(360, 480)) self._add = QW.QPushButton('add', self) self._add.clicked.connect(self.AddShortcut) self._edit = QW.QPushButton('edit', self) self._edit.clicked.connect(self.EditShortcuts) self._remove = QW.QPushButton('remove', self) self._remove.clicked.connect(self.RemoveShortcuts) # name = shortcuts.GetName() self._name.setText(name) self._this_is_custom = True if name in ClientGUIShortcuts.SHORTCUTS_RESERVED_NAMES: self._this_is_custom = False self._name.setEnabled(False) self._shortcuts.AddDatas(shortcuts) self._shortcuts.Sort(1) # action_buttons = QP.HBoxLayout() QP.AddToLayout(action_buttons, self._add, CC.FLAGS_VCENTER) QP.AddToLayout(action_buttons, self._edit, CC.FLAGS_VCENTER) QP.AddToLayout(action_buttons, self._remove, CC.FLAGS_VCENTER) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, ClientGUICommon.WrapInText(self._name, self, 'name: '), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) if name in ClientGUIShortcuts.shortcut_names_to_descriptions: description_text = ClientGUIShortcuts.shortcut_names_to_descriptions[ name] description = ClientGUICommon.BetterStaticText( self, description_text, description_text) description.setWordWrap(True) QP.AddToLayout(vbox, description, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._shortcuts_panel, CC.FLAGS_EXPAND_BOTH_WAYS) QP.AddToLayout(vbox, action_buttons, CC.FLAGS_BUTTON_SIZER) self.widget().setLayout(vbox)
def __init__(self, parent, flat_media, do_export_and_then_quit=False): ClientGUIScrolledPanels.ReviewPanel.__init__(self, parent) new_options = HG.client_controller.new_options self._media_to_paths = {} self._existing_filenames = set() self._last_phrase_used = '' self._last_dir_used = '' self._tags_box = ClientGUIListBoxes.StaticBoxSorterForListBoxTags( self, 'files\' tags') services_manager = HG.client_controller.services_manager self._neighbouring_txt_tag_service_keys = services_manager.FilterValidServiceKeys( new_options.GetKeyList( 'default_neighbouring_txt_tag_service_keys')) t = ClientGUIListBoxes.ListBoxTagsMedia( self._tags_box, ClientTags.TAG_DISPLAY_SIBLINGS_AND_PARENTS, include_counts=True) self._tags_box.SetTagsBox(t) self._tags_box.setMinimumSize(QC.QSize(220, 300)) columns = [('number', 8), ('filetype', 20), ('expected path', -1)] self._paths = ClientGUIListCtrl.BetterListCtrl( self, 'export_files', 24, 64, columns, self._ConvertDataToListCtrlTuples, use_simple_delete=True) self._paths.Sort(0) self._export_path_box = ClientGUICommon.StaticBox(self, 'export path') self._directory_picker = QP.DirPickerCtrl(self._export_path_box) self._directory_picker.dirPickerChanged.connect(self._RefreshPaths) self._open_location = QW.QPushButton('open this location', self._export_path_box) self._open_location.clicked.connect(self.EventOpenLocation) self._filenames_box = ClientGUICommon.StaticBox(self, 'filenames') self._pattern = QW.QLineEdit(self._filenames_box) self._update = QW.QPushButton('update', self._filenames_box) self._update.clicked.connect(self._RefreshPaths) self._examples = ClientGUICommon.ExportPatternButton( self._filenames_box) self._delete_files_after_export = QW.QCheckBox( 'delete files from client after export?', self) self._delete_files_after_export.setObjectName('HydrusWarning') self._export_symlinks = QW.QCheckBox('EXPERIMENTAL: export symlinks', self) self._export_symlinks.setObjectName('HydrusWarning') text = 'This will export all the files\' tags, newline separated, into .txts beside the files themselves.' self._export_tag_txts_services_button = ClientGUICommon.BetterButton( self, 'set .txt services', self._SetTxtServices) self._export_tag_txts = QW.QCheckBox('export tags to .txt files?', self) self._export_tag_txts.setToolTip(text) self._export_tag_txts.clicked.connect(self.EventExportTagTxtsChanged) self._export = QW.QPushButton('export', self) self._export.clicked.connect(self._DoExport) # export_path = ClientExporting.GetExportPath() self._directory_picker.SetPath(export_path) phrase = new_options.GetString('export_phrase') self._pattern.setText(phrase) if len(self._neighbouring_txt_tag_service_keys) > 0: self._export_tag_txts.setChecked(True) self._paths.SetData(list(enumerate(flat_media))) self._delete_files_after_export.setChecked( HG.client_controller.new_options.GetBoolean( 'delete_files_after_export')) self._delete_files_after_export.clicked.connect( self.EventDeleteFilesChanged) if not HG.client_controller.new_options.GetBoolean('advanced_mode'): self._export_symlinks.setVisible(False) # top_hbox = QP.HBoxLayout() QP.AddToLayout(top_hbox, self._tags_box, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(top_hbox, self._paths, CC.FLAGS_EXPAND_BOTH_WAYS) hbox = QP.HBoxLayout() QP.AddToLayout(hbox, self._directory_picker, CC.FLAGS_EXPAND_BOTH_WAYS) QP.AddToLayout(hbox, self._open_location, CC.FLAGS_VCENTER) self._export_path_box.Add(hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) hbox = QP.HBoxLayout() QP.AddToLayout(hbox, self._pattern, CC.FLAGS_EXPAND_BOTH_WAYS) QP.AddToLayout(hbox, self._update, CC.FLAGS_VCENTER) QP.AddToLayout(hbox, self._examples, CC.FLAGS_VCENTER) self._filenames_box.Add(hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) txt_hbox = QP.HBoxLayout() QP.AddToLayout(txt_hbox, self._export_tag_txts_services_button, CC.FLAGS_VCENTER) QP.AddToLayout(txt_hbox, self._export_tag_txts, CC.FLAGS_VCENTER) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, top_hbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS) QP.AddToLayout(vbox, self._export_path_box, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._filenames_box, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._delete_files_after_export, CC.FLAGS_LONE_BUTTON) QP.AddToLayout(vbox, self._export_symlinks, CC.FLAGS_LONE_BUTTON) QP.AddToLayout(vbox, txt_hbox, CC.FLAGS_LONE_BUTTON) QP.AddToLayout(vbox, self._export, CC.FLAGS_LONE_BUTTON) self.widget().setLayout(vbox) self._RefreshTags() self._UpdateTxtButton() HG.client_controller.CallAfterQtSafe(self._export, self._export.setFocus, QC.Qt.OtherFocusReason) self._paths.itemSelectionChanged.connect(self._RefreshTags) if do_export_and_then_quit: QP.CallAfter(self._DoExport, True)