def __init__( self, parent, management_controller = None ): QW.QWidget.__init__( self, parent ) self._management_controller = management_controller self._sort_type = ( 'system', CC.SORT_FILES_BY_FILESIZE ) self._sort_type_button = ClientGUICommon.BetterButton( self, 'sort', self._SortTypeButtonClick ) self._sort_order_choice = ClientGUICommon.BetterChoice( self ) type_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._sort_type_button, 14 ) self._sort_type_button.setMinimumWidth( type_width ) asc_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._sort_order_choice, 14 ) self._sort_order_choice.setMinimumWidth( asc_width ) self._sort_order_choice.addItem( '', CC.SORT_ASC ) self._UpdateSortTypeLabel() self._UpdateAscLabels() # hbox = QP.HBoxLayout( margin = 0 ) QP.AddToLayout( hbox, self._sort_type_button, CC.FLAGS_EXPAND_BOTH_WAYS ) QP.AddToLayout( hbox, self._sort_order_choice, CC.FLAGS_CENTER_PERPENDICULAR ) self.setLayout( hbox ) HG.client_controller.sub( self, 'ACollectHappened', 'a_collect_happened' ) HG.client_controller.sub( self, 'BroadcastSort', 'do_page_sort' ) if self._management_controller is not None and self._management_controller.HasVariable( 'media_sort' ): media_sort = self._management_controller.GetVariable( 'media_sort' ) try: self.SetSort( media_sort ) except: default_sort = ClientMedia.MediaSort( ( 'system', CC.SORT_FILES_BY_FILESIZE ), CC.SORT_ASC ) self.SetSort( default_sort ) self._sort_order_choice.currentIndexChanged.connect( self.EventSortAscChoice )
def __init__(self, parent, controller, frame_splash_status): QW.QWidget.__init__(self, parent) self._controller = controller self._my_status = frame_splash_status self._my_status.SetWindow(self) width = ClientGUIFunctions.ConvertTextToPixelWidth(self, 64) self.setMinimumWidth(width) self.setMaximumWidth(width * 2) self._drag_last_pos = None self._initial_position = self.parentWidget().pos() # this is 124 x 166 self._hydrus_pixmap = QG.QPixmap( os.path.join(HC.STATIC_DIR, 'hydrus_splash.png')) self._image_label = QW.QLabel(self) self._image_label.setPixmap(self._hydrus_pixmap) self._image_label.setAlignment(QC.Qt.AlignCenter) self._title_label = ClientGUICommon.BetterStaticText(self, label=' ') self._status_label = ClientGUICommon.BetterStaticText(self, label=' ') self._status_sub_label = ClientGUICommon.BetterStaticText(self, label=' ') self._title_label.setAlignment(QC.Qt.AlignCenter) self._status_label.setAlignment(QC.Qt.AlignCenter) self._status_sub_label.setAlignment(QC.Qt.AlignCenter) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, self._image_label, CC.FLAGS_CENTER) QP.AddToLayout(vbox, self._title_label, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._status_label, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._status_sub_label, CC.FLAGS_EXPAND_PERPENDICULAR) margin = ClientGUIFunctions.ConvertTextToPixelWidth(self, 3) self._image_label.setMargin(margin) self.setLayout(vbox)
def sizeHint(self): width = 0 width += self.frameWidth() * 2 # all but last column for i in range(self.columnCount() - 1): width += self.columnWidth(i) # # ok, we are going full slippery dippery doo now # the issue is: when we first boot up, we want to give a 'hey, it would be nice' size of the last actual recorded final column # HOWEVER, after that: we want to use the current size of the last column # so, if it is the first couple of seconds, lmao. after that, oaml # I later updated this to use the columnWidth, rather than hickery dickery text-to-pixel-width, since it was juddering resize around text width phase last_column_type = self._column_list_status.GetColumnTypes()[-1] if HydrusData.TimeHasPassed(self._creation_time + 2): width += self.columnWidth(self.columnCount() - 1) # this is a hack to stop the thing suddenly growing to screen width in a weird resize loop # I couldn't reproduce this error, so I assume it is a QSS or whatever font/style/scrollbar on some systems that caused inaccurate columnWidth result width = min(width, self.width()) else: last_column_chars = self._original_column_list_status.GetColumnWidth( last_column_type) main_tlw = HG.client_controller.GetMainTLW() width += ClientGUIFunctions.ConvertTextToPixelWidth( main_tlw, last_column_chars) # if self._forced_height_num_chars is None: num_rows = self._initial_height_num_chars else: num_rows = self._forced_height_num_chars header_size = self.header().sizeHint() data_area_height = self._GetRowHeightEstimate() * num_rows PADDING = 10 size_hint = QC.QSize(width, header_size.height() + data_area_height + PADDING) return size_hint
def sizeHint(self): width = 0 # all but last column for i in range(self.columnCount() - 1): width += self.columnWidth(i) # # ok, we are going full slippery dippery doo now # the issue is: when we first boot up, we want to give a 'hey, it would be nice' size of the last actual recorded final column # HOWEVER, after that: we want to use the current size of the last column # so, if it is the first couple of seconds, lmao. after that, oaml last_column_type = self._column_list_status.GetColumnTypes()[-1] if HydrusData.TimeHasPassed(self._creation_time + 2): last_column_chars = self._column_list_status.GetColumnWidth( last_column_type) else: last_column_chars = self._original_column_list_status.GetColumnWidth( last_column_type) main_tlw = HG.client_controller.GetMainTLW() width += ClientGUIFunctions.ConvertTextToPixelWidth( main_tlw, last_column_chars) # width += self.frameWidth() * 2 if self._forced_height_num_chars is None: num_rows = self._initial_height_num_chars else: num_rows = self._forced_height_num_chars header_size = self.header().sizeHint() data_area_height = self._GetRowHeightEstimate() * num_rows PADDING = 10 size_hint = QC.QSize(width, header_size.height() + data_area_height + PADDING) return size_hint
def __init__( self, parent, management_controller = None, silent = False ): QW.QWidget.__init__( self, parent ) # this is trash, rewrite it to deal with the media_collect object, not the management controller self._management_controller = management_controller if self._management_controller is not None and self._management_controller.HasVariable( 'media_collect' ): self._media_collect = self._management_controller.GetVariable( 'media_collect' ) else: self._media_collect = HG.client_controller.new_options.GetDefaultCollect() self._silent = silent self._collect_comboctrl = QP.CollectComboCtrl( self, self._media_collect ) self._collect_unmatched = ClientGUICommon.BetterChoice( self ) width = ClientGUIFunctions.ConvertTextToPixelWidth( self._collect_unmatched, 19 ) self._collect_unmatched.setMinimumWidth( width ) self._collect_unmatched.addItem( 'collect unmatched', True ) self._collect_unmatched.addItem( 'leave unmatched', False ) # self._collect_unmatched.SetValue( self._media_collect.collect_unmatched ) # hbox = QP.HBoxLayout( margin = 0 ) QP.AddToLayout( hbox, self._collect_comboctrl, CC.FLAGS_EXPAND_BOTH_WAYS ) QP.AddToLayout( hbox, self._collect_unmatched, CC.FLAGS_CENTER_PERPENDICULAR ) self.setLayout( hbox ) # self._UpdateLabel() self._collect_unmatched.currentIndexChanged.connect( self.CollectValuesChanged ) self._collect_comboctrl.itemChanged.connect( self.CollectValuesChanged ) HG.client_controller.sub( self, 'SetCollectFromPage', 'set_page_collect' )
def sizeHint(self): # still have an issue here where if the list gets populated with a bunch of stuff and hence gets a vertical scrollbar, it doesn't account for that # something like change this to viewportSizehint and/or doing updateGeometry on add data, if that isn't already done when scrollbars added? width = 0 for i in range(self.columnCount() - 1): width += self.columnWidth(i) # # we use the last value saved to options for this column. not what it currently is, but what user saw last # this might be from a few milliseconds ago, or last time dialog was open. main thing is this is a _sensible_ value for this column, to inform panels and so on last_column_type = self._column_list_status.GetColumnTypes()[-1] last_column_chars = self._column_list_status.GetColumnWidth( last_column_type) main_tlw = HG.client_controller.GetMainTLW() width += ClientGUIFunctions.ConvertTextToPixelWidth( main_tlw, last_column_chars) # width += self.frameWidth() * 2 if self._forced_height_num_chars is None: num_rows = self._initial_height_num_chars else: num_rows = self._forced_height_num_chars # + 2 for header and * 1.25 for magic (width_gumpf, height) = ClientGUIFunctions.ConvertTextToPixels( self, (20, int((num_rows + 2) * 1.25))) size_hint = QC.QSize(width, height) return size_hint
def __init__(self, parent, payload_objs): ClientGUIScrolledPanels.ReviewPanel.__init__(self, parent) self._payload_objs = payload_objs self._directory_picker = QP.DirPickerCtrl(self) dp_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._directory_picker, 52) self._directory_picker.setMinimumWidth(dp_width) self._width = QP.MakeQSpinBox(self, min=100, max=4096) self._export = ClientGUICommon.BetterButton(self, 'export', self.Export) # last_png_export_dir = HG.client_controller.new_options.GetNoneableString( 'last_png_export_dir') if last_png_export_dir is not None: self._directory_picker.SetPath(last_png_export_dir) self._width.setValue(512) self._Update() # rows = [] rows.append(('export path: ', self._directory_picker)) rows.append(('png width: ', self._width)) rows.append(('', self._export)) gridbox = ClientGUICommon.WrapInGrid(self, rows) self.widget().setLayout(gridbox) self._directory_picker.dirPickerChanged.connect(self._Update)
def __init__(self, parent: QW.QWidget, predicate: ClientSearch.Predicate): QW.QWidget.__init__(self, parent) from hydrus.client.gui.search import ClientGUIACDropdown if predicate.GetType() != ClientSearch.PREDICATE_TYPE_OR_CONTAINER: raise Exception( 'Launched an ORPredicateControl without an OR Pred!') predicates = predicate.GetValue() page_key = HydrusData.GenerateKey() location_context = HG.client_controller.new_options.GetDefaultLocalLocationContext( ) file_search_context = ClientSearch.FileSearchContext( location_context=location_context, predicates=predicates) self._search_control = ClientGUIACDropdown.AutoCompleteDropdownTagsRead( self, page_key, file_search_context, hide_favourites_edit_actions=True) self._search_control.setMinimumWidth( ClientGUIFunctions.ConvertTextToPixelWidth(self._search_control, 64)) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, self._search_control, CC.FLAGS_EXPAND_BOTH_WAYS) self.setLayout(vbox) ClientGUIFunctions.SetFocusLater(self._search_control)
def __init__( self, parent, payload_obj, title = None, description = None, payload_description = None ): ClientGUIScrolledPanels.ReviewPanel.__init__( self, parent ) self._payload_obj = payload_obj self._filepicker = QP.FilePickerCtrl( self, wildcard = 'PNG (*.png)' ) self._filepicker.SetSaveMode( True ) flp_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._filepicker, 64 ) self._filepicker.setMinimumWidth( flp_width ) self._title = QW.QLineEdit( self ) self._payload_description = QW.QLineEdit( self ) self._text = QW.QLineEdit( self ) self._width = QP.MakeQSpinBox( self, min=100, max=4096 ) self._export = ClientGUICommon.BetterButton( self, 'export', self.Export ) # if payload_description is None: ( payload_description, payload_bytes ) = ClientSerialisable.GetPayloadDescriptionAndBytes( self._payload_obj ) else: payload_bytes = ClientSerialisable.GetPayloadBytes( self._payload_obj ) payload_description += ' - ' + HydrusData.ToHumanBytes( len( payload_bytes ) ) self._payload_description.setText( payload_description ) self._payload_description.setEnabled( False ) self._width.setValue( 512 ) last_png_export_dir = HG.client_controller.new_options.GetNoneableString( 'last_png_export_dir' ) if title is not None: name = title elif isinstance( self._payload_obj, HydrusSerialisable.SerialisableBaseNamed ): name = self._payload_obj.GetName() else: name = payload_description self._title.setText( name ) if description is not None: self._text.setText( description ) if last_png_export_dir is not None: filename = name + '.png' filename = HydrusPaths.SanitizeFilename( filename ) path = os.path.join( last_png_export_dir, filename ) self._filepicker.SetPath( path ) self._Update() # rows = [] rows.append( ( 'export path: ', self._filepicker ) ) rows.append( ( 'title: ', self._title ) ) rows.append( ( 'payload description: ', self._payload_description ) ) rows.append( ( 'your description (optional): ', self._text ) ) rows.append( ( 'png width: ', self._width ) ) rows.append( ( '', self._export ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) self.widget().setLayout( gridbox ) self._filepicker.filePickerChanged.connect( self._Update ) self._title.textChanged.connect( self._Update )
def __init__(self, parent, column_list_type, height_num_chars, data_to_tuples_func, use_simple_delete=False, delete_key_callback=None, activation_callback=None, style=None, column_types_to_name_overrides=None): QW.QTreeWidget.__init__(self, parent) self._have_shown_a_column_data_error = False self._creation_time = HydrusData.GetNow() self._column_list_type = column_list_type self._column_list_status: ClientGUIListStatus.ColumnListStatus = HG.client_controller.column_list_manager.GetStatus( self._column_list_type) self._original_column_list_status = self._column_list_status self.setAlternatingRowColors(True) self.setColumnCount(self._column_list_status.GetColumnCount()) self.setSortingEnabled( False ) # Keeping the custom sort implementation. It would be better to use Qt's native sorting in the future so sort indicators are displayed on the headers as expected. self.setSelectionMode(QW.QAbstractItemView.ExtendedSelection) self.setRootIsDecorated(False) self._initial_height_num_chars = height_num_chars self._forced_height_num_chars = None self._data_to_tuples_func = data_to_tuples_func self._use_simple_delete = use_simple_delete self._menu_callable = None (self._sort_column_type, self._sort_asc) = self._column_list_status.GetSort() self._indices_to_data_info = {} self._data_to_indices = {} # old way ''' #sizing_column_initial_width = self.fontMetrics().boundingRect( 'x' * sizing_column_initial_width_num_chars ).width() total_width = self.fontMetrics().boundingRect( 'x' * sizing_column_initial_width_num_chars ).width() resize_column = 1 for ( i, ( name, width_num_chars ) ) in enumerate( columns ): if width_num_chars == -1: width = -1 resize_column = i + 1 else: width = self.fontMetrics().boundingRect( 'x' * width_num_chars ).width() total_width += width self.headerItem().setText( i, name ) self.setColumnWidth( i, width ) # Technically this is the previous behavior, but the two commented lines might work better in some cases (?) self.header().setStretchLastSection( False ) self.header().setSectionResizeMode( resize_column - 1 , QW.QHeaderView.Stretch ) #self.setColumnWidth( resize_column - 1, sizing_column_initial_width ) #self.header().setStretchLastSection( True ) self.setMinimumWidth( total_width ) ''' main_tlw = HG.client_controller.GetMainTLW() # if last section is set too low, for instance 3, the column seems unable to ever shrink from initial (expanded to fill space) size # _ _ ___ _ _ __ __ ___ # ( \/\/ )( _)( \/\/ ) ( ) ( ) ( \ # \ / ) _) \ / )(__ /__\ ) ) ) # \/\/ (___) \/\/ (____)(_)(_)(___/ # # I think this is because of mismatch between set size and min size! So ensuring we never set smaller than that initially should fix this???!? MIN_SECTION_SIZE_CHARS = 3 MIN_LAST_SECTION_SIZE_CHARS = 10 self._min_section_width = ClientGUIFunctions.ConvertTextToPixelWidth( main_tlw, MIN_SECTION_SIZE_CHARS) self.header().setMinimumSectionSize(self._min_section_width) last_column_index = self._column_list_status.GetColumnCount() - 1 for (i, column_type) in enumerate( self._column_list_status.GetColumnTypes()): self.headerItem().setData(i, QC.Qt.UserRole, column_type) if column_types_to_name_overrides is not None and column_type in column_types_to_name_overrides: name = column_types_to_name_overrides[column_type] else: name = CGLC.column_list_column_name_lookup[ self._column_list_type][column_type] self.headerItem().setText(i, name) self.headerItem().setToolTip(i, name) if i == last_column_index: width_chars = MIN_SECTION_SIZE_CHARS else: width_chars = self._column_list_status.GetColumnWidth( column_type) width_chars = max(width_chars, MIN_SECTION_SIZE_CHARS) # ok this is a pain in the neck issue, but fontmetrics changes afte widget init. I guess font gets styled on top afterwards # this means that if I use this window's fontmetrics here, in init, then it is different later on, and we get creeping growing columns lmao # several other places in the client are likely affected in different ways by this also! width_pixels = ClientGUIFunctions.ConvertTextToPixelWidth( main_tlw, width_chars) self.setColumnWidth(i, width_pixels) self.header().setStretchLastSection(True) self._delete_key_callback = delete_key_callback self._activation_callback = activation_callback self._widget_event_filter = QP.WidgetEventFilter(self) self._widget_event_filter.EVT_KEY_DOWN(self.EventKeyDown) self.itemDoubleClicked.connect(self.EventItemActivated) self.header().setSectionsMovable( False) # can only turn this on when we move from data/sort tuples # self.header().setFirstSectionMovable( True ) # same self.header().setSectionsClickable(True) self.header().sectionClicked.connect(self.EventColumnClick) #self.header().sectionMoved.connect( self._DoStatusChanged ) # same self.header().sectionResized.connect(self._SectionsResized)
def __init__(self, parent, message, default='', placeholder=None, allow_blank=False, suggestions=None, max_chars=None, password_entry=False, min_char_width=72): if suggestions is None: suggestions = [] Dialog.__init__(self, parent, 'enter text', position='center') self._chosen_suggestion = None self._allow_blank = allow_blank self._max_chars = max_chars button_choices = [] for text in suggestions: button_choices.append( ClientGUICommon.BetterButton(self, text, self.ButtonChoice, text)) self._text = QW.QLineEdit(self) self._text.textChanged.connect(self.EventText) self._text.installEventFilter( ClientGUICommon.TextCatchEnterEventFilter(self._text, self.EnterText)) width = ClientGUIFunctions.ConvertTextToPixelWidth( self._text, min_char_width) self._text.setMinimumWidth(width) if password_entry: self._text.setEchoMode(QW.QLineEdit.Password) if self._max_chars is not None: self._text.setMaxLength(self._max_chars) self._ok = ClientGUICommon.BetterButton(self, 'ok', self.done, QW.QDialog.Accepted) self._ok.setObjectName('HydrusAccept') self._cancel = QW.QPushButton('cancel', self) self._cancel.clicked.connect(self.reject) self._cancel.setObjectName('HydrusCancel') # self._text.setText(default) if placeholder is not None: self._text.setPlaceholderText(placeholder) if len(default) > 0: self._text.setSelection(0, len(default)) self._CheckText() # hbox = QP.HBoxLayout() QP.AddToLayout(hbox, self._ok, CC.FLAGS_CENTER_PERPENDICULAR) QP.AddToLayout(hbox, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR) st_message = ClientGUICommon.BetterStaticText(self, message) st_message.setWordWrap(True) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, st_message, CC.FLAGS_EXPAND_PERPENDICULAR) for button in button_choices: QP.AddToLayout(vbox, button, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._text, CC.FLAGS_EXPAND_BOTH_WAYS) QP.AddToLayout(vbox, hbox, CC.FLAGS_ON_RIGHT) self.setLayout(vbox) size_hint = self.sizeHint() size_hint.setWidth(max(size_hint.width(), 250)) QP.SetInitialSize(self, size_hint)
def __init__(self, parent, existing_folders_to_names, foldername, name, file_search_context, synchronised, media_sort, media_collect): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._existing_folders_to_names = existing_folders_to_names self._original_folder_and_name = (foldername, name) self._foldername = QW.QLineEdit(self) self._name = QW.QLineEdit(self) self._media_sort = ClientGUIResultsSortCollect.MediaSortControl(self) self._media_collect = ClientGUIResultsSortCollect.MediaCollectControl( self, silent=True) page_key = HydrusData.GenerateKey() from hydrus.client.gui.search import ClientGUIACDropdown self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsRead( self, page_key, file_search_context, media_sort_widget=self._media_sort, media_collect_widget=self._media_collect, synchronised=synchronised, hide_favourites_edit_actions=True) self._include_media_sort = QW.QCheckBox(self) self._include_media_collect = QW.QCheckBox(self) width = ClientGUIFunctions.ConvertTextToPixelWidth( self._include_media_collect, 48) self._include_media_collect.setMinimumWidth(width) self._include_media_sort.stateChanged.connect(self._UpdateWidgets) self._include_media_collect.stateChanged.connect(self._UpdateWidgets) # if foldername is not None: self._foldername.setText(foldername) self._name.setText(name) if media_sort is not None: self._include_media_sort.setChecked(True) self._media_sort.SetSort(media_sort) if media_collect is not None: self._include_media_collect.setChecked(True) self._media_collect.SetCollect(media_collect) # rows = [] rows.append(('folder (blank for none): ', self._foldername)) rows.append(('name: ', self._name)) top_gridbox = ClientGUICommon.WrapInGrid(self, rows) rows = [] rows.append(('save sort: ', self._include_media_sort)) rows.append(('sort: ', self._media_sort)) rows.append(('save collect: ', self._include_media_collect)) rows.append(('collect: ', self._media_collect)) bottom_gridbox = ClientGUICommon.WrapInGrid(self, rows) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, top_gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) QP.AddToLayout(vbox, self._tag_autocomplete, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, bottom_gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) self.widget().setLayout(vbox)
def __init__(self, parent, selectable_mimes): OptionsPanel.__init__(self, parent) self._selectable_mimes = set(selectable_mimes) self._mimes_to_checkboxes = {} self._general_mime_types_to_checkboxes = {} self._general_mime_types_to_buttons = {} general_mime_types = [] general_mime_types.append(HC.GENERAL_IMAGE) general_mime_types.append(HC.GENERAL_ANIMATION) general_mime_types.append(HC.GENERAL_VIDEO) general_mime_types.append(HC.GENERAL_AUDIO) general_mime_types.append(HC.GENERAL_APPLICATION) gridbox = QP.GridLayout(cols=3) gridbox.setColumnStretch(2, 1) for general_mime_type in general_mime_types: mimes_in_type = self._GetMimesForGeneralMimeType(general_mime_type) if len(mimes_in_type) == 0: continue general_mime_checkbox = QW.QCheckBox( HC.mime_string_lookup[general_mime_type], self) general_mime_checkbox.clicked.connect(self.EventMimeGroupCheckbox) self._general_mime_types_to_checkboxes[ general_mime_type] = general_mime_checkbox QP.AddToLayout(gridbox, general_mime_checkbox, CC.FLAGS_CENTER_PERPENDICULAR) show_hide_button = ClientGUICommon.BetterButton( self, self.BUTTON_CURRENTLY_SHOWING, self._ButtonShowHide, general_mime_type) max_width = ClientGUIFunctions.ConvertTextToPixelWidth( show_hide_button, 5) show_hide_button.setMaximumWidth(max_width) self._general_mime_types_to_buttons[ general_mime_type] = show_hide_button QP.AddToLayout(gridbox, show_hide_button, CC.FLAGS_CENTER_PERPENDICULAR) vbox = QP.VBoxLayout() for mime in mimes_in_type: m_checkbox = QW.QCheckBox(HC.mime_string_lookup[mime], self) m_checkbox.clicked.connect(self.EventMimeCheckbox) self._mimes_to_checkboxes[mime] = m_checkbox QP.AddToLayout(vbox, m_checkbox, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(gridbox, vbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS) self.setLayout(gridbox)
def __init__(self, parent, manager, job_key: ClientThreading.JobKey): PopupWindow.__init__(self, parent, manager) self.setSizePolicy(QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Fixed) self._job_key = job_key vbox = QP.VBoxLayout() self._title = ClientGUICommon.BetterStaticText(self) self._title.setAlignment(QC.Qt.AlignHCenter | QC.Qt.AlignVCenter) font = self._title.font() font.setBold(True) self._title.setFont(font) popup_message_character_width = HG.client_controller.new_options.GetInteger( 'popup_message_character_width') popup_char_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._title, popup_message_character_width) if HG.client_controller.new_options.GetBoolean( 'popup_message_force_min_width'): #QP.SetMinClientSize( self, ( wrap_width, -1 ) ) self.setFixedWidth(popup_char_width) else: self.setMaximumWidth(popup_char_width) self._title.setWordWrap(True) self._title_ev = QP.WidgetEventFilter(self._title) self._title_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._title.hide() self._text_1 = ClientGUICommon.BetterStaticText(self) self._text_1.setWordWrap(True) self._text_1_ev = QP.WidgetEventFilter(self._text_1) self._text_1_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._text_1.hide() self._gauge_1 = ClientGUICommon.Gauge(self) self._gauge_1_ev = QP.WidgetEventFilter(self._gauge_1) self._gauge_1_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._gauge_1.setMinimumWidth(int(popup_char_width * 0.9)) self._gauge_1.hide() self._text_2 = ClientGUICommon.BetterStaticText(self) self._text_2.setWordWrap(True) self._text_2_ev = QP.WidgetEventFilter(self._text_2) self._text_2_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._text_2.hide() self._gauge_2 = ClientGUICommon.Gauge(self) self._gauge_2_ev = QP.WidgetEventFilter(self._gauge_2) self._gauge_2_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._gauge_2.setMinimumWidth(int(popup_char_width * 0.9)) self._gauge_2.hide() self._text_yes_no = ClientGUICommon.BetterStaticText(self) self._text_yes_no_ev = QP.WidgetEventFilter(self._text_yes_no) self._text_yes_no_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._text_yes_no.hide() self._yes = ClientGUICommon.BetterButton(self, 'yes', self._YesButton) self._yes.hide() self._no = ClientGUICommon.BetterButton(self, 'no', self._NoButton) self._no.hide() self._network_job_ctrl = ClientGUINetworkJobControl.NetworkJobControl( self) self._network_job_ctrl.hide() self._copy_to_clipboard_button = ClientGUICommon.BetterButton( self, 'copy to clipboard', self.CopyToClipboard) self._copy_to_clipboard_button_ev = QP.WidgetEventFilter( self._copy_to_clipboard_button) self._copy_to_clipboard_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._copy_to_clipboard_button.hide() self._show_files_button = ClientGUICommon.BetterButton( self, 'show files', self.ShowFiles) self._show_files_button_ev = QP.WidgetEventFilter( self._show_files_button) self._show_files_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._show_files_button.hide() self._user_callable_button = ClientGUICommon.BetterButton( self, 'run command', self.CallUserCallable) self._user_callable_button_ev = QP.WidgetEventFilter( self._user_callable_button) self._user_callable_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._user_callable_button.hide() self._show_tb_button = ClientGUICommon.BetterButton( self, 'show traceback', self.ShowTB) self._show_tb_button_ev = QP.WidgetEventFilter(self._show_tb_button) self._show_tb_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._show_tb_button.hide() self._tb_text = ClientGUICommon.BetterStaticText(self) self._tb_text_ev = QP.WidgetEventFilter(self._tb_text) self._tb_text_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._tb_text.setWordWrap(True) self._tb_text.hide() self._copy_tb_button = ClientGUICommon.BetterButton( self, 'copy traceback information', self.CopyTB) self._copy_tb_button_ev = QP.WidgetEventFilter(self._copy_tb_button) self._copy_tb_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._copy_tb_button.hide() self._pause_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().pause, self.PausePlay) self._pause_button_ev = QP.WidgetEventFilter(self._pause_button) self._pause_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._pause_button.hide() self._cancel_button = ClientGUICommon.BetterBitmapButton( self, CC.global_pixmaps().stop, self.Cancel) self._cancel_button_ev = QP.WidgetEventFilter(self._cancel_button) self._cancel_button_ev.EVT_RIGHT_DOWN(self.EventDismiss) self._cancel_button.hide() hbox = QP.HBoxLayout() QP.AddToLayout(hbox, self._pause_button, CC.FLAGS_CENTER_PERPENDICULAR) QP.AddToLayout(hbox, self._cancel_button, CC.FLAGS_CENTER_PERPENDICULAR) yes_no_hbox = QP.HBoxLayout() QP.AddToLayout(yes_no_hbox, self._yes, CC.FLAGS_CENTER_PERPENDICULAR) QP.AddToLayout(yes_no_hbox, self._no, CC.FLAGS_CENTER_PERPENDICULAR) QP.AddToLayout(vbox, self._title, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._text_1, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._gauge_1, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._text_2, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._gauge_2, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, self._text_yes_no, CC.FLAGS_EXPAND_PERPENDICULAR) QP.AddToLayout(vbox, yes_no_hbox) QP.AddToLayout(vbox, self._network_job_ctrl) QP.AddToLayout(vbox, self._copy_to_clipboard_button) QP.AddToLayout(vbox, self._show_files_button) QP.AddToLayout(vbox, self._user_callable_button) QP.AddToLayout(vbox, self._show_tb_button) QP.AddToLayout(vbox, self._tb_text) QP.AddToLayout(vbox, self._copy_tb_button) QP.AddToLayout(vbox, hbox, CC.FLAGS_ON_RIGHT) self.setLayout(vbox)
def _Update( self ): if self._network_job is None or self._network_job.NoEngineYet(): can_cancel = False self._left_text.clear() self._right_text.clear() self._gauge.SetRange( 1 ) self._gauge.SetValue( 0 ) else: can_cancel = not self._network_job.IsDone() ( status_text, current_speed, bytes_read, bytes_to_read ) = self._network_job.GetStatus() self._left_text.setText( status_text ) speed_text = '' if bytes_read is not None and bytes_read > 0 and not self._network_job.HasError(): if bytes_to_read is not None and bytes_read != bytes_to_read: speed_text += HydrusData.ConvertValueRangeToBytes( bytes_read, bytes_to_read ) else: speed_text += HydrusData.ToHumanBytes( bytes_read ) if current_speed != bytes_to_read: # if it is a real quick download, just say its size speed_text += ' ' + HydrusData.ToHumanBytes( current_speed ) + '/s' show_right_text = speed_text != '' if self._right_text.isVisible() != show_right_text: self._right_text.setVisible( show_right_text ) self.updateGeometry() if speed_text != '': self._right_text.setText( speed_text ) right_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._right_text, len( speed_text ) ) right_min_width = right_width if right_min_width != self._last_right_min_width: self._last_right_min_width = right_min_width self._right_text.setMinimumWidth( right_min_width ) self.updateGeometry() self._gauge.SetRange( bytes_to_read ) self._gauge.SetValue( bytes_read ) if self._cancel_button.isEnabled() != can_cancel: self._cancel_button.setEnabled( can_cancel )
def _Update( self ): if self._network_job is None or self._network_job.NoEngineYet(): self._left_text.setText( '' ) self._right_text.setText( '' ) self._gauge.SetRange( 1 ) self._gauge.SetValue( 0 ) can_cancel = False else: if self._network_job.IsDone(): can_cancel = False else: can_cancel = True ( status_text, current_speed, bytes_read, bytes_to_read ) = self._network_job.GetStatus() self._left_text.setText( status_text ) if not self._download_started and current_speed > 0: self._download_started = True speed_text = '' if self._download_started and not self._network_job.HasError(): if bytes_read is not None: if bytes_to_read is not None and bytes_read != bytes_to_read: speed_text += HydrusData.ConvertValueRangeToBytes( bytes_read, bytes_to_read ) else: speed_text += HydrusData.ToHumanBytes( bytes_read ) if current_speed != bytes_to_read: # if it is a real quick download, just say its size speed_text += ' ' + HydrusData.ToHumanBytes( current_speed ) + '/s' self._right_text.setText( speed_text ) right_width = ClientGUIFunctions.ConvertTextToPixelWidth( self._right_text, len( speed_text ) ) right_min_width = right_width if right_min_width != self._last_right_min_width: self._last_right_min_width = right_min_width self._right_text.setMinimumWidth( right_min_width ) self._gauge.SetRange( bytes_to_read ) self._gauge.SetValue( bytes_read ) if can_cancel: if not self._cancel_button.isEnabled(): self._cancel_button.setEnabled( True ) else: if self._cancel_button.isEnabled(): self._cancel_button.setEnabled( False )
def __init__(self, parent, api_permissions): ClientGUIScrolledPanels.EditPanel.__init__(self, parent) self._original_api_permissions = api_permissions self._access_key = QW.QLineEdit() self._access_key.setReadOnly(True) width = ClientGUIFunctions.ConvertTextToPixelWidth( self._access_key, 66) self.setMinimumWidth(width) self._name = QW.QLineEdit(self) self._basic_permissions = QP.CheckListBox(self) for permission in ClientAPI.ALLOWED_PERMISSIONS: self._basic_permissions.Append( ClientAPI.basic_permission_to_str_lookup[permission], permission) search_tag_filter = api_permissions.GetSearchTagFilter() message = 'The API will only permit searching for tags that pass through this filter.' message += os.linesep * 2 message += 'If you want to allow all tags, just leave it as is, permitting everything. If you want to limit it to just one tag, such as "do waifu2x on this", set up a whitelist with only that tag allowed.' self._search_tag_filter = ClientGUITags.TagFilterButton( self, message, search_tag_filter, label_prefix='permitted tags: ') # access_key = api_permissions.GetAccessKey() self._access_key.setText(access_key.hex()) name = api_permissions.GetName() self._name.setText(name) basic_permissions = api_permissions.GetBasicPermissions() self._basic_permissions.SetCheckedData(basic_permissions) # rows = [] rows.append(('access key: ', self._access_key)) rows.append(('name: ', self._name)) rows.append(('permissions: ', self._basic_permissions)) rows.append(('tag search permissions: ', self._search_tag_filter)) gridbox = ClientGUICommon.WrapInGrid(self, rows) vbox = QP.VBoxLayout() QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR) self.widget().setLayout(vbox) # self._UpdateEnabled() self._basic_permissions.checkListBoxChanged.connect( self._UpdateEnabled)