+24
-21
@@ -169,27 +169,30 @@ class nwQuotes():
|
||||
Source: https://en.wikipedia.org/wiki/Quotation_mark
|
||||
"""
|
||||
|
||||
SYMBOLS = [
|
||||
"\u0022", # Quotation mark
|
||||
"\u0027", # Apostrophe
|
||||
"\u00ab", # Left-pointing double angle quotation mark
|
||||
"\u00bb", # Right-pointing double angle quotation mark
|
||||
"\u2018", # Left single quotation mark
|
||||
"\u2019", # Right single quotation mark
|
||||
"\u201a", # Single low-9 quotation mark
|
||||
"\u201b", # Single high-reversed-9 quotation mark
|
||||
"\u201c", # Left double quotation mark
|
||||
"\u201d", # Right double quotation mark
|
||||
"\u201e", # Double low-9 quotation mark
|
||||
"\u201f", # Double high-reversed-9 quotation mark
|
||||
"\u2039", # Single left-pointing angle quotation mark
|
||||
"\u203a", # Single right-pointing angle quotation mark
|
||||
"\u2e42", # Double low-reversed-9 quotation mark
|
||||
"\u300c", # Left corner bracket
|
||||
"\u300d", # Right corner bracket
|
||||
"\u300e", # Left white corner bracket
|
||||
"\u300f", # Right white corner bracket
|
||||
]
|
||||
SYMBOLS = {
|
||||
"\u0027" : "Straight single quotation mark",
|
||||
"\u0022" : "Straight double quotation mark",
|
||||
|
||||
"\u2018" : "Left single quotation mark",
|
||||
"\u2019" : "Right single quotation mark",
|
||||
"\u201a" : "Single low-9 quotation mark",
|
||||
"\u201b" : "Single high-reversed-9 quotation mark",
|
||||
"\u201c" : "Left double quotation mark",
|
||||
"\u201d" : "Right double quotation mark",
|
||||
"\u201e" : "Double low-9 quotation mark",
|
||||
"\u201f" : "Double high-reversed-9 quotation mark",
|
||||
"\u2e42" : "Double low-reversed-9 quotation mark",
|
||||
|
||||
"\u2039" : "Single left-pointing angle quotation mark",
|
||||
"\u203a" : "Single right-pointing angle quotation mark",
|
||||
"\u00ab" : "Left-pointing double angle quotation mark",
|
||||
"\u00bb" : "Right-pointing double angle quotation mark",
|
||||
|
||||
"\u300c" : "Left corner bracket",
|
||||
"\u300d" : "Right corner bracket",
|
||||
"\u300e" : "Left white corner bracket",
|
||||
"\u300f" : "Right white corner bracket",
|
||||
}
|
||||
|
||||
# END Class nwQuotes
|
||||
|
||||
|
||||
+100
-4
@@ -30,17 +30,17 @@
|
||||
import logging
|
||||
import nw
|
||||
|
||||
from PyQt5.QtGui import QColor, QPalette, QPainter
|
||||
from PyQt5.QtGui import QColor, QPalette, QPainter, QFontMetrics
|
||||
from PyQt5.QtCore import (
|
||||
Qt, QRect, QPoint, QSize, QRectF, QPropertyAnimation, pyqtProperty
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QSizePolicy,
|
||||
QAbstractButton, QDialog, QTabWidget, QTabBar, QStyle,
|
||||
QStylePainter, QStyleOptionTab
|
||||
QAbstractButton, QDialog, QTabWidget, QTabBar, QStyle, QDialogButtonBox,
|
||||
QStylePainter, QStyleOptionTab, QListWidget, QListWidgetItem, QFrame
|
||||
)
|
||||
|
||||
from nw.constants import nwUnicode
|
||||
from nw.constants import nwUnicode, nwQuotes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -436,3 +436,99 @@ class VerticalTabBar(QTabBar):
|
||||
return
|
||||
|
||||
# END Class VerticalTabBar
|
||||
|
||||
# =============================================================================================== #
|
||||
# Quotes Dialog
|
||||
# =============================================================================================== #
|
||||
|
||||
class QuotesDialog(QDialog):
|
||||
|
||||
def __init__(self, theParent=None, currentQuote="\""):
|
||||
QDialog.__init__(self, parent=theParent)
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
|
||||
self.outerBox = QVBoxLayout()
|
||||
self.innerBox = QHBoxLayout()
|
||||
self.labelBox = QVBoxLayout()
|
||||
|
||||
self.selectedQuote = currentQuote
|
||||
|
||||
qMetrics = QFontMetrics(self.font())
|
||||
pxW = 7*qMetrics.boundingRectChar("M").width()
|
||||
pxH = 7*qMetrics.boundingRectChar("M").height()
|
||||
pxH = 7*qMetrics.boundingRectChar("M").height()
|
||||
|
||||
lblFont = self.font()
|
||||
lblFont.setPointSizeF(4*lblFont.pointSizeF())
|
||||
|
||||
# Preview Label
|
||||
self.previewLabel = QLabel(currentQuote)
|
||||
self.previewLabel.setFont(lblFont)
|
||||
self.previewLabel.setFixedSize(QSize(pxW, pxH))
|
||||
self.previewLabel.setAlignment(Qt.AlignCenter)
|
||||
self.previewLabel.setFrameStyle(QFrame.Box | QFrame.Plain)
|
||||
|
||||
# Quote Symbols
|
||||
self.listBox = QListWidget()
|
||||
self.listBox.itemSelectionChanged.connect(self._selectedSymbol)
|
||||
|
||||
minSize = 100
|
||||
for sKey, sLabel in nwQuotes.SYMBOLS.items():
|
||||
theText = "[ %s ] %s" % (sKey, sLabel)
|
||||
minSize = max(minSize, qMetrics.boundingRect(theText).width())
|
||||
qtItem = QListWidgetItem(theText)
|
||||
qtItem.setData(Qt.UserRole, sKey)
|
||||
self.listBox.addItem(qtItem)
|
||||
if sKey == currentQuote:
|
||||
self.listBox.setCurrentItem(qtItem)
|
||||
|
||||
self.listBox.setMinimumWidth(minSize + self.mainConf.pxInt(40))
|
||||
self.listBox.setMinimumHeight(self.mainConf.pxInt(150))
|
||||
|
||||
# Buttons
|
||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
self.buttonBox.accepted.connect(self._doAccept)
|
||||
self.buttonBox.rejected.connect(self._doReject)
|
||||
|
||||
# Assemble
|
||||
self.labelBox.addWidget(self.previewLabel, 0, Qt.AlignTop)
|
||||
self.labelBox.addStretch(1)
|
||||
|
||||
self.innerBox.addLayout(self.labelBox)
|
||||
self.innerBox.addWidget(self.listBox)
|
||||
|
||||
self.outerBox.addLayout(self.innerBox)
|
||||
self.outerBox.addWidget(self.buttonBox)
|
||||
|
||||
self.setLayout(self.outerBox)
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Slots
|
||||
##
|
||||
|
||||
def _selectedSymbol(self):
|
||||
"""Update the preview label and the selected quote style.
|
||||
"""
|
||||
selItems = self.listBox.selectedItems()
|
||||
if selItems:
|
||||
theSymbol = selItems[0].data(Qt.UserRole)
|
||||
self.previewLabel.setText(theSymbol)
|
||||
self.selectedQuote = theSymbol
|
||||
return
|
||||
|
||||
def _doAccept(self):
|
||||
"""Ok button clicked.
|
||||
"""
|
||||
self.accept()
|
||||
return
|
||||
|
||||
def _doReject(self):
|
||||
"""Cancel button clicked.
|
||||
"""
|
||||
self.reject()
|
||||
return
|
||||
|
||||
# END Class QuotesDialog
|
||||
|
||||
+63
-37
@@ -37,9 +37,9 @@ from PyQt5.QtWidgets import (
|
||||
QDialogButtonBox, QFileDialog, QFontDialog
|
||||
)
|
||||
|
||||
from nw.gui.custom import QSwitch, QConfigLayout, PagedDialog
|
||||
from nw.gui.custom import QSwitch, QConfigLayout, PagedDialog, QuotesDialog
|
||||
from nw.core import NWSpellCheck, NWSpellSimple, NWSpellEnchant
|
||||
from nw.constants import nwAlert, nwQuotes
|
||||
from nw.constants import nwQuotes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -816,51 +816,72 @@ class GuiConfigEditAutoReplaceTab(QWidget):
|
||||
self.mainForm.addGroupLabel("Quotation Style")
|
||||
|
||||
qWidth = self.mainConf.pxInt(40)
|
||||
bWidth = int(2.5*self.theTheme.getTextWidth("..."))
|
||||
|
||||
## Single Quote Style
|
||||
self.quoteSingleStyleO = QLineEdit()
|
||||
self.quoteSingleStyleO.setMaxLength(1)
|
||||
self.quoteSingleStyleO.setReadOnly(True)
|
||||
self.quoteSingleStyleO.setFixedWidth(qWidth)
|
||||
self.quoteSingleStyleO.setAlignment(Qt.AlignCenter)
|
||||
self.quoteSingleStyleO.setText(self.mainConf.fmtSingleQuotes[0])
|
||||
self.btnSingleStyleO = QPushButton("...")
|
||||
self.btnSingleStyleO.setMaximumWidth(bWidth)
|
||||
self.btnSingleStyleO.clicked.connect(self._getSingleOpen)
|
||||
self.mainForm.addRow(
|
||||
"Single quote open style",
|
||||
self.quoteSingleStyleO,
|
||||
"Auto-replaces apostrophe before words."
|
||||
"Auto-replaces apostrophe before words.",
|
||||
theButton=self.btnSingleStyleO
|
||||
)
|
||||
|
||||
self.quoteSingleStyleC = QLineEdit()
|
||||
self.quoteSingleStyleC.setMaxLength(1)
|
||||
self.quoteSingleStyleC.setReadOnly(True)
|
||||
self.quoteSingleStyleC.setFixedWidth(qWidth)
|
||||
self.quoteSingleStyleC.setAlignment(Qt.AlignCenter)
|
||||
self.quoteSingleStyleC.setText(self.mainConf.fmtSingleQuotes[1])
|
||||
self.btnSingleStyleC = QPushButton("...")
|
||||
self.btnSingleStyleC.setMaximumWidth(bWidth)
|
||||
self.btnSingleStyleC.clicked.connect(self._getSingleClose)
|
||||
self.mainForm.addRow(
|
||||
"Single quote close style",
|
||||
self.quoteSingleStyleC,
|
||||
"Auto-replaces apostrophe after words."
|
||||
"Auto-replaces apostrophe after words.",
|
||||
theButton=self.btnSingleStyleC
|
||||
)
|
||||
|
||||
## Double Quote Style
|
||||
self.quoteDoubleStyleO = QLineEdit()
|
||||
self.quoteDoubleStyleO.setMaxLength(1)
|
||||
self.quoteDoubleStyleO.setReadOnly(True)
|
||||
self.quoteDoubleStyleO.setFixedWidth(qWidth)
|
||||
self.quoteDoubleStyleO.setAlignment(Qt.AlignCenter)
|
||||
self.quoteDoubleStyleO.setText(self.mainConf.fmtDoubleQuotes[0])
|
||||
self.btnDoubleStyleO = QPushButton("...")
|
||||
self.btnDoubleStyleO.setMaximumWidth(bWidth)
|
||||
self.btnDoubleStyleO.clicked.connect(self._getDoubleOpen)
|
||||
self.mainForm.addRow(
|
||||
"Double quote open style",
|
||||
self.quoteDoubleStyleO,
|
||||
"Auto-replaces straight quotes before words."
|
||||
"Auto-replaces straight quotes before words.",
|
||||
theButton=self.btnDoubleStyleO
|
||||
)
|
||||
|
||||
self.quoteDoubleStyleC = QLineEdit()
|
||||
self.quoteDoubleStyleC.setMaxLength(1)
|
||||
self.quoteDoubleStyleC.setReadOnly(True)
|
||||
self.quoteDoubleStyleC.setFixedWidth(qWidth)
|
||||
self.quoteDoubleStyleC.setAlignment(Qt.AlignCenter)
|
||||
self.quoteDoubleStyleC.setText(self.mainConf.fmtDoubleQuotes[1])
|
||||
self.btnDoubleStyleC = QPushButton("...")
|
||||
self.btnDoubleStyleC.setMaximumWidth(bWidth)
|
||||
self.btnDoubleStyleC.clicked.connect(self._getDoubleClose)
|
||||
self.mainForm.addRow(
|
||||
"Double quote close style",
|
||||
self.quoteDoubleStyleC,
|
||||
"Auto-replaces straight quotes after words."
|
||||
"Auto-replaces straight quotes after words.",
|
||||
theButton=self.btnDoubleStyleC
|
||||
)
|
||||
|
||||
return
|
||||
@@ -889,37 +910,10 @@ class GuiConfigEditAutoReplaceTab(QWidget):
|
||||
fmtDoubleQuotesO = self.quoteDoubleStyleO.text()
|
||||
fmtDoubleQuotesC = self.quoteDoubleStyleC.text()
|
||||
|
||||
if self._checkQuoteSymbol(fmtSingleQuotesO):
|
||||
self.mainConf.fmtSingleQuotes[0] = fmtSingleQuotesO
|
||||
else:
|
||||
self.theParent.makeAlert(
|
||||
"Invalid quote symbol: %s" % fmtSingleQuotesO, nwAlert.ERROR
|
||||
)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtSingleQuotesC):
|
||||
self.mainConf.fmtSingleQuotes[1] = fmtSingleQuotesC
|
||||
else:
|
||||
self.theParent.makeAlert(
|
||||
"Invalid quote symbol: %s" % fmtSingleQuotesC, nwAlert.ERROR
|
||||
)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtDoubleQuotesO):
|
||||
self.mainConf.fmtDoubleQuotes[0] = fmtDoubleQuotesO
|
||||
else:
|
||||
self.theParent.makeAlert(
|
||||
"Invalid quote symbol: %s" % fmtDoubleQuotesO, nwAlert.ERROR
|
||||
)
|
||||
validEntries = False
|
||||
|
||||
if self._checkQuoteSymbol(fmtDoubleQuotesC):
|
||||
self.mainConf.fmtDoubleQuotes[1] = fmtDoubleQuotesC
|
||||
else:
|
||||
self.theParent.makeAlert(
|
||||
"Invalid quote symbol: %s" % fmtDoubleQuotesC, nwAlert.ERROR
|
||||
)
|
||||
validEntries = False
|
||||
self.mainConf.fmtSingleQuotes[0] = fmtSingleQuotesO
|
||||
self.mainConf.fmtSingleQuotes[1] = fmtSingleQuotesC
|
||||
self.mainConf.fmtDoubleQuotes[0] = fmtDoubleQuotesO
|
||||
self.mainConf.fmtDoubleQuotes[1] = fmtDoubleQuotesC
|
||||
|
||||
self.mainConf.confChanged = True
|
||||
|
||||
@@ -939,6 +933,38 @@ class GuiConfigEditAutoReplaceTab(QWidget):
|
||||
self.autoReplaceDots.setEnabled(theState)
|
||||
return
|
||||
|
||||
def _getSingleOpen(self):
|
||||
"""Dialog for single quote open.
|
||||
"""
|
||||
qtBox = QuotesDialog(self, currentQuote=self.quoteSingleStyleO.text())
|
||||
if qtBox.exec_() == QDialog.Accepted:
|
||||
self.quoteSingleStyleO.setText(qtBox.selectedQuote)
|
||||
return
|
||||
|
||||
def _getSingleClose(self):
|
||||
"""Dialog for single quote close.
|
||||
"""
|
||||
qtBox = QuotesDialog(self, currentQuote=self.quoteSingleStyleC.text())
|
||||
if qtBox.exec_() == QDialog.Accepted:
|
||||
self.quoteSingleStyleC.setText(qtBox.selectedQuote)
|
||||
return
|
||||
|
||||
def _getDoubleOpen(self):
|
||||
"""Dialog for double quote open.
|
||||
"""
|
||||
qtBox = QuotesDialog(self, currentQuote=self.quoteDoubleStyleO.text())
|
||||
if qtBox.exec_() == QDialog.Accepted:
|
||||
self.quoteDoubleStyleO.setText(qtBox.selectedQuote)
|
||||
return
|
||||
|
||||
def _getDoubleClose(self):
|
||||
"""Dialog for double quote close.
|
||||
"""
|
||||
qtBox = QuotesDialog(self, currentQuote=self.quoteDoubleStyleC.text())
|
||||
if qtBox.exec_() == QDialog.Accepted:
|
||||
self.quoteDoubleStyleC.setText(qtBox.selectedQuote)
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
@@ -31,10 +31,9 @@ import nw
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
|
||||
QLabel, QWidget, QTabWidget, QDialogButtonBox, QListWidget, QPushButton,
|
||||
QListWidgetItem, QColorDialog, QAbstractItemView, QTreeWidget, QCheckBox,
|
||||
QTreeWidgetItem
|
||||
QHBoxLayout, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit, QLabel,
|
||||
QWidget, QDialogButtonBox, QListWidget, QPushButton, QListWidgetItem,
|
||||
QColorDialog, QAbstractItemView, QTreeWidget, QTreeWidgetItem
|
||||
)
|
||||
|
||||
from nw.constants import nwAlert
|
||||
@@ -73,8 +72,6 @@ class GuiProjectSettings(PagedDialog):
|
||||
self.buttonBox.rejected.connect(self._doClose)
|
||||
self.addControls(self.buttonBox)
|
||||
|
||||
self.show()
|
||||
|
||||
logger.debug("GuiProjectSettings initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
@@ -273,6 +273,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
|
||||
nwGUI.mainConf.backupPath = nwTempGUI
|
||||
|
||||
projEdit = GuiProjectSettings(nwGUI, nwGUI.theProject)
|
||||
projEdit.show()
|
||||
qtbot.addWidget(projEdit)
|
||||
|
||||
projEdit.tabMain.editName.setText("")
|
||||
|
||||
Reference in New Issue
Block a user