Skip to content

Commit

Permalink
Merge pull request #13 from dreamworksanimation/dev
Browse files Browse the repository at this point in the history
Version 0.7.0
  • Loading branch information
mds-dwa authored Jul 22, 2019
2 parents c81edfe + 615e675 commit 9dcc934
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 120 deletions.
127 changes: 80 additions & 47 deletions usdmanager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ class UsdMngrWindow(QtWidgets.QMainWindow):
- AddressBar file completer has problems occasionally.
- Figure out why network printers aren't showing up. Linux or DWA
issue? macOS and Windows are fine.
- When reading in a USDZ file, the progress bar gets stuck.
- Qt.py problems:
- PyQt5
Expand Down Expand Up @@ -208,7 +207,7 @@ def __init__(self, parent=None, **kwargs):
# externally. The user's preferred programs are stored in
# self.programs.
self.defaultPrograms = {x: "" for x in USD_EXTS}
self.defaultPrograms.update(self.app.appConfig.get("defaultPrograms", {}))
self.defaultPrograms.update(self.app.DEFAULTS['defaultPrograms'])
self.programs = self.defaultPrograms
self.masterHighlighters = {}

Expand Down Expand Up @@ -247,12 +246,14 @@ def setupUi(self):
self.baseInstance = utils.loadUiWidget('main_window.ui', self)

# You now have access to the widgets defined in the ui file.
self.defaultDocFont = QtGui.QFont()
self.defaultDocFont.setStyleHint(QtGui.QFont.Courier)
self.defaultDocFont.setFamily("Monospace")
self.defaultDocFont.setPointSize(9)
self.defaultDocFont.setBold(False)
self.defaultDocFont.setItalic(False)
# Update some app defaults that required the GUI to be created first.
defaultDocFont = QtGui.QFont()
defaultDocFont.setStyleHint(QtGui.QFont.Courier)
defaultDocFont.setFamily("Monospace")
defaultDocFont.setPointSize(9)
defaultDocFont.setBold(False)
defaultDocFont.setItalic(False)
self.app.DEFAULTS['font'] = defaultDocFont

self.readSettings()
self.compileLinkRegEx()
Expand Down Expand Up @@ -288,13 +289,13 @@ def setupUi(self):
</style></head><body style="white-space:pre">{}</body></html>"""

searchPaths = QtGui.QIcon.themeSearchPaths()
extraSearchPaths = [x for x in self.app.appConfig.get("themeSearchPaths", []) if x not in searchPaths]
extraSearchPaths = [x for x in self.app.DEFAULTS['themeSearchPaths'] if x not in searchPaths]
if extraSearchPaths:
searchPaths = extraSearchPaths + searchPaths
QtGui.QIcon.setThemeSearchPaths(searchPaths)

# Set the preferred theme name for some non-standard icons.
QtGui.QIcon.setThemeName(self.app.appConfig.get("iconTheme", "crystal_project"))
QtGui.QIcon.setThemeName(self.app.DEFAULTS['iconTheme'])

# Try to adhere to the freedesktop icon standards (https://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html).
# Some icons are preferred from the crystal_project set, which sadly follows different naming standards.
Expand Down Expand Up @@ -633,27 +634,27 @@ def readSettings(self):
""" Read in user config settings.
"""
logger.debug("Reading user settings from {}".format(self.config.fileName()))
# Get basic preferences.
# TODO: Read some of these from the same places as the preferences dialog so we don't have to maintain defaults in 2 places.
default = self.app.DEFAULTS
self.preferences = {
'parseLinks': self.config.boolValue("parseLinks", True),
'newTab': self.config.boolValue("newTab", False),
'syntaxHighlighting': self.config.boolValue("syntaxHighlighting", True),
'teletype': self.config.boolValue("teletype", True),
'lineNumbers': self.config.boolValue("lineNumbers", True),
'showAllMessages': self.config.boolValue("showAllMessages", True),
'showHiddenFiles': self.config.boolValue("showHiddenFiles", False),
'font': self.config.value("font", self.defaultDocFont),
'fontSizeAdjust': int(self.config.value("fontSizeAdjust", 0)),
'findMatchCase': self.config.boolValue("findMatchCase", self.checkBoxMatchCase.isChecked()),
'includeVisible': self.config.boolValue("includeVisible", self.actionIncludePanel.isChecked()),
'lastOpenWithStr': self.config.value("lastOpenWithStr", ""),
'textEditor': self.config.value("textEditor", os.getenv("EDITOR", self.app.appConfig.get("textEditor", "nedit"))),
'diffTool': self.config.value("diffTool", self.app.appConfig.get("diffTool", "xdiff")),
'autoCompleteAddressBar': self.config.boolValue("autoCompleteAddressBar", True),
'useSpaces': self.config.boolValue("useSpaces", True),
'tabSpaces': int(self.config.value("tabSpaces", 4)),
'theme': self.config.value("theme", None),
'parseLinks': self.config.boolValue("parseLinks", default['parseLinks']),
'newTab': self.config.boolValue("newTab", default['newTab']),
'syntaxHighlighting': self.config.boolValue("syntaxHighlighting", default['syntaxHighlighting']),
'teletype': self.config.boolValue("teletype", default['teletype']),
'lineNumbers': self.config.boolValue("lineNumbers", default['lineNumbers']),
'showAllMessages': self.config.boolValue("showAllMessages", default['showAllMessages']),
'showHiddenFiles': self.config.boolValue("showHiddenFiles", default['showHiddenFiles']),
'font': self.config.value("font", default['font']),
'fontSizeAdjust': int(self.config.value("fontSizeAdjust", default['fontSizeAdjust'])),
'findMatchCase': self.config.boolValue("findMatchCase", default['findMatchCase']),
'includeVisible': self.config.boolValue("includeVisible", default['includeVisible']),
'lastOpenWithStr': self.config.value("lastOpenWithStr", default['lastOpenWithStr']),
'textEditor': self.config.value("textEditor", default['textEditor']),
'diffTool': self.config.value("diffTool", default['diffTool']),
'autoCompleteAddressBar': self.config.boolValue("autoCompleteAddressBar", default['autoCompleteAddressBar']),
'useSpaces': self.config.boolValue("useSpaces", default['useSpaces']),
'tabSpaces': int(self.config.value("tabSpaces", default['tabSpaces'])),
'theme': self.config.value("theme", default['theme']),
'lineLimit': int(self.config.value("lineLimit", default['lineLimit'])),
}

# Read 'programs' settings object into self.programs.
Expand Down Expand Up @@ -736,6 +737,7 @@ def writeSettings(self):
self.config.setValue("useSpaces", self.preferences['useSpaces'])
self.config.setValue("tabSpaces", self.preferences['tabSpaces'])
self.config.setValue("theme", self.preferences['theme'])
self.config.setValue("lineLimit", self.preferences['lineLimit'])

# Write self.programs to settings object
exts = self.programs.keys()
Expand Down Expand Up @@ -1918,11 +1920,14 @@ def editPreferences(self):
dlg = PreferencesDialog(self)
# Open dialog.
if dlg.exec_() == dlg.Accepted:
# Save new preferences.
# Users currently have to refresh to see these changes.
self.preferences['parseLinks'] = dlg.getPrefParseLinks()
self.preferences['newTab'] = dlg.getPrefNewTab()
self.preferences['syntaxHighlighting'] = dlg.getPrefSyntaxHighlighting()
self.preferences['teletype'] = dlg.getPrefTeletypeConversion()
self.preferences['theme'] = dlg.getPrefTheme()

# These changes do not require the user to refresh any tabs to see the change.
self.preferences['newTab'] = dlg.getPrefNewTab()
self.preferences['lineNumbers'] = dlg.getPrefLineNumbers()
self.preferences['showAllMessages'] = dlg.getPrefShowAllMessages()
self.preferences['showHiddenFiles'] = dlg.getPrefShowHiddenFiles()
Expand All @@ -1932,7 +1937,7 @@ def editPreferences(self):
self.preferences['font'] = dlg.getPrefFont()
self.preferences['useSpaces'] = dlg.getPrefUseSpaces()
self.preferences['tabSpaces'] = dlg.getPrefTabSpaces()
self.preferences['theme'] = dlg.getPrefTheme()
self.preferences['lineLimit'] = dlg.getPrefLineLimit()

# Update font and line number visibility in all tabs.
self.tabWidget.setFont(self.preferences['font'])
Expand Down Expand Up @@ -1964,9 +1969,6 @@ def editPreferences(self):
else:
self.addressBar.setCompleter(QtWidgets.QCompleter())

if not self.currTab.isDirty():
self.refreshTab()

self.writeSettings()

@Slot(int)
Expand All @@ -1977,7 +1979,7 @@ def updatePreference_findMatchCase(self, checked):
checked : `int`
State of checkbox.
"""
checked = checked & QtCore.Qt.Checked
checked = checked == QtCore.Qt.Checked
if checked != self.preferences['findMatchCase']:
self.preferences['findMatchCase'] = checked
for lang, h in self.masterHighlighters.iteritems():
Expand Down Expand Up @@ -2185,7 +2187,7 @@ def restoreTab(self, tab):
self.menuRecentlyClosedTabs.setEnabled(False)

# Update settings in the recently re-opened tab that may have changed.
if self.preferences['font'] != self.defaultDocFont:
if self.preferences['font'] != self.app.DEFAULTS['font']:
tab.textBrowser.setFont(self.preferences['font'])
tab.textEditor.setFont(self.preferences['font'])
tab.lineNumbers.setVisible(self.preferences['lineNumbers'])
Expand Down Expand Up @@ -2348,7 +2350,7 @@ def launchTextEditor(self):
def launchUsdView(self):
""" Launch the current file in usdview.
"""
app = self.app.appConfig.get("usdview", "usdview")
app = self.app.DEFAULTS['usdview']
path = self.currTab.getCurrentPath()
# Files with spaces have to be double-quoted on Windows for usdview.
if os.name == "nt":
Expand Down Expand Up @@ -2557,9 +2559,9 @@ def setSource(self, link, isNewFile=True, newTab=False, hScrollPos=0, vScrollPos
vScrollPos : `int`
Vertical scroll bar position.
"""
# Check if the current tab is dirty before doing anything.
# If we're staying in the current tab, check if the tab is dirty before doing anything.
# Perform save operations if necessary.
if not self.dirtySave():
if not newTab and not self.dirtySave():
return True

# Re-cast the QUrl so any query strings are evaluated properly.
Expand Down Expand Up @@ -2681,6 +2683,8 @@ def setSource(self, link, isNewFile=True, newTab=False, hScrollPos=0, vScrollPos
layer = utils.queryItemValue(link, "layer")
dest = utils.unzip(fileStr, layer, self.app.tmpDir)
self.restoreOverrideCursor()
self.statusbar.removeWidget(loadingProgressBar)
self.statusbar.removeWidget(loadingProgressLabel)
return self.setSource(QtCore.QUrl(dest))
else:
if ext == "usda":
Expand Down Expand Up @@ -2709,11 +2713,13 @@ def setSource(self, link, isNewFile=True, newTab=False, hScrollPos=0, vScrollPos

# TODO: Figure out a better way to handle streaming text for large files like Crate geometry.
# Large chunks of text (e.g. 2.2 billion characters) will cause Qt to segfault when creating a QString.
if length > LINE_LIMIT:
length = LINE_LIMIT
lineLimit = self.preferences['lineLimit']
if length > lineLimit:
length = lineLimit
truncated = True
fileText = fileText[:length]
warning = "Extremely large file! Capping display at {:,d} lines.".format(LINE_LIMIT)
warning = "Extremely large file! Capping display at {:,d} lines. You can edit this cap in the "\
"Advanced tab of Preferences.".format(lineLimit)

loadingProgressBar.setMaximum(length - 1)
if self.stopLoadingTab:
Expand Down Expand Up @@ -4274,13 +4280,40 @@ def run(self):
try:
logger.info("Loading app config from {}".format(appConfigPath))
with open(appConfigPath) as f:
self.appConfig = json.load(f)
appConfig = json.load(f)
except Exception as e:
logger.error("Failed to load app config from {}: {}".format(appConfigPath, e))
self.appConfig = {}
appConfig = {}

# Define app defaults that we use when the user preference doesn't exist and when resetting preferences in the
# Preferences dialog.
self.DEFAULTS = {
'autoCompleteAddressBar': True,
'defaultPrograms': appConfig.get("defaultPrograms", {}),
'diffTool': appConfig.get("diffTool", "xdiff"),
'findMatchCase': False,
'fontSizeAdjust': 0,
'iconTheme': appConfig.get("iconTheme", "crystal_project"),
'includeVisible': True,
'lastOpenWithStr': "",
'lineLimit': LINE_LIMIT,
'lineNumbers': True,
'newTab': False,
'parseLinks': True,
'showAllMessages': True,
'showHiddenFiles': False,
'syntaxHighlighting': True,
'tabSpaces': 4,
'teletype': True,
'textEditor': os.getenv("EDITOR", appConfig.get("textEditor", "nedit")),
'theme': None,
'themeSearchPaths': appConfig.get("themeSearchPaths", []),
'usdview': appConfig.get("usdview", "usdview"),
'useSpaces': True,
}

# Documentation URL.
self.appURL = self.appConfig.get("appURL", "https://github.com/dreamworksanimation/usdmanager")
self.appURL = appConfig.get("appURL", "https://github.com/dreamworksanimation/usdmanager")

# Create a main window.
window = self.newWindow()
Expand Down
3 changes: 2 additions & 1 deletion usdmanager/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

# Truncate loading files with more lines than this.
# Display can slow down and/or become unusable with too many lines.
LINE_LIMIT = 10000
# This number is less important than the total number of characters and can be overridden in Preferences.
LINE_LIMIT = 50000

# Truncate loading files with more total chars than this.
# QString crashes at ~2.1 billion chars, but display slows down way before that.
Expand Down
40 changes: 26 additions & 14 deletions usdmanager/preferences_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from Qt.QtGui import QIcon, QRegExpValidator
from Qt.QtWidgets import (QAbstractButton, QDialog, QDialogButtonBox, QFontDialog, QLineEdit, QMessageBox, QVBoxLayout)

from .constants import LINE_LIMIT
from .utils import loadUiWidget


Expand Down Expand Up @@ -77,6 +78,7 @@ def setupUi(self, widget):
self.lineEditTextEditor.setText(parent.preferences['textEditor'])
self.lineEditDiffTool.setText(parent.preferences['diffTool'])
self.themeWidget.setChecked(parent.preferences['theme'] == "dark")
self.lineLimitSpinBox.setValue(parent.preferences['lineLimit'])
self.updateFontLabel()

# ----- Programs tab -----
Expand Down Expand Up @@ -189,6 +191,15 @@ def getPrefAutoCompleteAddressBar(self):
"""
return self.checkBox_autoCompleteAddressBar.isChecked()

def getPrefLineLimit(self):
"""
:Returns:
Number of lines to display before truncating a file.
:Rtype:
`int`
"""
return self.lineLimitSpinBox.value()

def getPrefSyntaxHighlighting(self):
"""
:Returns:
Expand Down Expand Up @@ -319,22 +330,23 @@ def restoreDefaults(self, btn):
self.deleteItems(self.extLayout)

# Set other preferences in the GUI.
window = self.parent().window()
self.checkBox_parseLinks.setChecked(True)
self.checkBox_newTab.setChecked(False)
self.checkBox_syntaxHighlighting.setChecked(True)
self.checkBox_teletypeConversion.setChecked(True)
self.checkBox_lineNumbers.setChecked(True)
self.checkBox_showAllMessages.setChecked(True)
self.checkBox_showHiddenFiles.setChecked(False)
self.checkBox_autoCompleteAddressBar.setChecked(True)
self.lineEditTextEditor.setText(os.getenv("EDITOR", window.app.appConfig.get("textEditor", "nedit")))
self.lineEditDiffTool.setText(window.app.appConfig.get("diffTool", "xdiff"))
self.useSpacesCheckBox.setChecked(True)
self.useSpacesSpinBox.setValue(4)
default = self.parent().window().app.DEFAULTS
self.checkBox_parseLinks.setChecked(default['parseLinks'])
self.checkBox_newTab.setChecked(default['newTab'])
self.checkBox_syntaxHighlighting.setChecked(default['syntaxHighlighting'])
self.checkBox_teletypeConversion.setChecked(default['teletype'])
self.checkBox_lineNumbers.setChecked(default['lineNumbers'])
self.checkBox_showAllMessages.setChecked(default['showAllMessages'])
self.checkBox_showHiddenFiles.setChecked(default['showHiddenFiles'])
self.checkBox_autoCompleteAddressBar.setChecked(default['autoCompleteAddressBar'])
self.lineEditTextEditor.setText(default['textEditor'])
self.lineEditDiffTool.setText(default['diffTool'])
self.useSpacesCheckBox.setChecked(default['useSpaces'])
self.useSpacesSpinBox.setValue(default['tabSpaces'])
self.themeWidget.setChecked(False)
self.docFont = window.defaultDocFont
self.docFont = default['font']
self.updateFontLabel()
self.lineLimitSpinBox.setValue(default['lineLimit'])

# Re-create file association fields with the default programs.
self.populateProgsAndExts(self.parent().defaultPrograms)
Expand Down
Loading

0 comments on commit 9dcc934

Please sign in to comment.