def __init__( self, parent, external_port, protocol_type, internal_port, description, duration ):
     
     Dialog.__init__( self, parent, 'configure upnp mapping' )
     
     self._external_port = QP.MakeQSpinBox( 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 = QP.MakeQSpinBox( self, min=0, max=65535 )
     self._description = QW.QLineEdit( self )
     self._duration = QP.MakeQSpinBox( 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 )
     
     HG.client_controller.CallAfterQtSafe( self._ok, self._ok.setFocus, QC.Qt.OtherFocusReason)
        def __init__(self, parent, services, media):

            QW.QWidget.__init__(self, parent)

            self._services = services

            self._media = media

            self._service_keys_to_controls = {}
            self._service_keys_to_original_ratings_states = {}

            rows = []

            for service in self._services:

                name = service.GetName()

                service_key = service.GetServiceKey()

                rating_state = ClientRatings.GetLikeStateFromMedia(
                    self._media, service_key)

                control = ClientGUICommon.RatingLikeDialog(self, service_key)

                control.SetRatingState(rating_state)

                self._service_keys_to_controls[service_key] = control
                self._service_keys_to_original_ratings_states[
                    service_key] = rating_state

                rows.append((name + ': ', control))

            gridbox = ClientGUICommon.WrapInGrid(self, rows, expand_text=True)

            self.setLayout(gridbox)
    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,
                 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)

        HG.client_controller.CallAfterQtSafe(self._ok, self._ok.setFocus,
                                             QC.Qt.OtherFocusReason)
Beispiel #5
0
    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, 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, 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)
Beispiel #8
0
    def __init__(self, parent, export_folder: ClientExporting.ExportFolder):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        self._export_folder = export_folder

        (name, path, export_type, delete_from_client_after_export,
         file_search_context, run_regularly, period, phrase,
         self._last_checked, paused, run_now) = self._export_folder.ToTuple()

        self._path_box = ClientGUICommon.StaticBox(self, 'name and location')

        self._name = QW.QLineEdit(self._path_box)

        self._path = QP.DirPickerCtrl(self._path_box)

        #

        self._type_box = ClientGUICommon.StaticBox(self, 'type of export')

        self._type = ClientGUICommon.BetterChoice(self._type_box)
        self._type.addItem('regular', HC.EXPORT_FOLDER_TYPE_REGULAR)
        self._type.addItem('synchronise', HC.EXPORT_FOLDER_TYPE_SYNCHRONISE)

        self._delete_from_client_after_export = QW.QCheckBox(self._type_box)

        #

        self._query_box = ClientGUICommon.StaticBox(self, 'query to export')

        self._page_key = 'export folders placeholder'

        self._tag_autocomplete = ClientGUIACDropdown.AutoCompleteDropdownTagsRead(
            self._query_box,
            self._page_key,
            file_search_context,
            allow_all_known_files=False,
            force_system_everything=True)

        #

        self._period_box = ClientGUICommon.StaticBox(self, 'export period')

        self._period = ClientGUITime.TimeDeltaButton(self._period_box,
                                                     min=3 * 60,
                                                     days=True,
                                                     hours=True,
                                                     minutes=True)

        self._run_regularly = QW.QCheckBox(self._period_box)

        self._paused = QW.QCheckBox(self._period_box)

        self._run_now = QW.QCheckBox(self._period_box)

        #

        self._phrase_box = ClientGUICommon.StaticBox(self, 'filenames')

        self._pattern = QW.QLineEdit(self._phrase_box)

        self._examples = ClientGUICommon.ExportPatternButton(self._phrase_box)

        #

        self._name.setText(name)

        self._path.SetPath(path)

        self._type.SetValue(export_type)

        self._delete_from_client_after_export.setChecked(
            delete_from_client_after_export)

        self._period.SetValue(period)

        self._run_regularly.setChecked(run_regularly)

        self._paused.setChecked(paused)

        self._run_now.setChecked(run_now)

        self._pattern.setText(phrase)

        #

        rows = []

        rows.append(('name: ', self._name))
        rows.append(('folder path: ', self._path))

        gridbox = ClientGUICommon.WrapInGrid(self._path_box, rows)

        self._path_box.Add(gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        #

        text = '''regular - try to export the files to the directory, overwriting if the filesize if different

synchronise - try to export the files to the directory, overwriting if the filesize if different, and delete anything else in the directory

If you select synchronise, be careful!'''

        st = ClientGUICommon.BetterStaticText(self._type_box, label=text)
        st.setWordWrap(True)

        self._type_box.Add(st, CC.FLAGS_EXPAND_PERPENDICULAR)
        self._type_box.Add(self._type, CC.FLAGS_EXPAND_PERPENDICULAR)

        rows = []

        rows.append(('delete files from client after export: ',
                     self._delete_from_client_after_export))

        gridbox = ClientGUICommon.WrapInGrid(self._type_box, rows)

        self._type_box.Add(gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        self._query_box.Add(self._tag_autocomplete)

        self._period_box.Add(self._period, CC.FLAGS_EXPAND_PERPENDICULAR)

        rows = []

        rows.append(('run regularly?: ', self._run_regularly))
        rows.append(('paused: ', self._paused))
        rows.append(('run on dialog ok: ', self._run_now))

        gridbox = ClientGUICommon.WrapInGrid(self._period_box, rows)

        self._period_box.Add(gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        phrase_hbox = QP.HBoxLayout()

        QP.AddToLayout(phrase_hbox, self._pattern, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(phrase_hbox, self._examples,
                       CC.FLAGS_CENTER_PERPENDICULAR)

        self._phrase_box.Add(phrase_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, self._path_box, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._type_box, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._query_box, CC.FLAGS_EXPAND_BOTH_WAYS)
        QP.AddToLayout(vbox, self._period_box, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._phrase_box, CC.FLAGS_EXPAND_PERPENDICULAR)

        self.widget().setLayout(vbox)

        self._UpdateTypeDeleteUI()

        self._type.currentIndexChanged.connect(self._UpdateTypeDeleteUI)
        self._delete_from_client_after_export.clicked.connect(
            self.EventDeleteFilesAfterExport)
Beispiel #9
0
    def __init__(self, parent, checker_options):

        ClientGUIScrolledPanels.EditPanel.__init__(self, parent)

        help_button = ClientGUICommon.BetterBitmapButton(
            self,
            CC.global_pixmaps().help, self._ShowHelp)
        help_button.setToolTip('Show help regarding these checker options.')

        help_hbox = ClientGUICommon.WrapInText(help_button, self,
                                               'help for this panel -->',
                                               QG.QColor(0, 0, 255))

        from hydrus.client import ClientDefaults

        defaults_panel = ClientGUICommon.StaticBox(self, 'reasonable defaults')

        defaults_1 = ClientGUICommon.BetterButton(
            defaults_panel, 'thread', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('thread'))
        defaults_2 = ClientGUICommon.BetterButton(
            defaults_panel, 'slow thread', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('slow thread'))
        defaults_3 = ClientGUICommon.BetterButton(
            defaults_panel, 'faster tag subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('fast tag subscription'))
        defaults_4 = ClientGUICommon.BetterButton(
            defaults_panel, 'medium tag/artist subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('artist subscription'))
        defaults_5 = ClientGUICommon.BetterButton(
            defaults_panel, 'slower tag subscription', self.SetValue,
            ClientDefaults.GetDefaultCheckerOptions('slow tag subscription'))

        #

        # add statictext or whatever that will update on any updates above to say 'given velocity of blah and last check at blah, next check in 5 mins'
        # or indeed this could just take the file_seed cache and last check of the caller, if there is one
        # this would be more useful to the user, to know 'right, on ok, it'll refresh in 30 mins'
        # this is actually more complicated--it also needs last check time to calc a fresh file velocity based on new death_file_velocity

        #

        min_unit_value = 0
        max_unit_value = 1000
        min_time_delta = 60

        self._death_file_velocity = VelocityCtrl(self,
                                                 min_unit_value,
                                                 max_unit_value,
                                                 min_time_delta,
                                                 days=True,
                                                 hours=True,
                                                 minutes=True,
                                                 per_phrase='in',
                                                 unit='files')

        self._flat_check_period_checkbox = QW.QCheckBox(self)

        #

        if HG.client_controller.new_options.GetBoolean('advanced_mode'):

            never_faster_than_min = 1
            never_slower_than_min = 1

            flat_check_period_min = 1

        else:

            never_faster_than_min = 30
            never_slower_than_min = 600

            flat_check_period_min = 180

        self._reactive_check_panel = ClientGUICommon.StaticBox(
            self, 'reactive checking')

        self._intended_files_per_check = QP.MakeQSpinBox(
            self._reactive_check_panel, min=1, max=1000)

        self._never_faster_than = TimeDeltaCtrl(self._reactive_check_panel,
                                                min=never_faster_than_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)

        self._never_slower_than = TimeDeltaCtrl(self._reactive_check_panel,
                                                min=never_slower_than_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)

        #

        self._static_check_panel = ClientGUICommon.StaticBox(
            self, 'static checking')

        self._flat_check_period = TimeDeltaCtrl(self._static_check_panel,
                                                min=flat_check_period_min,
                                                days=True,
                                                hours=True,
                                                minutes=True,
                                                seconds=True)

        #

        self.SetValue(checker_options)

        #

        defaults_panel.Add(defaults_1, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_2, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_3, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_4, CC.FLAGS_EXPAND_PERPENDICULAR)
        defaults_panel.Add(defaults_5, CC.FLAGS_EXPAND_PERPENDICULAR)

        #

        #

        rows = []

        rows.append(
            ('intended new files per check: ', self._intended_files_per_check))
        rows.append(
            ('never check faster than once per: ', self._never_faster_than))
        rows.append(
            ('never check slower than once per: ', self._never_slower_than))

        gridbox = ClientGUICommon.WrapInGrid(self._reactive_check_panel, rows)

        self._reactive_check_panel.Add(gridbox,
                                       CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        #

        rows = []

        rows.append(('check period: ', self._flat_check_period))

        gridbox = ClientGUICommon.WrapInGrid(self._static_check_panel, rows)

        self._static_check_panel.Add(gridbox,
                                     CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        #

        rows = []

        rows.append(('stop checking if new files found falls below: ',
                     self._death_file_velocity))
        rows.append(('just check at a static, regular interval: ',
                     self._flat_check_period_checkbox))

        gridbox = ClientGUICommon.WrapInGrid(self, rows)

        vbox = QP.VBoxLayout()

        QP.AddToLayout(vbox, help_hbox, CC.FLAGS_BUTTON_SIZER)
        QP.AddToLayout(vbox, defaults_panel, CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR)

        if HG.client_controller.new_options.GetBoolean('advanced_mode'):

            label = 'As you are in advanced mode, these options have extremely low limits. This is intended only for testing and small scale private network tasks. Do not use very fast check times for real world use on public websites, as it is wasteful and rude, hydrus will be overloaded with high-CPU parsing work, and you may get your IP banned.'

            st = ClientGUICommon.BetterStaticText(self, label=label)
            st.setObjectName('HydrusWarning')

            st.setWordWrap(True)

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

        QP.AddToLayout(vbox, self._reactive_check_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)
        QP.AddToLayout(vbox, self._static_check_panel,
                       CC.FLAGS_EXPAND_PERPENDICULAR)

        self.widget().setLayout(vbox)

        #

        self._flat_check_period_checkbox.clicked.connect(
            self.EventFlatPeriodCheck)