@@ -246,13 +246,32 @@ def setupUi(self):
246246 """
247247 self .baseInstance = utils .loadUiWidget ('main_window.ui' , self )
248248
249- # Set usdview stylesheet.
250- if self .app .opts ['dark' ]:
249+ # You now have access to the widgets defined in the ui file.
250+ self .defaultDocFont = QtGui .QFont ()
251+ self .defaultDocFont .setStyleHint (QtGui .QFont .Courier )
252+ self .defaultDocFont .setFamily ("Monospace" )
253+ self .defaultDocFont .setPointSize (9 )
254+ self .defaultDocFont .setBold (False )
255+ self .defaultDocFont .setItalic (False )
256+
257+ self .readSettings ()
258+ self .compileLinkRegEx ()
259+
260+ # Changing the theme while the app is already running doesn't work well.
261+ # Currently, we set this once, and the user must restart the application to see changes.
262+ userThemeName = self .app .opts ['theme' ] or self .preferences ['theme' ]
263+ if userThemeName == "dark" :
264+ # Set usdview-based stylesheet.
251265 stylesheet = resource_filename (__name__ , "usdviewstyle.qss" )
252266 with open (stylesheet ) as f :
253267 # Qt style sheet accepts only forward slashes as path separators.
254268 sheetString = f .read ().replace ('RESOURCE_DIR' , os .path .dirname (stylesheet ).replace ("\\ " , "/" ))
255269 self .setStyleSheet (sheetString )
270+
271+ # Do some additional adjustments for any dark theme, even if it's coming from the system settings.
272+ # TODO: Be able to make these adjustments on the fly if the user changes the system theme.
273+ if self .isDarkTheme ():
274+ highlighter .DARK_THEME = True
256275
257276 # Change some more stuff that the stylesheet doesn't catch.
258277 p = QtWidgets .QApplication .palette ()
@@ -267,19 +286,6 @@ def setupUi(self):
267286a.binary {{color:#69F}}
268287span.badLink {{color:#F33}}
269288</style></head><body style="white-space:pre">{}</body></html>"""
270-
271- highlighter .DARK_THEME = True
272-
273- # You now have access to the widgets defined in the ui file.
274- self .defaultDocFont = QtGui .QFont ()
275- self .defaultDocFont .setStyleHint (QtGui .QFont .Courier )
276- self .defaultDocFont .setFamily ("Monospace" )
277- self .defaultDocFont .setPointSize (9 )
278- self .defaultDocFont .setBold (False )
279- self .defaultDocFont .setItalic (False )
280-
281- self .readSettings ()
282- self .compileLinkRegEx ()
283289
284290 searchPaths = QtGui .QIcon .themeSearchPaths ()
285291 extraSearchPaths = [x for x in self .app .appConfig .get ("themeSearchPaths" , []) if x not in searchPaths ]
@@ -646,7 +652,8 @@ def readSettings(self):
646652 'diffTool' : self .config .value ("diffTool" , self .app .appConfig .get ("diffTool" , "xdiff" )),
647653 'autoCompleteAddressBar' : self .config .boolValue ("autoCompleteAddressBar" , True ),
648654 'useSpaces' : self .config .boolValue ("useSpaces" , True ),
649- 'tabSpaces' : int (self .config .value ("tabSpaces" , 4 ))
655+ 'tabSpaces' : int (self .config .value ("tabSpaces" , 4 )),
656+ 'theme' : self .config .value ("theme" , None ),
650657 }
651658
652659 # Read 'programs' settings object into self.programs.
@@ -728,6 +735,7 @@ def writeSettings(self):
728735 self .config .setValue ("autoCompleteAddressBar" , self .preferences ['autoCompleteAddressBar' ])
729736 self .config .setValue ("useSpaces" , self .preferences ['useSpaces' ])
730737 self .config .setValue ("tabSpaces" , self .preferences ['tabSpaces' ])
738+ self .config .setValue ("theme" , self .preferences ['theme' ])
731739
732740 # Write self.programs to settings object
733741 exts = self .programs .keys ()
@@ -1604,7 +1612,7 @@ def find(self, flags=None, startPos=3, loop=True):
16041612 if cursor .hasSelection ():
16051613 # Found phrase. Set cursor and formatting.
16061614 currTextWidget .setTextCursor (cursor )
1607- self .findBar .setStyleSheet ("QLineEdit{{background:{}}}" .format ("inherit" if self .app . opts [ 'dark' ] else "none" ))
1615+ self .findBar .setStyleSheet ("QLineEdit{{background:{}}}" .format ("inherit" if self .isDarkTheme () else "none" ))
16081616 if loop :
16091617 # Didn't just loop through the document, so hide any messages.
16101618 self .labelFindPixmap .setVisible (False )
@@ -1924,6 +1932,7 @@ def editPreferences(self):
19241932 self .preferences ['font' ] = dlg .getPrefFont ()
19251933 self .preferences ['useSpaces' ] = dlg .getPrefUseSpaces ()
19261934 self .preferences ['tabSpaces' ] = dlg .getPrefTabSpaces ()
1935+ self .preferences ['theme' ] = dlg .getPrefTheme ()
19271936
19281937 # Update font and line number visibility in all tabs.
19291938 self .tabWidget .setFont (self .preferences ['font' ])
@@ -1999,7 +2008,7 @@ def validateFindBar(self, text):
19992008 self .buttonHighlightAll .setEnabled (False )
20002009 if self .buttonHighlightAll .isChecked ():
20012010 self .findHighlightAll ()
2002- self .findBar .setStyleSheet ("QLineEdit{{background:{}}}" .format ("inherit" if self .app . opts [ 'dark' ] else "none" ))
2011+ self .findBar .setStyleSheet ("QLineEdit{{background:{}}}" .format ("inherit" if self .isDarkTheme () else "none" ))
20032012 self .labelFindPixmap .setVisible (False )
20042013 self .labelFindStatus .setVisible (False )
20052014
@@ -3028,6 +3037,17 @@ def currentTabChanged(self, idx):
30283037 if not self .quitting :
30293038 self .findHighlightAll ()
30303039
3040+ def isDarkTheme (self ):
3041+ """ Check if any dark theme is active based on the background lightness.
3042+
3043+ :Returns:
3044+ True if the lightness factor of the window background is less than 0.5.
3045+ The 0.5 threshold to determine if it's dark is completely arbitrary.
3046+ :Rtype:
3047+ `bool`
3048+ """
3049+ return self .palette ().window ().color ().lightnessF () < 0.5
3050+
30313051 def updateButtons (self ):
30323052 """ Update button states, text fields, and other GUI elements.
30333053 """
@@ -3733,7 +3753,7 @@ def keyPressEvent(self, e):
37333753 # Otherwise, QTextEdit already handles inserting the tab character.
37343754 self .insertPlainText (" " * self .tabSpaces )
37353755 return
3736- elif e .key () == QtCore .Qt .Key_Backtab and e .modifiers () == QtCore .Qt .ShiftModifier and self . textCursor (). hasSelection () :
3756+ elif e .key () == QtCore .Qt .Key_Backtab and e .modifiers () == QtCore .Qt .ShiftModifier :
37373757 self .unindentText ()
37383758 return
37393759 super (TextEdit , self ).keyPressEvent (e )
@@ -3844,7 +3864,7 @@ def indentText(self):
38443864 cursor .movePosition (cursor .StartOfBlock )
38453865 cursor .beginEditBlock ()
38463866 # Modify all blocks between selectionStart and selectionEnd
3847- while cursor .position () <= end and not cursor .atEnd ():
3867+ while cursor .position () < end and not cursor .atEnd ():
38483868 if self .useSpaces :
38493869 if self .tabSpaces :
38503870 cursor .insertText (" " * self .tabSpaces )
@@ -3869,7 +3889,7 @@ def unindentText(self):
38693889 cursor .movePosition (cursor .StartOfBlock )
38703890 cursor .beginEditBlock ()
38713891 # Modify all blocks between selectionStart and selectionEnd
3872- while cursor .position () <= end and not cursor .atEnd ():
3892+ while cursor .position () < end and not cursor .atEnd ():
38733893 currBlock = cursor .blockNumber ()
38743894
38753895 for i in range (self .tabSpaces ):
@@ -3915,7 +3935,7 @@ def __init__(self, parent=None):
39153935 """
39163936 super (BrowserTab , self ).__init__ (parent )
39173937
3918- if self .window ().app . opts [ 'dark' ] :
3938+ if self .window ().isDarkTheme () :
39193939 color = QtGui .QColor (35 , 35 , 35 ).name ()
39203940 else :
39213941 color = self .style ().standardPalette ().base ().color ().darker (105 ).name ()
@@ -4204,10 +4224,18 @@ def run(self):
42044224 description = 'File Browser/Text Editor for quick navigation and\n '
42054225 'editing among text-based files that reference other files.\n \n ' )
42064226 parser .add_argument ('fileName' , nargs = '*' , help = 'The file(s) to view.' )
4207- parser .add_argument ("-dark" ,
4227+
4228+ group = parser .add_mutually_exclusive_group ()
4229+ group .add_argument ("-theme" ,
4230+ choices = ["light" , "dark" ],
4231+ help = "Override the user theme preference. Use the Preferences dialog to save this setting)"
4232+ )
4233+ # Legacy flag, now equivalent to "-theme dark"
4234+ group .add_argument ("-dark" ,
42084235 action = "store_true" ,
4209- help = "Use usdview-like dark Qt theme"
4236+ help = argparse . SUPPRESS
42104237 )
4238+
42114239 parser .add_argument ("-info" ,
42124240 action = "store_true" ,
42134241 help = "Log info messages"
@@ -4217,11 +4245,14 @@ def run(self):
42174245 help = "Log debugging messages"
42184246 )
42194247 results = parser .parse_args ()
4248+ if results .dark :
4249+ results .theme = "dark"
4250+ logger .warning ('The -dark flag has been deprecated. Please use "-theme dark" instead.' )
42204251 self .opts = {
42214252 'dir' : os .getcwd (),
42224253 'info' : results .info ,
42234254 'debug' : results .debug ,
4224- 'dark ' : results .dark
4255+ 'theme ' : results .theme ,
42254256 }
42264257
42274258 # Initialize the application and settings.
0 commit comments