diff --git a/nw/__init__.py b/nw/__init__.py index 0b01a8f1..2b8b15a1 100644 --- a/nw/__init__.py +++ b/nw/__init__.py @@ -172,7 +172,7 @@ def main(sysArgs=None): debugLevel = logging.INFO elif inOpt == "--debug": debugLevel = logging.DEBUG - logFormat = "[{asctime:}] {name:>20}:{lineno:<4d} {levelname:8} {message:}" + logFormat = "[{asctime:}] {name:>22}:{lineno:<4d} {levelname:8} {message:}" elif inOpt == "--logfile": logFile = inArg toFile = True @@ -180,7 +180,7 @@ def main(sysArgs=None): toStd = False elif inOpt == "--verbose": debugLevel = VERBOSE - logFormat = "[{asctime:}] {name:>20}:{lineno:<4d} {levelname:8} {message:}" + logFormat = "[{asctime:}] {name:>22}:{lineno:<4d} {levelname:8} {message:}" elif inOpt == "--style": qtStyle = inArg elif inOpt == "--config": diff --git a/nw/config.py b/nw/config.py index 66fdb649..4995cafa 100644 --- a/nw/config.py +++ b/nw/config.py @@ -88,6 +88,7 @@ class Config: self.guiLang = "en" # Hardcoded for now self.guiFont = "" self.guiFontSize = 11 + self.guiScale = 1.0 # Set automatically by Theme class ## Sizes self.winGeometry = [1100, 650] @@ -125,8 +126,8 @@ class Config: self.highlightQuotes = True self.fmtApostrophe = nwUnicode.U_RSQUO - self.fmtSingleQuotes = [nwUnicode.U_LSQUO,nwUnicode.U_RSQUO] - self.fmtDoubleQuotes = [nwUnicode.U_LDQUO,nwUnicode.U_RDQUO] + self.fmtSingleQuotes = [nwUnicode.U_LSQUO, nwUnicode.U_RSQUO] + self.fmtDoubleQuotes = [nwUnicode.U_LDQUO, nwUnicode.U_RDQUO] self.spellTool = None self.spellLanguage = None @@ -197,7 +198,23 @@ class Config: return ## - # Actions + # Methods + ## + + def pxInt(self, theSize): + """Used to scale fixed gui sizes by the screen scale factor. + This function returns an int, which is always rounded down. + """ + return int(theSize*self.guiScale) + + def rpxInt(self, theSize): + """Used to un-scale fixed gui sizes by the screen scale factor. + This function returns an int, which is always rounded down. + """ + return int(theSize/self.guiScale) + + ## + # Config Actions ## def initConfig(self, confPath=None, dataPath=None): @@ -647,7 +664,7 @@ class Config: return True ## - # Setters and Getters + # Setters ## def setConfPath(self, newPath): @@ -677,6 +694,8 @@ class Config: return True def setWinSize(self, newWidth, newHeight): + newWidth = int(newWidth/self.guiScale) + newHeight = int(newHeight/self.guiScale) if abs(self.winGeometry[0] - newWidth) > 5: self.winGeometry[0] = newWidth self.confChanged = True @@ -686,27 +705,27 @@ class Config: return True def setTreeColWidths(self, colWidths): - self.treeColWidth = colWidths + self.treeColWidth = [int(x/self.guiScale) for x in colWidths] self.confChanged = True return True def setProjColWidths(self, colWidths): - self.projColWidth = colWidths + self.projColWidth = [int(x/self.guiScale) for x in colWidths] self.confChanged = True return True def setMainPanePos(self, panePos): - self.mainPanePos = panePos + self.mainPanePos = [int(x/self.guiScale) for x in panePos] self.confChanged = True return True def setDocPanePos(self, panePos): - self.docPanePos = panePos + self.docPanePos = [int(x/self.guiScale) for x in panePos] self.confChanged = True return True def setOutlinePanePos(self, panePos): - self.outlnPanePos = panePos + self.outlnPanePos = [int(x/self.guiScale) for x in panePos] self.confChanged = True return True @@ -726,6 +745,40 @@ class Config: self.errData = [] return errMessage + ## + # Getters + ## + + def getWinSize(self): + return [int(x*self.guiScale) for x in self.winGeometry] + + def getTreeColWidths(self): + return [int(x*self.guiScale) for x in self.treeColWidth] + + def getProjColWidths(self): + return [int(x*self.guiScale) for x in self.projColWidth] + + def getMainPanePos(self): + return [int(x*self.guiScale) for x in self.mainPanePos] + + def getDocPanePos(self): + return [int(x*self.guiScale) for x in self.docPanePos] + + def getOutlinePanePos(self): + return [int(x*self.guiScale) for x in self.outlnPanePos] + + def getTextWidth(self): + return self.pxInt(self.textWidth) + + def getTextMargin(self): + return self.pxInt(self.textMargin) + + def getTabWidth(self): + return self.pxInt(self.tabWidth) + + def getZenWidth(self): + return self.pxInt(self.zenWidth) + ## # Internal Functions ## diff --git a/nw/core/project.py b/nw/core/project.py index 43efa057..213426d8 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -213,14 +213,11 @@ class NWProject(): self.bookAuthors = [] self.autoReplace = {} self.titleFormat = { - "title" : r"%title%", - "chapter" : r"Chapter %ch%: %title%", - "unnumbered" : r"%title%", - "scene" : r"* * *", - "section" : r"", - "withSynopsis" : False, - "withComments" : False, - "withKeywords" : False, + "title" : r"%title%", + "chapter" : r"Chapter %ch%: %title%", + "unnumbered" : r"%title%", + "scene" : r"* * *", + "section" : r"", } self.spellCheck = False self.autoOutline = True @@ -835,10 +832,8 @@ class NWProject(): """Set the formatting of titles in the project. """ for valKey, valEntry in titleFormat.items(): - if valKey in ("title","chapter","unnumbered","scene","section"): + if valKey in self.titleFormat: self.titleFormat[valKey] = checkString(valEntry, self.titleFormat[valKey], False) - elif valKey in ("withSynopsis","withComments","withKeywords"): - self.titleFormat[valKey] = checkBool(valEntry, False, False) return def setProjectChanged(self, bValue): @@ -2018,6 +2013,7 @@ class OptionState(): def __init__(self, theProject): + self.mainConf = nw.CONFIG self.theProject = theProject self.theState = {} self.stringOpt = () @@ -2026,6 +2022,10 @@ class OptionState(): return + ## + # Load and Save Cache + ## + def loadSettings(self): """Load the options dictionary from the project settings file. """ @@ -2038,7 +2038,7 @@ class OptionState(): if path.isfile(stateFile): logger.debug("Loading GUI options file") try: - with open(stateFile,mode="r",encoding="utf8") as inFile: + with open(stateFile, mode="r", encoding="utf8") as inFile: theJson = inFile.read() theState = json.loads(theJson) except Exception as e: @@ -2060,7 +2060,7 @@ class OptionState(): logger.debug("Saving GUI options file") try: - with open(stateFile,mode="w+",encoding="utf8") as outFile: + with open(stateFile, mode="w+", encoding="utf8") as outFile: outFile.write(json.dumps(self.theState, indent=2)) except Exception as e: logger.error("Failed to save GUI options file") @@ -2069,6 +2069,10 @@ class OptionState(): return True + ## + # Setters + ## + def setValue(self, setGroup, setName, setValue): """Saves a value, with a given group and name. """ @@ -2077,6 +2081,10 @@ class OptionState(): self.theState[setGroup][setName] = setValue return True + ## + # Getters + ## + def getValue(self, getGroup, getName, defaultValue): """Return an arbitrary type value, if it exists. Otherwise, return the default value. @@ -2085,7 +2093,8 @@ class OptionState(): if getName in self.theState[getGroup]: try: return self.theState[getGroup][getName] - except: + except Exception as e: + logger.warning(str(e)) return defaultValue return defaultValue @@ -2109,7 +2118,8 @@ class OptionState(): if getName in self.theState[getGroup]: try: return int(self.theState[getGroup][getName]) - except: + except Exception as e: + logger.warning(str(e)) return defaultValue return defaultValue @@ -2121,7 +2131,8 @@ class OptionState(): if getName in self.theState[getGroup]: try: return float(self.theState[getGroup][getName]) - except: + except Exception as e: + logger.warning(str(e)) return defaultValue return defaultValue @@ -2133,10 +2144,15 @@ class OptionState(): if getName in self.theState[getGroup]: try: return bool(self.theState[getGroup][getName]) - except: + except Exception as e: + logger.warning(str(e)) return defaultValue return defaultValue + ## + # Validators + ## + def validIntRange(self, theValue, intA, intB, intDefault): """Check that an int is in a given range. If it isn't, return the default value. diff --git a/nw/gui/about.py b/nw/gui/about.py index 653f87ae..d432a4d9 100644 --- a/nw/gui/about.py +++ b/nw/gui/about.py @@ -48,22 +48,24 @@ class GuiAbout(QDialog): self.mainConf = nw.CONFIG self.theParent = theParent + self.theTheme = theParent.theTheme self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() - self.innerBox.setSpacing(16) + self.innerBox.setSpacing(self.mainConf.pxInt(16)) self.setWindowTitle("About %s" % nw.__package__) - self.setMinimumWidth(700) - self.setMinimumHeight(600) + self.setMinimumWidth(self.mainConf.pxInt(650)) + self.setMinimumHeight(self.mainConf.pxInt(600)) - self.guiDeco = self.theParent.theTheme.loadDecoration("nwicon", (96, 96)) + iPx = self.mainConf.pxInt(96) + self.guiDeco = self.theParent.theTheme.loadDecoration("nwicon", (iPx, iPx)) self.lblName = QLabel("%s" % nw.__package__) self.lblVers = QLabel("v%s" % nw.__version__) self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x")) - self.leftBox = QVBoxLayout() - self.leftBox.setSpacing(4) + self.leftBox = QVBoxLayout() + self.leftBox.setSpacing(self.mainConf.pxInt(4)) self.leftBox.addWidget(self.guiDeco, 0, Qt.AlignCenter) self.leftBox.addWidget(self.lblName, 0, Qt.AlignCenter) self.leftBox.addWidget(self.lblVers, 0, Qt.AlignCenter) @@ -74,20 +76,15 @@ class GuiAbout(QDialog): # Pages self.pageAbout = QTextBrowser() self.pageAbout.setOpenExternalLinks(True) - self.pageAbout.document().setDocumentMargin(16) - - # self.pageCredit = QTextBrowser() - # self.pageCredit.setOpenExternalLinks(True) - # self.pageCredit.document().setDocumentMargin(16) + self.pageAbout.document().setDocumentMargin(self.mainConf.pxInt(16)) self.pageLicense = QTextBrowser() self.pageLicense.setOpenExternalLinks(True) - self.pageLicense.document().setDocumentMargin(16) + self.pageLicense.document().setDocumentMargin(self.mainConf.pxInt(16)) # Main Tab Area self.tabBox = QTabWidget() self.tabBox.addTab(self.pageAbout, "About") - # self.tabBox.addTab(self.pageCredit, "Credit") self.tabBox.addTab(self.pageLicense, "License") self.innerBox.addWidget(self.tabBox) diff --git a/nw/gui/build.py b/nw/gui/build.py index f072b6ea..269c49d7 100644 --- a/nw/gui/build.py +++ b/nw/gui/build.py @@ -78,12 +78,12 @@ class GuiBuildNovel(QDialog): self.nwdText = [] # List of markdown documents self.setWindowTitle("Build Novel Project") - self.setMinimumWidth(900) - self.setMinimumHeight(800) + self.setMinimumWidth(self.mainConf.pxInt(900)) + self.setMinimumHeight(self.mainConf.pxInt(800)) self.resize( - self.optState.getInt("GuiBuildNovel", "winWidth", 900), - self.optState.getInt("GuiBuildNovel", "winHeight", 800) + self.mainConf.pxInt(self.optState.getInt("GuiBuildNovel", "winWidth", 900)), + self.mainConf.pxInt(self.optState.getInt("GuiBuildNovel", "winHeight", 800)) ) self.outerBox = QHBoxLayout() @@ -112,10 +112,11 @@ class GuiBuildNovel(QDialog): r"be centred automatically and only appear between sections of " r"the same type." ) + xFmt = self.mainConf.pxInt(220) self.fmtTitle = QLineEdit() self.fmtTitle.setMaxLength(200) - self.fmtTitle.setFixedWidth(220) + self.fmtTitle.setFixedWidth(xFmt) self.fmtTitle.setToolTip(fmtHelp) self.fmtTitle.setText( self._reFmtCodes(self.theProject.titleFormat["title"]) @@ -123,7 +124,7 @@ class GuiBuildNovel(QDialog): self.fmtChapter = QLineEdit() self.fmtChapter.setMaxLength(200) - self.fmtChapter.setFixedWidth(220) + self.fmtChapter.setFixedWidth(xFmt) self.fmtChapter.setToolTip(fmtHelp) self.fmtChapter.setText( self._reFmtCodes(self.theProject.titleFormat["chapter"]) @@ -131,7 +132,7 @@ class GuiBuildNovel(QDialog): self.fmtUnnumbered = QLineEdit() self.fmtUnnumbered.setMaxLength(200) - self.fmtUnnumbered.setFixedWidth(220) + self.fmtUnnumbered.setFixedWidth(xFmt) self.fmtUnnumbered.setToolTip(fmtHelp) self.fmtUnnumbered.setText( self._reFmtCodes(self.theProject.titleFormat["unnumbered"]) @@ -139,7 +140,7 @@ class GuiBuildNovel(QDialog): self.fmtScene = QLineEdit() self.fmtScene.setMaxLength(200) - self.fmtScene.setFixedWidth(220) + self.fmtScene.setFixedWidth(xFmt) self.fmtScene.setToolTip(fmtHelp + fmtScHelp) self.fmtScene.setText( self._reFmtCodes(self.theProject.titleFormat["scene"]) @@ -147,7 +148,7 @@ class GuiBuildNovel(QDialog): self.fmtSection = QLineEdit() self.fmtSection.setMaxLength(200) - self.fmtSection.setFixedWidth(220) + self.fmtSection.setFixedWidth(xFmt) self.fmtSection.setToolTip(fmtHelp + fmtScHelp) self.fmtSection.setText( self._reFmtCodes(self.theProject.titleFormat["section"]) @@ -176,7 +177,7 @@ class GuiBuildNovel(QDialog): ## Font Family self.textFont = QLineEdit() self.textFont.setReadOnly(True) - self.textFont.setFixedWidth(182) + self.textFont.setFixedWidth(self.mainConf.pxInt(182)) self.textFont.setText( self.optState.getString("GuiBuildNovel", "textFont", self.mainConf.textFont) ) @@ -185,7 +186,7 @@ class GuiBuildNovel(QDialog): self.fontButton.clicked.connect(self._selectFont) self.textSize = QSpinBox(self) - self.textSize.setFixedWidth(60) + self.textSize.setFixedWidth(5*self.theTheme.textNWidth) self.textSize.setMinimum(6) self.textSize.setMaximum(72) self.textSize.setSingleStep(1) @@ -236,26 +237,32 @@ class GuiBuildNovel(QDialog): self.includeSynopsis.setToolTip( "Include synopsis comments in the output." ) - self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"]) + self.includeSynopsis.setChecked( + self.optState.getBool("GuiBuildNovel", "incSynopsis", False) + ) self.includeComments = QSwitch() self.includeComments.setToolTip( "Include plain comments in the output." ) - self.includeComments.setChecked(self.theProject.titleFormat["withComments"]) + self.includeComments.setChecked( + self.optState.getBool("GuiBuildNovel", "incComments", False) + ) self.includeKeywords = QSwitch() self.includeKeywords.setToolTip( "Include meta keywords (tags, references) in the output." ) - self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"]) + self.includeKeywords.setChecked( + self.optState.getBool("GuiBuildNovel", "incKeywords", False) + ) self.includeBody = QSwitch() self.includeBody.setToolTip( "Include body text in the output." ) self.includeBody.setChecked( - self.optState.getBool("GuiBuildNovel", "includeBody", True) + self.optState.getBool("GuiBuildNovel", "incBodyText", True) ) self.textForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft) @@ -847,27 +854,41 @@ class GuiBuildNovel(QDialog): # Formatting self.theProject.setTitleFormat({ - "title" : self.fmtTitle.text().strip(), - "chapter" : self.fmtChapter.text().strip(), - "unnumbered" : self.fmtUnnumbered.text().strip(), - "scene" : self.fmtScene.text().strip(), - "section" : self.fmtSection.text().strip(), - "withSynopsis" : self.includeSynopsis.isChecked(), - "withComments" : self.includeComments.isChecked(), - "withKeywords" : self.includeKeywords.isChecked(), + "title" : self.fmtTitle.text().strip(), + "chapter" : self.fmtChapter.text().strip(), + "unnumbered" : self.fmtUnnumbered.text().strip(), + "scene" : self.fmtScene.text().strip(), + "section" : self.fmtSection.text().strip(), }) + winWidth = self.mainConf.pxInt(self.width()) + winHeight = self.mainConf.pxInt(self.height()) + justifyText = self.justifyText.isChecked() + noStyling = self.noStyling.isChecked() + textFont = self.textFont.text() + textSize = self.textSize.value() + novelFiles = self.novelFiles.isChecked() + noteFiles = self.noteFiles.isChecked() + ignoreFlag = self.ignoreFlag.isChecked() + incSynopsis = self.includeSynopsis.isChecked() + incComments = self.includeComments.isChecked() + incKeywords = self.includeKeywords.isChecked() + incBodyText = self.includeBody.isChecked() + # GUI Settings - self.optState.setValue("GuiBuildNovel", "winWidth", self.width()) - self.optState.setValue("GuiBuildNovel", "winHeight", self.height()) - self.optState.setValue("GuiBuildNovel", "justifyText", self.justifyText.isChecked()) - self.optState.setValue("GuiBuildNovel", "noStyling", self.noStyling.isChecked()) - self.optState.setValue("GuiBuildNovel", "textFont", self.textFont.text()) - self.optState.setValue("GuiBuildNovel", "textSize", self.textSize.value()) - self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked()) - self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked()) - self.optState.setValue("GuiBuildNovel", "ignoreFlag", self.ignoreFlag.isChecked()) - self.optState.setValue("GuiBuildNovel", "includeBody", self.includeBody.isChecked()) + self.optState.setValue("GuiBuildNovel", "winWidth", winWidth) + self.optState.setValue("GuiBuildNovel", "winHeight", winHeight) + self.optState.setValue("GuiBuildNovel", "justifyText", justifyText) + self.optState.setValue("GuiBuildNovel", "noStyling", noStyling) + self.optState.setValue("GuiBuildNovel", "textFont", textFont) + self.optState.setValue("GuiBuildNovel", "textSize", textSize) + self.optState.setValue("GuiBuildNovel", "addNovel", novelFiles) + self.optState.setValue("GuiBuildNovel", "addNotes", noteFiles) + self.optState.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag) + self.optState.setValue("GuiBuildNovel", "incSynopsis", incSynopsis) + self.optState.setValue("GuiBuildNovel", "incComments", incComments) + self.optState.setValue("GuiBuildNovel", "incKeywords", incKeywords) + self.optState.setValue("GuiBuildNovel", "incBodyText", incBodyText) self.optState.saveSettings() return @@ -894,7 +915,7 @@ class GuiBuildNovelDocView(QTextBrowser): self.theProject = theProject self.theParent = theParent - self.setMinimumWidth(400) + self.setMinimumWidth(40*self.theParent.theTheme.textNWidth) self.setOpenExternalLinks(False) self.qDocument = self.document() diff --git a/nw/gui/custom.py b/nw/gui/custom.py index 96e0c482..264a2c98 100644 --- a/nw/gui/custom.py +++ b/nw/gui/custom.py @@ -215,14 +215,22 @@ class QHelpLabel(QLabel): class QSwitch(QAbstractButton): - def __init__(self, parent=None): + def __init__(self, parent=None, width=40, height=20): super().__init__(parent=parent) + self._xW = int(nw.CONFIG.guiScale*width) + self._xH = int(nw.CONFIG.guiScale*height) + self._xR = int(self._xH*0.5) + self._xT = int(self._xH*0.6) + self._rB = int(nw.CONFIG.guiScale*2) + self._rH = self._xH - 2*self._rB + self._rR = self._xR - self._rB + self.setCheckable(True) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) - self.setFixedWidth(40) - self.setFixedHeight(20) - self._offset = 10 + self.setFixedWidth(self._xW) + self.setFixedHeight(self._xH) + self._offset = self._xR return @@ -249,9 +257,9 @@ class QSwitch(QAbstractButton): """ super().setChecked(isChecked) if isChecked: - self.offset = 30 + self.offset = self._xW - self._xR else: - self.offset = 10 + self.offset = self._xR return ## @@ -263,9 +271,9 @@ class QSwitch(QAbstractButton): """ super().resizeEvent(theEvent) if self.isChecked(): - self.offset = 30 + self.offset = self._xW - self._xR else: - self.offset = 10 + self.offset = self._xR return def paintEvent(self, event): @@ -297,17 +305,17 @@ class QSwitch(QAbstractButton): qPaint.setBrush(trackBrush) qPaint.setOpacity(trackOpacity) - qPaint.drawRoundedRect(0, 0, 40, 20, 10, 10) + qPaint.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR) qPaint.setBrush(thumbBrush) - qPaint.drawEllipse(self.offset - 8, 2, 16, 16) + qPaint.drawEllipse(self.offset - self._rR, self._rB, self._rH, self._rH) theFont = qPaint.font() - theFont.setPixelSize(12) + theFont.setPixelSize(self._xT) qPaint.setPen(textColor) qPaint.setFont(theFont) qPaint.drawText( - QRectF(self.offset - 8, 2, 16, 16), + QRectF(self.offset - self._rR, self._rB, self._rH, self._rH), Qt.AlignCenter, thumbText ) @@ -322,9 +330,9 @@ class QSwitch(QAbstractButton): doAnim.setDuration(120) doAnim.setStartValue(self.offset) if self.isChecked(): - doAnim.setEndValue(30) + doAnim.setEndValue(self._xW - self._xR) else: - doAnim.setEndValue(10) + doAnim.setEndValue(self._xR) doAnim.start() return diff --git a/nw/gui/docbars.py b/nw/gui/docbars.py index 0923cb91..3e65855d 100644 --- a/nw/gui/docbars.py +++ b/nw/gui/docbars.py @@ -53,7 +53,7 @@ class GuiSearchBar(QFrame): self.theTheme = theParent.theTheme self.repVisible = False - self.setContentsMargins(0,0,0,0) + self.setContentsMargins(0, 0, 0, 0) self.mainBox = QGridLayout(self) self.setLayout(self.mainBox) @@ -72,24 +72,25 @@ class GuiSearchBar(QFrame): self.searchBox.returnPressed.connect(self._doSearch) self.replaceBox.returnPressed.connect(self._doSearch) - self.mainBox.addWidget(QLabel(""), 0,0) - self.mainBox.addWidget(self.searchLabel, 0,1) - self.mainBox.addWidget(self.searchBox, 0,2) - self.mainBox.addWidget(self.searchButton, 0,3) - self.mainBox.addWidget(self.closeButton, 0,4) - self.mainBox.addWidget(self.replaceLabel, 1,1) - self.mainBox.addWidget(self.replaceBox, 1,2) - self.mainBox.addWidget(self.replaceButton, 1,3) + self.mainBox.addWidget(QLabel(""), 0, 0) + self.mainBox.addWidget(self.searchLabel, 0, 1) + self.mainBox.addWidget(self.searchBox, 0, 2) + self.mainBox.addWidget(self.searchButton, 0, 3) + self.mainBox.addWidget(self.closeButton, 0, 4) + self.mainBox.addWidget(self.replaceLabel, 1, 1) + self.mainBox.addWidget(self.replaceBox, 1, 2) + self.mainBox.addWidget(self.replaceButton, 1, 3) - self.mainBox.setColumnStretch(0,1) - self.mainBox.setColumnStretch(1,0) - self.mainBox.setColumnStretch(2,0) - self.mainBox.setColumnStretch(3,0) - self.mainBox.setColumnStretch(4,0) - self.mainBox.setContentsMargins(0,0,0,0) + self.mainBox.setColumnStretch(0, 1) + self.mainBox.setColumnStretch(1, 0) + self.mainBox.setColumnStretch(2, 0) + self.mainBox.setColumnStretch(3, 0) + self.mainBox.setColumnStretch(4, 0) + self.mainBox.setContentsMargins(0, 0, 0, 0) - self.searchBox.setMinimumWidth(180) - self.replaceBox.setMinimumWidth(180) + boxWidth = 16*self.theTheme.textNWidth + self.searchBox.setMinimumWidth(boxWidth) + self.replaceBox.setMinimumWidth(boxWidth) self._replaceVisible(False) @@ -175,15 +176,18 @@ class GuiNoticeBar(QFrame): logger.debug("Initialising GuiNoticeBar ...") - self.mainConf = nw.CONFIG - self.theParent = theParent - self.theTheme = theParent.theTheme + self.mainConf = nw.CONFIG + self.theParent = theParent + self.theTheme = theParent.theTheme - self.setContentsMargins(0,0,0,0) + self.setContentsMargins(0, 0, 0, 0) self.setFrameShape(QFrame.Box) + m8 = self.mainConf.pxInt(8) + m2 = self.mainConf.pxInt(2) + self.mainBox = QHBoxLayout(self) - self.mainBox.setContentsMargins(8,2,2,2) + self.mainBox.setContentsMargins(m8, m2, m2, m2) self.noteLabel = QLabel("") diff --git a/nw/gui/docdetails.py b/nw/gui/docdetails.py index 09b43426..7c4ec8f7 100644 --- a/nw/gui/docdetails.py +++ b/nw/gui/docdetails.py @@ -44,12 +44,17 @@ class GuiDocViewDetails(QWidget): self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theParent.theProject + self.theTheme = theParent.theTheme self.currHandle = None + x4 = self.mainConf.pxInt(4) + x80 = self.mainConf.pxInt(80) + iPx = self.theTheme.textIconSize + self.outerBox = QGridLayout(self) - self.outerBox.setContentsMargins(0,0,0,0) + self.outerBox.setContentsMargins(0, 0, 0, 0) self.outerBox.setHorizontalSpacing(0) - self.outerBox.setVerticalSpacing(4) + self.outerBox.setVerticalSpacing(x4) self.refLabel = QLabel("Referenced By", self) @@ -58,7 +63,7 @@ class GuiDocViewDetails(QWidget): self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly) self.showHide.setArrowType(Qt.DownArrow) self.showHide.setCheckable(True) - self.showHide.setIconSize(QSize(16,16)) + self.showHide.setIconSize(QSize(iPx, iPx)) self.showHide.toggled.connect(self._doShowHide) self.isSticky = QCheckBox("Sticky") @@ -75,7 +80,7 @@ class GuiDocViewDetails(QWidget): self.scrollBox.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollBox.setFrameStyle(QFrame.NoFrame) self.scrollBox.setWidgetResizable(True) - self.scrollBox.setFixedHeight(80) + self.scrollBox.setFixedHeight(x80) self.scrollBox.setWidget(self.refList) self.outerBox.addWidget(self.showHide, 0, 0) @@ -85,7 +90,7 @@ class GuiDocViewDetails(QWidget): self.outerBox.setColumnStretch(1, 1) self.setLayout(self.outerBox) - self.setContentsMargins(0,0,0,0) + self.setContentsMargins(0, 0, 0, 0) self._doShowHide(self.mainConf.showRefPanel) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 1b3f81bb..7b6ef81b 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -81,7 +81,7 @@ class GuiDocEditor(QTextEdit): # Core Elements self.qDocument = self.document() - self.qDocument.setDocumentMargin(self.mainConf.textMargin) + self.qDocument.setDocumentMargin(self.mainConf.getTextMargin()) self.qDocument.contentsChange.connect(self._docChange) # Document Title @@ -98,7 +98,7 @@ class GuiDocEditor(QTextEdit): # Editor State self.hasSelection = False - self.setMinimumWidth(300) + self.setMinimumWidth(self.mainConf.pxInt(300)) self.setAcceptRichText(False) # Custom Shortcuts @@ -192,14 +192,13 @@ class GuiDocEditor(QTextEdit): self.setPalette(docPalette) # Set default text margins - self.qDocument.setDocumentMargin(self.mainConf.textMargin) + self.qDocument.setDocumentMargin(self.mainConf.getTextMargin()) # Also set the document text options for the document text flow theOpt = QTextOption() - if self.mainConf.tabWidth is not None: - if self.mainConf.verQtValue >= 51000: - theOpt.setTabStopDistance(self.mainConf.tabWidth) + if self.mainConf.verQtValue >= 51000: + theOpt.setTabStopDistance(self.mainConf.getTabWidth()) if self.mainConf.doJustify: theOpt.setAlignment(Qt.AlignJustify) if self.mainConf.showTabsNSpaces: @@ -319,6 +318,7 @@ class GuiDocEditor(QTextEdit): Config.textFixedW is enabled or we're in Zen mode. Otherwise, just ensure the margins are set correctly. """ + cM = self.mainConf.getTextMargin() if self.mainConf.textFixedW or self.theParent.isZenMode: vBar = self.verticalScrollBar() if vBar.isVisible(): @@ -326,20 +326,20 @@ class GuiDocEditor(QTextEdit): else: sW = 0 if self.theParent.isZenMode: - tW = self.mainConf.zenWidth + tW = self.mainConf.getZenWidth() else: - tW = self.mainConf.textWidth + tW = self.mainConf.getTextWidth() wW = self.width() tM = int((wW - sW - tW)/2) - if tM < self.mainConf.textMargin: - tM = self.mainConf.textMargin + if tM < cM: + tM = cM else: - tM = self.mainConf.textMargin + tM = cM tB = self.lineWidth() tW = self.width() - 2*tB tH = self.docTitle.height() - tT = self.mainConf.textMargin - tH + tT = cM - tH self.docTitle.setGeometry(tB, tB, tW, tH) self.setViewportMargins(0, tH, 0, 0) diff --git a/nw/gui/docmerge.py b/nw/gui/docmerge.py index 73b15a6a..1294501f 100644 --- a/nw/gui/docmerge.py +++ b/nw/gui/docmerge.py @@ -62,8 +62,8 @@ class GuiDocMerge(QDialog): self.listBox = QListWidget() self.listBox.setDragDropMode(QAbstractItemView.InternalMove) - self.listBox.setMinimumWidth(400) - self.listBox.setMinimumHeight(180) + self.listBox.setMinimumWidth(self.mainConf.pxInt(400)) + self.listBox.setMinimumHeight(self.mainConf.pxInt(180)) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self._doMerge) @@ -72,9 +72,9 @@ class GuiDocMerge(QDialog): self.outerBox.setSpacing(0) self.outerBox.addWidget(self.headLabel) self.outerBox.addWidget(self.helpLabel) - self.outerBox.addSpacing(8) + self.outerBox.addSpacing(self.mainConf.pxInt(8)) self.outerBox.addWidget(self.listBox) - self.outerBox.addSpacing(12) + self.outerBox.addSpacing(self.mainConf.pxInt(12)) self.outerBox.addWidget(self.buttonBox) self.setLayout(self.outerBox) diff --git a/nw/gui/docsplit.py b/nw/gui/docsplit.py index 702e8f17..98ef95d7 100644 --- a/nw/gui/docsplit.py +++ b/nw/gui/docsplit.py @@ -62,8 +62,8 @@ class GuiDocSplit(QDialog): self.listBox = QListWidget() self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop) - self.listBox.setMinimumWidth(400) - self.listBox.setMinimumHeight(180) + self.listBox.setMinimumWidth(self.mainConf.pxInt(400)) + self.listBox.setMinimumHeight(self.mainConf.pxInt(180)) self.splitLevel = QComboBox(self) self.splitLevel.addItem("Split on Header Level 1 (Title)", 1) @@ -84,10 +84,10 @@ class GuiDocSplit(QDialog): self.outerBox.setSpacing(0) self.outerBox.addWidget(self.headLabel) self.outerBox.addWidget(self.helpLabel) - self.outerBox.addSpacing(8) + self.outerBox.addSpacing(self.mainConf.pxInt(8)) self.outerBox.addWidget(self.listBox) self.outerBox.addWidget(self.splitLevel) - self.outerBox.addSpacing(12) + self.outerBox.addSpacing(self.mainConf.pxInt(12)) self.outerBox.addWidget(self.buttonBox) self.setLayout(self.outerBox) diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py index fb1a9c99..a3d6eeda 100644 --- a/nw/gui/docviewer.py +++ b/nw/gui/docviewer.py @@ -53,7 +53,7 @@ class GuiDocViewer(QTextBrowser): self.theHandle = None self.qDocument = self.document() - self.setMinimumWidth(300) + self.setMinimumWidth(self.mainConf.pxInt(300)) self.setOpenExternalLinks(False) self.initViewer() @@ -105,7 +105,7 @@ class GuiDocViewer(QTextBrowser): docPalette.setColor(QPalette.Text, QColor(*self.theTheme.colText)) self.setPalette(docPalette) - self.qDocument.setDocumentMargin(self.mainConf.textMargin) + self.qDocument.setDocumentMargin(self.mainConf.getTextMargin()) theOpt = QTextOption() if self.mainConf.doJustify: theOpt.setAlignment(Qt.AlignJustify) @@ -216,7 +216,7 @@ class GuiDocViewer(QTextBrowser): tB = self.lineWidth() tW = self.width() - 2*tB tH = self.docTitle.height() - tT = self.mainConf.textMargin - tH + tT = self.mainConf.getTextMargin() - tH self.docTitle.setGeometry(tB, tB, tW, tH) self.setViewportMargins(0, tH, 0, 0) diff --git a/nw/gui/itemdetails.py b/nw/gui/itemdetails.py index 7335a596..182fb3fd 100644 --- a/nw/gui/itemdetails.py +++ b/nw/gui/itemdetails.py @@ -170,11 +170,11 @@ class GuiItemDetails(QWidget): self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1) self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1) - self.mainBox.setColumnStretch(0,0) - self.mainBox.setColumnStretch(1,0) - self.mainBox.setColumnStretch(2,1) - self.mainBox.setColumnStretch(3,0) - self.mainBox.setColumnStretch(4,0) + self.mainBox.setColumnStretch(0, 0) + self.mainBox.setColumnStretch(1, 0) + self.mainBox.setColumnStretch(2, 1) + self.mainBox.setColumnStretch(3, 0) + self.mainBox.setColumnStretch(4, 0) # Make sure the columns for flags and counts don't resize too often flagWidth = self.theTheme.getTextWidth("Mm", self.fntValue) diff --git a/nw/gui/itemeditor.py b/nw/gui/itemeditor.py index 7eb54b14..65c4cde9 100644 --- a/nw/gui/itemeditor.py +++ b/nw/gui/itemeditor.py @@ -61,8 +61,8 @@ class GuiItemEditor(QDialog): # Item Label self.editName = QLineEdit() - self.editName.setMinimumWidth(220) - self.editName.setMaxLength(200) + self.editName.setMinimumWidth(self.mainConf.pxInt(220)) + self.editName.setMaxLength(self.mainConf.pxInt(200)) # Item Status self.editStatus = QComboBox() @@ -135,7 +135,7 @@ class GuiItemEditor(QDialog): self.mainForm.addWidget(self.textExport, 3, 0, 1, 2) self.mainForm.addWidget(self.editExport, 3, 2, 1, 1) - self.outerBox.setSpacing(16) + self.outerBox.setSpacing(self.mainConf.pxInt(16)) self.outerBox.addLayout(self.mainForm) self.outerBox.addStretch(1) self.outerBox.addWidget(self.buttonBox) diff --git a/nw/gui/outline.py b/nw/gui/outline.py index bb080c1a..81cd805d 100644 --- a/nw/gui/outline.py +++ b/nw/gui/outline.py @@ -271,7 +271,7 @@ class GuiOutline(QTreeWidget): tmpWidth = self.optState.getValue("GuiOutline", "columnWidth", {}) for hName in tmpWidth: try: - self.colWidth[nwOutline[hName]] = tmpWidth[hName] + self.colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName]) except: logger.warning("Ignored unknown outline column '%s'" % str(hName)) @@ -301,7 +301,7 @@ class GuiOutline(QTreeWidget): colHidden = {} for hItem in nwOutline: - colWidth[hItem.name] = self.colWidth[hItem] + colWidth[hItem.name] = self.mainConf.rpxInt(self.colWidth[hItem]) colHidden[hItem.name] = self.colHidden[hItem] for iCol in range(self.columnCount()): @@ -309,7 +309,7 @@ class GuiOutline(QTreeWidget): treeOrder.append(hName) iLog = self.treeHead.logicalIndex(iCol) - logWidth = self.columnWidth(iLog) + logWidth = self.mainConf.rpxInt(self.columnWidth(iLog)) logHidden = self.isColumnHidden(iLog) colHidden[hName] = logHidden diff --git a/nw/gui/outlinedetails.py b/nw/gui/outlinedetails.py index 33048837..739b1c37 100644 --- a/nw/gui/outlinedetails.py +++ b/nw/gui/outlinedetails.py @@ -63,8 +63,8 @@ class GuiOutlineDetails(QScrollArea): minTitle = 30*self.theTheme.textNWidth maxTitle = 40*self.theTheme.textNWidth wCount = self.theTheme.getTextWidth("999,999") - hSpace = int(0.8*self.theTheme.textNWidth) - vSpace = int(0.2*self.theTheme.textNHeight) + hSpace = int(self.mainConf.pxInt(10)) + vSpace = int(self.mainConf.pxInt(4)) # Details Area self.titleLabel = QLabel("Title") diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py index a05e5eb0..17487a31 100644 --- a/nw/gui/preferences.py +++ b/nw/gui/preferences.py @@ -143,7 +143,7 @@ class GuiConfigEditGeneralTab(QWidget): ## Select Theme self.selectTheme = QComboBox() - self.selectTheme.setMinimumWidth(200) + self.selectTheme.setMinimumWidth(self.mainConf.pxInt(200)) self.theThemes = self.theTheme.listThemes() for themeDir, themeName in self.theThemes: self.selectTheme.addItem(themeName, themeDir) @@ -159,7 +159,7 @@ class GuiConfigEditGeneralTab(QWidget): ## Select Icon Theme self.selectIcons = QComboBox() - self.selectIcons.setMinimumWidth(200) + self.selectIcons.setMinimumWidth(self.mainConf.pxInt(200)) self.theIcons = self.theTheme.theIcons.listThemes() for iconDir, iconName in self.theIcons: self.selectIcons.addItem(iconName, iconDir) @@ -185,7 +185,7 @@ class GuiConfigEditGeneralTab(QWidget): ## Font Family self.guiFont = QLineEdit() self.guiFont.setReadOnly(True) - self.guiFont.setFixedWidth(162) + self.guiFont.setFixedWidth(self.mainConf.pxInt(162)) self.guiFont.setText(self.mainConf.guiFont) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("..."))) @@ -329,6 +329,8 @@ class GuiConfigEditGeneralTab(QWidget): ## def _backupFolder(self): + """Open a dialog to select the backup folder. + """ currDir = self.backupPath if not path.isdir(currDir): @@ -389,7 +391,7 @@ class GuiConfigEditLayoutTab(QWidget): ## Font Family self.textStyleFont = QLineEdit() self.textStyleFont.setReadOnly(True) - self.textStyleFont.setFixedWidth(162) + self.textStyleFont.setFixedWidth(self.mainConf.pxInt(162)) self.textStyleFont.setText(self.mainConf.textFont) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("..."))) @@ -575,7 +577,7 @@ class GuiConfigEditEditingTab(QWidget): ## Syntax Highlighting self.selectSyntax = QComboBox() - self.selectSyntax.setMinimumWidth(200) + self.selectSyntax.setMinimumWidth(self.mainConf.pxInt(200)) self.theSyntaxes = self.theTheme.listSyntax() for syntaxFile, syntaxName in self.theSyntaxes: self.selectSyntax.addItem(syntaxName, syntaxFile) @@ -789,10 +791,12 @@ class GuiConfigEditAutoReplaceTab(QWidget): # =============== self.mainForm.addGroupLabel("Quotation Style") + qWidth = self.mainConf.pxInt(40) + ## Single Quote Style self.quoteSingleStyleO = QLineEdit() self.quoteSingleStyleO.setMaxLength(1) - self.quoteSingleStyleO.setFixedWidth(40) + self.quoteSingleStyleO.setFixedWidth(qWidth) self.quoteSingleStyleO.setAlignment(Qt.AlignCenter) self.quoteSingleStyleO.setText(self.mainConf.fmtSingleQuotes[0]) self.mainForm.addRow( @@ -803,7 +807,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): self.quoteSingleStyleC = QLineEdit() self.quoteSingleStyleC.setMaxLength(1) - self.quoteSingleStyleC.setFixedWidth(40) + self.quoteSingleStyleC.setFixedWidth(qWidth) self.quoteSingleStyleC.setAlignment(Qt.AlignCenter) self.quoteSingleStyleC.setText(self.mainConf.fmtSingleQuotes[1]) self.mainForm.addRow( @@ -815,7 +819,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): ## Double Quote Style self.quoteDoubleStyleO = QLineEdit() self.quoteDoubleStyleO.setMaxLength(1) - self.quoteDoubleStyleO.setFixedWidth(40) + self.quoteDoubleStyleO.setFixedWidth(qWidth) self.quoteDoubleStyleO.setAlignment(Qt.AlignCenter) self.quoteDoubleStyleO.setText(self.mainConf.fmtDoubleQuotes[0]) self.mainForm.addRow( @@ -826,7 +830,7 @@ class GuiConfigEditAutoReplaceTab(QWidget): self.quoteDoubleStyleC = QLineEdit() self.quoteDoubleStyleC.setMaxLength(1) - self.quoteDoubleStyleC.setFixedWidth(40) + self.quoteDoubleStyleC.setFixedWidth(qWidth) self.quoteDoubleStyleC.setAlignment(Qt.AlignCenter) self.quoteDoubleStyleC.setText(self.mainConf.fmtDoubleQuotes[1]) self.mainForm.addRow( diff --git a/nw/gui/projload.py b/nw/gui/projload.py index 63f0be9f..45300332 100644 --- a/nw/gui/projload.py +++ b/nw/gui/projload.py @@ -61,17 +61,20 @@ class GuiProjectLoad(QDialog): self.openState = self.NONE_STATE self.openPath = None + sPx = self.mainConf.pxInt(16) + iPx = self.mainConf.pxInt(96) + self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() - self.outerBox.setSpacing(16) - self.innerBox.setSpacing(16) + self.outerBox.setSpacing(sPx) + self.innerBox.setSpacing(sPx) self.setWindowTitle("Open Project") - self.setMinimumWidth(650) - self.setMinimumHeight(400) + self.setMinimumWidth(self.mainConf.pxInt(650)) + self.setMinimumHeight(self.mainConf.pxInt(400)) self.setModal(True) - self.guiDeco = self.theTheme.loadDecoration("nwicon", (96, 96)) + self.guiDeco = self.theTheme.loadDecoration("nwicon", (iPx, iPx)) self.innerBox.addWidget(self.guiDeco, 0, Qt.AlignTop) self.projectForm = QGridLayout() @@ -81,10 +84,9 @@ class GuiProjectLoad(QDialog): self.listBox = QTreeWidget() self.listBox.setSelectionMode(QAbstractItemView.SingleSelection) self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop) - self.listBox.setColumnCount(4) - self.listBox.setHeaderLabels(["Working Title","Words","Last Opened","Path"]) + self.listBox.setColumnCount(3) + self.listBox.setHeaderLabels(["Working Title", "Words", "Last Opened"]) self.listBox.setRootIsDecorated(False) - self.listBox.setColumnHidden(3, True) self.listBox.itemSelectionChanged.connect(self._doSelectRecent) self.listBox.itemDoubleClicked.connect(self._doOpenRecent) self.listBox.setIconSize(QSize(iPx, iPx)) @@ -113,8 +115,8 @@ class GuiProjectLoad(QDialog): self.projectForm.setColumnStretch(0, 0) self.projectForm.setColumnStretch(1, 1) self.projectForm.setColumnStretch(2, 0) - self.projectForm.setVerticalSpacing(4) - self.projectForm.setHorizontalSpacing(8) + self.projectForm.setVerticalSpacing(self.mainConf.pxInt(4)) + self.projectForm.setHorizontalSpacing(self.mainConf.pxInt(8)) self.innerBox.addLayout(self.projectForm) @@ -151,7 +153,7 @@ class GuiProjectLoad(QDialog): self._saveDialogState() selItems = self.listBox.selectedItems() if selItems: - self.openPath = selItems[0].text(3) + self.openPath = selItems[0].data(0, Qt.UserRole) self.openState = self.OPEN_STATE self.accept() else: @@ -164,7 +166,7 @@ class GuiProjectLoad(QDialog): """ selList = self.listBox.selectedItems() if selList: - self.selPath.setText(selList[0].text(3)) + self.selPath.setText(selList[0].data(0, Qt.UserRole)) return def _doBrowse(self): @@ -254,9 +256,9 @@ class GuiProjectLoad(QDialog): newItem = QTreeWidgetItem([""]*4) newItem.setIcon(0, self.theParent.theTheme.getIcon("proj_nwx")) newItem.setText(0, listData[timeStamp][0]) + newItem.setData(0, Qt.UserRole, listData[timeStamp][2]) newItem.setText(1, formatInt(listData[timeStamp][1])) newItem.setText(2, datetime.fromtimestamp(timeStamp).strftime("%x %X")) - newItem.setText(3, listData[timeStamp][2]) newItem.setTextAlignment(0, Qt.AlignLeft | Qt.AlignVCenter) newItem.setTextAlignment(1, Qt.AlignRight | Qt.AlignVCenter) newItem.setTextAlignment(2, Qt.AlignRight | Qt.AlignVCenter) @@ -268,8 +270,9 @@ class GuiProjectLoad(QDialog): newItem.setSelected(True) hasSelection = True + projColWidth = self.mainConf.getProjColWidths() for i in range(3): - self.listBox.setColumnWidth(i, self.mainConf.projColWidth[i]) + self.listBox.setColumnWidth(i, projColWidth[i]) return diff --git a/nw/gui/projsettings.py b/nw/gui/projsettings.py index a1c28ca4..2a4dc680 100644 --- a/nw/gui/projsettings.py +++ b/nw/gui/projsettings.py @@ -119,6 +119,7 @@ class GuiProjectEditMain(QWidget): def __init__(self, theParent, theProject): QWidget.__init__(self, theParent) + self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theProject @@ -129,9 +130,12 @@ class GuiProjectEditMain(QWidget): self.mainForm.addGroupLabel("Project Settings") + xW = self.mainConf.pxInt(250) + xH = self.mainConf.pxInt(100) + self.editName = QLineEdit() self.editName.setMaxLength(200) - self.editName.setFixedWidth(250) + self.editName.setFixedWidth(xW) self.editName.setText(self.theProject.projName) self.mainForm.addRow( "Working title", @@ -141,7 +145,7 @@ class GuiProjectEditMain(QWidget): self.editTitle = QLineEdit() self.editTitle.setMaxLength(200) - self.editTitle.setFixedWidth(250) + self.editTitle.setFixedWidth(xW) self.editTitle.setText(self.theProject.bookTitle) self.mainForm.addRow( "Novel title", @@ -154,8 +158,8 @@ class GuiProjectEditMain(QWidget): for bookAuthor in self.theProject.bookAuthors: bookAuthors += bookAuthor+"\n" self.editAuthors.setPlainText(bookAuthors) - self.editAuthors.setFixedHeight(100) - self.editAuthors.setFixedWidth(250) + self.editAuthors.setFixedHeight(xH) + self.editAuthors.setFixedWidth(xW) self.mainForm.addRow( "Author(s)", self.editAuthors, @@ -179,9 +183,12 @@ class GuiProjectEditMeta(QWidget): def __init__(self, theParent, theProject): QWidget.__init__(self, theParent) + self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theProject + xInd = self.mainConf.pxInt(8) + # The Form self.mainForm = QGridLayout() self.setLayout(self.mainForm) @@ -189,17 +196,17 @@ class GuiProjectEditMeta(QWidget): self.headLabel = QLabel("Project Details") self.nameLabel = QLabel("Working title:") - self.nameLabel.setIndent(8) + self.nameLabel.setIndent(xInd) self.nameValue = QLabel(self.theProject.projName) self.nameValue.setWordWrap(True) self.pathLabel = QLabel("Project path:") - self.pathLabel.setIndent(8) + self.pathLabel.setIndent(xInd) self.pathValue = QLabel(self.theProject.projPath) self.pathValue.setWordWrap(True) self.revLabel = QLabel("Revision count:") - self.revLabel.setIndent(8) + self.revLabel.setIndent(xInd) self.revValue = QLabel("{:n}".format(self.theProject.saveCount)) self.statsLabel = QLabel("Project Stats") @@ -207,19 +214,19 @@ class GuiProjectEditMeta(QWidget): nR, nD, nF = self.theProject.projTree.countTypes() self.nRootLabel = QLabel("Root folders:") - self.nRootLabel.setIndent(8) + self.nRootLabel.setIndent(xInd) self.nRootValue = QLabel("{:n}".format(nR)) self.nDirLabel = QLabel("Folders:") - self.nDirLabel.setIndent(8) + self.nDirLabel.setIndent(xInd) self.nDirValue = QLabel("{:n}".format(nD)) self.nFileLabel = QLabel("Documents:") - self.nFileLabel.setIndent(8) + self.nFileLabel.setIndent(xInd) self.nFileValue = QLabel("{:n}".format(nF)) self.wordsLabel = QLabel("Word count:") - self.wordsLabel.setIndent(8) + self.wordsLabel.setIndent(xInd) self.wordsValue = QLabel("{:n}".format(self.theProject.currWCount)) self.mainForm.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignTop) @@ -240,8 +247,8 @@ class GuiProjectEditMeta(QWidget): self.mainForm.addWidget(self.wordsLabel, 8, 0, 1, 1, Qt.AlignTop) self.mainForm.addWidget(self.wordsValue, 8, 1, 1, 1, Qt.AlignTop) - self.mainForm.setVerticalSpacing(6) - self.mainForm.setHorizontalSpacing(12) + self.mainForm.setVerticalSpacing(self.mainConf.pxInt(6)) + self.mainForm.setHorizontalSpacing(self.mainConf.pxInt(12)) self.mainForm.setColumnStretch(0, 0) self.mainForm.setColumnStretch(1, 1) self.mainForm.setRowStretch(10, 1) @@ -255,8 +262,10 @@ class GuiProjectEditStatus(QWidget): def __init__(self, theParent, theProject, isStatus): QWidget.__init__(self, theParent) + self.mainConf = nw.CONFIG self.theParent = theParent self.theProject = theProject + self.theTheme = theParent.theTheme if isStatus: self.theStatus = self.theProject.statusItems else: @@ -267,6 +276,8 @@ class GuiProjectEditStatus(QWidget): self.colChanged = False self.selColour = None + self.iPx = self.theTheme.textIconSize + self.outerBox = QVBoxLayout() self.mainBox = QHBoxLayout() self.mainForm = QVBoxLayout() @@ -285,8 +296,8 @@ class GuiProjectEditStatus(QWidget): self.newButton = QPushButton("New") self.delButton = QPushButton("Delete") self.saveButton = QPushButton("Save") - self.colPixmap = QPixmap(16,16) - self.colPixmap.fill(QColor(120,120,120)) + self.colPixmap = QPixmap(self.iPx, self.iPx) + self.colPixmap.fill(QColor(120, 120, 120)) self.colButton = QPushButton(QIcon(self.colPixmap),"Colour") self.colButton.setIconSize(self.colPixmap.rect().size()) @@ -339,7 +350,7 @@ class GuiProjectEditStatus(QWidget): ) if newCol: self.selColour = newCol - colPixmap = QPixmap(16,16) + colPixmap = QPixmap(self.iPx, self.iPx) colPixmap.fill(newCol) self.colButton.setIcon(QIcon(colPixmap)) self.colButton.setIconSize(colPixmap.rect().size()) @@ -348,7 +359,7 @@ class GuiProjectEditStatus(QWidget): def _newItem(self): logger.verbose("New item button clicked") newItem = self._addItem("New Item", (0, 0, 0), None, 0) - newItem.setBackground(QBrush(QColor(0,255,0,80))) + newItem.setBackground(QBrush(QColor(0, 255, 0, 80))) self.colChanged = True return @@ -387,14 +398,14 @@ class GuiProjectEditStatus(QWidget): return def _addItem(self, iName, iCol, oName, nUse): - newIcon = QPixmap(16,16) + newIcon = QPixmap(self.iPx, self.iPx) newIcon.fill(QColor(*iCol)) newItem = QListWidgetItem() newItem.setText("%s [%d]" % (iName, nUse)) newItem.setIcon(QIcon(newIcon)) newItem.setData(Qt.UserRole, len(self.colData)) self.listBox.addItem(newItem) - self.colData.append((iName,iCol[0],iCol[1],iCol[2],oName)) + self.colData.append((iName, iCol[0], iCol[1], iCol[2], oName)) self.colCounts.append(nUse) return newItem @@ -404,8 +415,8 @@ class GuiProjectEditStatus(QWidget): if selItem is not None: selIdx = selItem.data(Qt.UserRole) selVal = self.colData[selIdx] - self.selColour = QColor(selVal[1],selVal[2],selVal[3]) - newIcon = QPixmap(16,16) + self.selColour = QColor(selVal[1], selVal[2], selVal[3]) + newIcon = QPixmap(self.iPx, self.iPx) newIcon.fill(self.selColour) self.editName.setText(selVal[0]) self.colButton.setIcon(QIcon(newIcon)) diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index 97b87a2e..5bef07bf 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -112,8 +112,9 @@ class GuiProjectTree(QTreeWidget): # self.setSelectionBehavior(QAbstractItemView.SelectRows) # Get user's column width preferences for NAME and COUNT - if len(self.mainConf.treeColWidth) <= 4: - for colN, colW in enumerate(self.mainConf.treeColWidth): + treeColWidth = self.mainConf.getTreeColWidths() + if len(treeColWidth) <= 4: + for colN, colW in enumerate(treeColWidth): self.setColumnWidth(colN, colW) # The last column should just auto-scale diff --git a/nw/gui/sessionlog.py b/nw/gui/sessionlog.py index fdda4166..5f3c61f0 100644 --- a/nw/gui/sessionlog.py +++ b/nw/gui/sessionlog.py @@ -61,32 +61,26 @@ class GuiSessionLogView(QDialog): self.bottomBox = QHBoxLayout() self.setWindowTitle("Session Log") - self.setMinimumWidth(420) - self.setMinimumHeight(400) + self.setMinimumWidth(self.mainConf.pxInt(420)) + self.setMinimumHeight(self.mainConf.pxInt(400)) - widthCol0 = self.optState.validIntRange( - self.optState.getInt("GuiSession", "widthCol0", 180), 30, 999, 180 - ) - widthCol1 = self.optState.validIntRange( - self.optState.getInt("GuiSession", "widthCol1", 80), 30, 999, 80 - ) - widthCol2 = self.optState.validIntRange( - self.optState.getInt("GuiSession", "widthCol2", 80), 30, 999, 80 - ) + wCol0 = self.mainConf.pxInt(self.optState.getInt("GuiSession", "widthCol0", 180)) + wCol1 = self.mainConf.pxInt(self.optState.getInt("GuiSession", "widthCol1", 80)) + wCol2 = self.mainConf.pxInt(self.optState.getInt("GuiSession", "widthCol2", 80)) self.listBox = QTreeWidget() self.listBox.setHeaderLabels(["Session Start","Length","Words",""]) self.listBox.setIndentation(0) - self.listBox.setColumnWidth(0,widthCol0) - self.listBox.setColumnWidth(1,widthCol1) - self.listBox.setColumnWidth(2,widthCol2) - self.listBox.setColumnWidth(3,0) + self.listBox.setColumnWidth(0, wCol0) + self.listBox.setColumnWidth(1, wCol1) + self.listBox.setColumnWidth(2, wCol2) + self.listBox.setColumnWidth(3, 0) hHeader = self.listBox.headerItem() hHeader.setTextAlignment(1,Qt.AlignRight) hHeader.setTextAlignment(2,Qt.AlignRight) - self.monoFont = QFont("Monospace",10) + self.monoFont = QFont("Monospace", 10) sortValid = (Qt.AscendingOrder, Qt.DescendingOrder) sortCol = self.optState.validIntRange( @@ -226,20 +220,20 @@ class GuiSessionLogView(QDialog): def _doClose(self): - widthCol0 = self.listBox.columnWidth(0) - widthCol1 = self.listBox.columnWidth(1) - widthCol2 = self.listBox.columnWidth(2) + widthCol0 = self.mainConf.rpxInt(self.listBox.columnWidth(0)) + widthCol1 = self.mainConf.rpxInt(self.listBox.columnWidth(1)) + widthCol2 = self.mainConf.rpxInt(self.listBox.columnWidth(2)) sortCol = self.listBox.sortColumn() sortOrder = self.listBox.header().sortIndicatorOrder() hideZeros = self.hideZeros.isChecked() hideNegative = self.hideNegative.isChecked() - self.optState.setValue("GuiSession", "widthCol0", widthCol0) - self.optState.setValue("GuiSession", "widthCol1", widthCol1) - self.optState.setValue("GuiSession", "widthCol2", widthCol2) - self.optState.setValue("GuiSession", "sortCol", sortCol) - self.optState.setValue("GuiSession", "sortOrder", sortOrder) - self.optState.setValue("GuiSession", "hideZeros", hideZeros) + self.optState.setValue("GuiSession", "widthCol0", widthCol0) + self.optState.setValue("GuiSession", "widthCol1", widthCol1) + self.optState.setValue("GuiSession", "widthCol2", widthCol2) + self.optState.setValue("GuiSession", "sortCol", sortCol) + self.optState.setValue("GuiSession", "sortOrder", sortOrder) + self.optState.setValue("GuiSession", "hideZeros", hideZeros) self.optState.setValue("GuiSession", "hideNegative", hideNegative) self.optState.saveSettings() diff --git a/nw/gui/statusbar.py b/nw/gui/statusbar.py index 129ab9a8..a7fbc342 100644 --- a/nw/gui/statusbar.py +++ b/nw/gui/statusbar.py @@ -66,12 +66,14 @@ class GuiMainStatus(QStatusBar): # Permanent Widgets # ================= + xM = self.mainConf.pxInt(8) + ## The Spell Checker Language self.langIcon = QLabel("") self.langText = QLabel("None") self.langIcon.setPixmap(self.theTheme.getPixmap("status_lang", (iPx, iPx))) self.langIcon.setContentsMargins(0, 0, 0, 0) - self.langText.setContentsMargins(0, 0, 8, 0) + self.langText.setContentsMargins(0, 0, xM, 0) self.addPermanentWidget(self.langIcon) self.addPermanentWidget(self.langText) @@ -79,7 +81,7 @@ class GuiMainStatus(QStatusBar): self.docIcon = StatusLED(colNone, colTrue, colFalse, iPx, iPx, self) self.docText = QLabel("Editor") self.docIcon.setContentsMargins(0, 0, 0, 0) - self.docText.setContentsMargins(0, 0, 8, 0) + self.docText.setContentsMargins(0, 0, xM, 0) self.addPermanentWidget(self.docIcon) self.addPermanentWidget(self.docText) @@ -87,7 +89,7 @@ class GuiMainStatus(QStatusBar): self.projIcon = StatusLED(colNone, colTrue, colFalse, iPx, iPx, self) self.projText = QLabel("Project") self.projIcon.setContentsMargins(0, 0, 0, 0) - self.projText.setContentsMargins(0, 0, 8, 0) + self.projText.setContentsMargins(0, 0, xM, 0) self.addPermanentWidget(self.projIcon) self.addPermanentWidget(self.projText) @@ -96,7 +98,7 @@ class GuiMainStatus(QStatusBar): self.statsText = QLabel("") self.statsIcon.setPixmap(self.theTheme.getPixmap("status_stats", (iPx, iPx))) self.statsIcon.setContentsMargins(0, 0, 0, 0) - self.statsText.setContentsMargins(0, 0, 8, 0) + self.statsText.setContentsMargins(0, 0, xM, 0) self.addPermanentWidget(self.statsIcon) self.addPermanentWidget(self.statsText) diff --git a/nw/gui/theme.py b/nw/gui/theme.py index 8c736719..b17b7055 100644 --- a/nw/gui/theme.py +++ b/nw/gui/theme.py @@ -132,9 +132,13 @@ class GuiTheme: self.loadDecoration = self.theIcons.loadDecoration # Extract Other Info - self.guiDPI = qApp.primaryScreen().physicalDotsPerInch() - self.guiFont = qApp.font() + self.guiDPI = qApp.primaryScreen().physicalDotsPerInchX() + self.guiScale = qApp.primaryScreen().logicalDotsPerInchX()/96.0 + self.mainConf.guiScale = self.guiScale + logger.verbose("GUI DPI: %.1f" % self.guiDPI) + logger.verbose("GUI Scale: %.2f" % self.guiScale) + self.guiFont = qApp.font() qMetric = QFontMetrics(self.guiFont) self.fontPointSize = self.guiFont.pointSizeF() self.fontPixelSize = int(round(qMetric.height())) @@ -148,6 +152,8 @@ class GuiTheme: logger.verbose("GUI Font Pixel Size: %d" % self.fontPixelSize) logger.verbose("GUI Base Icon Size: %d" % self.baseIconSize) logger.verbose("GUI Text Icon Size: %d" % self.textIconSize) + logger.verbose("Text 'N' Height: %d" % self.textNHeight) + logger.verbose("Text 'N' Width: %d" % self.textNWidth) return diff --git a/nw/guimain.py b/nw/guimain.py index e9d9b81d..549e25b5 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -81,7 +81,7 @@ class GuiMain(QMainWindow): self.isZenMode = False # Prepare main window - self.resize(*self.mainConf.winGeometry) + self.resize(*self.mainConf.getWinSize()) self._setWindowTitle() self.setWindowIcon(QIcon(self.mainConf.appIcon)) @@ -108,15 +108,15 @@ class GuiMain(QMainWindow): # Assemble Main Window self.treePane = QWidget() self.treeBox = QVBoxLayout() - self.treeBox.setContentsMargins(0,0,0,0) + self.treeBox.setContentsMargins(0, 0, 0, 0) self.treeBox.addWidget(self.treeView) self.treeBox.addWidget(self.treeMeta) self.treePane.setLayout(self.treeBox) self.editPane = QWidget() self.docEdit = QVBoxLayout() - self.docEdit.setContentsMargins(0,0,0,0) - self.docEdit.setSpacing(2) + self.docEdit.setContentsMargins(0, 0, 0, 0) + self.docEdit.setSpacing(self.mainConf.pxInt(2)) self.docEdit.addWidget(self.searchBar) self.docEdit.addWidget(self.noticeBar) self.docEdit.addWidget(self.docEditor) @@ -124,8 +124,8 @@ class GuiMain(QMainWindow): self.viewPane = QWidget() self.docView = QVBoxLayout() - self.docView.setContentsMargins(0,0,0,0) - self.docView.setSpacing(2) + self.docView.setContentsMargins(0, 0, 0, 0) + self.docView.setSpacing(self.mainConf.pxInt(2)) self.docView.addWidget(self.docViewer) self.docView.addWidget(self.viewMeta) self.docView.setStretch(0, 1) @@ -139,7 +139,7 @@ class GuiMain(QMainWindow): self.splitOutline = QSplitter(Qt.Vertical) self.splitOutline.addWidget(self.projView) self.splitOutline.addWidget(self.projMeta) - self.splitOutline.setSizes(self.mainConf.outlnPanePos) + self.splitOutline.setSizes(self.mainConf.getOutlinePanePos()) self.tabWidget = QTabWidget() self.tabWidget.setTabPosition(QTabWidget.East) @@ -148,12 +148,13 @@ class GuiMain(QMainWindow): self.tabWidget.addTab(self.splitOutline, "Outline") self.tabWidget.currentChanged.connect(self._mainTabChanged) + xCM = self.mainConf.pxInt(4) self.splitMain = QSplitter(Qt.Horizontal) - self.splitMain.setContentsMargins(4,4,4,4) + self.splitMain.setContentsMargins(xCM, xCM, xCM, xCM) self.splitMain.setOpaqueResize(False) self.splitMain.addWidget(self.treePane) self.splitMain.addWidget(self.tabWidget) - self.splitMain.setSizes(self.mainConf.mainPanePos) + self.splitMain.setSizes(self.mainConf.getMainPanePos()) self.setCentralWidget(self.splitMain) @@ -513,9 +514,9 @@ class GuiMain(QMainWindow): if not self.viewPane.isVisible(): bPos = self.splitMain.sizes() self.viewPane.setVisible(True) - vPos = [0,0] + vPos = [0, 0] vPos[0] = int(bPos[1]/2) - vPos[1] = bPos[1]-vPos[0] + vPos[1] = bPos[1] - vPos[0] self.splitView.setSizes(vPos) self.docViewer.navigateTo(navLink) @@ -877,7 +878,7 @@ class GuiMain(QMainWindow): self.theProject.setLastViewed(None) bPos = self.splitMain.sizes() self.viewPane.setVisible(False) - vPos = [bPos[1],0] + vPos = [bPos[1], 0] self.splitView.setSizes(vPos) return not self.viewPane.isVisible() @@ -988,16 +989,18 @@ class GuiMain(QMainWindow): def _makeStatusIcons(self): self.statusIcons = {} + iPx = self.mainConf.pxInt(32) for sLabel, sCol, _ in self.theProject.statusItems: - theIcon = QPixmap(32,32) + theIcon = QPixmap(iPx, iPx) theIcon.fill(QColor(*sCol)) self.statusIcons[sLabel] = QIcon(theIcon) return def _makeImportIcons(self): self.importIcons = {} + iPx = self.mainConf.pxInt(32) for sLabel, sCol, _ in self.theProject.importItems: - theIcon = QPixmap(32,32) + theIcon = QPixmap(iPx, iPx) theIcon.fill(QColor(*sCol)) self.importIcons[sLabel] = QIcon(theIcon) return diff --git a/tests/reference/gui/0_nwProject.nwx b/tests/reference/gui/0_nwProject.nwx index dcf46837..c564337a 100644 --- a/tests/reference/gui/0_nwProject.nwx +++ b/tests/reference/gui/0_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/gui/1_nwProject.nwx b/tests/reference/gui/1_nwProject.nwx index ab090c92..db077dde 100644 --- a/tests/reference/gui/1_nwProject.nwx +++ b/tests/reference/gui/1_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/gui/2_nwProject.nwx b/tests/reference/gui/2_nwProject.nwx index 11fc5dbe..1f63cb60 100644 --- a/tests/reference/gui/2_nwProject.nwx +++ b/tests/reference/gui/2_nwProject.nwx @@ -22,9 +22,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/gui/3_nwProject.nwx b/tests/reference/gui/3_nwProject.nwx index e7f9e514..88a00d4b 100644 --- a/tests/reference/gui/3_nwProject.nwx +++ b/tests/reference/gui/3_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/proj/1_nwProject.nwx b/tests/reference/proj/1_nwProject.nwx index 5ba28cae..8156cf1e 100644 --- a/tests/reference/proj/1_nwProject.nwx +++ b/tests/reference/proj/1_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/proj/2_nwProject.nwx b/tests/reference/proj/2_nwProject.nwx index fe5bf878..b8e454d6 100644 --- a/tests/reference/proj/2_nwProject.nwx +++ b/tests/reference/proj/2_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New diff --git a/tests/reference/proj/3_nwProject.nwx b/tests/reference/proj/3_nwProject.nwx index 2e3cb6c0..130933e0 100644 --- a/tests/reference/proj/3_nwProject.nwx +++ b/tests/reference/proj/3_nwProject.nwx @@ -18,9 +18,6 @@ %title% * * *
- False - False - False New