278 lines
14 KiB
Python
278 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
from pathlib import Path
|
|
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets, Qsci
|
|
|
|
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.resize(800, 600)
|
|
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.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.setStatusBar(self.statusbar)
|
|
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.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.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.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"""
|
|
if QtCore.QSettings().value('files/last-directory'):
|
|
last_directory = QtCore.QSettings().value('files/last-directory')
|
|
else:
|
|
last_directory = ''
|
|
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.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)
|