class GuiPreferencesAutomation(QWidget): def __init__(self, mainGui): QWidget.__init__(self, mainGui) self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme # The Form self.mainForm = QConfigLayout() self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.setLayout(self.mainForm) # Automatic Features # ================== self.mainForm.addGroupLabel(self.tr("Automatic Features")) # Auto-Select Word Under Cursor self.autoSelect = QSwitch() self.autoSelect.setChecked(self.mainConf.autoSelect) self.mainForm.addRow( self.tr("Auto-select word under cursor"), self.autoSelect, self.tr("Apply formatting to word under cursor if no selection is made.") ) # Auto-Replace as You Type Main Switch self.doReplace = QSwitch() self.doReplace.setChecked(self.mainConf.doReplace) self.doReplace.toggled.connect(self._toggleAutoReplaceMain) self.mainForm.addRow( self.tr("Auto-replace text as you type"), self.doReplace, self.tr("Allow the editor to replace symbols as you type.") ) # Replace as You Type # =================== self.mainForm.addGroupLabel(self.tr("Replace as You Type")) # Auto-Replace Single Quotes self.doReplaceSQuote = QSwitch() self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote) self.doReplaceSQuote.setEnabled(self.mainConf.doReplace) self.mainForm.addRow( self.tr("Auto-replace single quotes"), self.doReplaceSQuote, self.tr("Try to guess which is an opening or a closing quote.") ) # Auto-Replace Double Quotes self.doReplaceDQuote = QSwitch() self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote) self.doReplaceDQuote.setEnabled(self.mainConf.doReplace) self.mainForm.addRow( self.tr("Auto-replace double quotes"), self.doReplaceDQuote, self.tr("Try to guess which is an opening or a closing quote.") ) # Auto-Replace Hyphens self.doReplaceDash = QSwitch() self.doReplaceDash.setChecked(self.mainConf.doReplaceDash) self.doReplaceDash.setEnabled(self.mainConf.doReplace) self.mainForm.addRow( self.tr("Auto-replace dashes"), self.doReplaceDash, self.tr("Double and triple hyphens become short and long dashes.") ) # Auto-Replace Dots self.doReplaceDots = QSwitch() self.doReplaceDots.setChecked(self.mainConf.doReplaceDots) self.doReplaceDots.setEnabled(self.mainConf.doReplace) self.mainForm.addRow( self.tr("Auto-replace dots"), self.doReplaceDots, self.tr("Three consecutive dots become ellipsis.") ) # Automatic Padding # ================= self.mainForm.addGroupLabel(self.tr("Automatic Padding")) # Pad Before self.fmtPadBefore = QLineEdit() self.fmtPadBefore.setMaxLength(32) self.fmtPadBefore.setText(self.mainConf.fmtPadBefore) self.mainForm.addRow( self.tr("Insert non-breaking space before"), self.fmtPadBefore, self.tr("Automatically add space before any of these symbols."), ) # Pad After self.fmtPadAfter = QLineEdit() self.fmtPadAfter.setMaxLength(32) self.fmtPadAfter.setText(self.mainConf.fmtPadAfter) self.mainForm.addRow( self.tr("Insert non-breaking space after"), self.fmtPadAfter, self.tr("Automatically add space after any of these symbols."), ) # Use Thin Space self.fmtPadThin = QSwitch() self.fmtPadThin.setChecked(self.mainConf.fmtPadThin) self.fmtPadThin.setEnabled(self.mainConf.doReplace) self.mainForm.addRow( self.tr("Use thin space instead"), self.fmtPadThin, self.tr("Inserts a thin space instead of a regular space.") ) return def saveValues(self): """Save the values set for this tab. """ # Automatic Features self.mainConf.autoSelect = self.autoSelect.isChecked() self.mainConf.doReplace = self.doReplace.isChecked() # Replace as You Type self.mainConf.doReplaceSQuote = self.doReplaceSQuote.isChecked() self.mainConf.doReplaceDQuote = self.doReplaceDQuote.isChecked() self.mainConf.doReplaceDash = self.doReplaceDash.isChecked() self.mainConf.doReplaceDots = self.doReplaceDots.isChecked() # Automatic Padding self.mainConf.fmtPadBefore = self.fmtPadBefore.text().strip() self.mainConf.fmtPadAfter = self.fmtPadAfter.text().strip() self.mainConf.fmtPadThin = self.fmtPadThin.isChecked() self.mainConf.confChanged = True return ## # Slots ## def _toggleAutoReplaceMain(self, theState): """Enables or disables switches controlled by the main auto replace switch. """ self.doReplaceSQuote.setEnabled(theState) self.doReplaceDQuote.setEnabled(theState) self.doReplaceDash.setEnabled(theState) self.doReplaceDots.setEnabled(theState) self.fmtPadThin.setEnabled(theState) return
class GuiPreferencesSyntax(QWidget): def __init__(self, mainGui): QWidget.__init__(self, mainGui) self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme # The Form self.mainForm = QConfigLayout() self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.setLayout(self.mainForm) # Quotes & Dialogue # ================= self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue")) self.highlightQuotes = QSwitch() self.highlightQuotes.setChecked(self.mainConf.highlightQuotes) self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes) self.mainForm.addRow( self.tr("Highlight text wrapped in quotes"), self.highlightQuotes, self.tr("Applies to the document editor only.") ) self.allowOpenSQuote = QSwitch() self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote) self.mainForm.addRow( self.tr("Allow open-ended single quotes"), self.allowOpenSQuote, self.tr("Highlight single-quoted line with no closing quote.") ) self.allowOpenDQuote = QSwitch() self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote) self.mainForm.addRow( self.tr("Allow open-ended double quotes"), self.allowOpenDQuote, self.tr("Highlight double-quoted line with no closing quote.") ) # Text Emphasis # ============= self.mainForm.addGroupLabel(self.tr("Text Emphasis")) self.highlightEmph = QSwitch() self.highlightEmph.setChecked(self.mainConf.highlightEmph) self.mainForm.addRow( self.tr("Add highlight colour to emphasised text"), self.highlightEmph, self.tr("Applies to the document editor only.") ) # Text Errors # =========== self.mainForm.addGroupLabel(self.tr("Text Errors")) self.showMultiSpaces = QSwitch() self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces) self.mainForm.addRow( self.tr("Highlight multiple or trailing spaces"), self.showMultiSpaces, self.tr("Applies to the document editor only.") ) return def saveValues(self): """Save the values set for this tab. """ # Quotes & Dialogue self.mainConf.highlightQuotes = self.highlightQuotes.isChecked() self.mainConf.allowOpenSQuote = self.allowOpenSQuote.isChecked() self.mainConf.allowOpenDQuote = self.allowOpenDQuote.isChecked() # Text Emphasis self.mainConf.highlightEmph = self.highlightEmph.isChecked() # Text Errors self.mainConf.showMultiSpaces = self.showMultiSpaces.isChecked() self.mainConf.confChanged = True return ## # Slots ## def _toggleHighlightQuotes(self, theState): """Enables or disables switches controlled by the highlight quotes switch. """ self.allowOpenSQuote.setEnabled(theState) self.allowOpenDQuote.setEnabled(theState) return
class GuiPreferencesSyntax(QWidget): def __init__(self, theParent): QWidget.__init__(self, theParent) self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theTheme = theParent.theTheme # The Form self.mainForm = QConfigLayout() self.mainForm.setHelpTextStyle(self.theTheme.helpText) self.setLayout(self.mainForm) # Highlighting Theme # ================== self.mainForm.addGroupLabel(self.tr("Highlighting Theme")) self.guiSyntax = QComboBox() self.guiSyntax.setMinimumWidth(self.mainConf.pxInt(200)) self.theSyntaxes = self.theTheme.listSyntax() for syntaxFile, syntaxName in self.theSyntaxes: self.guiSyntax.addItem(syntaxName, syntaxFile) syntaxIdx = self.guiSyntax.findData(self.mainConf.guiSyntax) if syntaxIdx != -1: self.guiSyntax.setCurrentIndex(syntaxIdx) self.mainForm.addRow( self.tr("Highlighting theme"), self.guiSyntax, self.tr("Colour theme for the editor and viewer.")) # Quotes & Dialogue # ================= self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue")) self.highlightQuotes = QSwitch() self.highlightQuotes.setChecked(self.mainConf.highlightQuotes) self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes) self.mainForm.addRow(self.tr("Highlight text wrapped in quotes"), self.highlightQuotes, self.tr("Applies to the document editor only.")) self.allowOpenSQuote = QSwitch() self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote) self.mainForm.addRow( self.tr("Allow open-ended single quotes"), self.allowOpenSQuote, self.tr("Highlight single-quoted line with no closing quote.")) self.allowOpenDQuote = QSwitch() self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote) self.mainForm.addRow( self.tr("Allow open-ended double quotes"), self.allowOpenDQuote, self.tr("Highlight double-quoted line with no closing quote.")) # Text Emphasis # ============= self.mainForm.addGroupLabel(self.tr("Text Emphasis")) self.highlightEmph = QSwitch() self.highlightEmph.setChecked(self.mainConf.highlightEmph) self.mainForm.addRow( self.tr("Add highlight colour to emphasised text"), self.highlightEmph, self.tr("Applies to the document editor only.")) # Text Errors # =========== self.mainForm.addGroupLabel(self.tr("Text Errors")) self.showMultiSpaces = QSwitch() self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces) self.mainForm.addRow(self.tr("Highlight multiple spaces"), self.showMultiSpaces, self.tr("Applies to the document editor only.")) return def saveValues(self): """Save the values set for this tab. """ # Highlighting Theme self.mainConf.guiSyntax = self.guiSyntax.currentData() # Quotes & Dialogue self.mainConf.highlightQuotes = self.highlightQuotes.isChecked() self.mainConf.allowOpenSQuote = self.allowOpenSQuote.isChecked() self.mainConf.allowOpenDQuote = self.allowOpenDQuote.isChecked() # Text Emphasis self.mainConf.highlightEmph = self.highlightEmph.isChecked() # Text Errors self.mainConf.showMultiSpaces = self.showMultiSpaces.isChecked() self.mainConf.confChanged = True return ## # Slots ## def _toggleHighlightQuotes(self, theState): """Enables or disables switches controlled by the highlight quotes switch. """ self.allowOpenSQuote.setEnabled(theState) self.allowOpenDQuote.setEnabled(theState) return
class GuiPreferencesProjects(QWidget): def __init__(self, mainGui): QWidget.__init__(self, mainGui) self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme # The Form self.mainForm = QConfigLayout() self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.setLayout(self.mainForm) # Automatic Save # ============== self.mainForm.addGroupLabel(self.tr("Automatic Save")) # Document Save Timer self.autoSaveDoc = QSpinBox(self) self.autoSaveDoc.setMinimum(5) self.autoSaveDoc.setMaximum(600) self.autoSaveDoc.setSingleStep(1) self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc) self.mainForm.addRow( self.tr("Save document interval"), self.autoSaveDoc, self.tr("How often the document is automatically saved."), theUnit=self.tr("seconds") ) # Project Save Timer self.autoSaveProj = QSpinBox(self) self.autoSaveProj.setMinimum(5) self.autoSaveProj.setMaximum(600) self.autoSaveProj.setSingleStep(1) self.autoSaveProj.setValue(self.mainConf.autoSaveProj) self.mainForm.addRow( self.tr("Save project interval"), self.autoSaveProj, self.tr("How often the project is automatically saved."), theUnit=self.tr("seconds") ) # Project Backup # ============== self.mainForm.addGroupLabel(self.tr("Project Backup")) # Backup Path self.backupPath = self.mainConf.backupPath self.backupGetPath = QPushButton(self.tr("Browse")) self.backupGetPath.clicked.connect(self._backupFolder) self.backupPathRow = self.mainForm.addRow( self.tr("Backup storage location"), self.backupGetPath, self.tr("Path: {0}").format(self.backupPath) ) # Run when closing self.backupOnClose = QSwitch() self.backupOnClose.setChecked(self.mainConf.backupOnClose) self.backupOnClose.toggled.connect(self._toggledBackupOnClose) self.mainForm.addRow( self.tr("Run backup when the project is closed"), self.backupOnClose, self.tr("Can be overridden for individual projects in Project Settings.") ) # Ask before backup # Only enabled when "Run when closing" is checked self.askBeforeBackup = QSwitch() self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup) self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose) self.mainForm.addRow( self.tr("Ask before running backup"), self.askBeforeBackup, self.tr("If off, backups will run in the background.") ) # Session Timer # ============= self.mainForm.addGroupLabel(self.tr("Session Timer")) # Pause when idle self.stopWhenIdle = QSwitch() self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle) self.mainForm.addRow( self.tr("Pause the session timer when not writing"), self.stopWhenIdle, self.tr("Also pauses when the application window does not have focus.") ) # Inactive time for idle self.userIdleTime = QDoubleSpinBox() self.userIdleTime.setMinimum(0.5) self.userIdleTime.setMaximum(600.0) self.userIdleTime.setSingleStep(0.5) self.userIdleTime.setDecimals(1) self.userIdleTime.setValue(self.mainConf.userIdleTime/60.0) self.mainForm.addRow( self.tr("Editor inactive time before pausing timer"), self.userIdleTime, self.tr("User activity includes typing and changing the content."), theUnit=self.tr("minutes") ) return def saveValues(self): """Save the values set for this tab. """ # Automatic Save self.mainConf.autoSaveDoc = self.autoSaveDoc.value() self.mainConf.autoSaveProj = self.autoSaveProj.value() # Project Backup self.mainConf.backupPath = self.backupPath self.mainConf.backupOnClose = self.backupOnClose.isChecked() self.mainConf.askBeforeBackup = self.askBeforeBackup.isChecked() # Session Timer self.mainConf.stopWhenIdle = self.stopWhenIdle.isChecked() self.mainConf.userIdleTime = round(self.userIdleTime.value() * 60) self.mainConf.confChanged = True return ## # Slots ## def _backupFolder(self): """Open a dialog to select the backup folder. """ currDir = self.backupPath if not os.path.isdir(currDir): currDir = "" newDir = QFileDialog.getExistingDirectory( self, self.tr("Backup Directory"), currDir, options=QFileDialog.ShowDirsOnly ) if newDir: self.backupPath = newDir self.mainForm.setHelpText( self.backupPathRow, self.tr("Path: {0}").format(self.backupPath) ) return True return False def _toggledBackupOnClose(self, theState): """Enable or disable switch that depends on the backup on close switch. """ self.askBeforeBackup.setEnabled(theState) return
class GuiItemEditor(QDialog): def __init__(self, theParent, tHandle): QDialog.__init__(self, theParent) logger.debug("Initialising GuiItemEditor ...") self.setObjectName("GuiItemEditor") self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theProject = theParent.theProject ## # Build GUI ## self.theItem = self.theProject.projTree[tHandle] if self.theItem is None: self.close() return self.setWindowTitle(self.tr("Item Settings")) mVd = self.mainConf.pxInt(220) mSp = self.mainConf.pxInt(16) vSp = self.mainConf.pxInt(4) # Item Label self.editName = QLineEdit() self.editName.setMinimumWidth(mVd) self.editName.setMaxLength(200) # Item Status self.editStatus = QComboBox() self.editStatus.setMinimumWidth(mVd) if self.theItem.itemClass in nwLists.CLS_NOVEL: for sLabel, _, _, sIcon in self.theProject.statusItems: self.editStatus.addItem(sIcon, sLabel, sLabel) else: for sLabel, _, _, sIcon in self.theProject.importItems: self.editStatus.addItem(sIcon, sLabel, sLabel) # Item Layout self.editLayout = QComboBox() self.editLayout.setMinimumWidth(mVd) validLayouts = [] if self.theItem.itemType == nwItemType.FILE: if self.theItem.itemClass in nwLists.CLS_NOVEL: validLayouts.append(nwItemLayout.DOCUMENT) validLayouts.append(nwItemLayout.NOTE) else: validLayouts.append(nwItemLayout.NO_LAYOUT) self.editLayout.setEnabled(False) for itemLayout in nwItemLayout: if itemLayout in validLayouts: self.editLayout.addItem( trConst(nwLabels.LAYOUT_NAME[itemLayout]), itemLayout) # Export Switch self.textExport = QLabel(self.tr("Include when building project")) self.editExport = QSwitch() if self.theItem.itemType == nwItemType.FILE: self.editExport.setEnabled(True) self.editExport.setChecked(self.theItem.isExported) else: self.editExport.setEnabled(False) self.editExport.setChecked(False) # Buttons self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self._doSave) self.buttonBox.rejected.connect(self._doClose) # Set Current Values self.editName.setText(self.theItem.itemName) self.editName.selectAll() currStatus, _ = self.theItem.getImportStatus() statusIdx = self.editStatus.findData(currStatus) if statusIdx != -1: self.editStatus.setCurrentIndex(statusIdx) layoutIdx = self.editLayout.findData(self.theItem.itemLayout) if layoutIdx != -1: self.editLayout.setCurrentIndex(layoutIdx) ## # Assemble ## nameLabel = QLabel(self.tr("Label")) statusLabel = QLabel(self.tr("Status")) layoutLabel = QLabel(self.tr("Layout")) self.mainForm = QGridLayout() self.mainForm.setVerticalSpacing(vSp) self.mainForm.setHorizontalSpacing(mSp) self.mainForm.addWidget(nameLabel, 0, 0, 1, 1) self.mainForm.addWidget(self.editName, 0, 1, 1, 2) self.mainForm.addWidget(statusLabel, 1, 0, 1, 1) self.mainForm.addWidget(self.editStatus, 1, 1, 1, 2) self.mainForm.addWidget(layoutLabel, 2, 0, 1, 1) self.mainForm.addWidget(self.editLayout, 2, 1, 1, 2) self.mainForm.addWidget(self.textExport, 3, 0, 1, 2) self.mainForm.addWidget(self.editExport, 3, 2, 1, 1) self.mainForm.setColumnStretch(0, 0) self.mainForm.setColumnStretch(1, 1) self.mainForm.setColumnStretch(2, 0) self.outerBox = QVBoxLayout() self.outerBox.setSpacing(mSp) self.outerBox.addLayout(self.mainForm) self.outerBox.addStretch(1) self.outerBox.addWidget(self.buttonBox) self.setLayout(self.outerBox) self.rejected.connect(self._doClose) logger.debug("GuiItemEditor initialisation complete") return ## # Slots ## @pyqtSlot() def _doSave(self): """Save the setting to the item. """ logger.verbose("ItemEditor save button clicked") itemName = self.editName.text() itemStatus = self.editStatus.currentData() itemLayout = self.editLayout.currentData() isExported = self.editExport.isChecked() self.theItem.setName(itemName) self.theItem.setImportStatus(itemStatus) self.theItem.setLayout(itemLayout) self.theItem.setExported(isExported) self.theProject.setProjectChanged(True) self.accept() self.close() return @pyqtSlot() def _doClose(self): """Close the dialog without saving the settings. """ logger.verbose("ItemEditor cancel button clicked") self.close() return