Add syntax highlighting and dynamic previewing
This commit is contained in:
parent
6354752eab
commit
b9666a7503
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@ -0,0 +1,17 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{html,js,json,py,yaml,yml}]
|
||||
indent_style = space
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
max_line_length = 120
|
||||
|
||||
[*.{html,js,json,yaml,yml}]
|
||||
indent_size = 2
|
18
setup.cfg
Normal file
18
setup.cfg
Normal file
@ -0,0 +1,18 @@
|
||||
[pep8]
|
||||
exclude=resources.py,vlc.py
|
||||
max-line-length = 120
|
||||
ignore = E402,E722,W503,W504
|
||||
|
||||
[flake8]
|
||||
exclude=resources.py,vlc.py
|
||||
max-line-length = 120
|
||||
ignore = E402,W503,W504
|
||||
|
||||
[pycodestyle]
|
||||
exclude = resources.py,vlc.py
|
||||
max-line-length = 120
|
||||
# Ignoring:
|
||||
# E402 module level import not at top of file
|
||||
# W503 line break before binary operator
|
||||
# W504 line break after binary operator
|
||||
ignore = E402,W503,W504
|
168
src/ukatali/lexer.py
Normal file
168
src/ukatali/lexer.py
Normal file
@ -0,0 +1,168 @@
|
||||
import re
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, Qsci
|
||||
from chordpro.constants import KNOWN_DIRECTIVES, KNOWN_VERSE_TYPES
|
||||
|
||||
PALETTE_ROLES = {
|
||||
'window': QtGui.QPalette.WindowText,
|
||||
'background': QtGui.QPalette.Background,
|
||||
'windowtext': QtGui.QPalette.WindowText,
|
||||
'foreground': QtGui.QPalette.Foreground,
|
||||
'base': QtGui.QPalette.Base,
|
||||
'alternatebase': QtGui.QPalette.AlternateBase,
|
||||
'tooltipbase': QtGui.QPalette.ToolTipBase,
|
||||
'tooltiptext': QtGui.QPalette.ToolTipText,
|
||||
'placeholderText': QtGui.QPalette.PlaceholderText,
|
||||
'text': QtGui.QPalette.Text,
|
||||
'button': QtGui.QPalette.Button,
|
||||
'buttontext': QtGui.QPalette.ButtonText,
|
||||
'brighttext': QtGui.QPalette.BrightText,
|
||||
'light': QtGui.QPalette.Light,
|
||||
'midlight': QtGui.QPalette.Midlight,
|
||||
'dark': QtGui.QPalette.Dark,
|
||||
'mid': QtGui.QPalette.Mid,
|
||||
'shadow': QtGui.QPalette.Shadow,
|
||||
'highlight': QtGui.QPalette.Highlight,
|
||||
'highlightedtext': QtGui.QPalette.HighlightedText,
|
||||
'link': QtGui.QPalette.Link,
|
||||
'linkvisited': QtGui.QPalette.LinkVisited
|
||||
}
|
||||
|
||||
|
||||
class ChordProStyle(object):
|
||||
Default = 0
|
||||
Keyword = 1
|
||||
Identifier = 2
|
||||
Chord = 3
|
||||
|
||||
@staticmethod
|
||||
def to_string(style):
|
||||
"""Return the name for the style"""
|
||||
return {
|
||||
ChordProStyle.Default: 'Default',
|
||||
ChordProStyle.Keyword: 'Keyword',
|
||||
ChordProStyle.Identifier: 'Identifier',
|
||||
ChordProStyle.Chord: 'Chord'
|
||||
}.get(style)
|
||||
|
||||
|
||||
class ChordProLexer(Qsci.QsciLexerCustom):
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.settings = QtCore.QSettings()
|
||||
self.settings.beginGroup('syntax')
|
||||
self.init_style()
|
||||
|
||||
def _get_color(self, name, default):
|
||||
"""Get a QColor object from the settings"""
|
||||
color = self.settings.value(name, default)
|
||||
if isinstance(color, str):
|
||||
if color.startswith('palette:'):
|
||||
palette_role = PALETTE_ROLES[color.split(':', 1)[1].lower()]
|
||||
color = QtWidgets.QApplication.palette().color(palette_role)
|
||||
else:
|
||||
color = QtGui.QColor(color)
|
||||
return color
|
||||
|
||||
def _get_font(self, name):
|
||||
"""Get a QFont object from the settings"""
|
||||
font = self.settings.value(name, None)
|
||||
if not font:
|
||||
font = QtGui.QFont('monospace')
|
||||
elif isinstance(font, str):
|
||||
font = QtGui.QFont.fromString(font)
|
||||
return font
|
||||
|
||||
def init_style(self):
|
||||
"""Set up the colours and fonts"""
|
||||
# Defaults
|
||||
self.setDefaultColor(self._get_color('default-foreground', 'palette:windowtext'))
|
||||
self.setDefaultPaper(self._get_color('default-background', 'palette:base'))
|
||||
self.setDefaultFont(self._get_font('default-font'))
|
||||
self.setColor(self._get_color('default-foreground', 'palette:windowtext'),
|
||||
ChordProStyle.Default)
|
||||
self.setPaper(self._get_color('default-background', 'palette:base'),
|
||||
ChordProStyle.Default)
|
||||
self.setFont(self._get_font('default-font'), ChordProStyle.Default)
|
||||
# Keywords
|
||||
kwfg = self._get_color('keywords-foreground', '#009fe3')
|
||||
if kwfg:
|
||||
self.setColor(kwfg, ChordProStyle.Keyword)
|
||||
kwbg = self._get_color('keywords-background', None)
|
||||
if kwbg:
|
||||
self.setPaper(kwbg, ChordProStyle.Keyword)
|
||||
kwft = self._get_font('keywords-font')
|
||||
if kwft:
|
||||
self.setFont(kwft, ChordProStyle.Keyword)
|
||||
# Identifiers
|
||||
idfg = self._get_color('identifiers-foreground', '#fdadff')
|
||||
if idfg:
|
||||
self.setColor(idfg, ChordProStyle.Identifier)
|
||||
idbg = self._get_color('identifiers-background', None)
|
||||
if idbg:
|
||||
self.setPaper(idbg, ChordProStyle.Identifier)
|
||||
idft = self._get_font('identifiers-font')
|
||||
if idft:
|
||||
self.setFont(idft, ChordProStyle.Identifier)
|
||||
# Chords
|
||||
chfg = self._get_color('chords-foreground', '#73ff6c')
|
||||
if chfg:
|
||||
self.setColor(chfg, ChordProStyle.Chord)
|
||||
chbg = self._get_color('chords-background', None)
|
||||
if chbg:
|
||||
self.setPaper(chbg, ChordProStyle.Chord)
|
||||
chft = self._get_font('chords-font')
|
||||
if chft:
|
||||
self.setFont(chft, ChordProStyle.Chord)
|
||||
|
||||
def language(self):
|
||||
"""Return the language name"""
|
||||
return "ChordPro"
|
||||
|
||||
def description(self, style):
|
||||
"""Return the name for the style number"""
|
||||
return ChordProStyle.to_string(style)
|
||||
|
||||
def styleText(self, start, end):
|
||||
"""Style the text"""
|
||||
|
||||
keywords = ['chorus'] + \
|
||||
[d for t in KNOWN_DIRECTIVES for d in t] + \
|
||||
['start_of_' + vt for vt in KNOWN_VERSE_TYPES] + \
|
||||
['end_of_' + vt for vt in KNOWN_VERSE_TYPES]
|
||||
is_directive = False
|
||||
is_identifier = False
|
||||
is_chord = False
|
||||
pattern = re.compile(r'\s+|\w+|\W')
|
||||
|
||||
self.startStyling(start)
|
||||
text = self.parent().text()[start:end]
|
||||
|
||||
token_list = [(token, len(bytearray(token, "utf-8"))) for token in pattern.findall(text)]
|
||||
|
||||
for idx, token in enumerate(token_list):
|
||||
if token[0] == '{':
|
||||
is_directive = True
|
||||
self.setStyling(token[1], ChordProStyle.Keyword)
|
||||
elif is_directive and token[0] in keywords:
|
||||
self.setStyling(token[1], ChordProStyle.Keyword)
|
||||
elif is_directive and token[0] == ':':
|
||||
is_identifier = True
|
||||
self.setStyling(token[1], ChordProStyle.Keyword)
|
||||
elif is_directive and token[0] == '}':
|
||||
is_directive = False
|
||||
is_identifier = False
|
||||
self.setStyling(token[1], ChordProStyle.Keyword)
|
||||
elif is_identifier:
|
||||
self.setStyling(token[1], ChordProStyle.Identifier)
|
||||
elif token[0] == '[':
|
||||
is_chord = True
|
||||
self.setStyling(token[1], ChordProStyle.Chord)
|
||||
elif is_chord and token[0] == ']':
|
||||
is_chord = False
|
||||
self.setStyling(token[1], ChordProStyle.Chord)
|
||||
elif is_chord:
|
||||
self.setStyling(token[1], ChordProStyle.Chord)
|
||||
else:
|
||||
self.setStyling(token[1], ChordProStyle.Default)
|
@ -2,219 +2,227 @@
|
||||
from pathlib import Path
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets, Qsci
|
||||
|
||||
OPEN_COUNT = 0
|
||||
from chordpro import Song
|
||||
from chordpro.renderers.html import render
|
||||
from ukatali.lexer import ChordProLexer
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setup_ui()
|
||||
self.filename = None
|
||||
|
||||
def setup_ui(self):
|
||||
self.setObjectName("MainWindow")
|
||||
self.setObjectName('MainWindow')
|
||||
self.resize(800, 600)
|
||||
self.editorWidget = QtWidgets.QWidget(self)
|
||||
self.editorWidget.setObjectName("editorWidget")
|
||||
self.editorLayout = QtWidgets.QVBoxLayout(self.editorWidget)
|
||||
self.editorLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.editorLayout.setSpacing(0)
|
||||
self.editorLayout.setObjectName("editorLayout")
|
||||
self.fileEditor = Qsci.QsciScintilla(self.editorWidget)
|
||||
self.fileEditor.setFont(QtGui.QFont("monospace"))
|
||||
self.fileEditor.setColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.fileEditor.setCaretWidth(2)
|
||||
self.fileEditor.setCaretForegroundColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.fileEditor.setMarginsBackgroundColor(QtWidgets.QApplication.palette().window().color())
|
||||
self.fileEditor.setMarginsForegroundColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.fileEditor.setMarginLineNumbers(1, True)
|
||||
self.fileEditor.setMarginWidth(1, "000")
|
||||
self.fileEditor.setObjectName("fileEditor")
|
||||
self.editorLayout.addWidget(self.fileEditor)
|
||||
self.setCentralWidget(self.editorWidget)
|
||||
self.editor_widget = QtWidgets.QWidget(self)
|
||||
self.editor_widget.setObjectName('editor_widget')
|
||||
self.editor_layout = QtWidgets.QVBoxLayout(self.editor_widget)
|
||||
self.editor_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.editor_layout.setSpacing(0)
|
||||
self.editor_layout.setObjectName('editor_layout')
|
||||
self.file_editor = Qsci.QsciScintilla(self.editor_widget)
|
||||
self.file_editor.setFont(QtGui.QFont('monospace'))
|
||||
self.file_editor.setColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.file_editor.setCaretWidth(2)
|
||||
self.file_editor.setCaretForegroundColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.file_editor.setMarginsBackgroundColor(QtWidgets.QApplication.palette().window().color())
|
||||
self.file_editor.setMarginsForegroundColor(QtWidgets.QApplication.palette().windowText().color())
|
||||
self.file_editor.setMarginLineNumbers(1, True)
|
||||
self.file_editor.setMarginWidth(1, '000')
|
||||
self.file_editor.setObjectName('file_editor')
|
||||
self.chordpro_lexer = ChordProLexer(self.file_editor)
|
||||
self.file_editor.setLexer(self.chordpro_lexer)
|
||||
self.editor_layout.addWidget(self.file_editor)
|
||||
self.setCentralWidget(self.editor_widget)
|
||||
self.menubar = QtWidgets.QMenuBar(self)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 28))
|
||||
self.menubar.setObjectName("menubar")
|
||||
self.fileMenu = QtWidgets.QMenu(self.menubar)
|
||||
self.fileMenu.setObjectName("fileMenu")
|
||||
self.editMenu = QtWidgets.QMenu(self.menubar)
|
||||
self.editMenu.setObjectName("editMenu")
|
||||
self.settingsMenu = QtWidgets.QMenu(self.menubar)
|
||||
self.settingsMenu.setObjectName("settingsMenu")
|
||||
self.helpMenu = QtWidgets.QMenu(self.menubar)
|
||||
self.helpMenu.setObjectName("helpMenu")
|
||||
self.menubar.setObjectName('menubar')
|
||||
self.file_menu = QtWidgets.QMenu(self.menubar)
|
||||
self.file_menu.setObjectName('file_menu')
|
||||
self.edit_menu = QtWidgets.QMenu(self.menubar)
|
||||
self.edit_menu.setObjectName('edit_menu')
|
||||
self.settings_menu = QtWidgets.QMenu(self.menubar)
|
||||
self.settings_menu.setObjectName('settings_menu')
|
||||
self.help_menu = QtWidgets.QMenu(self.menubar)
|
||||
self.help_menu.setObjectName('help_menu')
|
||||
self.setMenuBar(self.menubar)
|
||||
self.statusbar = QtWidgets.QStatusBar(self)
|
||||
self.statusbar.setObjectName("statusbar")
|
||||
self.statusbar.setObjectName('statusbar')
|
||||
self.setStatusBar(self.statusbar)
|
||||
self.previewDock = QtWidgets.QDockWidget(self)
|
||||
self.previewDock.setObjectName("previewDock")
|
||||
self.previewDockContents = QtWidgets.QWidget()
|
||||
self.previewDockContents.setObjectName("previewDockContents")
|
||||
self.previewLayout = QtWidgets.QVBoxLayout(self.previewDockContents)
|
||||
self.previewLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.previewLayout.setSpacing(0)
|
||||
self.previewLayout.setObjectName("previewLayout")
|
||||
self.previewView = QtWebEngineWidgets.QWebEngineView(self.previewDockContents)
|
||||
self.previewView.setUrl(QtCore.QUrl("about:blank"))
|
||||
self.previewView.setObjectName("previewView")
|
||||
self.previewLayout.addWidget(self.previewView)
|
||||
self.previewDock.setWidget(self.previewDockContents)
|
||||
self.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.previewDock)
|
||||
self.toolBar = QtWidgets.QToolBar(self)
|
||||
self.toolBar.setObjectName("toolBar")
|
||||
self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
|
||||
self.newAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-new")
|
||||
self.newAction.setIcon(icon)
|
||||
self.newAction.setObjectName("newAction")
|
||||
self.openAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-open")
|
||||
self.openAction.setIcon(icon)
|
||||
self.openAction.setObjectName("openAction")
|
||||
self.saveAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-save")
|
||||
self.saveAction.setIcon(icon)
|
||||
self.saveAction.setObjectName("saveAction")
|
||||
self.saveAsAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-save-as")
|
||||
self.saveAsAction.setIcon(icon)
|
||||
self.saveAsAction.setObjectName("saveAsAction")
|
||||
self.printAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-print")
|
||||
self.printAction.setIcon(icon)
|
||||
self.printAction.setObjectName("printAction")
|
||||
self.exportAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("document-export")
|
||||
self.exportAction.setIcon(icon)
|
||||
self.exportAction.setObjectName("exportAction")
|
||||
self.undoAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("edit-undo")
|
||||
self.undoAction.setIcon(icon)
|
||||
self.undoAction.setObjectName("undoAction")
|
||||
self.redoAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("edit-redo")
|
||||
self.redoAction.setIcon(icon)
|
||||
self.redoAction.setObjectName("redoAction")
|
||||
self.cutAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("edit-cut")
|
||||
self.cutAction.setIcon(icon)
|
||||
self.cutAction.setObjectName("cutAction")
|
||||
self.copyAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("edit-copy")
|
||||
self.copyAction.setIcon(icon)
|
||||
self.copyAction.setObjectName("copyAction")
|
||||
self.pasteAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("edit-paste")
|
||||
self.pasteAction.setIcon(icon)
|
||||
self.pasteAction.setObjectName("pasteAction")
|
||||
self.configureAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("configure")
|
||||
self.configureAction.setIcon(icon)
|
||||
self.configureAction.setObjectName("configureAction")
|
||||
self.aboutAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("help-about")
|
||||
self.aboutAction.setIcon(icon)
|
||||
self.aboutAction.setObjectName("aboutAction")
|
||||
self.exitAction = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme("application-exit")
|
||||
self.exitAction.setIcon(icon)
|
||||
self.exitAction.setObjectName("exitAction")
|
||||
self.fileMenu.addAction(self.newAction)
|
||||
self.fileMenu.addAction(self.openAction)
|
||||
self.fileMenu.addAction(self.saveAction)
|
||||
self.fileMenu.addAction(self.saveAsAction)
|
||||
self.fileMenu.addSeparator()
|
||||
self.fileMenu.addAction(self.exportAction)
|
||||
self.fileMenu.addAction(self.printAction)
|
||||
self.fileMenu.addSeparator()
|
||||
self.fileMenu.addAction(self.exitAction)
|
||||
self.editMenu.addAction(self.undoAction)
|
||||
self.editMenu.addAction(self.redoAction)
|
||||
self.editMenu.addSeparator()
|
||||
self.editMenu.addAction(self.cutAction)
|
||||
self.editMenu.addAction(self.copyAction)
|
||||
self.editMenu.addAction(self.pasteAction)
|
||||
self.settingsMenu.addAction(self.configureAction)
|
||||
self.helpMenu.addAction(self.aboutAction)
|
||||
self.menubar.addAction(self.fileMenu.menuAction())
|
||||
self.menubar.addAction(self.editMenu.menuAction())
|
||||
self.menubar.addAction(self.settingsMenu.menuAction())
|
||||
self.menubar.addAction(self.helpMenu.menuAction())
|
||||
self.toolBar.addAction(self.newAction)
|
||||
self.toolBar.addAction(self.openAction)
|
||||
self.toolBar.addAction(self.saveAction)
|
||||
self.toolBar.addSeparator()
|
||||
self.toolBar.addAction(self.exportAction)
|
||||
self.toolBar.addAction(self.printAction)
|
||||
self.toolBar.addSeparator()
|
||||
self.toolBar.addAction(self.undoAction)
|
||||
self.toolBar.addAction(self.redoAction)
|
||||
self.toolBar.addSeparator()
|
||||
self.toolBar.addAction(self.cutAction)
|
||||
self.toolBar.addAction(self.copyAction)
|
||||
self.toolBar.addAction(self.pasteAction)
|
||||
self.toolBar.addSeparator()
|
||||
self.toolBar.addAction(self.configureAction)
|
||||
self.preview_dock = QtWidgets.QDockWidget(self)
|
||||
self.preview_dock.setObjectName('preview_dock')
|
||||
self.preview_dock_contents = QtWidgets.QWidget()
|
||||
self.preview_dock_contents.setObjectName('preview_dock_contents')
|
||||
self.preview_layout = QtWidgets.QVBoxLayout(self.preview_dock_contents)
|
||||
self.preview_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.preview_layout.setSpacing(0)
|
||||
self.preview_layout.setObjectName('preview_layout')
|
||||
self.preview_view = QtWebEngineWidgets.QWebEngineView(self.preview_dock_contents)
|
||||
self.preview_view.setUrl(QtCore.QUrl('about:blank'))
|
||||
self.preview_view.setObjectName('preview_view')
|
||||
self.preview_layout.addWidget(self.preview_view)
|
||||
self.preview_dock.setWidget(self.preview_dock_contents)
|
||||
self.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.preview_dock)
|
||||
self.toolbar = QtWidgets.QToolBar(self)
|
||||
self.toolbar.setObjectName('toolbar')
|
||||
self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolbar)
|
||||
self.new_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-new')
|
||||
self.new_action.setIcon(icon)
|
||||
self.new_action.setObjectName('new_action')
|
||||
self.open_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-open')
|
||||
self.open_action.setIcon(icon)
|
||||
self.open_action.setObjectName('open_action')
|
||||
self.save_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-save')
|
||||
self.save_action.setIcon(icon)
|
||||
self.save_action.setObjectName('save_action')
|
||||
self.save_as_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-save-as')
|
||||
self.save_as_action.setIcon(icon)
|
||||
self.save_as_action.setObjectName('save_as_action')
|
||||
self.print_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-print')
|
||||
self.print_action.setIcon(icon)
|
||||
self.print_action.setObjectName('print_action')
|
||||
self.export_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('document-export')
|
||||
self.export_action.setIcon(icon)
|
||||
self.export_action.setObjectName('export_action')
|
||||
self.undo_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('edit-undo')
|
||||
self.undo_action.setIcon(icon)
|
||||
self.undo_action.setObjectName('undo_action')
|
||||
self.redo_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('edit-redo')
|
||||
self.redo_action.setIcon(icon)
|
||||
self.redo_action.setObjectName('redo_action')
|
||||
self.cut_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('edit-cut')
|
||||
self.cut_action.setIcon(icon)
|
||||
self.cut_action.setObjectName('cut_action')
|
||||
self.copy_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('edit-copy')
|
||||
self.copy_action.setIcon(icon)
|
||||
self.copy_action.setObjectName('copy_action')
|
||||
self.paste_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('edit-paste')
|
||||
self.paste_action.setIcon(icon)
|
||||
self.paste_action.setObjectName('paste_action')
|
||||
self.configure_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('configure')
|
||||
self.configure_action.setIcon(icon)
|
||||
self.configure_action.setObjectName('configure_action')
|
||||
self.about_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('help-about')
|
||||
self.about_action.setIcon(icon)
|
||||
self.about_action.setObjectName('about_action')
|
||||
self.exit_action = QtWidgets.QAction(self)
|
||||
icon = QtGui.QIcon.fromTheme('application-exit')
|
||||
self.exit_action.setIcon(icon)
|
||||
self.exit_action.setObjectName('exit_action')
|
||||
self.file_menu.addAction(self.new_action)
|
||||
self.file_menu.addAction(self.open_action)
|
||||
self.file_menu.addAction(self.save_action)
|
||||
self.file_menu.addAction(self.save_as_action)
|
||||
self.file_menu.addSeparator()
|
||||
self.file_menu.addAction(self.export_action)
|
||||
self.file_menu.addAction(self.print_action)
|
||||
self.file_menu.addSeparator()
|
||||
self.file_menu.addAction(self.exit_action)
|
||||
self.edit_menu.addAction(self.undo_action)
|
||||
self.edit_menu.addAction(self.redo_action)
|
||||
self.edit_menu.addSeparator()
|
||||
self.edit_menu.addAction(self.cut_action)
|
||||
self.edit_menu.addAction(self.copy_action)
|
||||
self.edit_menu.addAction(self.paste_action)
|
||||
self.settings_menu.addAction(self.configure_action)
|
||||
self.help_menu.addAction(self.about_action)
|
||||
self.menubar.addAction(self.file_menu.menuAction())
|
||||
self.menubar.addAction(self.edit_menu.menuAction())
|
||||
self.menubar.addAction(self.settings_menu.menuAction())
|
||||
self.menubar.addAction(self.help_menu.menuAction())
|
||||
self.toolbar.addAction(self.new_action)
|
||||
self.toolbar.addAction(self.open_action)
|
||||
self.toolbar.addAction(self.save_action)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addAction(self.export_action)
|
||||
self.toolbar.addAction(self.print_action)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addAction(self.undo_action)
|
||||
self.toolbar.addAction(self.redo_action)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addAction(self.cut_action)
|
||||
self.toolbar.addAction(self.copy_action)
|
||||
self.toolbar.addAction(self.paste_action)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.addAction(self.configure_action)
|
||||
|
||||
self.retranslate_ui()
|
||||
self.exitAction.triggered.connect(self.close)
|
||||
self.undoAction.triggered.connect(self.fileEditor.undo)
|
||||
self.redoAction.triggered.connect(self.fileEditor.redo)
|
||||
self.cutAction.triggered.connect(self.fileEditor.cut)
|
||||
self.copyAction.triggered.connect(self.fileEditor.copy)
|
||||
self.pasteAction.triggered.connect(self.fileEditor.paste)
|
||||
self.exit_action.triggered.connect(self.close)
|
||||
self.undo_action.triggered.connect(self.file_editor.undo)
|
||||
self.redo_action.triggered.connect(self.file_editor.redo)
|
||||
self.cut_action.triggered.connect(self.file_editor.cut)
|
||||
self.copy_action.triggered.connect(self.file_editor.copy)
|
||||
self.paste_action.triggered.connect(self.file_editor.paste)
|
||||
# QtCore.QMetaObject.connectSlotsByName(self)
|
||||
self.openAction.triggered.connect(self.on_open_clicked)
|
||||
self.open_action.triggered.connect(self.on_open_clicked)
|
||||
self.save_action.triggered.connect(self.on_save_clicked)
|
||||
self.save_as_action.triggered.connect(self.on_save_as_clicked)
|
||||
self.file_editor.textChanged.connect(self.on_text_changed)
|
||||
|
||||
def retranslate_ui(self):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.setWindowTitle(_translate("MainWindow", "Ukatali"))
|
||||
self.fileMenu.setTitle(_translate("MainWindow", "&File"))
|
||||
self.editMenu.setTitle(_translate("MainWindow", "&Edit"))
|
||||
self.settingsMenu.setTitle(_translate("MainWindow", "&Settings"))
|
||||
self.helpMenu.setTitle(_translate("MainWindow", "&Help"))
|
||||
self.previewDock.setWindowTitle(_translate("MainWindow", "Preview"))
|
||||
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
|
||||
self.newAction.setText(_translate("MainWindow", "&New"))
|
||||
self.newAction.setToolTip(_translate("MainWindow", "Create a new ChordPro file"))
|
||||
self.newAction.setShortcut(_translate("MainWindow", "Ctrl+N"))
|
||||
self.openAction.setText(_translate("MainWindow", "&Open..."))
|
||||
self.openAction.setToolTip(_translate("MainWindow", "Open an existing ChordPro file"))
|
||||
self.openAction.setShortcut(_translate("MainWindow", "Ctrl+O"))
|
||||
self.saveAction.setText(_translate("MainWindow", "&Save"))
|
||||
self.saveAction.setToolTip(_translate("MainWindow", "Save the current ChordPro file"))
|
||||
self.saveAction.setShortcut(_translate("MainWindow", "Ctrl+S"))
|
||||
self.saveAsAction.setText(_translate("MainWindow", "Save &As..."))
|
||||
self.saveAsAction.setToolTip(_translate("MainWindow", "Save the current file under a new name"))
|
||||
self.saveAsAction.setShortcut(_translate("MainWindow", "Ctrl+Shift+S"))
|
||||
self.printAction.setText(_translate("MainWindow", "&Print"))
|
||||
self.printAction.setToolTip(_translate("MainWindow", "Print the current ChordPro file"))
|
||||
self.printAction.setShortcut(_translate("MainWindow", "Ctrl+P"))
|
||||
self.exportAction.setText(_translate("MainWindow", "&Export..."))
|
||||
self.exportAction.setToolTip(_translate("MainWindow", "Export the current file as a different format"))
|
||||
self.exportAction.setShortcut(_translate("MainWindow", "Ctrl+E"))
|
||||
self.undoAction.setText(_translate("MainWindow", "&Undo"))
|
||||
self.undoAction.setToolTip(_translate("MainWindow", "Undo the last edit"))
|
||||
self.undoAction.setShortcut(_translate("MainWindow", "Ctrl+Z"))
|
||||
self.redoAction.setText(_translate("MainWindow", "&Redo"))
|
||||
self.redoAction.setToolTip(_translate("MainWindow", "Redo the last undone action"))
|
||||
self.redoAction.setShortcut(_translate("MainWindow", "Ctrl+Shift+Z"))
|
||||
self.cutAction.setText(_translate("MainWindow", "Cu&t"))
|
||||
self.cutAction.setToolTip(_translate("MainWindow", "Cut the currently selected text"))
|
||||
self.cutAction.setShortcut(_translate("MainWindow", "Ctrl+X"))
|
||||
self.copyAction.setText(_translate("MainWindow", "&Copy"))
|
||||
self.copyAction.setToolTip(_translate("MainWindow", "Copy the currently selected text to the clipboard"))
|
||||
self.copyAction.setShortcut(_translate("MainWindow", "Ctrl+C"))
|
||||
self.pasteAction.setText(_translate("MainWindow", "&Paste"))
|
||||
self.pasteAction.setToolTip(_translate("MainWindow", "Paste the current clipboard text into the editor"))
|
||||
self.pasteAction.setShortcut(_translate("MainWindow", "Ctrl+V"))
|
||||
self.configureAction.setText(_translate("MainWindow", "&Configure..."))
|
||||
self.configureAction.setToolTip(_translate("MainWindow", "Configure Ukatali"))
|
||||
self.aboutAction.setText(_translate("MainWindow", "&About"))
|
||||
self.aboutAction.setToolTip(_translate("MainWindow", "About Ukatali"))
|
||||
self.exitAction.setText(_translate("MainWindow", "E&xit"))
|
||||
self.exitAction.setToolTip(_translate("MainWindow", "Quit Ukatali"))
|
||||
self.exitAction.setShortcut(_translate("MainWindow", "Alt+F4"))
|
||||
self.setWindowTitle(_translate('MainWindow', 'Ukatali'))
|
||||
self.file_menu.setTitle(_translate('MainWindow', '&File'))
|
||||
self.edit_menu.setTitle(_translate('MainWindow', '&Edit'))
|
||||
self.settings_menu.setTitle(_translate('MainWindow', '&Settings'))
|
||||
self.help_menu.setTitle(_translate('MainWindow', '&Help'))
|
||||
self.preview_dock.setWindowTitle(_translate('MainWindow', 'Preview'))
|
||||
self.toolbar.setWindowTitle(_translate('MainWindow', 'toolbar'))
|
||||
self.new_action.setText(_translate('MainWindow', '&New'))
|
||||
self.new_action.setToolTip(_translate('MainWindow', 'Create a new ChordPro file'))
|
||||
self.new_action.setShortcut(_translate('MainWindow', 'Ctrl+N'))
|
||||
self.open_action.setText(_translate('MainWindow', '&Open...'))
|
||||
self.open_action.setToolTip(_translate('MainWindow', 'Open an existing ChordPro file'))
|
||||
self.open_action.setShortcut(_translate('MainWindow', 'Ctrl+O'))
|
||||
self.save_action.setText(_translate('MainWindow', '&Save'))
|
||||
self.save_action.setToolTip(_translate('MainWindow', 'Save the current ChordPro file'))
|
||||
self.save_action.setShortcut(_translate('MainWindow', 'Ctrl+S'))
|
||||
self.save_as_action.setText(_translate('MainWindow', 'Save &As...'))
|
||||
self.save_as_action.setToolTip(_translate('MainWindow', 'Save the current file under a new name'))
|
||||
self.save_as_action.setShortcut(_translate('MainWindow', 'Ctrl+Shift+S'))
|
||||
self.print_action.setText(_translate('MainWindow', '&Print'))
|
||||
self.print_action.setToolTip(_translate('MainWindow', 'Print the current ChordPro file'))
|
||||
self.print_action.setShortcut(_translate('MainWindow', 'Ctrl+P'))
|
||||
self.export_action.setText(_translate('MainWindow', '&Export...'))
|
||||
self.export_action.setToolTip(_translate('MainWindow', 'Export the current file as a different format'))
|
||||
self.export_action.setShortcut(_translate('MainWindow', 'Ctrl+E'))
|
||||
self.undo_action.setText(_translate('MainWindow', '&Undo'))
|
||||
self.undo_action.setToolTip(_translate('MainWindow', 'Undo the last edit'))
|
||||
self.undo_action.setShortcut(_translate('MainWindow', 'Ctrl+Z'))
|
||||
self.redo_action.setText(_translate('MainWindow', '&Redo'))
|
||||
self.redo_action.setToolTip(_translate('MainWindow', 'Redo the last undone action'))
|
||||
self.redo_action.setShortcut(_translate('MainWindow', 'Ctrl+Shift+Z'))
|
||||
self.cut_action.setText(_translate('MainWindow', 'Cu&t'))
|
||||
self.cut_action.setToolTip(_translate('MainWindow', 'Cut the currently selected text'))
|
||||
self.cut_action.setShortcut(_translate('MainWindow', 'Ctrl+X'))
|
||||
self.copy_action.setText(_translate('MainWindow', '&Copy'))
|
||||
self.copy_action.setToolTip(_translate('MainWindow', 'Copy the currently selected text to the clipboard'))
|
||||
self.copy_action.setShortcut(_translate('MainWindow', 'Ctrl+C'))
|
||||
self.paste_action.setText(_translate('MainWindow', '&Paste'))
|
||||
self.paste_action.setToolTip(_translate('MainWindow', 'Paste the current clipboard text into the editor'))
|
||||
self.paste_action.setShortcut(_translate('MainWindow', 'Ctrl+V'))
|
||||
self.configure_action.setText(_translate('MainWindow', '&Configure...'))
|
||||
self.configure_action.setToolTip(_translate('MainWindow', 'Configure Ukatali'))
|
||||
self.about_action.setText(_translate('MainWindow', '&About'))
|
||||
self.about_action.setToolTip(_translate('MainWindow', 'About Ukatali'))
|
||||
self.exit_action.setText(_translate('MainWindow', 'E&xit'))
|
||||
self.exit_action.setToolTip(_translate('MainWindow', 'Quit Ukatali'))
|
||||
self.exit_action.setShortcut(_translate('MainWindow', 'Alt+F4'))
|
||||
|
||||
def on_open_clicked(self):
|
||||
"""Open the file"""
|
||||
@ -222,13 +230,48 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
last_directory = QtCore.QSettings().value('files/last-directory')
|
||||
else:
|
||||
last_directory = ''
|
||||
filename = QtWidgets.QFileDialog.getOpenFileName(self, "Open file", last_directory,
|
||||
filter="All files *")
|
||||
filename = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', last_directory,
|
||||
filter='All files *')
|
||||
if isinstance(filename, tuple):
|
||||
filename = filename[0]
|
||||
if not filename:
|
||||
return
|
||||
|
||||
self.filename = filename
|
||||
file_path = Path(filename)
|
||||
if file_path.exists():
|
||||
QtCore.QSettings().setValue('files/last-directory', str(file_path.parent))
|
||||
self.fileEditor.setText(file_path.open().read())
|
||||
self.file_editor.setText(file_path.open().read())
|
||||
|
||||
def on_save_clicked(self):
|
||||
"""Save the file"""
|
||||
if not self.filename:
|
||||
self.on_save_as_clicked()
|
||||
else:
|
||||
with open(self.filename, 'w') as fd:
|
||||
fd.write(self.file_editor.text())
|
||||
|
||||
def on_save_as_clicked(self):
|
||||
"""Save the file"""
|
||||
if QtCore.QSettings().value('files/last-directory'):
|
||||
last_directory = QtCore.QSettings().value('files/last-directory')
|
||||
else:
|
||||
last_directory = ''
|
||||
filename = QtWidgets.QFileDialog.getSaveFileName(self, 'Save file', last_directory,
|
||||
filter='All files *')
|
||||
if isinstance(filename, tuple):
|
||||
filename = filename[0]
|
||||
if not filename:
|
||||
return
|
||||
|
||||
self.filename = filename
|
||||
QtCore.QSettings().setValue('files/last-directory', str(Path(filename).parent))
|
||||
self.on_save_clicked()
|
||||
|
||||
def on_text_changed(self):
|
||||
"""Update the preview when the text changes"""
|
||||
text = self.file_editor.text()
|
||||
song = Song()
|
||||
song.parse(text)
|
||||
html = render(song)
|
||||
self.preview_view.setHtml(html)
|
||||
|
Loading…
Reference in New Issue
Block a user