Esempio n. 1
0
 def __init__( self, parent, label ):
     
     ClientGUIScrolledPanels.ResizingScrolledPanel.__init__( self, parent )
     
     self._commit = ClientGUICommon.BetterButton( self, 'commit', self.parentWidget().done, QW.QDialog.Accepted )
     self._commit.setObjectName( 'HydrusAccept' )
     
     self._forget = ClientGUICommon.BetterButton( self, 'forget', self.parentWidget().done, QW.QDialog.Rejected )
     self._forget.setObjectName( 'HydrusCancel' )
     
     def cancel_callback( parent ):
         
         parent.SetCancelled( True )
         parent.done( QW.QDialog.Rejected )
         
     
     self._back = ClientGUICommon.BetterButton( self, 'back to filtering', cancel_callback, parent )
     
     hbox = QP.HBoxLayout()
     
     QP.AddToLayout( hbox, self._commit, CC.FLAGS_EXPAND_BOTH_WAYS )
     QP.AddToLayout( hbox, self._forget, CC.FLAGS_EXPAND_BOTH_WAYS )
     
     vbox = QP.VBoxLayout()
     
     QP.AddToLayout( vbox, QP.MakeQLabelWithAlignment( label, self, QC.Qt.AlignVCenter | QC.Qt.AlignHCenter ), CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
     QP.AddToLayout( vbox, QP.MakeQLabelWithAlignment( '-or-', self, QC.Qt.AlignVCenter | QC.Qt.AlignHCenter ), CC.FLAGS_EXPAND_PERPENDICULAR )
     QP.AddToLayout( vbox, self._back, CC.FLAGS_EXPAND_PERPENDICULAR )
     
     self.widget().setLayout( vbox )
     
     ClientGUIFunctions.SetFocusLater( self._commit )
Esempio n. 2
0
 def __init__( self, parent, message, yes_label = 'yes', no_label = 'no' ):
     
     ClientGUIScrolledPanels.ResizingScrolledPanel.__init__( self, parent )
     
     self._yes = ClientGUICommon.BetterButton( self, yes_label, self.parentWidget().done, QW.QDialog.Accepted )
     self._yes.setObjectName( 'HydrusAccept' )
     self._yes.setText( yes_label )
     
     self._no = ClientGUICommon.BetterButton( self, no_label, self.parentWidget().done, QW.QDialog.Rejected )
     self._no.setObjectName( 'HydrusCancel' )
     self._no.setText( no_label )
     
     #
     
     hbox = QP.HBoxLayout()
     
     QP.AddToLayout( hbox, self._yes )
     QP.AddToLayout( hbox, self._no )
     
     vbox = QP.VBoxLayout()
     
     text = ClientGUICommon.BetterStaticText( self, message )
     text.setWordWrap( True )
     
     QP.AddToLayout( vbox, text )
     QP.AddToLayout( vbox, hbox, CC.FLAGS_ON_RIGHT )
     
     self.widget().setLayout( vbox )
     
     ClientGUIFunctions.SetFocusLater( self._yes )
Esempio n. 3
0
        def __init__(self, parent, predicate_panel_class, predicate):

            QW.QWidget.__init__(self, parent)

            self._defaults_button = ClientGUICommon.BetterBitmapButton(
                self,
                CC.global_pixmaps().star, self._DefaultsMenu)
            self._defaults_button.setToolTip('Set a new default.')

            self._predicate_panel = predicate_panel_class(self, predicate)
            self._parent = parent

            self._ok = QW.QPushButton('ok', self)
            self._ok.clicked.connect(self._DoOK)
            self._ok.setObjectName('HydrusAccept')

            hbox = QP.HBoxLayout()

            QP.AddToLayout(hbox, self._defaults_button,
                           CC.FLAGS_CENTER_PERPENDICULAR)
            QP.AddToLayout(hbox, self._predicate_panel,
                           CC.FLAGS_EXPAND_SIZER_BOTH_WAYS)
            QP.AddToLayout(hbox, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)

            self.setLayout(hbox)

            ClientGUIFunctions.SetFocusLater(self._ok)
    def __init__(self, parent, label):

        ClientGUIScrolledPanels.ResizingScrolledPanel.__init__(self, parent)

        self._commit = ClientGUICommon.BetterButton(self,
                                                    'commit and continue',
                                                    self.parentWidget().done,
                                                    QW.QDialog.Accepted)
        self._commit.setObjectName('HydrusAccept')

        self._back = ClientGUICommon.BetterButton(self, 'go back',
                                                  self.parentWidget().done,
                                                  QW.QDialog.Rejected)

        vbox = QP.VBoxLayout()

        st = ClientGUICommon.BetterStaticText(self, label)

        st.setAlignment(QC.Qt.AlignCenter)

        QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._commit, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        st = ClientGUICommon.BetterStaticText(self, '-or-')

        st.setAlignment(QC.Qt.AlignCenter)

        QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._back, CC.FLAGS_EXPAND_PERPENDICULAR)

        self.widget().setLayout(vbox)

        ClientGUIFunctions.SetFocusLater(self._commit)
Esempio n. 5
0
    def __init__(self,
                 parent,
                 message,
                 title='Are you sure?',
                 yes_tuples=None,
                 no_label='no'):

        if yes_tuples is None:

            yes_tuples = [('yes', 'yes')]

        Dialog.__init__(self, parent, title, position='center')

        self._value = None

        yes_buttons = []

        for (label, data) in yes_tuples:

            yes_button = ClientGUICommon.BetterButton(self, label, self._DoYes,
                                                      data)
            yes_button.setObjectName('HydrusAccept')

            yes_buttons.append(yes_button)

        self._no = ClientGUICommon.BetterButton(self, no_label, self.done,
                                                QW.QDialog.Rejected)
        self._no.setObjectName('HydrusCancel')

        #

        hbox = QP.HBoxLayout()

        for yes_button in yes_buttons:

            QP.AddToLayout(hbox, yes_button, CC.FLAGS_CENTER_PERPENDICULAR)

        QP.AddToLayout(hbox, self._no, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        text = ClientGUICommon.BetterStaticText(self, message)
        text.setWordWrap(True)

        QP.AddToLayout(vbox, 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)

        ClientGUIFunctions.SetFocusLater(yes_buttons[0])
    def __init__(self, parent, message, yes_tuples=None, no_label='no'):

        ClientGUIScrolledPanels.ResizingScrolledPanel.__init__(self, parent)

        if yes_tuples is None:

            yes_tuples = [('yes', 'yes')]

        self._value = yes_tuples[0][1]

        yes_buttons = []

        for (label, data) in yes_tuples:

            yes_button = ClientGUICommon.BetterButton(self, label, self._DoYes,
                                                      data)
            yes_button.setObjectName('HydrusAccept')

            yes_buttons.append(yes_button)

        self._no = ClientGUICommon.BetterButton(self, no_label,
                                                self.parentWidget().done,
                                                QW.QDialog.Rejected)
        self._no.setObjectName('HydrusCancel')

        #

        text = ClientGUICommon.BetterStaticText(self, message)
        text.setWordWrap(True)

        hbox = QP.HBoxLayout()

        for yes_button in yes_buttons:

            QP.AddToLayout(hbox, yes_button, CC.FLAGS_CENTER_PERPENDICULAR)

        QP.AddToLayout(hbox, self._no, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, text, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, hbox, CC.FLAGS_ON_RIGHT)

        self.widget().setLayout(vbox)

        ClientGUIFunctions.SetFocusLater(yes_buttons[0])
Esempio n. 7
0
    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)
Esempio n. 8
0
    def __init__(self, parent):

        Dialog.__init__(self,
                        parent,
                        'how to set up the account?',
                        position='center')

        register_message = 'I want to initialise a new account with the server. I have a registration token (a hexadecimal key starting with \'r\').'

        self._register = QW.QPushButton(register_message, self)
        self._register.clicked.connect(self.EventRegister)

        setup_message = 'The account is already initialised; I just want to add it to this client. I have a normal access key.'

        self._setup = QW.QPushButton(setup_message, self)
        self._setup.clicked.connect(self.accept)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, self._register, CC.FLAGS_EXPAND_PERPENDICULAR)

        st = ClientGUICommon.BetterStaticText(self, '-or-')

        st.setAlignment(QC.Qt.AlignCenter)

        QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._setup, CC.FLAGS_EXPAND_PERPENDICULAR)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        self._should_register = False

        ClientGUIFunctions.SetFocusLater(self._register)
Esempio n. 9
0
    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_ACTUAL,
                                                include_counts=True)

        self._tags_box.SetTagsBox(t)

        self._tags_box.setMinimumSize(QC.QSize(220, 300))

        self._paths = ClientGUIListCtrl.BetterListCtrl(
            self,
            CGLC.COLUMN_LIST_EXPORT_FILES.ID,
            24,
            self._ConvertDataToListCtrlTuples,
            use_simple_delete=True)

        self._paths.Sort()

        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()

        if export_path is not None:

            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_CENTER_PERPENDICULAR)

        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_CENTER_PERPENDICULAR)
        QP.AddToLayout(hbox, self._examples, CC.FLAGS_CENTER_PERPENDICULAR)

        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_CENTER_PERPENDICULAR)
        QP.AddToLayout(txt_hbox, self._export_tag_txts,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        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_ON_RIGHT)
        QP.AddToLayout(vbox, self._export_symlinks, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, txt_hbox, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, self._export, CC.FLAGS_ON_RIGHT)

        self.widget().setLayout(vbox)

        self._RefreshTags()

        self._UpdateTxtButton()

        ClientGUIFunctions.SetFocusLater(self._export)

        self._paths.itemSelectionChanged.connect(self._RefreshTags)

        if do_export_and_then_quit:

            HG.client_controller.CallAfterQtSafe(
                self, 'doing export before dialog quit', self._DoExport, True)
Esempio n. 10
0
    def __init__(self, parent, predicate: ClientSearch.Predicate):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        predicate_type = predicate.GetType()

        self._predicates = []

        label = None
        editable_pred_panels = []
        static_pred_buttons = []

        recent_predicate_types = [predicate_type]

        if predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_AGE:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 0, 1, 0))), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 0, 7, 0))), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_AGE,
                        ('<', 'delta', (0, 1, 0, 0))), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemAgeDelta,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemAgeDate,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MODIFIED_TIME:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemModifiedDelta, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemModifiedDate,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_DIMENSIONS:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH,
                ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_PIXELS
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 16, 9)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 9, 16)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 4, 3)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_RATIO,
                        ('=', 1, 1)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 1920)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 1080))),
                    forced_label='1080p'))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 1280)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 720))),
                    forced_label='720p'))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self,
                    self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_WIDTH, ('=', 3840)),
                           ClientSearch.Predicate(
                               ClientSearch.PREDICATE_TYPE_SYSTEM_HEIGHT,
                               ('=', 2160))),
                    forced_label='4k'))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemHeight,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemWidth,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemRatio,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumPixels,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_FRAMES
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                        ('>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_DURATION,
                        ('=', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                        ('=', 30)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_FRAMERATE,
                        ('=', 60)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemDuration,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemFramerate,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumFrames,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemFileService,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsExactURL, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsDomain, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsRegex, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemKnownURLsURLClass, predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO:

            recent_predicate_types = []

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO,
                        True), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_AUDIO,
                        False), )))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_HASH:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemHash,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT:

            label = 'system:limit clips a large search result down to the given number of files. It is very useful for processing in smaller batches.'
            label += os.linesep * 2
            label += 'For all the simpler sorts (filesize, duration, etc...), it will select the n largest/smallest in the result set appropriate for that sort. For complicated sorts like tags, it will sample randomly.'

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 64), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 256), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_LIMIT, 1024), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemLimit,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_MIME:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemMime,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS,
                        (None, '>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_TAGS,
                        (None, '=', 0)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumTags,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NOTES:

            recent_predicate_types = [
                ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                ClientSearch.PREDICATE_TYPE_SYSTEM_HAS_NOTE_NAME
            ]

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                        ('>', 0)), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_NOTES,
                        ('=', 0)), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumNotes,
                    predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemHasNoteName,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_NUM_WORDS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemNumWords,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_RATING:

            services_manager = HG.client_controller.services_manager

            ratings_services = services_manager.GetServices(
                (HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL))

            if len(ratings_services) > 0:

                editable_pred_panels.append(
                    self._PredOKPanel(
                        self,
                        ClientGUIPredicatesMultiple.PanelPredicateSystemRating,
                        (predicate, )))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemSimilarTo,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_SIZE:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.PanelPredicateSystemSize,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_TAG_AS_NUMBER:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self,
                    ClientGUIPredicatesSingle.PanelPredicateSystemTagAsNumber,
                    predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS:

            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.
                        PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS_KING,
                        False), )))
            static_pred_buttons.append(
                ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                    self, self, (ClientSearch.Predicate(
                        ClientSearch.
                        PREDICATE_TYPE_SYSTEM_FILE_RELATIONSHIPS_KING,
                        True), )))

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemDuplicateRelationships, predicate))

        elif predicate_type == ClientSearch.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:

            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemFileViewingStatsViews, predicate))
            editable_pred_panels.append(
                self._PredOKPanel(
                    self, ClientGUIPredicatesSingle.
                    PanelPredicateSystemFileViewingStatsViewtime, predicate))

        vbox = QP.VBoxLayout()

        if label is not None:

            st = ClientGUICommon.BetterStaticText(self, label=label)

            st.setWordWrap(True)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

        recent_predicates = []

        if len(recent_predicate_types) > 0:

            recent_predicates = HG.client_controller.new_options.GetRecentPredicates(
                recent_predicate_types)

            if len(recent_predicates) > 0:

                recent_predicates_box = ClientGUICommon.StaticBox(
                    self, 'recent')

                for recent_predicate in recent_predicates:

                    button = ClientGUIPredicatesSingle.StaticSystemPredicateButton(
                        recent_predicates_box, self, (recent_predicate, ))

                    recent_predicates_box.Add(button,
                                              CC.FLAGS_EXPAND_PERPENDICULAR)

                QP.AddToLayout(vbox, recent_predicates_box,
                               CC.FLAGS_EXPAND_PERPENDICULAR)

        for button in static_pred_buttons:

            QP.AddToLayout(vbox, button, CC.FLAGS_EXPAND_PERPENDICULAR)

        for panel in editable_pred_panels:

            QP.AddToLayout(vbox, panel, CC.FLAGS_EXPAND_PERPENDICULAR)

        if len(static_pred_buttons) > 0 and len(editable_pred_panels) == 0:

            ClientGUIFunctions.SetFocusLater(static_pred_buttons[0])

        self.widget().setLayout(vbox)
Esempio n. 11
0
    def __init__(self, parent, external_port, protocol_type, internal_port,
                 description, duration):

        Dialog.__init__(self, parent, 'configure upnp mapping')

        self._external_port = ClientGUICommon.BetterSpinBox(self,
                                                            min=0,
                                                            max=65535)

        self._protocol_type = ClientGUICommon.BetterChoice(self)
        self._protocol_type.addItem('TCP', 'TCP')
        self._protocol_type.addItem('UDP', 'UDP')

        self._internal_port = ClientGUICommon.BetterSpinBox(self,
                                                            min=0,
                                                            max=65535)
        self._description = QW.QLineEdit(self)
        self._duration = ClientGUICommon.BetterSpinBox(self, min=0, max=86400)

        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._external_port.setValue(external_port)

        if protocol_type == 'TCP': self._protocol_type.setCurrentIndex(0)
        elif protocol_type == 'UDP': self._protocol_type.setCurrentIndex(1)

        self._internal_port.setValue(internal_port)
        self._description.setText(description)
        self._duration.setValue(duration)

        #

        rows = []

        rows.append(('external port: ', self._external_port))
        rows.append(('protocol type: ', self._protocol_type))
        rows.append(('internal port: ', self._internal_port))
        rows.append(('description: ', self._description))
        rows.append(('duration (0 = indefinite): ', self._duration))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
Esempio n. 12
0
    def __init__(self,
                 parent,
                 service_key,
                 tag_display_type,
                 tags,
                 message=''):

        Dialog.__init__(self, parent, 'input tags')

        self._service_key = service_key

        self._tags = ClientGUIListBoxes.ListBoxTagsStringsAddRemove(
            self, service_key, tag_display_type)

        default_location_context = HG.client_controller.new_options.GetDefaultLocalLocationContext(
        )

        self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsWrite(
            self,
            self.EnterTags,
            default_location_context,
            service_key,
            show_paste_button=True)

        self._tag_autocomplete.nullEntered.connect(self.OK)

        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._tags.SetTags(tags)

        #

        b_box = QP.HBoxLayout()

        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        if message != '':

            st = ClientGUICommon.BetterStaticText(self, message)

            st.setWordWrap(True)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

        QP.AddToLayout(vbox, self._tags, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, self._tag_autocomplete)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 300))

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._tag_autocomplete)
Esempio n. 13
0
    def __init__(self, parent, namespace='', regex=''):

        Dialog.__init__(self, parent, 'configure quick namespace')

        self._namespace = QW.QLineEdit(self)

        self._regex = QW.QLineEdit(self)

        self._shortcuts = ClientGUICommon.RegexButton(self)

        self._regex_intro_link = ClientGUICommon.BetterHyperLink(
            self, 'a good regex introduction',
            'https://www.aivosto.com/vbtips/regex.html')
        self._regex_practise_link = ClientGUICommon.BetterHyperLink(
            self, 'regex practice', 'https://regexr.com/3cvmf')

        self._ok = QW.QPushButton('OK', self)
        self._ok.clicked.connect(self.EventOK)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._namespace.setText(namespace)
        self._regex.setText(regex)

        #

        control_box = QP.HBoxLayout()

        QP.AddToLayout(control_box, self._namespace, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(control_box,
                       ClientGUICommon.BetterStaticText(self, ':'),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(control_box, self._regex, CC.FLAGS_EXPAND_BOTH_WAYS)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        intro = r'Put the namespace (e.g. page) on the left.' + os.linesep + r'Put the regex (e.g. [1-9]+\d*(?=.{4}$)) on the right.' + os.linesep + r'All files will be tagged with "namespace:regex".'

        QP.AddToLayout(vbox, ClientGUICommon.BetterStaticText(self, intro),
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, control_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, self._shortcuts, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, self._regex_intro_link, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, self._regex_practise_link, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
Esempio n. 14
0
    def __init__(self,
                 parent,
                 share_key,
                 name,
                 text,
                 timeout,
                 hashes,
                 new_share=False):

        Dialog.__init__(self, parent, 'configure local booru share')

        self._name = QW.QLineEdit(self)

        self._text = QW.QPlainTextEdit(self)
        self._text.setMinimumHeight(100)

        message = 'expires in'

        self._timeout_number = ClientGUICommon.NoneableSpinCtrl(
            self,
            message,
            none_phrase='no expiration',
            max=1000000,
            multiplier=1)

        self._timeout_multiplier = ClientGUICommon.BetterChoice(self)
        self._timeout_multiplier.addItem('minutes', 60)
        self._timeout_multiplier.addItem('hours', 60 * 60)
        self._timeout_multiplier.addItem('days', 60 * 60 * 24)

        self._copy_internal_share_link = QW.QPushButton(
            'copy internal share link', self)
        self._copy_internal_share_link.clicked.connect(
            self.EventCopyInternalShareURL)

        self._copy_external_share_link = QW.QPushButton(
            'copy external share link', self)
        self._copy_external_share_link.clicked.connect(
            self.EventCopyExternalShareURL)

        self._ok = QW.QPushButton('ok', self)
        self._ok.clicked.connect(self.accept)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._share_key = share_key
        self._name.setText(name)
        self._text.setPlainText(text)

        if timeout is None:

            self._timeout_number.SetValue(None)

            self._timeout_multiplier.SetValue(60)

        else:

            time_left = HydrusData.GetTimeDeltaUntilTime(timeout)

            if time_left < 60 * 60 * 12: time_value = 60
            elif time_left < 60 * 60 * 24 * 7: time_value = 60 * 60
            else: time_value = 60 * 60 * 24

            self._timeout_number.SetValue(time_left // time_value)

            self._timeout_multiplier.SetValue(time_value)

        self._hashes = hashes

        self._service = HG.client_controller.services_manager.GetService(
            CC.LOCAL_BOORU_SERVICE_KEY)

        internal_port = self._service.GetPort()

        if internal_port is None:

            self._copy_internal_share_link.setEnabled(False)
            self._copy_external_share_link.setEnabled(False)

        #

        rows = []

        rows.append(('share name: ', self._name))
        rows.append(('share text: ', self._text))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        timeout_box = QP.HBoxLayout()
        QP.AddToLayout(timeout_box, self._timeout_number,
                       CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(timeout_box, self._timeout_multiplier,
                       CC.FLAGS_EXPAND_BOTH_WAYS)

        link_box = QP.HBoxLayout()
        QP.AddToLayout(link_box, self._copy_internal_share_link,
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(link_box, self._copy_external_share_link,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        intro = 'Sharing ' + HydrusData.ToHumanInt(len(
            self._hashes)) + ' files.'
        intro += os.linesep + 'Title and text are optional.'

        if new_share:
            intro += os.linesep + 'The link will not work until you ok this dialog.'

        QP.AddToLayout(vbox, ClientGUICommon.BetterStaticText(self, intro),
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, timeout_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, link_box, CC.FLAGS_ON_RIGHT)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        size_hint.setWidth(max(size_hint.width(), 350))

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
Esempio n. 15
0
    def __init__(self, parent, service_key):

        Dialog.__init__(self, parent, 'configure new accounts')

        self._service_key = service_key

        self._num = ClientGUICommon.BetterSpinBox(self,
                                                  min=1,
                                                  max=10000,
                                                  width=80)

        self._account_types = ClientGUICommon.BetterChoice(self)

        self._lifetime = ClientGUICommon.BetterChoice(self)

        self._ok = QW.QPushButton('OK', self)
        self._ok.clicked.connect(self.EventOK)
        self._ok.setObjectName('HydrusAccept')

        self._cancel = QW.QPushButton('Cancel', self)
        self._cancel.clicked.connect(self.reject)
        self._cancel.setObjectName('HydrusCancel')

        #

        self._num.setValue(1)

        service = HG.client_controller.services_manager.GetService(service_key)

        response = service.Request(HC.GET, 'account_types')

        account_types = response['account_types']

        for account_type in account_types:

            self._account_types.addItem(account_type.GetTitle(), account_type)

        self._account_types.setCurrentIndex(0)

        for (s, value) in HC.lifetimes:

            self._lifetime.addItem(s, value)

        self._lifetime.setCurrentIndex(3)  # one year

        #

        ctrl_box = QP.HBoxLayout()

        QP.AddToLayout(ctrl_box,
                       ClientGUICommon.BetterStaticText(self, 'generate'),
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._num, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._account_types,
                       CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(
            ctrl_box,
            ClientGUICommon.BetterStaticText(self, 'accounts, to expire in'),
            CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(ctrl_box, self._lifetime, CC.FLAGS_CENTER_PERPENDICULAR)

        b_box = QP.HBoxLayout()
        QP.AddToLayout(b_box, self._ok, CC.FLAGS_CENTER_PERPENDICULAR)
        QP.AddToLayout(b_box, self._cancel, CC.FLAGS_CENTER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, ctrl_box, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)
        QP.AddToLayout(vbox, b_box, CC.FLAGS_ON_RIGHT)

        self.setLayout(vbox)

        size_hint = self.sizeHint()

        QP.SetInitialSize(self, size_hint)

        ClientGUIFunctions.SetFocusLater(self._ok)
    def __init__(self, parent, kept_label: typing.Optional[str],
                 deletion_options):

        ClientGUIScrolledPanels.ResizingScrolledPanel.__init__(self, parent)

        self._location_context = ClientLocation.LocationContext()  # empty

        vbox = QP.VBoxLayout()

        first_commit = None

        if len(deletion_options) == 0:

            if kept_label is None:

                kept_label = 'ERROR: do not seem to have any actions at all!'

            label = '{}?'.format(kept_label)

            st = ClientGUICommon.BetterStaticText(self, label)

            st.setAlignment(QC.Qt.AlignCenter)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

            first_commit = ClientGUICommon.BetterButton(
                self, 'commit', self.DoCommit,
                ClientLocation.LocationContext())
            first_commit.setObjectName('HydrusAccept')

            QP.AddToLayout(vbox, first_commit, CC.FLAGS_EXPAND_PERPENDICULAR)

        elif len(deletion_options) == 1:

            (location_context, delete_label) = deletion_options[0]

            if kept_label is None:

                label = '{}?'.format(delete_label)

            else:

                label = '{} and {}?'.format(kept_label, delete_label)

            st = ClientGUICommon.BetterStaticText(self, label)

            st.setAlignment(QC.Qt.AlignCenter)

            QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

            first_commit = ClientGUICommon.BetterButton(
                self, 'commit', self.DoCommit, location_context)
            first_commit.setObjectName('HydrusAccept')

            QP.AddToLayout(vbox, first_commit, CC.FLAGS_EXPAND_PERPENDICULAR)

        else:

            if kept_label is not None:

                label = '{}{}-and-'.format(kept_label, os.linesep)

                st = ClientGUICommon.BetterStaticText(self, label)

                st.setAlignment(QC.Qt.AlignCenter)

                QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

            for (location_context, delete_label) in deletion_options:

                label = '{}?'.format(delete_label)

                st = ClientGUICommon.BetterStaticText(self, label)

                st.setAlignment(QC.Qt.AlignCenter)

                QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)

                commit = ClientGUICommon.BetterButton(self, 'commit',
                                                      self.DoCommit,
                                                      location_context)
                commit.setObjectName('HydrusAccept')

                QP.AddToLayout(vbox, commit, CC.FLAGS_EXPAND_PERPENDICULAR)

                if first_commit is None:

                    first_commit = commit

        self._forget = ClientGUICommon.BetterButton(self, 'forget',
                                                    self.parentWidget().done,
                                                    QW.QDialog.Rejected)
        self._forget.setObjectName('HydrusCancel')

        self._back = ClientGUICommon.BetterButton(self, 'back to filtering',
                                                  self.DoGoBack)

        QP.AddToLayout(vbox, self._forget, CC.FLAGS_EXPAND_PERPENDICULAR)

        st = ClientGUICommon.BetterStaticText(self, '-or-')

        st.setAlignment(QC.Qt.AlignCenter)

        QP.AddToLayout(vbox, st, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._back, CC.FLAGS_EXPAND_PERPENDICULAR)

        self.widget().setLayout(vbox)

        ClientGUIFunctions.SetFocusLater(first_commit)