14 Commits

  1. 3
      .gitignore
  2. 6
      README.md
  3. 2
      _version.py
  4. 7
      chordsheet/common.py
  5. 21
      chordsheet/document.py
  6. 7
      chordsheet/parsers.py
  7. 56
      chordsheet/pdfViewer.py
  8. 11
      chordsheet/render.py
  9. 43
      cli.py
  10. 0
      csgui/comboBox.py
  11. 81
      csgui/dialogs.py
  12. 124
      csgui/messageBox.py
  13. 64
      csgui/panels.py
  14. 96
      csgui/pdfViewer.py
  15. 27
      csgui/tableView.py
  16. 1453
      gui.py
  17. 2
      linux.spec
  18. 4
      requirements.txt
  19. 17
      ui/aboutdialog.ui
  20. 291
      ui/blocks.ui
  21. 237
      ui/chords.ui
  22. 162
      ui/docinfo.ui
  23. 57
      ui/document.ui
  24. 1071
      ui/mainwindow.ui
  25. 83
      ui/preview.ui
  26. 326
      ui/psetup.ui
  27. 165
      ui/sections.ui
  28. 8
      version.rc

3
.gitignore

@ -52,3 +52,6 @@ docs/_build/
# Mac stuff
.DS_Store
.vscode/
# Syncthing conflicts
*.sync-conflict-*

6
README.md

@ -10,10 +10,10 @@ Chordsheet works on a system of blocks, each with a certain length. Blocks may h
## Get started
To run Chordsheet, go to the Releases tab and download the most recent version for your OS. Releases are currently provided for macOS, Linux and Windows. These binaries are created with PyInstaller and so can't be used for development. You do not need to install anything else to run Chordsheet this way.
To develop Chordsheet, clone this repository and run gui.py using a recent Python 3 interpreter. Make sure you have the dependencies installed!
To develop Chordsheet, clone this repository and run gui.py using Python 3.7 or newer. Make sure you have the dependencies installed!
## Current status
Chordsheet is beta-grade software. Most things should work, but I haven't tested it too extensively.
Chordsheet is alpha-grade software. Most things should work, but I haven't tested it too extensively.
### Features
- Guitar and piano chords can be entered and rendered
@ -36,6 +36,8 @@ This command should sort you out:
pip3 install pymupdf reportlab pyqt5
```
Note that if you have downloaded a binary from the Releases tab, these libraries are included already so you don't need to install them separately.
## Building (freezing)
To build the binary distribution using PyInstaller, simply run:
```bash

2
_version.py

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
appName = "Chordsheet"
version = '0.4.6'
version = '0.5.0'

7
chordsheet/common.py

@ -0,0 +1,7 @@
import sys, os
# set the directory where our files are depending on whether we're running a pyinstaller binary or not
if getattr(sys, 'frozen', False):
scriptDir = sys._MEIPASS
else:
scriptDir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir))

21
chordsheet/document.py

@ -7,7 +7,6 @@ from reportlab.lib.pagesizes import A4
defaultTimeSignature = 4
class Style:
def __init__(self, **kwargs):
# set up the style using sane defaults
@ -144,16 +143,7 @@ class Document:
self.tempo = (root.find('tempo').text if root.find(
'tempo') is not None else None)
@classmethod
def newFromXML(cls, filepath):
"""
Create a new Document object directly from an XML file.
"""
doc = cls()
doc.loadXML(filepath)
return doc
def saveXML(self, filepath):
def toXML(self):
"""
Write the contents of the Document object to an XML file.
"""
@ -200,7 +190,16 @@ class Document:
ET.SubElement(blockElement, "notes").text = b.notes
tree = ET.ElementTree(root)
return tree
def saveXML(self, filepath):
tree = self.toXML()
tree.write(filepath)
return hash(ET.tostring(tree.getroot()))
def getHash(self):
tree = self.toXML()
return hash(ET.tostring(tree.getroot()))
def loadCSMacro(self, filepath):
"""

7
chordsheet/parsers.py

@ -7,14 +7,13 @@ def parseFingering(fingering, instrument):
"""
if instrument == 'guitar':
numStrings = 6
if len(fingering) == numStrings: # if the fingering is entered in concise format e.g. xx4455
if "," not in fingering and len(fingering) == numStrings: # if the fingering is entered in concise format e.g. xx4455
output = list(fingering)
else: # if entered in long format e.g. x,x,10,10,11,11
output = [f.strip() for f in fingering.split(",")]
if len(output) == numStrings:
if len(output) != numStrings:
print("Voicing <{}> is malformed.".format(fingering))
return output
else:
raise Exception("Voicing <{}> is malformed.".format(fingering))
elif instrument == 'piano':
return [parseName(note).upper().strip() for note in fingering.split(",")]
else:

56
chordsheet/pdfViewer.py

@ -1,56 +0,0 @@
from PyQt5.QtWidgets import QScrollArea, QLabel, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QImage
import fitz
class PDFViewer(QScrollArea):
def __init__(self, parent):
super().__init__(parent)
self.scrollAreaContents = QWidget()
self.scrollAreaLayout = QVBoxLayout()
self.setWidget(self.scrollAreaContents)
self.setWidgetResizable(True)
self.scrollAreaContents.setLayout(self.scrollAreaLayout)
self.pixmapList = []
def resizeEvent(self, event):
pass
# do something about this later
def update(self, pdf):
self.render(pdf)
self.clear()
self.show()
def render(self, pdf):
"""
Update the preview shown by rendering a new PDF and drawing it to the scroll area.
"""
self.pixmapList = []
pdfView = fitz.Document(stream=pdf, filetype='pdf')
# render at 4x resolution and scale
for page in pdfView:
self.pixmapList.append(page.getPixmap(matrix=fitz.Matrix(4, 4), alpha=False))
def clear(self):
while self.scrollAreaLayout.count():
item = self.scrollAreaLayout.takeAt(0)
w = item.widget()
if w:
w.deleteLater()
def show(self):
for p in self.pixmapList:
label = QLabel(parent=self.scrollAreaContents)
label.setAlignment(Qt.AlignHCenter)
qtimg = QImage(p.samples, p.width, p.height, p.stride, QImage.Format_RGB888)
# -45 because of various margins... value obtained by trial and error.
label.setPixmap(QPixmap.fromImage(qtimg).scaled(self.width()-45, self.height()*2, Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation))
self.scrollAreaLayout.addWidget(label)
# necessary on Mojave with PyInstaller (or previous contents will be shown)
self.repaint()

11
chordsheet/render.py

@ -12,6 +12,7 @@ from reportlab.platypus import BaseDocTemplate, Spacer, Paragraph, Flowable, Fra
from chordsheet.document import Block
from chordsheet.rlStylesheet import getStyleSheet
defaultSpacing = 1.15
def writeText(canvas, style, string, size, vpos, width, **kwargs):
"""
@ -122,7 +123,7 @@ class GuitarChart(Flowable):
for i in range(self.nStrings+1): # i is the string line currently being drawn
writeText(canvas, self.style, ['e', 'B', 'G', 'D', 'A', 'E', 'Name'][i], fontsize, v_origin-(
i*self.stringHeight), self.width, hpos=chartmargin, align='right')
i*self.stringHeight), self.width, hpos=chartmargin, align='right', spacing=defaultSpacing)
# j is which chord (0 is first chord, 1 is 2nd etc)
for j in range(len(stringList[-1])):
@ -152,7 +153,7 @@ class GuitarChart(Flowable):
canvas.line(x, y, x+l, y)
writeText(canvas, self.style, stringList[i][j], fontsize, v_origin-(
i*self.stringHeight), self.width, hpos=chartmargin+self.stringHzSp*(j+0.5))
i*self.stringHeight), self.width, hpos=chartmargin+self.stringHzSp*(j+0.5), spacing=defaultSpacing)
lastWidth = currentWidth
@ -458,7 +459,7 @@ class ChordProgression(Flowable):
if u == maxWidth: # Avoid writing beat number after the final line
break
writeText(canvas, self.style, str((u % self.timeSignature)+1), self.style.beatsFontSize,
v_origin+self.beatsHeight, self.width, hpos=x+unitWidth/2)
v_origin+self.beatsHeight, self.width, hpos=x+unitWidth/2, spacing=defaultSpacing)
parsedBlockList = self.wrapBlocks(self.blockList, maxWidth)
@ -470,12 +471,12 @@ class ChordProgression(Flowable):
b.length*unitWidth, self.unitHeight)
if b.notes is not None:
writeText(canvas, self.style, b.notes, self.style.notesFontSize, v_origin-((v_loc+1)*self.unitHeight)+(
1.3*self.style.notesFontSize), self.width, hpos=h_offset+((h_loc+b.length/2)*unitWidth))
1.3*self.style.notesFontSize), self.width, hpos=h_offset+((h_loc+b.length/2)*unitWidth), spacing=defaultSpacing)
v_offset = ((v_loc*self.unitHeight) +
self.unitHeight/2)-self.style.chordNameFontSize/2
if b.chord is not None:
writeText(canvas, self.style, b.chord.name, self.style.chordNameFontSize,
v_origin-v_offset, self.width, hpos=h_offset+((h_loc+b.length/2)*unitWidth))
v_origin-v_offset, self.width, hpos=h_offset+((h_loc+b.length/2)*unitWidth), spacing=defaultSpacing)
h_loc += b.length

43
cli.py

@ -0,0 +1,43 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
import time
from reportlab.lib.units import mm, cm, inch, pica
from reportlab.lib.pagesizes import A4, A5, LETTER, LEGAL
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from chordsheet.common import scriptDir
from chordsheet.document import Document, Style, Chord, Block, Section
from chordsheet.render import Renderer
from chordsheet.parsers import parseFingering, parseName
import _version
pdfmetrics.registerFont(
TTFont('FreeSans', os.path.join(scriptDir, 'fonts', 'FreeSans.ttf')))
if sys.platform == "darwin":
pdfmetrics.registerFont(
TTFont('HelveticaNeue', 'HelveticaNeue.ttc', subfontIndex=0))
if len(sys.argv) == 2:
inputFilePath = sys.argv[1]
else:
print("Please provide a .cml, .xml, or .cma file to process.")
sys.exit()
doc = Document()
if inputFilePath[-4:] == ".cma":
doc.loadCSMacro(inputFilePath)
else:
doc.loadXML(inputFilePath)
style = Style()
renderer = Renderer(doc, style)
outputFilePath = ".".join(inputFilePath.split(".")[:-1]) + ".pdf"
renderer.savePDF(outputFilePath)

0
chordsheet/comboBox.py → csgui/comboBox.py

81
csgui/dialogs.py

@ -0,0 +1,81 @@
import os
from PyQt5.QtWidgets import QApplication, QAction, QLabel, QDialogButtonBox, QDialog, QFileDialog, QMessageBox, QPushButton, QLineEdit, QCheckBox, QSpinBox, QDoubleSpinBox, QTableWidgetItem, QTabWidget, QComboBox, QWidget, QScrollArea, QMainWindow, QShortcut
from PyQt5.QtCore import QFile, QObject, Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5 import uic
from chordsheet.common import scriptDir
import _version
class GuitarDialog(QDialog):
"""
Dialogue to allow the user to enter a guitar chord voicing. Not particularly advanced at present!
May be extended in future.
"""
def __init__(self):
super().__init__()
self.UIFileLoader(
str(os.path.join(scriptDir, 'ui', 'guitardialog.ui')))
def UIFileLoader(self, ui_file):
ui_file = QFile(ui_file)
ui_file.open(QFile.ReadOnly)
self.dialog = uic.loadUi(ui_file)
ui_file.close()
def getVoicing(self, existingVoicing):
"""
Show the dialogue and return the voicing that has been entered.
"""
lineEditsList = [
self.dialog.ELineEdit,
self.dialog.ALineEdit,
self.dialog.DLineEdit,
self.dialog.GLineEdit,
self.dialog.BLineEdit,
self.dialog.eLineEdit
]
# Read the present voicing
if type(existingVoicing) == list:
for count in range(len(existingVoicing)):
lineEditsList[count].setText(existingVoicing[count])
if self.dialog.exec_() == QDialog.Accepted:
result = [self.dialog.ELineEdit.text() or 'x',
self.dialog.ALineEdit.text() or 'x',
self.dialog.DLineEdit.text() or 'x',
self.dialog.GLineEdit.text() or 'x',
self.dialog.BLineEdit.text() or 'x',
self.dialog.eLineEdit.text() or 'x']
resultJoined = ",".join(result)
return resultJoined
else:
return None
class AboutDialog(QDialog):
"""
Dialogue showing information about the program.
"""
def __init__(self):
super().__init__()
self.UIFileLoader(str(os.path.join(scriptDir, 'ui', 'aboutdialog.ui')))
icon = QImage(str(os.path.join(scriptDir, 'ui', 'icon.png')))
self.dialog.iconLabel.setPixmap(QPixmap.fromImage(icon).scaled(self.dialog.iconLabel.width(
), self.dialog.iconLabel.height(), Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation))
self.dialog.versionLabel.setText("Version " + _version.version)
self.dialog.exec()
def UIFileLoader(self, ui_file):
ui_file = QFile(ui_file)
ui_file.open(QFile.ReadOnly)
self.dialog = uic.loadUi(ui_file)
ui_file.close()

124
csgui/messageBox.py

@ -0,0 +1,124 @@
from PyQt5.QtWidgets import QApplication, QAction, QLabel, QDialogButtonBox, QDialog, QFileDialog, QMessageBox, QPushButton, QLineEdit, QCheckBox, QSpinBox, QDoubleSpinBox, QTableWidgetItem, QTabWidget, QComboBox, QWidget, QScrollArea, QMainWindow, QShortcut, QDialogButtonBox
import sys
class UnsavedMessageBox(QMessageBox):
"""
Message box to alert the user of unsaved changes and allow them to choose how to act.
"""
def __init__(self, fileName):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("Unsaved changes")
self.setText(f"The document \"{fileName}\" has been modified.")
self.setInformativeText("Do you want to save your changes?")
self.setStandardButtons(
QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
self.setDefaultButton(QMessageBox.Save)
# If we are running on Haiku, use the MacOS button style to fit in more
# with native applications
if sys.platform.startswith("haiku"):
buttonBox = self.findChild(QDialogButtonBox)
buttonBox.setStyleSheet("* { button-layout: 1}")
class UnreadableMessageBox(QMessageBox):
"""
Message box to warn the user that the chosen file cannot be opened.
"""
def __init__(self, fileName):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle(f"File \"{fileName}\" cannot be opened")
self.setText("The file you have selected cannot be opened.")
self.setInformativeText("Please make sure it is in the right format.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)
class ChordNameWarningMessageBox(QMessageBox):
"""
Message box to warn the user that a chord must have a name
"""
def __init__(self):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("Unnamed chord")
self.setText("Chords must have a name.")
self.setInformativeText("Please give your chord a name and try again.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)
class SectionNameWarningMessageBox(QMessageBox):
"""
Message box to warn the user that a section must have a name
"""
def __init__(self):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("Unnamed section")
self.setText("Sections must have a unique name.")
self.setInformativeText(
"Please give your section a unique name and try again.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)
class BlockMustHaveSectionWarningMessageBox(QMessageBox):
"""
Message box to warn the user that a block must belong to a section
"""
def __init__(self):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("No sections found")
self.setText("Each block must belong to a section, but no sections have yet been created.")
self.setInformativeText(
"Please create a section before adding blocks.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)
class VoicingWarningMessageBox(QMessageBox):
"""
Message box to warn the user that the voicing entered could not be parsed
"""
def __init__(self):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("Malformed voicing")
self.setText(
"The voicing you entered was not understood and has not been applied.")
self.setInformativeText(
"Please try re-entering it in the correct format.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)
class LengthWarningMessageBox(QMessageBox):
"""
Message box to warn the user that a block must have a length
"""
def __init__(self):
super().__init__()
self.setIcon(QMessageBox.Information)
self.setWindowTitle("Block without valid length")
self.setText("Blocks must have a length.")
self.setInformativeText(
"Please enter a valid length for your block and try again.")
self.setStandardButtons(QMessageBox.Ok)
self.setDefaultButton(QMessageBox.Ok)

64
csgui/panels.py

@ -0,0 +1,64 @@
import os
from PyQt5.QtWidgets import QApplication, QAction, QLabel, QDialogButtonBox, QDialog, QFileDialog, QMessageBox, QPushButton, QLineEdit, QCheckBox, QSpinBox, QDoubleSpinBox, QTableWidgetItem, QTabWidget, QComboBox, QWidget, QScrollArea, QMainWindow, QShortcut, QDockWidget, QLineEdit, QTableView
from PyQt5.QtCore import QFile, QObject, Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5 import uic
from chordsheet.common import scriptDir
from csgui.tableView import MTableView
class UIFileDockWidget(QDockWidget):
def __init__(self):
super().__init__()
def UIFileLoader(self, ui_file):
ui_file = QFile(os.path.join(scriptDir, 'ui', ui_file))
ui_file.open(QFile.ReadOnly)
self.setWidget(uic.loadUi(ui_file))
ui_file.close()
def clear(self):
# Clear all the fields
for lineEdit in self.findChildren(QLineEdit):
lineEdit.clear()
for comboBox in self.findChildren(QComboBox):
comboBox.clear()
for tableView in self.findChildren(MTableView):
tableView.clear()
class DocInfoDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('docinfo.ui')
self.setWindowTitle("Document information")
class PageSetupDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('psetup.ui')
self.setWindowTitle("Page setup")
class ChordsDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('chords.ui')
self.setWindowTitle("Chords")
class SectionsDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('sections.ui')
self.setWindowTitle("Sections")
class BlocksDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('blocks.ui')
self.setWindowTitle("Blocks")
class PreviewDockWidget(UIFileDockWidget):
def __init__(self):
super().__init__()
self.UIFileLoader('preview.ui')
self.setWindowTitle("Preview")

96
csgui/pdfViewer.py

@ -0,0 +1,96 @@
from PyQt5.QtWidgets import QScrollArea, QLabel, QVBoxLayout, QWidget, QSizePolicy
from PyQt5.QtCore import Qt, QPoint, QSize
from PyQt5.QtGui import QPixmap, QImage, QResizeEvent, QPainter
import fitz
class PDFLabel(QLabel):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
def paintEvent(self, event):
self.adjustSize()
if self.pixmap() is not None:
painter = QPainter(self)
# painter.setRenderHint(QPainter.Antialiasing)
parentLayoutMargins = self.parent.scrollAreaLayout.getContentsMargins()
parentMargins = self.parent.getContentsMargins()
if self.parent.verticalScrollBar().isVisible():
scrollBarWidth = self.parent.verticalScrollBar().sizeHint().width()
else:
scrollBarWidth = 0
totalMargin = parentLayoutMargins[0] + parentLayoutMargins[2] + \
parentMargins[0]*2 + scrollBarWidth
idealWidth = self.parent.width() - totalMargin
# print(idealWidth)
pixSize = self.pixmap().size()
# print(pixSize)
# print((self.parent.scrollAreaContents.size()))
pixSize.scale(idealWidth, 1000000, Qt.KeepAspectRatio)
scaledPix = self.pixmap().scaled(pixSize, Qt.KeepAspectRatio, Qt.SmoothTransformation)
painter.drawPixmap(QPoint(), scaledPix)
self.setMaximumSize(pixSize)
class PDFViewer(QScrollArea):
def __init__(self, parent):
super().__init__(parent)
self.scrollAreaContents = QWidget()
self.scrollAreaLayout = QVBoxLayout()
self.setWidget(self.scrollAreaContents)
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# set a fixed background colour
# on some OSes (Mac, Haiku) it is grey automatically but not on KDE
self.setStyleSheet('PDFViewer {background-color: #D8D8D8}')
self.scrollAreaContents.setLayout(self.scrollAreaLayout)
self.pixmapList = []
self.lastVScrollPosition = None
def update_pdf(self, pdf):
self.render(pdf)
self.clear()
self.show()
def render(self, pdf):
"""
Update the preview shown by rendering a new PDF and drawing it to the scroll area.
"""
self.pixmapList = []
pdfView = fitz.Document(stream=pdf, filetype='pdf')
for page in pdfView:
# needs to be high enough for big monitors. 300 should do it...
self.pixmapList.append(page.get_pixmap(dpi=300, alpha=False))
def clear(self):
self.lastVScrollPosition = self.verticalScrollBar().value()
while self.scrollAreaLayout.count():
item = self.scrollAreaLayout.takeAt(0)
w = item.widget()
if w:
w.deleteLater()
def show(self):
for p in self.pixmapList:
label = PDFLabel(parent=self)
label.setAlignment(Qt.AlignHCenter)
qtimg = QImage(p.samples, p.width, p.height, p.stride, QImage.Format_RGB888)
label.setPixmap(QPixmap.fromImage(qtimg))
self.scrollAreaLayout.addWidget(label)
self.scrollAreaLayout.addStretch(1)
# Somewhat of a hack. Should really replace pixmaps in place
# rather than removing labels elsewhere in code.
if self.lastVScrollPosition:
self.verticalScrollBar().setValue(self.lastVScrollPosition)

27
chordsheet/tableView.py → csgui/tableView.py

@ -1,16 +1,35 @@
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import pyqtSignal, Qt, QModelIndex
class MItemModel(QtGui.QStandardItemModel):
"""
Special item model to ensure whole row is moved.
"""
itemsDropped = pyqtSignal()
def __init__(self):
super().__init__()
self.pendingRemoveRows = False
def dropMimeData(self, data, action, row, col, parent):
"""
Always move the entire row, and don't allow column "shifting"
"""
return super().dropMimeData(data, action, row, 0, parent)
ret = super().dropMimeData(data, Qt.MoveAction, row, 0, parent)
if ret:
self.pendingRemoveRows = True
return ret
def removeRows(self, row, count, index=QModelIndex()):
"""
Emit a signal after rows have been moved
"""
ret = super().removeRows(row, count, index)
if self.pendingRemoveRows:
self.itemsDropped.emit()
self.pendingRemoveRows = False
return ret
class MProxyStyle(QtWidgets.QProxyStyle):
@ -50,11 +69,13 @@ class MTableView(QtWidgets.QTableView):
self.setShowGrid(False)
# self.setDragDropMode(self.InternalMove)
# self.setDragDropOverwriteMode(False)
self.setDragDropOverwriteMode(False)
# Set our custom style - this draws the drop indicator across the whole row
self.setStyle(MProxyStyle())
def clear(self):
self.model.removeRows(0, self.model.rowCount())
class ChordTableView(MTableView):
"""

1453
gui.py
File diff suppressed because it is too large
View File

2
linux.spec

@ -12,7 +12,7 @@ a = Analysis(['gui.py'],
('fonts', 'fonts'),
('ui', 'ui')
],
hiddenimports=[],
hiddenimports=['PyQt5.sip'],
hookspath=[],
runtime_hooks=[],
excludes=[],

4
requirements.txt

@ -0,0 +1,4 @@
reportlab>=3.5.67
PyMuPDF>=1.18.13
PyQt5>=5.15.4
PyQt5.Sip

17
ui/aboutdialog.ui

@ -14,7 +14,7 @@
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -25,10 +25,25 @@
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>436</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>About Chordsheet</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<layout class="QVBoxLayout" name="leftPane">
<item>

291
ui/blocks.ui

@ -0,0 +1,291 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>blocksWidget</class>
<widget class="QWidget" name="blocksWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>387</width>
<height>206</height>
</rect>
</property>
<property name="windowTitle">
<string>Blocks</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout_5">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="blockSectionLabel">
<property name="text">
<string>Section</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="MComboBox" name="blockSectionComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="BlockTableView" name="blockTableView">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::TargetMoveAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="blockGridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="blockLengthLabel">
<property name="text">
<string>Length</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QComboBox" name="blockChordComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="blockNotesLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Notes</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="blockChordLabel">
<property name="text">
<string>Chord</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="blockLengthLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QLineEdit" name="blockNotesLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="bottomBlockHorizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="removeBlockButton">
<property name="text">
<string>Remove block</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="updateBlockButton">
<property name="text">
<string>Update block</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addBlockButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Add block</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlockTableView</class>
<extends>QTableView</extends>
<header>csgui/tableView.h</header>
</customwidget>
<customwidget>
<class>MComboBox</class>
<extends>QComboBox</extends>
<header>csgui/comboBox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>blockLengthLineEdit</tabstop>
<tabstop>blockChordComboBox</tabstop>
<tabstop>blockNotesLineEdit</tabstop>
<tabstop>removeBlockButton</tabstop>
<tabstop>updateBlockButton</tabstop>
<tabstop>addBlockButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

237
ui/chords.ui

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>chordsWidget</class>
<widget class="QWidget" name="chordsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>393</width>
<height>236</height>
</rect>
</property>
<property name="windowTitle">
<string>Chords</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="ChordTableView" name="chordTableView">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::IgnoreAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QGridLayout" name="chordGridLayout">
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="guitarVoicingLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="guitarVoicingLabel">
<property name="text">
<string>Guitar voicing</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="pianoVoicingLineEdit"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="chordNameLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pianoVoicingLabel">
<property name="text">
<string>Piano voicing</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="chordNameLabel">
<property name="text">
<string>Chord name</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="guitarVoicingButton">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Editor...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="bottomChordHorizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="removeChordButton">
<property name="text">
<string>Remove chord</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="updateChordButton">
<property name="text">
<string>Update chord</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addChordButton">
<property name="text">
<string>Add chord</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ChordTableView</class>
<extends>QTableView</extends>
<header>csgui/tableView.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>chordNameLineEdit</tabstop>
<tabstop>guitarVoicingLineEdit</tabstop>
<tabstop>guitarVoicingButton</tabstop>
<tabstop>pianoVoicingLineEdit</tabstop>
<tabstop>removeChordButton</tabstop>
<tabstop>updateChordButton</tabstop>
<tabstop>addChordButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

162
ui/docinfo.ui

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>docInfoWidget</class>
<widget class="QWidget" name="docInfoWidget">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>291</width>
<height>170</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Document information</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QFormLayout" name="formLayoutOverview">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="titleLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="subtitleLabel">
<property name="text">
<string>Subtitle</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="subtitleLineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="composerLabel">
<property name="text">
<string>Composer</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="composerLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="arrangerLabel">
<property name="text">
<string>Arranger</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="arrangerLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="tempoLabel">
<property name="text">
<string>Tempo</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="tempoLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="timeSignatureLabel">
<property name="text">
<string>Time</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="timeSignatureSpinBox">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="specialValueText">
<string/>
</property>
<property name="value">
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

57
ui/document.ui

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>docWindow</class>
<widget class="QWidget" name="docWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>424</width>
<height>324</height>
</rect>
</property>
<property name="windowTitle">
<string>Unsaved</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="PDFViewer" name="pdfArea" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>300</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>PDFViewer</class>
<extends>QWidget</extends>
<header>csgui/pdfViewer.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

1071
ui/mainwindow.ui
File diff suppressed because it is too large
View File

83
ui/preview.ui

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>previewPanel</class>
<widget class="QWidget" name="previewPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>202</width>
<height>72</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>202</width>
<height>72</height>
</size>
</property>
<property name="windowTitle">
<string>Preview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item alignment="Qt::AlignHCenter">
<widget class="QCheckBox" name="autoUpdatePreviewCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatically update preview</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="updatePreviewButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Update preview</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

326
ui/psetup.ui

@ -0,0 +1,326 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>psetupWidget</class>
<widget class="QWidget" name="psetupWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>173</width>
<height>306</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Page setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0,0,0,0,0" columnstretch="0,0">
<property name="spacing">
<number>6</number>
</property>
<item row="6" column="0" colspan="2">
<widget class="QFontComboBox" name="fontComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="maxVisibleItems">
<number>12</number>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="writingSystem">
<enum>QFontDatabase::Any</enum>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="includedFontCheckBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>FreeSans</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="rightMarginLineEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="bottomMarginLineEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="fontLabel">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Font</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="pageSizeComboBox">
<property name="maximumSize">
<size>
<width>70</width>
<height>26</height>
</size>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="beatWidthLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Beat width</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="topMarginLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Top margin</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="documentUnitsComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>26</height>
</size>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="leftMarginLineEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="topMarginLineEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="pageSizeLabel">
<property name="text">
<string>Page size</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLineEdit" name="beatWidthLineEdit">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="leftMarginLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Left margin</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="bottomMarginLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Bottom margin</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="lineSpacingLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Line spacing</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="rightMarginLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Right margin</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="documentUnitsLabel">
<property name="text">
<string>Units</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QDoubleSpinBox" name="lineSpacingDoubleSpinBox">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>pageSizeComboBox</tabstop>
<tabstop>documentUnitsComboBox</tabstop>
<tabstop>leftMarginLineEdit</tabstop>
<tabstop>rightMarginLineEdit</tabstop>
<tabstop>topMarginLineEdit</tabstop>
<tabstop>bottomMarginLineEdit</tabstop>
<tabstop>fontComboBox</tabstop>
<tabstop>includedFontCheckBox</tabstop>
<tabstop>lineSpacingDoubleSpinBox</tabstop>
<tabstop>beatWidthLineEdit</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

165
ui/sections.ui

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>sectionsWidget</class>
<widget class="QWidget" name="sectionsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>170</height>
</rect>
</property>
<property name="windowTitle">
<string>Sections</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="SectionTableView" name="sectionTableView">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::TargetMoveAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="sectionNameLabel">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="sectionNameLineEdit"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="bottomSectionHorizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="removeSectionButton">
<property name="text">
<string>Remove section</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="updateSectionButton">
<property name="text">
<string>Update section</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addSectionButton">
<property name="text">
<string>Add section</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SectionTableView</class>
<extends>QTableView</extends>
<header>csgui/tableView.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

8
version.rc

@ -6,8 +6,8 @@ VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(0, 4, 6, 0),
prodvers=(0, 4, 6, 0),
filevers=(0, 5, 0, 0),
prodvers=(0, 5, 0, 0),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
@ -31,12 +31,12 @@ StringFileInfo(
u'040904B0',
[StringStruct(u'CompanyName', u'Ivan Holmes'),
StringStruct(u'FileDescription', u'Chordsheet'),
StringStruct(u'FileVersion', u'0.4.6'),
StringStruct(u'FileVersion', u'0.5.0'),
StringStruct(u'InternalName', u'Chordsheet'),
StringStruct(u'LegalCopyright', u'Copyright (c) Ivan Holmes, 2020. Some rights reserved.'),
StringStruct(u'OriginalFilename', u'chordsheet.exe'),
StringStruct(u'ProductName', u'Chordsheet'),
StringStruct(u'ProductVersion', u'0.4.6')])
StringStruct(u'ProductVersion', u'0.5.0')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
]
Loading…
Cancel
Save