2013-02-19 00:11:43 +00:00
import os
2018-09-26 19:05:12 +00:00
import re
2020-05-13 19:03:16 +00:00
import typing
2020-04-22 21:00:35 +00:00
2019-11-14 03:56:30 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
2020-04-22 21:00:35 +00:00
from hydrus . core import HydrusConstants as HC
from hydrus . core import HydrusData
from hydrus . core import HydrusExceptions
from hydrus . core import HydrusGlobals as HG
2020-07-29 20:52:44 +00:00
2020-07-08 22:00:33 +00:00
from hydrus . client import ClientApplicationCommand as CAC
2020-04-22 21:00:35 +00:00
from hydrus . client import ClientConstants as CC
from hydrus . client import ClientPaths
from hydrus . client . gui import ClientGUICore as CGC
from hydrus . client . gui import ClientGUIFunctions
from hydrus . client . gui import ClientGUIMenus
from hydrus . client . gui import ClientGUIShortcuts
from hydrus . client . gui import QtPorting as QP
2013-02-19 00:11:43 +00:00
2020-02-05 22:55:21 +00:00
CANVAS_MEDIA_VIEWER = 0
CANVAS_PREVIEW = 1
canvas_str_lookup = { }
canvas_str_lookup [ CANVAS_MEDIA_VIEWER ] = ' media viewer '
canvas_str_lookup [ CANVAS_PREVIEW ] = ' preview '
2020-07-29 20:52:44 +00:00
def AddGridboxStretchSpacer ( layout : QW . QGridLayout ) :
layout . addItem ( QW . QSpacerItem ( 10 , 10 , QW . QSizePolicy . Expanding , QW . QSizePolicy . Fixed ) )
2019-11-14 03:56:30 +00:00
def WrapInGrid ( parent , rows , expand_text = False , add_stretch_at_end = True ) :
2016-08-31 19:55:14 +00:00
2019-11-14 03:56:30 +00:00
gridbox = QP . GridLayout ( cols = 2 )
2016-08-31 19:55:14 +00:00
if expand_text :
2019-11-14 03:56:30 +00:00
gridbox . setColumnStretch ( 0 , 1 )
2016-08-31 19:55:14 +00:00
2020-08-05 20:10:36 +00:00
text_flags = CC . FLAGS_EXPAND_BOTH_WAYS
2020-07-29 20:52:44 +00:00
control_flags = CC . FLAGS_CENTER_PERPENDICULAR
sizer_flags = CC . FLAGS_CENTER_PERPENDICULAR
2016-08-31 19:55:14 +00:00
else :
2019-11-14 03:56:30 +00:00
gridbox . setColumnStretch ( 1 , 1 )
2016-08-31 19:55:14 +00:00
2020-07-29 20:52:44 +00:00
text_flags = CC . FLAGS_ON_LEFT
2019-11-14 03:56:30 +00:00
control_flags = CC . FLAGS_NONE
2016-09-07 20:01:05 +00:00
sizer_flags = CC . FLAGS_EXPAND_SIZER_BOTH_WAYS
2016-08-31 19:55:14 +00:00
for ( text , control ) in rows :
2020-02-12 22:50:37 +00:00
if isinstance ( text , BetterStaticText ) :
st = text
else :
st = BetterStaticText ( parent , text )
2018-04-18 22:10:15 +00:00
2019-11-14 03:56:30 +00:00
if isinstance ( control , QW . QLayout ) :
2016-09-07 20:01:05 +00:00
cflags = sizer_flags
else :
cflags = control_flags
2019-11-14 03:56:30 +00:00
if control . toolTip ( ) != ' ' :
2018-04-18 22:10:15 +00:00
2019-11-14 03:56:30 +00:00
st . setToolTip ( control . toolTip ( ) )
2018-04-18 22:10:15 +00:00
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( gridbox , st , text_flags )
QP . AddToLayout ( gridbox , control , cflags )
2016-08-31 19:55:14 +00:00
2020-03-11 21:52:11 +00:00
if add_stretch_at_end :
gridbox . setRowStretch ( gridbox . rowCount ( ) , 1 )
2016-08-31 19:55:14 +00:00
return gridbox
2018-02-28 22:30:36 +00:00
def WrapInText ( control , parent , text , colour = None ) :
2016-08-17 20:07:22 +00:00
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( )
2016-08-17 20:07:22 +00:00
2017-04-19 20:58:30 +00:00
st = BetterStaticText ( parent , text )
2018-02-28 22:30:36 +00:00
if colour is not None :
2019-11-14 03:56:30 +00:00
QP . SetForegroundColour ( st , colour )
2018-02-28 22:30:36 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , st , CC . FLAGS_CENTER_PERPENDICULAR )
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , control , CC . FLAGS_EXPAND_BOTH_WAYS )
2016-08-17 20:07:22 +00:00
return hbox
2019-06-05 19:42:39 +00:00
class ShortcutAwareToolTipMixin ( object ) :
def __init__ ( self , tt_callable ) :
self . _tt_callable = tt_callable
self . _tt = ' '
self . _simple_shortcut_command = None
2020-03-25 21:15:57 +00:00
if ClientGUIShortcuts . shortcuts_manager_initialised ( ) :
ClientGUIShortcuts . shortcuts_manager ( ) . shortcutsChanged . connect ( self . RefreshToolTip )
2019-06-05 19:42:39 +00:00
def _RefreshToolTip ( self ) :
tt = self . _tt
if self . _simple_shortcut_command is not None :
tt + = os . linesep * 2
tt + = ' ---------- '
2020-03-25 21:15:57 +00:00
names_to_shortcuts = ClientGUIShortcuts . shortcuts_manager ( ) . GetNamesToShortcuts ( self . _simple_shortcut_command )
2019-06-05 19:42:39 +00:00
if len ( names_to_shortcuts ) > 0 :
2020-05-13 19:03:16 +00:00
names = sorted ( names_to_shortcuts . keys ( ) )
2019-06-05 19:42:39 +00:00
for name in names :
shortcuts = names_to_shortcuts [ name ]
2020-05-13 19:03:16 +00:00
shortcut_strings = sorted ( ( shortcut . ToString ( ) for shortcut in shortcuts ) )
2019-06-05 19:42:39 +00:00
2020-07-08 22:00:33 +00:00
if name in ClientGUIShortcuts . shortcut_names_to_pretty_names :
pretty_name = ClientGUIShortcuts . shortcut_names_to_pretty_names [ name ]
else :
pretty_name = name
2019-06-05 19:42:39 +00:00
tt + = os . linesep * 2
tt + = ' , ' . join ( shortcut_strings )
tt + = os . linesep
2020-07-08 22:00:33 +00:00
tt + = ' ( {} -> {} ) ' . format ( pretty_name , CAC . simple_enum_to_str_lookup [ self . _simple_shortcut_command ] )
2019-06-05 19:42:39 +00:00
else :
tt + = os . linesep * 2
tt + = ' no shortcuts set '
tt + = os . linesep
2020-07-08 22:00:33 +00:00
tt + = ' ( {} ) ' . format ( CAC . simple_enum_to_str_lookup [ self . _simple_shortcut_command ] )
2019-06-05 19:42:39 +00:00
self . _tt_callable ( tt )
2020-03-25 21:15:57 +00:00
def RefreshToolTip ( self ) :
2019-06-05 19:42:39 +00:00
2020-03-25 21:15:57 +00:00
if ClientGUIShortcuts . shortcuts_manager_initialised ( ) :
self . _RefreshToolTip ( )
2019-06-05 19:42:39 +00:00
2020-07-08 22:00:33 +00:00
def SetToolTipWithShortcuts ( self , tt : str , simple_shortcut_command : int ) :
2019-06-05 19:42:39 +00:00
self . _tt = tt
self . _simple_shortcut_command = simple_shortcut_command
self . _RefreshToolTip ( )
2019-11-14 03:56:30 +00:00
class BetterBitmapButton ( ShortcutAwareToolTipMixin , QW . QPushButton ) :
2017-01-18 22:52:39 +00:00
2017-01-25 22:56:55 +00:00
def __init__ ( self , parent , bitmap , func , * args , * * kwargs ) :
2017-01-18 22:52:39 +00:00
2019-11-14 03:56:30 +00:00
QW . QPushButton . __init__ ( self , parent )
self . setIcon ( QG . QIcon ( bitmap ) )
self . setIconSize ( bitmap . size ( ) )
self . setSizePolicy ( QW . QSizePolicy . Maximum , QW . QSizePolicy . Maximum )
ShortcutAwareToolTipMixin . __init__ ( self , self . setToolTip )
2017-01-18 22:52:39 +00:00
2017-01-25 22:56:55 +00:00
self . _func = func
2017-01-18 22:52:39 +00:00
self . _args = args
self . _kwargs = kwargs
2019-06-05 19:42:39 +00:00
2019-11-14 03:56:30 +00:00
self . clicked . connect ( self . EventButton )
2017-01-18 22:52:39 +00:00
2019-11-14 03:56:30 +00:00
def EventButton ( self ) :
2017-01-18 22:52:39 +00:00
2017-01-25 22:56:55 +00:00
self . _func ( * self . _args , * * self . _kwargs )
2017-01-18 22:52:39 +00:00
2019-11-14 03:56:30 +00:00
class BetterButton ( ShortcutAwareToolTipMixin , QW . QPushButton ) :
2016-10-19 20:02:56 +00:00
2017-01-25 22:56:55 +00:00
def __init__ ( self , parent , label , func , * args , * * kwargs ) :
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
QW . QPushButton . __init__ ( self , parent )
ShortcutAwareToolTipMixin . __init__ ( self , self . setToolTip )
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
self . setText ( label )
2016-10-19 20:02:56 +00:00
2017-01-25 22:56:55 +00:00
self . _func = func
2016-12-07 22:12:52 +00:00
self . _args = args
self . _kwargs = kwargs
2021-04-07 21:26:45 +00:00
self . _yes_no_text = None
2019-11-14 03:56:30 +00:00
self . clicked . connect ( self . EventButton )
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
def EventButton ( self ) :
2016-10-19 20:02:56 +00:00
2021-04-07 21:26:45 +00:00
if self . _yes_no_text is not None :
from hydrus . client . gui import ClientGUIDialogsQuick
result = ClientGUIDialogsQuick . GetYesNo ( self , message = self . _yes_no_text )
if result != QW . QDialog . Accepted :
return
2017-01-25 22:56:55 +00:00
self . _func ( * self . _args , * * self . _kwargs )
2016-10-19 20:02:56 +00:00
2021-04-07 21:26:45 +00:00
def SetYesNoText ( self , text : str ) :
# this should probably be setyesnotextfactory, but WHATEVER for now
self . _yes_no_text = text
2019-11-14 03:56:30 +00:00
def setText ( self , label ) :
2017-05-31 21:50:53 +00:00
2020-04-22 21:00:35 +00:00
button_label = ClientGUIFunctions . EscapeMnemonics ( label )
2017-05-31 21:50:53 +00:00
2019-11-14 03:56:30 +00:00
QW . QPushButton . setText ( self , button_label )
2017-05-31 21:50:53 +00:00
2019-11-14 03:56:30 +00:00
class BetterChoice ( QW . QComboBox ) :
def __init__ ( self , * args , * * kwargs ) :
2019-02-06 22:41:35 +00:00
2019-11-14 03:56:30 +00:00
QW . QComboBox . __init__ ( self , * args , * * kwargs )
self . setMaxVisibleItems ( 32 )
2019-02-06 22:41:35 +00:00
2019-11-14 03:56:30 +00:00
def addItem ( self , display_string , client_data ) :
2017-10-11 17:38:14 +00:00
2019-11-14 03:56:30 +00:00
QW . QComboBox . addItem ( self , display_string , client_data )
2017-10-11 17:38:14 +00:00
2019-11-14 03:56:30 +00:00
if self . count ( ) == 1 :
2017-10-11 17:38:14 +00:00
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( 0 )
2017-10-11 17:38:14 +00:00
2019-07-24 21:39:02 +00:00
def GetValue ( self ) :
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
selection = self . currentIndex ( )
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
if selection != - 1 :
2019-05-08 21:06:42 +00:00
2020-03-18 21:35:57 +00:00
return self . itemData ( selection , QC . Qt . UserRole )
2019-05-08 21:06:42 +00:00
2019-11-14 03:56:30 +00:00
elif self . count ( ) > 0 :
2019-05-08 21:06:42 +00:00
2020-03-18 21:35:57 +00:00
return self . itemData ( 0 , QC . Qt . UserRole )
2019-05-08 21:06:42 +00:00
else :
return None
2016-10-19 20:02:56 +00:00
2019-07-24 21:39:02 +00:00
def SetValue ( self , data ) :
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
for i in range ( self . count ( ) ) :
2016-10-19 20:02:56 +00:00
2020-03-18 21:35:57 +00:00
if data == self . itemData ( i , QC . Qt . UserRole ) :
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( i )
2016-10-19 20:02:56 +00:00
return
2019-11-14 03:56:30 +00:00
if self . count ( ) > 0 :
2016-11-09 23:13:22 +00:00
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( 0 )
2016-11-09 23:13:22 +00:00
2016-10-19 20:02:56 +00:00
2019-11-14 03:56:30 +00:00
class BetterColourControl ( QP . ColourPickerCtrl ) :
2018-09-26 19:05:12 +00:00
def __init__ ( self , * args , * * kwargs ) :
2019-11-14 03:56:30 +00:00
QP . ColourPickerCtrl . __init__ ( self , * args , * * kwargs )
2018-09-26 19:05:12 +00:00
2019-11-14 03:56:30 +00:00
self . _widget_event_filter = QP . WidgetEventFilter ( self )
2018-09-26 19:05:12 +00:00
def _ImportHexFromClipboard ( self ) :
try :
import_string = HG . client_controller . GetClipboardText ( )
except Exception as e :
2019-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( self , ' Error ' , str ( e ) )
2018-09-26 19:05:12 +00:00
return
if import_string . startswith ( ' # ' ) :
import_string = import_string [ 1 : ]
import_string = ' # ' + re . sub ( ' [^0-9a-fA-F] ' , ' ' , import_string )
if len ( import_string ) != 7 :
2019-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( self , ' Error ' , ' That did not appear to be a hex string! ' )
2018-09-26 19:05:12 +00:00
return
try :
2019-11-14 03:56:30 +00:00
colour = QG . QColor ( import_string )
2018-09-26 19:05:12 +00:00
except Exception as e :
2019-11-14 03:56:30 +00:00
QW . QMessageBox . critical ( self , ' Error ' , str ( e ) )
2018-09-26 19:05:12 +00:00
HydrusData . ShowException ( e )
return
self . SetColour ( colour )
2020-02-12 22:50:37 +00:00
def contextMenuEvent ( self , event ) :
if event . reason ( ) == QG . QContextMenuEvent . Keyboard :
self . ShowMenu ( )
2019-12-11 23:18:37 +00:00
def mouseReleaseEvent ( self , event ) :
if event . button ( ) != QC . Qt . RightButton :
QP . ColourPickerCtrl . mouseReleaseEvent ( self , event )
return
2018-09-26 19:05:12 +00:00
2020-02-12 22:50:37 +00:00
self . ShowMenu ( )
def ShowMenu ( self ) :
2019-11-14 03:56:30 +00:00
menu = QW . QMenu ( )
2018-09-26 19:05:12 +00:00
2019-11-14 03:56:30 +00:00
hex_string = self . GetColour ( ) . name ( QG . QColor . HexRgb )
2018-09-26 19:05:12 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' copy ' + hex_string + ' to the clipboard ' , ' Copy the current colour to the clipboard. ' , HG . client_controller . pub , ' clipboard ' , ' text ' , hex_string )
ClientGUIMenus . AppendMenuItem ( menu , ' import a hex colour from the clipboard ' , ' Look at the clipboard for a colour in the format #FF0000, and set the colour. ' , self . _ImportHexFromClipboard )
2018-09-26 19:05:12 +00:00
2020-03-04 22:12:53 +00:00
CGC . core ( ) . PopupMenu ( self , menu )
2018-09-26 19:05:12 +00:00
2019-11-14 03:56:30 +00:00
class BetterNotebook ( QW . QTabWidget ) :
2018-05-16 20:09:50 +00:00
def _ShiftSelection ( self , delta ) :
2019-11-14 03:56:30 +00:00
existing_selection = self . currentIndex ( )
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
if existing_selection != - 1 :
2018-05-16 20:09:50 +00:00
2019-11-14 03:56:30 +00:00
new_selection = ( existing_selection + delta ) % self . count ( )
2018-05-16 20:09:50 +00:00
if new_selection != existing_selection :
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( new_selection )
2018-05-16 20:09:50 +00:00
2020-05-13 19:03:16 +00:00
def DeleteAllPages ( self ) :
while self . count ( ) > 0 :
page = self . widget ( 0 )
self . removeTab ( 0 )
page . deleteLater ( )
2018-05-16 20:09:50 +00:00
def GetPages ( self ) :
2019-11-14 03:56:30 +00:00
return [ self . widget ( i ) for i in range ( self . count ( ) ) ]
2018-05-16 20:09:50 +00:00
def SelectLeft ( self ) :
self . _ShiftSelection ( - 1 )
2019-05-08 21:06:42 +00:00
def SelectPage ( self , page ) :
2019-11-14 03:56:30 +00:00
for i in range ( self . count ( ) ) :
2019-05-08 21:06:42 +00:00
2019-11-14 03:56:30 +00:00
if self . widget ( i ) == page :
2019-05-08 21:06:42 +00:00
2019-11-14 03:56:30 +00:00
self . setCurrentIndex ( i )
2019-05-08 21:06:42 +00:00
return
2018-05-16 20:09:50 +00:00
def SelectRight ( self ) :
self . _ShiftSelection ( 1 )
2019-11-14 03:56:30 +00:00
class BetterRadioBox ( QP . RadioBox ) :
2017-01-04 22:48:23 +00:00
def __init__ ( self , * args , * * kwargs ) :
self . _indices_to_data = { i : data for ( i , ( s , data ) ) in enumerate ( kwargs [ ' choices ' ] ) }
kwargs [ ' choices ' ] = [ s for ( s , data ) in kwargs [ ' choices ' ] ]
2019-11-14 03:56:30 +00:00
QP . RadioBox . __init__ ( self , * args , * * kwargs )
2017-01-04 22:48:23 +00:00
2019-07-24 21:39:02 +00:00
def GetValue ( self ) :
2017-01-04 22:48:23 +00:00
2019-11-14 03:56:30 +00:00
index = self . GetCurrentIndex ( )
2017-01-04 22:48:23 +00:00
return self . _indices_to_data [ index ]
2020-11-18 22:15:21 +00:00
def SetValue ( self , data ) :
for ( i , d ) in self . _indices_to_data . items ( ) :
if d == data :
self . Select ( i )
return
2019-11-14 03:56:30 +00:00
class BetterStaticText ( QP . EllipsizedLabel ) :
2017-04-19 20:58:30 +00:00
2018-11-07 23:09:40 +00:00
def __init__ ( self , parent , label = None , tooltip_label = False , * * kwargs ) :
2017-04-19 20:58:30 +00:00
2019-11-14 03:56:30 +00:00
ellipsize_end = ' ellipsize_end ' in kwargs and kwargs [ ' ellipsize_end ' ]
QP . EllipsizedLabel . __init__ ( self , parent , ellipsize_end = ellipsize_end )
2017-04-19 20:58:30 +00:00
2019-11-28 01:11:46 +00:00
# otherwise by default html in 'this is a <hr> parsing step' stuff renders fully lmaoooo
self . setTextFormat ( QC . Qt . PlainText )
2018-11-07 23:09:40 +00:00
self . _tooltip_label = tooltip_label
2019-11-14 03:56:30 +00:00
if ' ellipsize_end ' in kwargs and kwargs [ ' ellipsize_end ' ] :
2018-11-07 23:09:40 +00:00
self . _tooltip_label = True
2018-07-04 20:48:28 +00:00
self . _last_set_text = ' ' # we want a separate copy since the one we'll send to the st will be wrapped and have additional '\n's
self . _wrap_width = None
2017-04-19 20:58:30 +00:00
if label is not None :
2019-11-14 03:56:30 +00:00
self . setText ( label )
2017-04-19 20:58:30 +00:00
2019-11-20 23:10:46 +00:00
2021-02-24 22:35:18 +00:00
def clear ( self ) :
self . _last_set_text = ' '
QP . EllipsizedLabel . clear ( self )
2019-11-14 03:56:30 +00:00
def setText ( self , text ) :
# this doesn't need mnemonic escape _unless_ a buddy is set, wew lad
2017-07-12 20:03:45 +00:00
2018-07-04 20:48:28 +00:00
if text != self . _last_set_text :
self . _last_set_text = text
2017-07-12 20:03:45 +00:00
2019-11-14 03:56:30 +00:00
QP . EllipsizedLabel . setText ( self , text )
2017-07-12 20:03:45 +00:00
2018-11-07 23:09:40 +00:00
if self . _tooltip_label :
2019-11-14 03:56:30 +00:00
self . setToolTip ( text )
2018-11-07 23:09:40 +00:00
2018-07-04 20:48:28 +00:00
2018-08-29 20:20:41 +00:00
class BetterHyperLink ( BetterStaticText ) :
def __init__ ( self , parent , label , url ) :
BetterStaticText . __init__ ( self , parent , label )
self . _url = url
2019-11-14 03:56:30 +00:00
self . setToolTip ( self . _url )
self . setTextFormat ( QC . Qt . RichText )
self . setTextInteractionFlags ( QC . Qt . TextBrowserInteraction )
2018-08-29 20:20:41 +00:00
2019-11-14 03:56:30 +00:00
self . setText ( ' <a href= " {} " > {} </a> ' . format ( url , label ) )
2019-11-20 23:10:46 +00:00
2019-12-11 23:18:37 +00:00
self . linkActivated . connect ( self . Activated )
def Activated ( self ) :
ClientPaths . LaunchURLInWebBrowser ( self . _url )
2019-11-14 03:56:30 +00:00
class BufferedWindow ( QW . QWidget ) :
2013-03-15 02:38:12 +00:00
def __init__ ( self , * args , * * kwargs ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , * args )
2013-03-15 02:38:12 +00:00
if ' size ' in kwargs :
2020-02-26 22:28:52 +00:00
size = kwargs [ ' size ' ]
if isinstance ( size , QC . QSize ) :
self . setFixedSize ( kwargs [ ' size ' ] )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
def _Draw ( self , painter ) :
2015-11-18 22:44:07 +00:00
raise NotImplementedError ( )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
def paintEvent ( self , event ) :
2015-11-18 22:44:07 +00:00
2019-11-14 03:56:30 +00:00
painter = QG . QPainter ( self )
2015-11-18 22:44:07 +00:00
2019-11-14 03:56:30 +00:00
self . _Draw ( painter )
2013-03-15 02:38:12 +00:00
2015-05-13 20:22:39 +00:00
class BufferedWindowIcon ( BufferedWindow ) :
2020-05-06 21:31:41 +00:00
def __init__ ( self , parent , bmp , click_callable = None ) :
2015-05-13 20:22:39 +00:00
2019-11-14 03:56:30 +00:00
BufferedWindow . __init__ ( self , parent , size = bmp . size ( ) )
2015-05-13 20:22:39 +00:00
self . _bmp = bmp
2020-05-06 21:31:41 +00:00
self . _click_callable = click_callable
2015-05-13 20:22:39 +00:00
2015-11-18 22:44:07 +00:00
2019-11-14 03:56:30 +00:00
def _Draw ( self , painter ) :
2015-05-13 20:22:39 +00:00
2019-11-14 03:56:30 +00:00
background_colour = QP . GetBackgroundColour ( self . parentWidget ( ) )
2015-05-13 20:22:39 +00:00
2019-11-14 03:56:30 +00:00
painter . setBackground ( QG . QBrush ( background_colour ) )
2015-05-13 20:22:39 +00:00
2019-11-14 03:56:30 +00:00
painter . eraseRect ( painter . viewport ( ) )
2015-05-13 20:22:39 +00:00
2019-11-14 03:56:30 +00:00
if isinstance ( self . _bmp , QG . QImage ) :
painter . drawImage ( 0 , 0 , self . _bmp )
else :
painter . drawPixmap ( 0 , 0 , self . _bmp )
2015-05-13 20:22:39 +00:00
2020-05-06 21:31:41 +00:00
def mousePressEvent ( self , event ) :
if self . _click_callable is None :
return BufferedWindow . mousePressEvent ( self , event )
else :
self . _click_callable ( )
2017-09-27 21:52:54 +00:00
class CheckboxManager ( object ) :
def GetCurrentValue ( self ) :
raise NotImplementedError ( )
def Invert ( self ) :
raise NotImplementedError ( )
2018-06-27 19:27:05 +00:00
class CheckboxManagerBoolean ( CheckboxManager ) :
def __init__ ( self , obj , name ) :
CheckboxManager . __init__ ( self )
self . _obj = obj
self . _name = name
def GetCurrentValue ( self ) :
if not self . _obj :
return False
return getattr ( self . _obj , self . _name )
def Invert ( self ) :
if not self . _obj :
return
value = getattr ( self . _obj , self . _name )
setattr ( self . _obj , self . _name , not value )
2017-09-27 21:52:54 +00:00
class CheckboxManagerCalls ( CheckboxManager ) :
def __init__ ( self , invert_call , value_call ) :
CheckboxManager . __init__ ( self )
self . _invert_call = invert_call
self . _value_call = value_call
def GetCurrentValue ( self ) :
return self . _value_call ( )
def Invert ( self ) :
self . _invert_call ( )
class CheckboxManagerOptions ( CheckboxManager ) :
def __init__ ( self , boolean_name ) :
CheckboxManager . __init__ ( self )
self . _boolean_name = boolean_name
def GetCurrentValue ( self ) :
2017-12-06 22:06:56 +00:00
new_options = HG . client_controller . new_options
2017-09-27 21:52:54 +00:00
return new_options . GetBoolean ( self . _boolean_name )
def Invert ( self ) :
2017-12-06 22:06:56 +00:00
new_options = HG . client_controller . new_options
2017-09-27 21:52:54 +00:00
new_options . InvertBoolean ( self . _boolean_name )
2019-07-31 22:01:02 +00:00
HG . client_controller . pub ( ' checkbox_manager_inverted ' )
2020-10-28 22:20:33 +00:00
HG . client_controller . pub ( ' notify_new_menu_option ' )
2019-07-31 22:01:02 +00:00
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
class AlphaColourControl ( QW . QWidget ) :
2018-03-07 22:48:29 +00:00
def __init__ ( self , parent ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2018-03-07 22:48:29 +00:00
2018-09-26 19:05:12 +00:00
self . _colour_picker = BetterColourControl ( self )
2018-03-07 22:48:29 +00:00
2019-11-14 03:56:30 +00:00
self . _alpha_selector = QP . MakeQSpinBox ( self , min = 0 , max = 255 )
hbox = QP . HBoxLayout ( spacing = 5 )
2018-03-07 22:48:29 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _colour_picker , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( hbox , BetterStaticText ( self , ' alpha: ' ) , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( hbox , self . _alpha_selector , CC . FLAGS_CENTER_PERPENDICULAR )
2018-03-07 22:48:29 +00:00
2019-11-14 03:56:30 +00:00
hbox . addStretch ( 1 )
2018-03-07 22:48:29 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2018-03-07 22:48:29 +00:00
def GetValue ( self ) :
colour = self . _colour_picker . GetColour ( )
2019-11-14 03:56:30 +00:00
a = self . _alpha_selector . value ( )
2018-03-07 22:48:29 +00:00
2020-02-26 22:28:52 +00:00
colour . setAlpha ( a )
2018-03-07 22:48:29 +00:00
return colour
2020-02-26 22:28:52 +00:00
def SetValue ( self , colour : QG . QColor ) :
2018-03-07 22:48:29 +00:00
2020-02-26 22:28:52 +00:00
picker_colour = QG . QColor ( colour . rgb ( ) )
2018-03-07 22:48:29 +00:00
2020-03-04 22:12:53 +00:00
self . _colour_picker . SetColour ( picker_colour )
2018-03-07 22:48:29 +00:00
2020-02-26 22:28:52 +00:00
self . _alpha_selector . setValue ( colour . alpha ( ) )
2018-03-07 22:48:29 +00:00
2017-08-30 20:27:47 +00:00
class ExportPatternButton ( BetterButton ) :
2014-02-26 22:09:54 +00:00
def __init__ ( self , parent ) :
2017-08-30 20:27:47 +00:00
BetterButton . __init__ ( self , parent , ' pattern shortcuts ' , self . _Hit )
2014-02-26 22:09:54 +00:00
2017-08-30 20:27:47 +00:00
def _Hit ( self ) :
2014-02-26 22:09:54 +00:00
2019-11-14 03:56:30 +00:00
menu = QW . QMenu ( )
2014-02-26 22:09:54 +00:00
2017-08-30 20:27:47 +00:00
ClientGUIMenus . AppendMenuLabel ( menu , ' click on a phrase to copy to clipboard ' )
2014-02-26 22:09:54 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2014-02-26 22:09:54 +00:00
2019-12-05 05:29:32 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' unique numerical file id - {file_id} ' , ' copy " {file_id} " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' {file_id} ' )
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' the file \' s hash - {hash} ' , ' copy " {hash} " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' {hash} ' )
ClientGUIMenus . AppendMenuItem ( menu , ' all the file \' s tags - {tags} ' , ' copy " {tags} " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' {tags} ' )
ClientGUIMenus . AppendMenuItem ( menu , ' all the file \' s non-namespaced tags - { nn tags} ' , ' copy " { nn tags} " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' { nn tags} ' )
2014-02-26 22:09:54 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2014-02-26 22:09:54 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' all instances of a particular namespace - [ \u2026 ] ' , ' copy " [ \u2026 ] " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' [ \u2026 ] ' )
2014-02-26 22:09:54 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2014-02-26 22:09:54 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( menu , ' a particular tag, if the file has it - ( \u2026 ) ' , ' copy " ( \u2026 ) " to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' ( \u2026 ) ' )
2014-02-26 22:09:54 +00:00
2020-03-04 22:12:53 +00:00
CGC . core ( ) . PopupMenu ( self , menu )
2014-02-26 22:09:54 +00:00
2019-11-14 03:56:30 +00:00
class Gauge ( QW . QProgressBar ) :
2013-03-15 02:38:12 +00:00
def __init__ ( self , * args , * * kwargs ) :
2019-11-14 03:56:30 +00:00
QW . QProgressBar . __init__ ( self , * args , * * kwargs )
2013-03-15 02:38:12 +00:00
2018-05-09 20:23:00 +00:00
self . _actual_value = None
2017-07-12 20:03:45 +00:00
self . _actual_range = None
self . _is_pulsing = False
2013-03-15 02:38:12 +00:00
2021-04-28 21:43:16 +00:00
self . SetRange ( 1 )
self . SetValue ( 0 )
2013-03-15 02:38:12 +00:00
2018-05-09 20:23:00 +00:00
def GetValueRange ( self ) :
if self . _actual_range is None :
2019-11-14 03:56:30 +00:00
range = self . maximum ( )
2018-05-09 20:23:00 +00:00
else :
range = self . _actual_range
return ( self . _actual_value , range )
2017-07-12 20:03:45 +00:00
def SetRange ( self , range ) :
2013-03-15 02:38:12 +00:00
2021-04-28 21:43:16 +00:00
if range is None or range == 0 :
2017-01-25 22:56:55 +00:00
self . Pulse ( )
2013-03-15 02:38:12 +00:00
else :
2017-07-12 20:48:21 +00:00
if self . _is_pulsing :
self . StopPulsing ( )
2017-07-12 20:03:45 +00:00
if range > 1000 :
self . _actual_range = range
range = 1000
else :
self . _actual_range = None
2019-11-14 03:56:30 +00:00
if range != self . maximum ( ) :
2017-07-12 20:03:45 +00:00
2019-11-14 03:56:30 +00:00
QW . QProgressBar . setMaximum ( self , range )
2017-07-12 20:03:45 +00:00
2013-03-15 02:38:12 +00:00
def SetValue ( self , value ) :
2018-05-09 20:23:00 +00:00
self . _actual_value = value
2017-07-12 20:48:21 +00:00
if not self . _is_pulsing :
2017-01-25 22:56:55 +00:00
2017-07-12 20:48:21 +00:00
if value is None :
2017-07-12 20:03:45 +00:00
2017-07-12 20:48:21 +00:00
self . Pulse ( )
2017-07-12 20:03:45 +00:00
2017-07-12 20:48:21 +00:00
else :
if self . _actual_range is not None :
2019-01-09 22:59:03 +00:00
value = min ( int ( 1000 * ( value / self . _actual_range ) ) , 1000 )
2017-07-12 20:48:21 +00:00
2017-07-12 20:03:45 +00:00
2019-11-14 03:56:30 +00:00
value = min ( value , self . maximum ( ) )
2017-08-09 21:33:51 +00:00
2019-11-14 03:56:30 +00:00
if value != self . value ( ) :
2017-07-12 20:48:21 +00:00
2019-11-14 03:56:30 +00:00
QW . QProgressBar . setValue ( self , value )
2017-07-12 20:48:21 +00:00
2017-07-12 20:03:45 +00:00
2017-01-25 22:56:55 +00:00
2013-03-15 02:38:12 +00:00
2017-07-12 20:48:21 +00:00
def StopPulsing ( self ) :
self . _is_pulsing = False
self . SetRange ( 1 )
self . SetValue ( 0 )
2019-11-14 03:56:30 +00:00
def Pulse ( self ) :
2021-04-07 21:26:45 +00:00
# pulse looked stupid, was turning on too much, should improve it later
#self.setMaximum( 0 )
2019-11-14 03:56:30 +00:00
2021-04-07 21:26:45 +00:00
#self.setMinimum( 0 )
self . SetRange ( 1 )
self . SetValue ( 0 )
2019-11-14 03:56:30 +00:00
self . _is_pulsing = True
class ListBook ( QW . QWidget ) :
2013-03-15 02:38:12 +00:00
def __init__ ( self , * args , * * kwargs ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , * args , * * kwargs )
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
self . _keys_to_active_pages = { }
self . _keys_to_proto_pages = { }
2015-05-06 20:26:18 +00:00
2019-11-14 03:56:30 +00:00
self . _list_box = QW . QListWidget ( self )
self . _list_box . setSelectionMode ( QW . QListWidget . SingleSelection )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . _empty_panel = QW . QWidget ( self )
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
self . _current_key = None
2013-03-15 02:38:12 +00:00
self . _current_panel = self . _empty_panel
2019-11-14 03:56:30 +00:00
self . _panel_sizer = QP . VBoxLayout ( )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _panel_sizer , self . _empty_panel , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( margin = 0 )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _list_box , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( hbox , self . _panel_sizer , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . _list_box . itemSelectionChanged . connect ( self . EventSelection )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
def _ActivatePage ( self , key ) :
( classname , args , kwargs ) = self . _keys_to_proto_pages [ key ]
page = classname ( * args , * * kwargs )
2019-11-14 03:56:30 +00:00
page . setVisible ( False )
2016-05-18 20:07:14 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _panel_sizer , page , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2016-05-18 20:07:14 +00:00
self . _keys_to_active_pages [ key ] = page
del self . _keys_to_proto_pages [ key ]
def _GetIndex ( self , key ) :
2019-11-14 03:56:30 +00:00
for i in range ( self . _list_box . count ( ) ) :
2013-12-18 22:49:24 +00:00
2020-03-18 21:35:57 +00:00
i_key = self . _list_box . item ( i ) . data ( QC . Qt . UserRole )
2016-05-18 20:07:14 +00:00
if i_key == key :
2013-12-18 22:49:24 +00:00
2016-05-18 20:07:14 +00:00
return i
2013-12-18 22:49:24 +00:00
2019-11-14 03:56:30 +00:00
return - 1
2016-07-06 21:13:15 +00:00
2013-03-15 02:38:12 +00:00
def _Select ( self , selection ) :
2019-11-14 03:56:30 +00:00
if selection == - 1 :
2016-05-18 20:07:14 +00:00
self . _current_key = None
else :
2020-03-18 21:35:57 +00:00
self . _current_key = self . _list_box . item ( selection ) . data ( QC . Qt . UserRole )
2016-05-18 20:07:14 +00:00
2013-03-23 17:57:29 +00:00
2019-11-14 03:56:30 +00:00
self . _current_panel . setVisible ( False )
self . _list_box . blockSignals ( True )
QP . ListWidgetSetSelection ( self . _list_box , selection )
2013-03-23 17:57:29 +00:00
2019-11-14 03:56:30 +00:00
self . _list_box . blockSignals ( False )
2013-03-23 17:57:29 +00:00
2019-11-14 03:56:30 +00:00
if selection == - 1 :
2016-05-18 20:07:14 +00:00
self . _current_panel = self . _empty_panel
2013-03-23 17:57:29 +00:00
else :
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
if self . _current_key in self . _keys_to_proto_pages :
2013-03-23 17:57:29 +00:00
2016-05-18 20:07:14 +00:00
self . _ActivatePage ( self . _current_key )
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
self . _current_panel = self . _keys_to_active_pages [ self . _current_key ]
2013-03-23 17:57:29 +00:00
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . _current_panel . show ( )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . update ( )
2013-03-15 02:38:12 +00:00
2016-05-18 20:07:14 +00:00
def AddPage ( self , display_name , key , page , select = False ) :
2019-11-14 03:56:30 +00:00
if self . _GetIndex ( key ) != - 1 :
2016-05-18 20:07:14 +00:00
raise HydrusExceptions . NameException ( ' That entry already exists! ' )
2013-03-15 02:38:12 +00:00
2016-01-13 22:08:19 +00:00
if not isinstance ( page , tuple ) :
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
page . setVisible ( False )
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _panel_sizer , page , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2013-03-15 02:38:12 +00:00
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
# Could call QListWidget.sortItems() here instead of doing it manually
2016-05-25 21:54:03 +00:00
2019-11-14 03:56:30 +00:00
current_display_names = QP . ListWidgetGetStrings ( self . _list_box )
2016-05-25 21:54:03 +00:00
insertion_index = len ( current_display_names )
for ( i , current_display_name ) in enumerate ( current_display_names ) :
2017-02-01 21:11:17 +00:00
if current_display_name > display_name :
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
insertion_index = i
2016-02-17 22:06:47 +00:00
2017-02-01 21:11:17 +00:00
break
2016-01-06 21:17:20 +00:00
2014-08-13 22:18:12 +00:00
2019-11-14 03:56:30 +00:00
item = QW . QListWidgetItem ( )
item . setText ( display_name )
item . setData ( QC . Qt . UserRole , key )
self . _list_box . insertItem ( insertion_index , item )
2017-02-01 21:11:17 +00:00
self . _keys_to_active_pages [ key ] = page
2019-11-14 03:56:30 +00:00
if self . _list_box . count ( ) == 1 :
2016-04-27 19:20:37 +00:00
2017-02-01 21:11:17 +00:00
self . _Select ( 0 )
elif select :
index = self . _GetIndex ( key )
self . _Select ( index )
2016-04-27 19:20:37 +00:00
2014-02-26 22:09:54 +00:00
2017-02-01 21:11:17 +00:00
def AddPageArgs ( self , display_name , key , classname , args , kwargs ) :
2013-07-24 20:26:00 +00:00
2019-11-14 03:56:30 +00:00
if self . _GetIndex ( key ) != - 1 :
2017-02-01 21:11:17 +00:00
raise HydrusExceptions . NameException ( ' That entry already exists! ' )
2013-08-14 20:21:49 +00:00
2019-11-14 03:56:30 +00:00
# Could call QListWidget.sortItems() here instead of doing it manually
2013-08-14 20:21:49 +00:00
2019-11-14 03:56:30 +00:00
current_display_names = QP . ListWidgetGetStrings ( self . _list_box )
2013-08-14 20:21:49 +00:00
2017-02-01 21:11:17 +00:00
insertion_index = len ( current_display_names )
for ( i , current_display_name ) in enumerate ( current_display_names ) :
if current_display_name > display_name :
insertion_index = i
break
2019-11-14 03:56:30 +00:00
item = QW . QListWidgetItem ( )
item . setText ( display_name )
item . setData ( QC . Qt . UserRole , key )
self . _list_box . insertItem ( insertion_index , item )
2013-07-24 20:26:00 +00:00
2017-02-01 21:11:17 +00:00
self . _keys_to_proto_pages [ key ] = ( classname , args , kwargs )
2014-02-26 22:09:54 +00:00
2019-11-14 03:56:30 +00:00
if self . _list_box . count ( ) == 1 :
2017-02-01 21:11:17 +00:00
self . _Select ( 0 )
2014-02-26 22:09:54 +00:00
2013-07-31 21:26:38 +00:00
2017-02-01 21:11:17 +00:00
def DeleteAllPages ( self ) :
2016-01-06 21:17:20 +00:00
2019-11-14 03:56:30 +00:00
self . _panel_sizer . removeWidget ( self . _empty_panel )
2016-03-16 22:19:14 +00:00
2019-11-14 03:56:30 +00:00
QP . ClearLayout ( self . _panel_sizer , delete_widgets = True )
2016-01-06 21:17:20 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _panel_sizer , self . _empty_panel , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
self . _current_key = None
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
self . _current_panel = self . _empty_panel
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
self . _keys_to_active_pages = { }
self . _keys_to_proto_pages = { }
2016-01-06 21:17:20 +00:00
2019-11-14 03:56:30 +00:00
self . _list_box . clear ( )
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
def DeleteCurrentPage ( self ) :
2013-07-31 21:26:38 +00:00
2019-11-14 03:56:30 +00:00
selection = QP . ListWidgetGetSelection ( self . _list_box )
2013-08-14 20:21:49 +00:00
2019-11-14 03:56:30 +00:00
if selection != - 1 :
2013-07-31 21:26:38 +00:00
2017-02-01 21:11:17 +00:00
key_to_delete = self . _current_key
page_to_delete = self . _current_panel
2013-07-31 21:26:38 +00:00
2017-02-01 21:11:17 +00:00
next_selection = selection + 1
previous_selection = selection - 1
2014-12-10 22:02:39 +00:00
2019-11-14 03:56:30 +00:00
if next_selection < self . _list_box . count ( ) :
2017-02-01 21:11:17 +00:00
self . _Select ( next_selection )
elif previous_selection > = 0 :
self . _Select ( previous_selection )
else :
2019-11-14 03:56:30 +00:00
self . _Select ( - 1 )
2017-02-01 21:11:17 +00:00
2016-01-06 21:17:20 +00:00
2019-11-14 03:56:30 +00:00
self . _panel_sizer . removeWidget ( page_to_delete )
2013-07-31 21:26:38 +00:00
2019-11-14 03:56:30 +00:00
page_to_delete . deleteLater ( )
2013-07-31 21:26:38 +00:00
2017-02-01 21:11:17 +00:00
del self . _keys_to_active_pages [ key_to_delete ]
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
QP . ListWidgetDelete ( self . _list_box , selection )
2015-02-03 20:40:21 +00:00
2017-02-01 21:11:17 +00:00
2019-11-14 03:56:30 +00:00
def EventSelection ( self ) :
2017-02-01 21:11:17 +00:00
2019-11-14 03:56:30 +00:00
selection = QP . ListWidgetGetSelection ( self . _list_box )
if selection != self . _GetIndex ( self . _current_key ) :
2017-02-01 21:11:17 +00:00
2019-11-14 03:56:30 +00:00
self . _Select ( selection )
2016-01-06 21:17:20 +00:00
2013-08-14 20:21:49 +00:00
2013-07-24 20:26:00 +00:00
2017-02-01 21:11:17 +00:00
def GetCurrentKey ( self ) :
2016-07-13 17:37:44 +00:00
2017-02-01 21:11:17 +00:00
return self . _current_key
2016-07-13 17:37:44 +00:00
2017-02-01 21:11:17 +00:00
def GetCurrentPage ( self ) :
2015-10-28 21:29:05 +00:00
2017-02-01 21:11:17 +00:00
if self . _current_panel == self . _empty_panel :
return None
else :
return self . _current_panel
2015-10-28 21:29:05 +00:00
2017-02-01 21:11:17 +00:00
def GetActivePages ( self ) :
2015-10-28 21:29:05 +00:00
2019-01-09 22:59:03 +00:00
return list ( self . _keys_to_active_pages . values ( ) )
2016-12-07 22:12:52 +00:00
2017-02-01 21:11:17 +00:00
def GetPage ( self , key ) :
2016-12-07 22:12:52 +00:00
2017-02-01 21:11:17 +00:00
if key in self . _keys_to_proto_pages :
self . _ActivatePage ( key )
2015-10-28 21:29:05 +00:00
2017-02-01 21:11:17 +00:00
if key in self . _keys_to_active_pages :
return self . _keys_to_active_pages [ key ]
2013-07-24 20:26:00 +00:00
2017-02-01 21:11:17 +00:00
raise Exception ( ' That page not found! ' )
2013-08-14 20:21:49 +00:00
2017-02-01 21:11:17 +00:00
2017-03-22 22:38:15 +00:00
def GetPageCount ( self ) :
return len ( self . _keys_to_active_pages ) + len ( self . _keys_to_proto_pages )
2017-02-01 21:11:17 +00:00
def KeyExists ( self , key ) :
2015-02-03 20:40:21 +00:00
2017-02-01 21:11:17 +00:00
return key in self . _keys_to_active_pages or key in self . _keys_to_proto_pages
2014-10-29 21:39:01 +00:00
2017-02-01 21:11:17 +00:00
def Select ( self , key ) :
2015-12-09 23:16:41 +00:00
2017-02-01 21:11:17 +00:00
index = self . _GetIndex ( key )
2015-12-09 23:16:41 +00:00
2019-11-14 03:56:30 +00:00
if index != - 1 and index != QP . ListWidgetGetSelection ( self . _list_box ) :
2020-03-04 22:12:53 +00:00
self . _Select ( index )
2015-12-09 23:16:41 +00:00
2017-02-01 21:11:17 +00:00
def SelectDown ( self ) :
2013-07-24 20:26:00 +00:00
2019-11-14 03:56:30 +00:00
current_selection = QP . ListWidgetGetSelection ( self . _list_box )
2017-02-01 21:11:17 +00:00
2019-11-14 03:56:30 +00:00
if current_selection != - 1 :
2016-12-21 22:30:54 +00:00
2019-11-14 03:56:30 +00:00
num_entries = self . _list_box . count ( )
2016-12-21 22:30:54 +00:00
2017-02-01 21:11:17 +00:00
if current_selection == num_entries - 1 : selection = 0
else : selection = current_selection + 1
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
if selection != current_selection :
self . _Select ( selection )
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
def SelectPage ( self , page_to_select ) :
2013-07-24 20:26:00 +00:00
2019-01-09 22:59:03 +00:00
for ( key , page ) in list ( self . _keys_to_active_pages . items ( ) ) :
2016-01-06 21:17:20 +00:00
2017-02-01 21:11:17 +00:00
if page == page_to_select :
self . _Select ( self . _GetIndex ( key ) )
return
2016-01-06 21:17:20 +00:00
2013-07-24 20:26:00 +00:00
2015-02-03 20:40:21 +00:00
2017-02-01 21:11:17 +00:00
def SelectUp ( self ) :
2013-07-24 20:26:00 +00:00
2019-11-14 03:56:30 +00:00
current_selection = QP . ListWidgetGetSelection ( self . _list_box )
2015-10-28 21:29:05 +00:00
2019-11-14 03:56:30 +00:00
if current_selection != - 1 :
2017-02-01 21:11:17 +00:00
2019-11-14 03:56:30 +00:00
num_entries = self . _list_box . count ( )
2017-02-01 21:11:17 +00:00
if current_selection == 0 : selection = num_entries - 1
else : selection = current_selection - 1
2015-10-28 21:29:05 +00:00
2017-02-01 21:11:17 +00:00
if selection != current_selection :
self . _Select ( selection )
2015-10-28 21:29:05 +00:00
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
class NoneableSpinCtrl ( QW . QWidget ) :
valueChanged = QC . Signal ( )
2015-02-03 20:40:21 +00:00
2017-03-02 02:14:56 +00:00
def __init__ ( self , parent , message = ' ' , none_phrase = ' no limit ' , min = 0 , max = 1000000 , unit = None , multiplier = 1 , num_dimensions = 1 ) :
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2013-02-19 00:11:43 +00:00
2015-12-02 22:32:18 +00:00
self . _unit = unit
2015-02-03 20:40:21 +00:00
self . _multiplier = multiplier
2015-12-02 22:32:18 +00:00
self . _num_dimensions = num_dimensions
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
self . _checkbox = QW . QCheckBox ( self )
self . _checkbox . stateChanged . connect ( self . EventCheckBox )
self . _checkbox . setText ( none_phrase )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . _one = QP . MakeQSpinBox ( self , min = min , max = max )
2018-03-22 00:03:33 +00:00
2019-06-26 21:27:18 +00:00
width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _one , len ( str ( max ) ) + 5 )
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setMaximumWidth ( width )
2013-02-19 00:11:43 +00:00
2015-12-23 22:51:04 +00:00
if num_dimensions == 2 :
2019-11-14 03:56:30 +00:00
self . _two = QP . MakeQSpinBox ( self , initial = 0 , min = min , max = max )
self . _two . valueChanged . connect ( self . _HandleValueChanged )
2018-03-22 00:03:33 +00:00
2019-06-26 21:27:18 +00:00
width = ClientGUIFunctions . ConvertTextToPixelWidth ( self . _two , len ( str ( max ) ) + 5 )
2018-03-22 00:03:33 +00:00
2019-11-14 03:56:30 +00:00
self . _two . setMinimumWidth ( width )
2015-12-23 22:51:04 +00:00
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( margin = 0 )
2013-02-19 00:11:43 +00:00
2015-07-15 20:28:26 +00:00
if len ( message ) > 0 :
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , BetterStaticText ( self , message + ' : ' ) , CC . FLAGS_CENTER_PERPENDICULAR )
2015-07-15 20:28:26 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _one , CC . FLAGS_CENTER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
2015-02-03 20:40:21 +00:00
if self . _num_dimensions == 2 :
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , BetterStaticText ( self , ' x ' ) , CC . FLAGS_CENTER_PERPENDICULAR )
QP . AddToLayout ( hbox , self . _two , CC . FLAGS_CENTER_PERPENDICULAR )
2015-02-03 20:40:21 +00:00
2013-02-19 00:11:43 +00:00
2015-12-02 22:32:18 +00:00
if self . _unit is not None :
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , BetterStaticText ( self , self . _unit ) , CC . FLAGS_CENTER_PERPENDICULAR )
2019-11-14 03:56:30 +00:00
2015-12-02 22:32:18 +00:00
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _checkbox , CC . FLAGS_CENTER_PERPENDICULAR )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
hbox . addStretch ( 1 )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . _one . valueChanged . connect ( self . _HandleValueChanged )
self . _checkbox . stateChanged . connect ( self . _HandleValueChanged )
2015-04-01 20:44:54 +00:00
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
def _HandleValueChanged ( self , val ) :
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
self . valueChanged . emit ( )
2020-07-08 22:00:33 +00:00
2019-11-14 03:56:30 +00:00
def EventCheckBox ( self , state ) :
2015-04-01 20:44:54 +00:00
2019-11-14 03:56:30 +00:00
if self . _checkbox . isChecked ( ) :
2015-04-01 20:44:54 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setEnabled ( False )
2018-04-11 22:30:40 +00:00
if self . _num_dimensions == 2 :
2019-11-14 03:56:30 +00:00
self . _two . setEnabled ( False )
2018-04-11 22:30:40 +00:00
2013-02-19 00:11:43 +00:00
2015-02-03 20:40:21 +00:00
else :
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setEnabled ( True )
2018-04-11 22:30:40 +00:00
if self . _num_dimensions == 2 :
2019-11-14 03:56:30 +00:00
self . _two . setEnabled ( True )
2018-04-11 22:30:40 +00:00
2013-02-19 00:11:43 +00:00
2015-02-03 20:40:21 +00:00
def GetValue ( self ) :
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
if self . _checkbox . isChecked ( ) :
2017-10-18 19:41:25 +00:00
return None
2015-02-03 20:40:21 +00:00
else :
2017-10-18 19:41:25 +00:00
if self . _num_dimensions == 2 :
2019-11-14 03:56:30 +00:00
return ( self . _one . value ( ) * self . _multiplier , self . _two . value ( ) * self . _multiplier )
2017-10-18 19:41:25 +00:00
else :
2019-11-14 03:56:30 +00:00
return self . _one . value ( ) * self . _multiplier
2017-10-18 19:41:25 +00:00
2015-02-03 20:40:21 +00:00
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
def setToolTip ( self , text ) :
2016-06-22 20:59:24 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . setToolTip ( self , text )
2016-06-22 20:59:24 +00:00
2019-11-14 03:56:30 +00:00
for c in self . children ( ) :
2016-06-22 20:59:24 +00:00
2019-11-14 03:56:30 +00:00
if isinstance ( c , QW . QWidget ) :
c . setToolTip ( text )
2016-06-22 20:59:24 +00:00
2015-02-03 20:40:21 +00:00
def SetValue ( self , value ) :
2013-03-15 02:38:12 +00:00
2015-02-03 20:40:21 +00:00
if value is None :
2019-11-14 03:56:30 +00:00
self . _checkbox . setChecked ( True )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setEnabled ( False )
if self . _num_dimensions == 2 : self . _two . setEnabled ( False )
2015-02-03 20:40:21 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _checkbox . setChecked ( False )
2015-02-03 20:40:21 +00:00
if self . _num_dimensions == 2 :
2019-11-14 03:56:30 +00:00
self . _two . setEnabled ( True )
2015-02-03 20:40:21 +00:00
( value , y ) = value
2019-11-14 03:56:30 +00:00
self . _two . setValue ( y / / self . _multiplier )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setEnabled ( True )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
self . _one . setValue ( value / / self . _multiplier )
2015-02-03 20:40:21 +00:00
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
class NoneableTextCtrl ( QW . QWidget ) :
valueChanged = QC . Signal ( )
2017-10-18 19:41:25 +00:00
2018-10-03 21:00:15 +00:00
def __init__ ( self , parent , message = ' ' , none_phrase = ' none ' ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _checkbox = QW . QCheckBox ( self )
self . _checkbox . stateChanged . connect ( self . EventCheckBox )
self . _checkbox . setText ( none_phrase )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _text = QW . QLineEdit ( self )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
hbox = QP . HBoxLayout ( margin = 0 )
2017-10-18 19:41:25 +00:00
if len ( message ) > 0 :
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , BetterStaticText ( self , message + ' : ' ) , CC . FLAGS_CENTER_PERPENDICULAR )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( hbox , self . _text , CC . FLAGS_EXPAND_BOTH_WAYS )
2020-07-29 20:52:44 +00:00
QP . AddToLayout ( hbox , self . _checkbox , CC . FLAGS_CENTER_PERPENDICULAR )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( hbox )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _checkbox . stateChanged . connect ( self . _HandleValueChanged )
self . _text . textChanged . connect ( self . _HandleValueChanged )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
def _HandleValueChanged ( self , val ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . valueChanged . emit ( )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
def EventCheckBox ( self , state ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
if self . _checkbox . isChecked ( ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _text . setEnabled ( False )
2017-10-18 19:41:25 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _text . setEnabled ( True )
2017-10-18 19:41:25 +00:00
def GetValue ( self ) :
2019-11-14 03:56:30 +00:00
if self . _checkbox . isChecked ( ) :
2017-10-18 19:41:25 +00:00
return None
else :
2019-11-14 03:56:30 +00:00
return self . _text . text ( )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
def setToolTip ( self , text ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
QW . QWidget . setToolTip ( self , text )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
for c in self . children ( ) :
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
if isinstance ( c , QW . QWidget ) :
c . setToolTip ( text )
2017-10-18 19:41:25 +00:00
def SetValue ( self , value ) :
if value is None :
2019-11-14 03:56:30 +00:00
self . _checkbox . setChecked ( True )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _text . setEnabled ( False )
2017-10-18 19:41:25 +00:00
else :
2019-11-14 03:56:30 +00:00
self . _checkbox . setChecked ( False )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _text . setEnabled ( True )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
self . _text . setText ( value )
2017-10-18 19:41:25 +00:00
2019-11-14 03:56:30 +00:00
class OnOffButton ( QW . QPushButton ) :
2013-03-15 02:38:12 +00:00
2020-05-20 21:36:02 +00:00
valueChanged = QC . Signal ( bool )
def __init__ ( self , parent , on_label , off_label = None , start_on = True ) :
2013-03-15 02:38:12 +00:00
2015-02-03 20:40:21 +00:00
if start_on : label = on_label
else : label = off_label
2013-03-15 02:38:12 +00:00
2019-11-14 03:56:30 +00:00
QW . QPushButton . __init__ ( self , parent )
QW . QPushButton . setText ( self , label )
2013-03-15 02:38:12 +00:00
2020-02-26 22:28:52 +00:00
self . setObjectName ( ' HydrusOnOffButton ' )
2015-02-03 20:40:21 +00:00
self . _on_label = on_label
2013-03-15 02:38:12 +00:00
2020-02-26 22:28:52 +00:00
if off_label is None :
self . _off_label = on_label
else :
self . _off_label = off_label
2013-09-18 17:23:30 +00:00
2020-02-26 22:28:52 +00:00
self . setProperty ( ' hydrus_on ' , start_on )
2013-09-18 17:23:30 +00:00
2020-03-25 21:15:57 +00:00
self . clicked . connect ( self . Flip )
2013-09-18 17:23:30 +00:00
2020-03-11 21:52:11 +00:00
def _SetValue ( self , value ) :
2013-09-18 17:23:30 +00:00
2020-03-11 21:52:11 +00:00
self . setProperty ( ' hydrus_on ' , value )
2020-02-26 22:28:52 +00:00
2020-03-11 21:52:11 +00:00
if value :
2013-09-18 17:23:30 +00:00
2019-11-14 03:56:30 +00:00
self . setText ( self . _on_label )
2013-09-18 17:23:30 +00:00
2020-02-26 22:28:52 +00:00
else :
2014-02-12 23:09:38 +00:00
2020-02-26 22:28:52 +00:00
self . setText ( self . _off_label )
2014-02-12 23:09:38 +00:00
2013-02-19 00:11:43 +00:00
2020-05-20 21:36:02 +00:00
self . valueChanged . emit ( value )
2020-02-26 22:28:52 +00:00
self . style ( ) . polish ( self )
2013-02-19 00:11:43 +00:00
2020-03-25 21:15:57 +00:00
def Flip ( self ) :
2020-03-11 21:52:11 +00:00
new_value = not self . property ( ' hydrus_on ' )
self . _SetValue ( new_value )
def IsOn ( self ) :
return self . property ( ' hydrus_on ' )
def SetOnOff ( self , value ) :
self . _SetValue ( value )
2014-09-03 20:26:49 +00:00
2017-09-06 20:18:20 +00:00
class RegexButton ( BetterButton ) :
2015-02-03 20:40:21 +00:00
def __init__ ( self , parent ) :
2013-07-24 20:26:00 +00:00
2017-09-06 20:18:20 +00:00
BetterButton . __init__ ( self , parent , ' regex shortcuts ' , self . _ShowMenu )
2013-07-24 20:26:00 +00:00
2015-02-03 20:40:21 +00:00
2017-09-06 20:18:20 +00:00
def _ShowMenu ( self ) :
2013-11-06 18:22:07 +00:00
2019-11-14 03:56:30 +00:00
menu = QW . QMenu ( )
2013-07-24 20:26:00 +00:00
2017-09-06 20:18:20 +00:00
ClientGUIMenus . AppendMenuLabel ( menu , ' click on a phrase to copy it to the clipboard ' )
2013-07-24 20:26:00 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( menu )
2014-03-12 22:08:23 +00:00
2019-11-14 03:56:30 +00:00
submenu = QW . QMenu ( menu )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , r ' whitespace character - \ s ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' \ s ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' number character - \ d ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' \ d ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' alphanumeric or backspace character - \ w ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' \ w ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' any character - . ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' . ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' backslash character - \\ ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' \\ ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' beginning of line - ^ ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' ^ ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' end of line - $ ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' $ ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' any of these - [ \u2026 ] ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' [ \u2026 ] ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' anything other than these - [^ \u2026 ] ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' [^ \u2026 ] ' )
2015-02-03 20:40:21 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( submenu )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , r ' 0 or more matches, consuming as many as possible - * ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' * ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' 1 or more matches, consuming as many as possible - + ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' + ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' 0 or 1 matches, preferring 1 - ? ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' ? ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' 0 or more matches, consuming as few as possible - *? ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' *? ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' 1 or more matches, consuming as few as possible - +? ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' +? ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' 0 or 1 matches, preferring 0 - ?? ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' ?? ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' exactly m matches - {m} ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' {m} ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' m to n matches, consuming as many as possible - { m,n} ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' { m,n} ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' m to n matches, consuming as few as possible - { m,n}? ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' { m,n}? ' )
2015-02-03 20:40:21 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( submenu )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , ' the next characters are: (non-consuming) - (?= \u2026 ) ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' (?= \u2026 ) ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' the next characters are not: (non-consuming) - (?! \u2026 ) ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' (?! \u2026 ) ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' the previous characters are: (non-consuming) - (?<= \u2026 ) ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' (?<= \u2026 ) ' )
ClientGUIMenus . AppendMenuItem ( submenu , ' the previous characters are not: (non-consuming) - (?<! \u2026 ) ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' (?<! \u2026 ) ' )
2015-02-03 20:40:21 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( submenu )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , r ' 0074 -> 74 - [1-9]+ \ d* ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , r ' [1-9]+ \ d* ' )
ClientGUIMenus . AppendMenuItem ( submenu , r ' filename - (?<= ' + re . escape ( os . path . sep ) + r ' )[^ ' + re . escape ( os . path . sep ) + r ' ]*?(?= \ ..*$) ' , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , ' (?<= ' + re . escape ( os . path . sep ) + r ' )[^ ' + re . escape ( os . path . sep ) + r ' ]*?(?= \ ..*$) ' )
2015-09-23 21:21:02 +00:00
2017-09-06 20:18:20 +00:00
ClientGUIMenus . AppendMenu ( menu , submenu , ' regex components ' )
2015-09-23 21:21:02 +00:00
2019-11-14 03:56:30 +00:00
submenu = QW . QMenu ( menu )
2015-09-23 21:21:02 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , ' manage favourites ' , ' manage some custom favourite phrases ' , self . _ManageFavourites )
2015-09-23 21:21:02 +00:00
2017-03-15 20:13:04 +00:00
ClientGUIMenus . AppendSeparator ( submenu )
2015-09-23 21:21:02 +00:00
2017-09-06 20:18:20 +00:00
for ( regex_phrase , description ) in HC . options [ ' regex_favourites ' ] :
2019-12-11 23:18:37 +00:00
2019-11-14 03:56:30 +00:00
ClientGUIMenus . AppendMenuItem ( submenu , description , ' copy this phrase to the clipboard ' , HG . client_controller . pub , ' clipboard ' , ' text ' , regex_phrase )
2015-09-23 21:21:02 +00:00
2015-02-03 20:40:21 +00:00
2017-09-06 20:18:20 +00:00
ClientGUIMenus . AppendMenu ( menu , submenu , ' favourites ' )
2015-02-03 20:40:21 +00:00
2020-03-04 22:12:53 +00:00
CGC . core ( ) . PopupMenu ( self , menu )
2014-03-12 22:08:23 +00:00
2017-09-06 20:18:20 +00:00
def _ManageFavourites ( self ) :
2013-02-19 00:11:43 +00:00
2017-11-08 22:07:12 +00:00
regex_favourites = HC . options [ ' regex_favourites ' ]
2013-02-19 00:11:43 +00:00
2020-04-29 21:44:12 +00:00
from hydrus . client . gui import ClientGUITopLevelWindowsPanels
2020-04-22 21:00:35 +00:00
from hydrus . client . gui import ClientGUIScrolledPanelsEdit
2020-03-04 22:12:53 +00:00
2020-04-29 21:44:12 +00:00
with ClientGUITopLevelWindowsPanels . DialogEdit ( self , ' manage regex favourites ' ) as dlg :
2015-09-23 21:21:02 +00:00
2017-11-08 22:07:12 +00:00
panel = ClientGUIScrolledPanelsEdit . EditRegexFavourites ( dlg , regex_favourites )
dlg . SetPanel ( panel )
2019-11-14 03:56:30 +00:00
if dlg . exec ( ) == QW . QDialog . Accepted :
2017-11-08 22:07:12 +00:00
regex_favourites = panel . GetValue ( )
HC . options [ ' regex_favourites ' ] = regex_favourites
HG . client_controller . Write ( ' save_options ' , HC . options )
2015-09-23 21:21:02 +00:00
2013-02-19 00:11:43 +00:00
2019-11-14 03:56:30 +00:00
class StaticBox ( QW . QFrame ) :
2016-11-02 21:09:14 +00:00
2019-11-14 03:56:30 +00:00
def __init__ ( self , parent , title ) :
2016-11-02 21:09:14 +00:00
2019-11-14 03:56:30 +00:00
QW . QFrame . __init__ ( self , parent )
2016-11-02 21:09:14 +00:00
2019-11-14 03:56:30 +00:00
self . setFrameStyle ( QW . QFrame . Box | QW . QFrame . Raised )
self . _spacer = QW . QSpacerItem ( 0 , 0 , QW . QSizePolicy . Minimum , QW . QSizePolicy . MinimumExpanding )
2013-10-09 18:13:42 +00:00
2019-11-14 03:56:30 +00:00
self . _sizer = QP . VBoxLayout ( )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
normal_font = QW . QApplication . font ( )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
normal_font_size = normal_font . pointSize ( )
normal_font_family = normal_font . family ( )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
title_font = QG . QFont ( normal_font_family , int ( normal_font_size ) , QG . QFont . Bold )
2015-02-03 20:40:21 +00:00
2021-09-01 21:09:01 +00:00
self . _title_st = BetterStaticText ( self , label = title )
self . _title_st . setFont ( title_font )
2015-02-03 20:40:21 +00:00
2021-09-01 21:09:01 +00:00
QP . AddToLayout ( self . _sizer , self . _title_st , CC . FLAGS_CENTER )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( self . _sizer )
2015-02-03 20:40:21 +00:00
2019-11-14 03:56:30 +00:00
self . layout ( ) . addSpacerItem ( self . _spacer )
2013-10-09 18:13:42 +00:00
2019-11-14 03:56:30 +00:00
def Add ( self , widget , flags = None ) :
self . layout ( ) . removeItem ( self . _spacer )
2018-01-31 22:58:15 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( self . _sizer , widget , flags )
self . layout ( ) . addSpacerItem ( self . _spacer )
2018-01-31 22:58:15 +00:00
2015-02-03 20:40:21 +00:00
2021-09-01 21:09:01 +00:00
def SetTitle ( self , title ) :
self . _title_st . setText ( title )
2017-09-27 21:52:54 +00:00
class RadioBox ( StaticBox ) :
def __init__ ( self , parent , title , choice_pairs , initial_index = None ) :
StaticBox . __init__ ( self , parent , title )
self . _indices_to_radio_buttons = { }
self . _radio_buttons_to_data = { }
for ( index , ( text , data ) ) in enumerate ( choice_pairs ) :
2019-11-14 03:56:30 +00:00
radio_button = QW . QRadioButton ( text , self )
2017-09-27 21:52:54 +00:00
2018-01-03 22:37:30 +00:00
self . Add ( radio_button , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-09-27 21:52:54 +00:00
self . _indices_to_radio_buttons [ index ] = radio_button
self . _radio_buttons_to_data [ radio_button ] = data
2019-11-14 03:56:30 +00:00
if initial_index is not None and initial_index in self . _indices_to_radio_buttons : self . _indices_to_radio_buttons [ initial_index ] . setChecked ( True )
2017-09-27 21:52:54 +00:00
def GetSelectedClientData ( self ) :
2019-01-09 22:59:03 +00:00
for radio_button in list ( self . _radio_buttons_to_data . keys ( ) ) :
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
if radio_button . isDown ( ) : return self . _radio_buttons_to_data [ radio_button ]
2017-09-27 21:52:54 +00:00
2017-11-29 21:48:23 +00:00
def SetSelection ( self , index ) :
2019-11-14 03:56:30 +00:00
self . _indices_to_radio_buttons [ index ] . setChecked ( True )
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
2017-11-29 21:48:23 +00:00
def SetString ( self , index , text ) :
2019-11-14 03:56:30 +00:00
self . _indices_to_radio_buttons [ index ] . setText ( text )
class TextCatchEnterEventFilter ( QC . QObject ) :
def __init__ ( self , parent , callable , * args , * * kwargs ) :
QC . QObject . __init__ ( self , parent )
self . _callable = HydrusData . Call ( callable , * args , * * kwargs )
def eventFilter ( self , watched , event ) :
if event . type ( ) == QC . QEvent . KeyPress and event . key ( ) in ( QC . Qt . Key_Enter , QC . Qt . Key_Return ) :
self . _callable ( )
2020-02-12 22:50:37 +00:00
event . accept ( )
2019-11-14 03:56:30 +00:00
return True
return False
2017-11-29 21:48:23 +00:00
2017-09-27 21:52:54 +00:00
2019-11-14 03:56:30 +00:00
class TextAndGauge ( QW . QWidget ) :
2017-01-11 22:31:30 +00:00
def __init__ ( self , parent ) :
2019-11-14 03:56:30 +00:00
QW . QWidget . __init__ ( self , parent )
2017-01-11 22:31:30 +00:00
2017-04-19 20:58:30 +00:00
self . _st = BetterStaticText ( self )
2017-01-11 22:31:30 +00:00
self . _gauge = Gauge ( self )
2019-11-14 03:56:30 +00:00
vbox = QP . VBoxLayout ( margin = 0 )
2017-01-11 22:31:30 +00:00
2019-11-14 03:56:30 +00:00
QP . AddToLayout ( vbox , self . _st , CC . FLAGS_EXPAND_PERPENDICULAR )
QP . AddToLayout ( vbox , self . _gauge , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-01-11 22:31:30 +00:00
2019-11-14 03:56:30 +00:00
self . setLayout ( vbox )
2017-01-11 22:31:30 +00:00
2020-10-21 22:22:10 +00:00
def SetText ( self , text ) :
if not self or not QP . isValid ( self ) :
return
self . _st . setText ( text )
2017-01-11 22:31:30 +00:00
def SetValue ( self , text , value , range ) :
2019-11-14 03:56:30 +00:00
if not self or not QP . isValid ( self ) :
2017-11-29 21:48:23 +00:00
return
2019-11-14 03:56:30 +00:00
self . _st . setText ( text )
2017-01-11 22:31:30 +00:00
2017-07-12 20:03:45 +00:00
self . _gauge . SetRange ( range )
self . _gauge . SetValue ( value )
2017-01-11 22:31:30 +00:00