diff options
| -rw-r--r-- | Lib/defconQt/fontView.py | 203 | ||||
| -rw-r--r-- | Lib/defconQt/glyphView.py | 4 | ||||
| -rw-r--r-- | Lib/defconQt/metricsWindow.py (renamed from Lib/defconQt/spaceCenter.py) | 127 |
3 files changed, 214 insertions, 120 deletions
diff --git a/Lib/defconQt/fontView.py b/Lib/defconQt/fontView.py index b0cc7e9..523719f 100644 --- a/Lib/defconQt/fontView.py +++ b/Lib/defconQt/fontView.py @@ -1,3 +1,4 @@ +from defconQt import __version__ from defconQt.featureTextEditor import MainEditWindow from defconQt.fontInfo import TabDialog from defconQt.glyphCollectionView import GlyphCollectionWidget @@ -8,7 +9,7 @@ from defconQt.scriptingWindow import MainScriptingWindow from defconQt.objects.defcon import GlyphSet, TFont, TGlyph from defconQt.util import platformSpecific from defcon import Color, Component -from defconQt.spaceCenter import MainSpaceWindow, comboBoxItems +from defconQt.metricsWindow import MainMetricsWindow, comboBoxItems from PyQt5.QtCore import ( pyqtSignal, QEvent, QMimeData, QRegularExpression, QSettings, Qt) from PyQt5.QtGui import ( @@ -16,13 +17,14 @@ from PyQt5.QtGui import ( QRegularExpressionValidator, QTextCursor) from PyQt5.QtWidgets import ( QAbstractItemView, QAction, QApplication, QCheckBox, QComboBox, QDialog, - QDialogButtonBox, QErrorMessage, QFileDialog, QGridLayout, QGroupBox, - QLabel, QLineEdit, QListWidget, QListWidgetItem, QMainWindow, QMenu, - QMessageBox, QPlainTextEdit, QPushButton, QRadioButton, QSlider, QSplitter, - QTabWidget, QTextEdit, QToolTip, QVBoxLayout, QWidget) + QDialogButtonBox, QFileDialog, QGridLayout, QGroupBox, QLabel, QLineEdit, + QListWidget, QListWidgetItem, QMainWindow, QMenu, QMessageBox, + QPlainTextEdit, QPushButton, QRadioButton, QSlider, QSplitter, QTabWidget, + QTextEdit, QToolTip, QVBoxLayout, QWidget) from collections import OrderedDict import os import pickle +import platform import traceback cannedDesign = [ @@ -114,11 +116,11 @@ class Application(QApplication): MAX_RECENT_FILES = 6 -class InspectorWindow(QWidget): +class InfoPanel(QWidget): def __init__(self): - super(InspectorWindow, self).__init__(flags=Qt.Tool) - self.setWindowTitle("Inspector") + super().__init__(flags=Qt.Tool) + self.setWindowTitle("Info Panel") self._blocked = False self._glyph = None @@ -248,7 +250,8 @@ class InspectorWindow(QWidget): self.setLayout(mainLayout) def showEvent(self, event): - super(InspectorWindow, self).showEvent(event) + super().showEvent(event) + # TODO: does not put window on secondary screen if applicable screenRect = QApplication.desktop().screenGeometry() widgetRect = self.frameGeometry() x = screenRect.width() - (widgetRect.width() + 20) @@ -381,11 +384,11 @@ class InspectorWindow(QWidget): self._blocked = False -class AddGlyphDialog(QDialog): +class AddGlyphsDialog(QDialog): # TODO: implement Frederik's Glyph Construction Builder def __init__(self, currentGlyphs=None, parent=None): - super(AddGlyphDialog, self).__init__(parent) + super(AddGlyphsDialog, self).__init__(parent) self.setWindowModality(Qt.WindowModal) self.setWindowTitle("Add glyphs…") self.currentGlyphs = currentGlyphs @@ -398,8 +401,8 @@ class AddGlyphDialog(QDialog): for name, glyphNames in glyphSets.items(): self.importCharDrop.addItem(name, glyphNames) self.importCharDrop.currentIndexChanged[int].connect(self.importGlyphs) - self.addGlyphEdit = QPlainTextEdit(self) - self.addGlyphEdit.setFocus(True) + self.addGlyphsEdit = QPlainTextEdit(self) + self.addGlyphsEdit.setFocus(True) self.addUnicodeBox = QCheckBox("Add Unicode", self) self.addUnicodeBox.setChecked(True) @@ -415,7 +418,7 @@ class AddGlyphDialog(QDialog): l = 0 layout.addWidget(self.importCharDrop, l, 3, 1, 2) l += 1 - layout.addWidget(self.addGlyphEdit, l, 0, 1, 5) + layout.addWidget(self.addGlyphsEdit, l, 0, 1, 5) l += 1 layout.addWidget(self.addUnicodeBox, l, 0) layout.addWidget(self.addAsTemplateBox, l, 1) @@ -435,7 +438,7 @@ class AddGlyphDialog(QDialog): sortFont=dialog.sortFontBox.isChecked(), ) newGlyphNames = [] - for name in dialog.addGlyphEdit.toPlainText().split(): + for name in dialog.addGlyphsEdit.toPlainText().split(): if name not in dialog.currentGlyphNames: newGlyphNames.append(name) return (newGlyphNames, params, result) @@ -444,7 +447,7 @@ class AddGlyphDialog(QDialog): if index == 0: return glyphNames = self.importCharDrop.currentData() - editorNames = self.addGlyphEdit.toPlainText().split() + editorNames = self.addGlyphsEdit.toPlainText().split() currentNames = set(self.currentGlyphNames) ^ set(editorNames) changed = False for name in glyphNames: @@ -452,12 +455,12 @@ class AddGlyphDialog(QDialog): changed = True editorNames.append(name) if changed: - self.addGlyphEdit.setPlainText(" ".join(editorNames)) - cursor = self.addGlyphEdit.textCursor() + self.addGlyphsEdit.setPlainText(" ".join(editorNames)) + cursor = self.addGlyphsEdit.textCursor() cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) - self.addGlyphEdit.setTextCursor(cursor) + self.addGlyphsEdit.setTextCursor(cursor) self.importCharDrop.setCurrentIndex(0) - self.addGlyphEdit.setFocus(True) + self.addGlyphsEdit.setFocus(True) class SortDialog(QDialog): @@ -467,7 +470,7 @@ class SortDialog(QDialog): self.setWindowModality(Qt.WindowModal) self.setWindowTitle("Sort…") - self.smartSortBox = QRadioButton("Smart sort", self) + self.smartSortBox = QRadioButton("Optimized sort", self) self.smartSortBox.setToolTip("A combination of simple, complex and " "custom sorts that give optimized " "ordering results.") @@ -624,10 +627,16 @@ class MainWindow(QMainWindow): self.collectionWidget = GlyphCollectionWidget(self) self._font = None self._sortDescriptor = None - if font is None: - self.newFile(True) - else: + settings = QSettings() + loadRecentFile = settings.value("core/loadRecentFile", False, bool) + if font is None and loadRecentFile: + recentFiles = settings.value("core/recentFiles", [], type=str) + if len(recentFiles): + self.openFile(recentFiles[0], True) + elif font is not None: self.font = font + if self._font is None: + self.newFile(True) self.collectionWidget.glyphSelectedCallback = self._selectionChanged self.collectionWidget.doubleClickCallback = self._glyphOpened # TODO: should default be True or False? @@ -640,7 +649,7 @@ class MainWindow(QMainWindow): fileMenu.addAction("&New…", self.newFile, QKeySequence.New) fileMenu.addAction("&Open…", self.openFile, QKeySequence.Open) # recent files - self.recentFilesMenu = QMenu("Open &recent…", self) + self.recentFilesMenu = QMenu("Open &Recent…", self) for i in range(MAX_RECENT_FILES): action = QAction(self.recentFilesMenu) action.setVisible(False) @@ -650,14 +659,14 @@ class MainWindow(QMainWindow): fileMenu.addMenu(self.recentFilesMenu) fileMenu.addSeparator() fileMenu.addAction("&Save", self.saveFile, QKeySequence.Save) - fileMenu.addAction("Save &as…", self.saveFileAs, QKeySequence.SaveAs) + fileMenu.addAction("Save &As…", self.saveFileAs, QKeySequence.SaveAs) fileMenu.addAction("Export…", self.export) - fileMenu.addAction("Reload from disk", self.reload) + fileMenu.addAction("Reload From Disk", self.reload) fileMenu.addAction("E&xit", self.close, QKeySequence.Quit) menuBar.addMenu(fileMenu) editMenu = QMenu("&Edit", self) - markColorMenu = QMenu("Flag color", self) + markColorMenu = QMenu("Flag Color", self) pixmap = QPixmap(24, 24) none = markColorMenu.addAction("None", self.markColor) none.setData(None) @@ -675,7 +684,7 @@ class MainWindow(QMainWindow): green.setData(QColor(Qt.green)) editMenu.addMenu(markColorMenu) editMenu.addAction("Copy", self.copy, QKeySequence.Copy) - editMenu.addAction("Copy as component", + editMenu.addAction("Copy As Component", self.copyAsComponent, "Ctrl+Alt+C") editMenu.addAction("Paste", self.paste, QKeySequence.Paste) editMenu.addSeparator() @@ -685,23 +694,23 @@ class MainWindow(QMainWindow): fontMenu = QMenu("&Font", self) # TODO: work out sensible shortcuts and make sure they're # cross-platform ready - consider extracting them into separate file? - fontMenu.addAction("&Add glyph", self.addGlyph, "Ctrl+G") - fontMenu.addAction("Font &info", self.fontInfo, "Ctrl+Alt+I") - fontMenu.addAction("Font &features", self.fontFeatures, "Ctrl+Alt+F") + fontMenu.addAction("&Add Glyphs…", self.addGlyphs, "Ctrl+G") + fontMenu.addAction("Font &Info", self.fontInfo, "Ctrl+Alt+I") + fontMenu.addAction("Font &Features", self.fontFeatures, "Ctrl+Alt+F") fontMenu.addSeparator() - fontMenu.addAction("Sort…", self.sortGlyphs) + fontMenu.addAction("&Sort…", self.sortGlyphs) menuBar.addMenu(fontMenu) pythonMenu = QMenu("&Python", self) - pythonMenu.addAction("Scripting &window", self.scripting, "Ctrl+Alt+R") + pythonMenu.addAction("Scripting &Window", self.scripting, "Ctrl+Alt+R") menuBar.addMenu(pythonMenu) windowMenu = QMenu("&Windows", self) - action = windowMenu.addAction("&Inspector", self.inspector, "Ctrl+I") + action = windowMenu.addAction("&Info Panel", self.infoPanel, "Ctrl+I") # XXX: we're getting duplicate shortcut when we spawn a new window... action.setShortcutContext(Qt.ApplicationShortcut) - windowMenu.addAction("&Space center", self.spaceCenter, "Ctrl+Alt+S") - windowMenu.addAction("&Groups window", self.fontGroups, "Ctrl+Alt+G") + windowMenu.addAction("&Metrics Window", self.metrics, "Ctrl+Alt+S") + windowMenu.addAction("&Groups Window", self.groups, "Ctrl+Alt+G") menuBar.addMenu(windowMenu) helpMenu = QMenu("&Help", self) @@ -753,7 +762,7 @@ class MainWindow(QMainWindow): else: self.font = font - def openFile(self, path=None): + def openFile(self, path=None, stickToSelf=False): if not path: path, ok = QFileDialog.getOpenFileName( self, "Open File", '', @@ -765,7 +774,7 @@ class MainWindow(QMainWindow): if ".plist" in path: path = os.path.dirname(path) for window in QApplication.topLevelWidgets(): - if (isinstance(window, MainWindow) + if (isinstance(window, MainWindow) and window._font is not None and window._font.path == path): window.raise_() return @@ -774,8 +783,11 @@ class MainWindow(QMainWindow): except: print(traceback.format_exc()) return - window = MainWindow(font) - window.show() + if not stickToSelf: + window = MainWindow(font) + window.show() + else: + self.font = font def openRecentFont(self): fontPath = self.sender().toolTip() @@ -822,12 +834,12 @@ class MainWindow(QMainWindow): try: from ufo2fdk import haveFDK, OTFCompiler except Exception as e: - errorMessage = QErrorMessage(self) - errorMessage.showMessage(e) + title = e.__class__.__name__ + QMessageBox.critical(self, title, str(e)) return if not haveFDK(): - errorMessage = QErrorMessage(self) - errorMessage.showMessage("The Adobe FDK could not be found.") + QMessageBox.critical(self, "Missing dependency", "The Adobe FDK " + "could not be found.") return path, ok = QFileDialog.getSaveFileName(self, "Save File", None, @@ -1095,32 +1107,31 @@ class MainWindow(QMainWindow): else: self.fontFeaturesWindow.raise_() - def spaceCenter(self): + def metrics(self): # TODO: see up here - # TODO: show selection in a space center, rewind selection if we raise - # window (rf) - if not (hasattr(self, 'spaceCenterWindow') - and self.spaceCenterWindow.isVisible()): - self.spaceCenterWindow = MainSpaceWindow(self.font, parent=self) - self.spaceCenterWindow.show() + if not (hasattr(self, 'metricsWindow') + and self.metricsWindow.isVisible()): + self.metricsWindow = MainMetricsWindow(self.font, parent=self) + self.metricsWindow.show() else: - self.spaceCenterWindow.raise_() + self.metricsWindow.raise_() + # TODO: decouple selection = self.collectionWidget.selection if selection: glyphs = [] for item in sorted(selection): glyph = self.collectionWidget.glyphs[item] glyphs.append(glyph) - self.spaceCenterWindow.setGlyphs(glyphs) + self.metricsWindow.setGlyphs(glyphs) - def fontGroups(self): + def groups(self): # TODO: see up here - if not (hasattr(self, 'fontGroupsWindow') - and self.fontGroupsWindow.isVisible()): - self.fontGroupsWindow = GroupsWindow(self.font, self) - self.fontGroupsWindow.show() + if not (hasattr(self, 'groupsWindow') + and self.groupsWindow.isVisible()): + self.groupsWindow = GroupsWindow(self.font, self) + self.groupsWindow.show() else: - self.fontGroupsWindow.raise_() + self.groupsWindow.raise_() def scripting(self): app = QApplication.instance() @@ -1132,18 +1143,18 @@ class MainWindow(QMainWindow): else: app.scriptingWindow.show() - def inspector(self): + def infoPanel(self): app = QApplication.instance() - if not hasattr(app, 'inspectorWindow'): - app.inspectorWindow = InspectorWindow() - app.inspectorWindow.show() - elif app.inspectorWindow.isVisible(): + if not hasattr(app, 'infoPanelWindow'): + app.infoPanelWindow = InfoPanel() + app.infoPanelWindow.show() + elif app.infoPanelWindow.isVisible(): # TODO: do this only if the widget is user-visible, otherwise the # key press feels as if it did nothing # toggle - app.inspectorWindow.close() + app.infoPanelWindow.close() else: - app.inspectorWindow.show() + app.infoPanelWindow.show() def sortGlyphs(self): sortDescriptor, ok = SortDialog.getDescriptor(self, @@ -1151,9 +1162,9 @@ class MainWindow(QMainWindow): if ok: self.sortDescriptor = sortDescriptor - def addGlyph(self): + def addGlyphs(self): glyphs = self.collectionWidget.glyphs - newGlyphNames, params, ok = AddGlyphDialog.getNewGlyphNames( + newGlyphNames, params, ok = AddGlyphsDialog.getNewGlyphNames( self, glyphs) if ok: sortFont = params.pop("sortFont") @@ -1171,12 +1182,19 @@ class MainWindow(QMainWindow): def about(self): name = QApplication.applicationName() - QMessageBox.about( - self, "About {}".format(name), - "<h3>About {}</h3>" - "<p>I am a new UFO-centric font editor and I aim to bring " - "the <b>robofab</b> ecosystem to all main operating systems, " - "in a fast and dependency-free package.</p>".format(name)) + domain = QApplication.organizationDomain() + text = "<h3>About {}</h3>" \ + "<p>I am a new UFO-centric font editor and I aim to bring " \ + "the <b>robofab</b> ecosystem to all main operating systems, " \ + "in a fast and dependency-free package.</p>" \ + "<p>Version {} – Python {}.".format( + name, __version__, platform.python_version()) + if domain: + text += "<br>See <a href='http://{d}'>{d}</a> for more " \ + "information.</p>".format(d=domain) + else: + text += "</p>" + QMessageBox.about(self, "About {}".format(name), text) class SettingsDialog(QDialog): @@ -1188,7 +1206,8 @@ class SettingsDialog(QDialog): self.tabWidget = QTabWidget(self) self.tabWidget.addTab(GlyphSetTab(self), "Glyph sets") - self.tabWidget.addTab(SpaceCenterTab(self), "Space center") + self.tabWidget.addTab(MetricsWindowTab(self), "Metrics Window") + self.tabWidget.addTab(MiscTab(self), "Misc") buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) @@ -1232,7 +1251,7 @@ def readGlyphSets(settings=None): class GlyphSetTab(QWidget): def __init__(self, parent=None): - super(GlyphSetTab, self).__init__(parent) + super().__init__(parent) settings = QSettings() self.defaultGlyphSetBox = QCheckBox("Default glyph set:", self) @@ -1366,16 +1385,16 @@ class GlyphSetTab(QWidget): settings.setValue("settings/defaultGlyphSet", defaultGlyphSet) -class SpaceCenterTab(QTabWidget): +class MetricsWindowTab(QTabWidget): def __init__(self, parent=None): - super(SpaceCenterTab, self).__init__(parent) + super().__init__(parent) settings = QSettings() self.inputTextLabel = QLabel("Default text:", self) self.inputTextList = QListWidget(self) self.inputTextList.setDragDropMode(QAbstractItemView.InternalMove) - entries = settings.value("spaceCenter/comboBoxItems", comboBoxItems, + entries = settings.value("metricsWindow/comboBoxItems", comboBoxItems, str) for entry in entries: item = QListWidgetItem(entry, self.inputTextList) @@ -1414,4 +1433,26 @@ class SpaceCenterTab(QTabWidget): item = self.inputTextList.item(i) entries.append(item.text()) settings = QSettings() - settings.setValue("spaceCenter/comboBoxItems", entries) + settings.setValue("metricsWindow/comboBoxItems", entries) + + +class MiscTab(QTabWidget): + + def __init__(self, parent=None): + super().__init__(parent) + + settings = QSettings() + loadRecentFile = settings.value("core/loadRecentFile", False, bool) + self.loadRecentFileBox = QCheckBox("Load most recent file on start", + self) + self.loadRecentFileBox.setChecked(loadRecentFile) + + layout = QVBoxLayout(self) + l = 0 + layout.addWidget(self.loadRecentFileBox, l) + self.setLayout(layout) + + def writeValues(self): + settings = QSettings() + loadRecentFile = self.loadRecentFileBox.isChecked() + settings.setValue("core/loadRecentFile", loadRecentFile) diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py index 87232c3..c9b483a 100644 --- a/Lib/defconQt/glyphView.py +++ b/Lib/defconQt/glyphView.py @@ -181,7 +181,7 @@ class AddLayerDialog(QDialog): layout.addWidget(layerNameLabel, l, 0) layout.addWidget(self.layerNameEdit, l, 1) l += 1 - layout.addWidget(buttonBox, l, 2) + layout.addWidget(buttonBox, l, 0, 1, 2) self.setLayout(layout) @classmethod @@ -302,7 +302,7 @@ class MainGfxWindow(QMainWindow): menuBar.addMenu(fileMenu) glyphMenu = QMenu("&Glyph", self) - glyphMenu.addAction("&Jump", self.changeGlyph, "J") + glyphMenu.addAction("&Go to…", self.changeGlyph, "G") menuBar.addMenu(glyphMenu) self._displaySettings = DisplayStyleSettings( diff --git a/Lib/defconQt/spaceCenter.py b/Lib/defconQt/metricsWindow.py index e360653..27689ab 100644 --- a/Lib/defconQt/spaceCenter.py +++ b/Lib/defconQt/metricsWindow.py @@ -1,6 +1,7 @@ from defconQt import icons_db # noqa -from defconQt.glyphCollectionView import cellSelectionColor +from defconQt.glyphCollectionView import arrowKeys, cellSelectionColor from defconQt.glyphView import MainGfxWindow +from defconQt.objects.defcon import TGlyph from getpass import getuser from PyQt5.QtCore import QEvent, QSettings, QSize, Qt from PyQt5.QtGui import ( @@ -10,6 +11,7 @@ from PyQt5.QtWidgets import ( QAbstractItemView, QActionGroup, QApplication, QComboBox, QLineEdit, QMenu, QPushButton, QScrollArea, QStyledItemDelegate, QTableWidget, QTableWidgetItem, QVBoxLayout, QSizePolicy, QToolBar, QWidget) +import re comboBoxItems = [ "abcdefghijklmnopqrstuvwxyz", @@ -23,12 +25,19 @@ defaultPointSize = 150 glyphSelectionColor = QColor(cellSelectionColor) glyphSelectionColor.setAlphaF(.09) +escapeRep = { + "//": "/slash ", + "\\n": "\u2029", +} +escapeRep = dict((re.escape(k), v) for k, v in escapeRep.items()) +escapeRe = re.compile("|".join(escapeRep.keys())) -class MainSpaceWindow(QWidget): + +class MainMetricsWindow(QWidget): def __init__(self, font, string=None, pointSize=defaultPointSize, parent=None): - super(MainSpaceWindow, self).__init__(parent, Qt.Window) + super().__init__(parent, Qt.Window) if string is None: try: @@ -65,7 +74,7 @@ class MainSpaceWindow(QWidget): self.font.info.addObserver(self, "_fontInfoChanged", "Info.Changed") - self.setWindowTitle("Space center – %s %s" % ( + self.setWindowTitle("Metrics Window – %s %s" % ( self.font.info.familyName, self.font.info.styleName)) def setupFileMenu(self): @@ -77,41 +86,45 @@ class MainSpaceWindow(QWidget): def close(self): self.font.info.removeObserver(self, "Info.Changed") self._unsubscribeFromGlyphs() - super(MainSpaceWindow, self).close() + super().close() def _fontInfoChanged(self, notification): self.canvas.fetchFontMetrics() self.canvas.update() def _glyphChanged(self, notification): - self.canvas.update() - self.table.updateCells() + if not self.canvas._editing: + self.canvas.update() + if not self.table._editing: + self.table.updateCells(self.canvas._editing) def _glyphOpened(self, glyph): glyphViewWindow = MainGfxWindow(glyph, self.parent()) glyphViewWindow.show() def _textChanged(self): + def fetchGlyphs(glyphNames, leftGlyphs=[], rightGlyphs=[]): + ret = [] + for name in glyphNames: + if name == "\u2029": + glyph = TGlyph() + glyph.unicode = 2029 + ret.append(glyph) + elif name in self.font: + ret.extend(leftGlyphs) + ret.append(self.font[name]) + ret.extend(rightGlyphs) + return ret + # unsubscribe from the old glyphs self._unsubscribeFromGlyphs() # subscribe to the new glyphs left = self.textToGlyphNames(self.toolbar.leftTextField.text()) newText = self.textToGlyphNames(self.toolbar.textField.currentText()) right = self.textToGlyphNames(self.toolbar.rightTextField.text()) - leftGlyphs = [] - for name in left: - if name in self.font: - leftGlyphs.append(self.font[name]) - rightGlyphs = [] - for name in right: - if name in self.font: - rightGlyphs.append(self.font[name]) - finalGlyphs = [] - for name in newText: - if name in self.font: - finalGlyphs.extend(leftGlyphs) - finalGlyphs.append(self.font[name]) - finalGlyphs.extend(rightGlyphs) + leftGlyphs = fetchGlyphs(left) + rightGlyphs = fetchGlyphs(right) + finalGlyphs = fetchGlyphs(newText, leftGlyphs, rightGlyphs) self._subscribeToGlyphs(finalGlyphs) # set the records into the view self.canvas.setGlyphs(self.glyphs) @@ -128,8 +141,8 @@ class MainSpaceWindow(QWidget): glyphNames.append("".join(compileStack)) app = QApplication.instance() - # escape // - text = text.replace("//", "/slash ") + # escape //, \n + text = escapeRe.sub(lambda m: escapeRep[re.escape(m.group(0))], text) # glyphNames = [] compileStack = None @@ -157,7 +170,11 @@ class MainSpaceWindow(QWidget): compileStack.append(c) # adding a character that needs to be converted to a glyph name. else: - glyphName = self.font.unicodeData.glyphNameForUnicode(ord(c)) + uni = ord(c) + if uni == 0x2029: + glyphName = c + else: + glyphName = self.font.unicodeData.glyphNameForUnicode(uni) glyphNames.append(glyphName) # catch remaining compile. if compileStack is not None and compileStack: @@ -217,7 +234,7 @@ class FontToolBar(QToolBar): # XXX: had to use Maximum because Preferred did entend the widget(?) self.textField.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) - items = QSettings().value("spaceCenter/comboBoxItems", comboBoxItems, + items = QSettings().value("metricsWindow/comboBoxItems", comboBoxItems, str) self.textField.addItems(items) self.rightTextField = QLineEdit(self) @@ -314,6 +331,9 @@ class GlyphsCanvas(QWidget): def __init__(self, font, pointSize=defaultPointSize, parent=None): super(GlyphsCanvas, self).__init__(parent) + self.setAttribute(Qt.WA_KeyCompression) + # TODO: should we take focus by tabbing + self.setFocusPolicy(Qt.ClickFocus) # XXX: make canvas font-agnostic as in defconAppkit and use # glyph.getParent() instead self.font = font @@ -322,6 +342,7 @@ class GlyphsCanvas(QWidget): self.ptSize = pointSize self.calculateScale() self.padding = 10 + self._editing = False self._showKerning = False self._showMetrics = False self._verticalFlip = False @@ -487,10 +508,36 @@ class GlyphsCanvas(QWidget): return kerning[pair] return 0 + def _arrowKeyPressEvent(self, event): + key = event.key() + modifiers = event.modifiers() + self._editing = True + if self._selected is not None: + glyph = self.glyphs[self._selected] + # TODO: not really DRY w other widgets + delta = event.count() + if modifiers & Qt.ShiftModifier: + delta *= 10 + if modifiers & Qt.ControlModifier: + delta *= 10 + if key == Qt.Key_Left: + delta = -delta + if modifiers & Qt.AltModifier: + if glyph.leftMargin is not None: + glyph.leftMargin += delta + else: + glyph.width += delta + self._editing = False + event.accept() + + def keyPressEvent(self, event): + key = event.key() + if key in arrowKeys: + self._arrowKeyPressEvent(event) + else: + super().keyPressEvent(event) + def mousePressEvent(self, event): - # Take focus to quit eventual cell editing - # XXX: shouldnt set focus if we are in input field... - self.setFocus(Qt.MouseFocusReason) if event.button() == Qt.LeftButton: # XXX: investigate, baselineShift is unused # if self._verticalFlip: @@ -527,6 +574,10 @@ class GlyphsCanvas(QWidget): self.selectionChangedCallback(self._selected) event.accept() self.update() + # restore focus to ourselves, the table widget did take it when we + # sent notification + # TODO: maybe not set focus on notifiee instead + self.setFocus(Qt.MouseFocusReason) else: super(GlyphsCanvas, self).mousePressEvent(event) @@ -578,9 +629,8 @@ class GlyphsCanvas(QWidget): self.glyphs[index - 1].name, glyph.name) * self.scale else: kern = 0 - if (self._wrapLines and - cur_width + gWidth + kern + 2 * self.padding > - self.width()): + if (self._wrapLines and cur_width + gWidth + kern + + 2 * self.padding > self.width()) or glyph.unicode == 2029: painter.translate(-cur_width, self.ptSize * self._lineHeight) if self._showMetrics: paintLineMarks(painter) @@ -688,6 +738,7 @@ class SpaceTable(QTableWidget): self.setColumnWidth(0, self._cellWidth) self.horizontalHeader().hide() self.verticalHeader().hide() + self._coloredColumn = None # always show a scrollbar to fix layout self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) @@ -703,20 +754,21 @@ class SpaceTable(QTableWidget): self.setEditTriggers(QAbstractItemView.CurrentChanged) self._editing = False self.selectionChangedCallback = None - self._coloredColumn = None def setGlyphs(self, newGlyphs): self.glyphs = newGlyphs # TODO: we don't need to reallocate cells, split alloc and fill self.updateCells() - def updateCells(self): + def updateCells(self, keepColor=False): self.blockSignals(True) - if self._editing: - coloredColumn = self._coloredColumn + self.setEditTriggers(QAbstractItemView.NoEditTriggers) + coloredColumn = self._coloredColumn self.fillGlyphs() - if self._editing: - self._coloredColumn = coloredColumn + if keepColor and coloredColumn is not None and \ + coloredColumn < self.columnCount(): + self.colorColumn(coloredColumn) + self.setEditTriggers(QAbstractItemView.CurrentChanged) self.blockSignals(False) def _cellEdited(self, row, col): @@ -808,6 +860,7 @@ class SpaceTable(QTableWidget): # item.setTextAlignment(Qt.AlignCenter) return item + self._coloredColumn = None self.setColumnCount(len(self.glyphs) + 1) for index, glyph in enumerate(self.glyphs): # TODO: see about allowing glyph name edit here |
