71 Commits
50 changed files with 4863 additions and 1611 deletions
-
3.gitignore
-
41README.md
-
4_version.py
-
7chordsheet/common.py
-
61chordsheet/components/chordprogression.py
-
56chordsheet/components/guitarchart.py
-
4chordsheet/components/header.py
-
247chordsheet/document.py
-
22chordsheet/parsers.py
-
39chordsheet/primitives.py
-
583chordsheet/render.py
-
51chordsheet/rlStylesheet.py
-
78chordsheet/tableView.py
-
43cli.py
-
12csgui/comboBox.py
-
81csgui/dialogs.py
-
124csgui/messageBox.py
-
64csgui/panels.py
-
96csgui/pdfViewer.py
-
153csgui/tableView.py
-
6examples/ah.xml
-
309examples/ahlong.xml
-
1examples/angela.xml
-
89examples/example.xml
-
143examples/examplelong.xml
-
24examples/kissoflife.cma
-
1examples/kissoflife.xml
-
1examples/test.xml
-
15generate_version_rc.py
-
1235gui.py
-
47linux.spec
-
19mac.spec
-
4requirements.txt
-
142ui/aboutdialog.ui
-
291ui/blocks.ui
-
237ui/chords.ui
-
162ui/docinfo.ui
-
57ui/document.ui
-
2ui/guitardialog.ui
-
BINui/icon.afdesign
-
BINui/icon.icns
-
BINui/icon.ico
-
BINui/icon.png
-
896ui/mainwindow.ui
-
83ui/preview.ui
-
326ui/psetup.ui
-
165ui/sections.ui
-
43version.rc
-
43version.rc.template
-
20win.spec
@ -1,23 +1,52 @@ |
|||||
# Chordsheet |
# Chordsheet |
||||
|
|
||||
Chordsheet is a piece of software that generates a chord sheet, with a simple GUI. |
Chordsheet is a piece of software that generates a chord sheet, with a simple GUI. |
||||
It can load and save chordsheets in its own XML-based format, and can save them in PDF format for printing. |
It can load and save chordsheets in its own XML-based format, and can save them in PDF format for printing. |
||||
|
It's now possible to write a chordsheet in a custom macro language, and import this for further editing in the GUI. See the examples folder for details. |
||||
|
|
||||
I wrote Chordsheet because no other software offered what I was looking for. I did not want to have to enter lyrics (most of the music I am charting is instrumental anyway), needed definite timing information, and wanted to be able to represent guitar chords (with a view to supporting other instruments in future). |
|
||||
|
I wrote Chordsheet because no other software offered what I was looking for. I did not want to have to enter lyrics (most of the music I am charting is instrumental anyway), needed definite timing information, and wanted to be able to represent guitar and piano chords (with a view to supporting other instruments in future). |
||||
|
|
||||
Chordsheet works on a system of blocks, each with a certain length. Blocks may have an assigned chord, or additional information. These blocks can then be ordered and the output generated. |
Chordsheet works on a system of blocks, each with a certain length. Blocks may have an assigned chord, or additional information. These blocks can then be ordered and the output generated. |
||||
|
|
||||
|
## 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 Python 3.7 or newer. Make sure you have the dependencies installed! |
||||
|
|
||||
## Current status |
## Current status |
||||
|
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 |
||||
|
- Multiple sections of the same piece are supported |
||||
|
- Supports reading Chordsheet macro files (custom macro language designed to make it easy to quickly generate chordsheets, see examples folder) |
||||
|
- High quality PDF output |
||||
|
|
||||
Chordsheet is alpha-grade software. At present, the program will crash readily given user input it doesn't expect. |
|
||||
### Limitations |
### Limitations |
||||
- No support for multiple pages |
|
||||
- Only guitar chords can be entered and shown |
|
||||
- No support for lyrics or melody (use something else!) |
- No support for lyrics or melody (use something else!) |
||||
- PDF preview is blurry on high DPI monitors |
- PDF preview is blurry on high DPI monitors |
||||
- Chord names and notes can spill out of their block if it's not big enough |
|
||||
|
- Chord names and notes can spill out of their block if it's not big enough (partially remedied by allowing the user to change the beat width) |
||||
- Poor font handling (choice of either FreeSans or Helvetica Neue if installed) |
- Poor font handling (choice of either FreeSans or Helvetica Neue if installed) |
||||
|
- No internal support for printing |
||||
|
|
||||
## Dependencies |
## Dependencies |
||||
Chordsheet depends on pymupdf (to show the preview), reportlab (to generate the PDF), and PyQt5 (for the GUI). |
Chordsheet depends on pymupdf (to show the preview), reportlab (to generate the PDF), and PyQt5 (for the GUI). |
||||
Also, a font that supports musical symbols is required. A copy of FreeSans is bundled (in the fonts folder). |
Also, a font that supports musical symbols is required. A copy of FreeSans is bundled (in the fonts folder). |
||||
|
This command should sort you out: |
||||
|
```bash |
||||
|
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 |
||||
|
pyinstaller {mac|linux|win}.spec |
||||
|
``` |
||||
|
The generated binary will be in the 'dist' subfolder. |
||||
|
|
||||
|
### Version numbering on Windows |
||||
|
If you are building on Windows and alter the version number, make sure to run `generate_version_rc.py` to update the version.rc file. This file is included in the generated executable and contains the version information viewable in Windows Explorer properties. |
||||
|
|
||||
|
## License |
||||
|
Chordsheet is licensed under the AGPLv3, included in full in 'LICENSE'. |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
appName = "Chordsheet" |
||||
|
version = '0.5.0' |
@ -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)) |
@ -1,61 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from reportlab.pdfgen import canvas |
|
||||
from reportlab.lib.units import mm |
|
||||
from reportlab.lib.pagesizes import A4 |
|
||||
from reportlab.pdfbase import pdfmetrics |
|
||||
from reportlab.pdfbase.ttfonts import TTFont |
|
||||
from reportlab.graphics.shapes import * |
|
||||
|
|
||||
from graphics.primitives import * |
|
||||
|
|
||||
class ChordProgression: |
|
||||
def __init__(self, currentCanvas, blockList, **kwargs): |
|
||||
self.currentCanvas = currentCanvas |
|
||||
|
|
||||
self.beatsHeight = kwargs.get('beatsHeight', 5*mm) |
|
||||
self.timeFontSize = kwargs.get('timeFontSize', 12) |
|
||||
self.chordNameFontSize = kwargs.get('chordNameFontSize', 18) |
|
||||
self.notesFontSize = kwargs.get('notesFontSize', 12) |
|
||||
self.unitWidth = kwargs.get('unitWidth', 10*mm) |
|
||||
self.unitHeight = kwargs.get('unitHeight', 20*mm) |
|
||||
|
|
||||
self.timeSignature = kwargs.get('timeSignature', 4) |
|
||||
def draw(self): |
|
||||
global cur_pos, margin, pagesize |
|
||||
writeText(self.currentCanvas, "Chord progression", size=18, align="left") |
|
||||
|
|
||||
v_origin = cur_pos + 2*mm + self.beatsHeight |
|
||||
h_origin = margin |
|
||||
|
|
||||
h_loc = 0 |
|
||||
v_loc = 0 |
|
||||
|
|
||||
maxWidth = int((((pagesize[0]-(2*margin))/self.unitWidth)//(self.timeSignature*2))*(self.timeSignature*2)) # use integer division to round maxWidth to nearest multiple of time signature |
|
||||
|
|
||||
for u in range(maxWidth+1): |
|
||||
s = 0 |
|
||||
x = u*self.unitWidth+margin |
|
||||
if u % self.timeSignature == 0: |
|
||||
e = -self.beatsHeight |
|
||||
else: |
|
||||
e = -self.beatsHeight/2 |
|
||||
drawVertLine(self.currentCanvas, s, e, x, h_origin, v_origin) |
|
||||
if u == maxWidth: # Avoid writing beat number after the final line |
|
||||
break |
|
||||
writeText(str((u % self.timeSignature)+1),size=self.timeFontSize, hpos=x+self.unitWidth/2, vpos=v_origin-self.beatsHeight) |
|
||||
|
|
||||
blockList = parseBlockList(self.blockList, maxWidth) |
|
||||
|
|
||||
for b in blockList: |
|
||||
if h_loc == maxWidth: |
|
||||
v_loc += 1 |
|
||||
h_loc = 0 |
|
||||
currentCanvas.rect(h_origin+(h_loc*self.unitWidth), v_origin+(v_loc*self.unitHeight), b[0]*self.unitWidth, self.unitHeight) |
|
||||
if b[2]: |
|
||||
writeText(currentCanvas, b[2], size=self.notesFontSize, hpos=h_origin+((h_loc+b[0]/2)*self.unitWidth), vpos=v_origin+((v_loc+1)*self.unitHeight)-(1.3*self.notesFontSize)) |
|
||||
v_offset = (v_loc*self.unitHeight+self.unitHeight/2)-self.chordNameFontSize/2 |
|
||||
writeText(currentCanvas, parseName(b[1]), size=self.chordNameFontSize, hpos=h_origin+((h_loc+b[0]/2)*self.unitWidth), vpos=v_origin+v_offset) |
|
||||
h_loc += b[0] |
|
||||
|
|
||||
cur_pos = v_origin+(v_loc+1)*self.unitHeight+self.beatsHeight |
|
@ -1,56 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from reportlab.pdfgen import canvas |
|
||||
from reportlab.lib.units import mm |
|
||||
from reportlab.lib.pagesizes import A4 |
|
||||
from reportlab.pdfbase import pdfmetrics |
|
||||
from reportlab.pdfbase.ttfonts import TTFont |
|
||||
from reportlab.graphics.shapes import * |
|
||||
|
|
||||
from graphics.primitives import * |
|
||||
|
|
||||
string_hz_sp = 20*mm |
|
||||
string_hz_gap = 2*mm |
|
||||
string_height = 5*mm |
|
||||
|
|
||||
def guitarChart(currentCanvas, string_hz_sp, string_hz_gap, string_height): |
|
||||
global cur_pos, margin, pagesize |
|
||||
|
|
||||
writeText("Guitar chord voicings", size=18, align="left") |
|
||||
|
|
||||
chartmargin = 15*mm |
|
||||
v_origin = cur_pos + 2*mm |
|
||||
h_origin = margin + chartmargin |
|
||||
nstrings = 6 |
|
||||
fontsize = 12 |
|
||||
|
|
||||
guitarChordList = [[chordList[q].guitar[r] for q in range(len(chordList)) if hasattr(chordList[q], 'guitar')] for r in range(6)] |
|
||||
guitarChordList.append([chordList[q].name for q in range(len(chordList))]) |
|
||||
|
|
||||
for i in range(nstrings+1): # i is the string currently being drawn |
|
||||
writeText(['e','B','G','D','A','E','Name'][i], size=fontsize, hpos=(h_origin), vpos=v_origin+(i*string_height), align='right') |
|
||||
|
|
||||
for j in range(len(ls.chords)): # j is which chord (0 is first chord, 1 is 2nd etc) |
|
||||
if j == 0: |
|
||||
charpos = string_hz_sp/2 |
|
||||
s = string_hz_gap |
|
||||
e = charpos-((c.stringWidth(chordList[i][j])/2)+string_hz_gap) |
|
||||
y = v_origin+(string_height*i)+string_height/2 |
|
||||
drawHorizLine(currentCanvas, s, e, y, h_origin, v_origin) |
|
||||
else: |
|
||||
charpos = string_hz_sp*(j+0.5) |
|
||||
s = charpos-string_hz_sp+(lastWidth/2+string_hz_gap) |
|
||||
e = charpos-((currentCanvas.stringWidth(chordList[i][j])/2)+string_hz_gap) |
|
||||
y = v_origin+(string_height*i)+string_height/2 |
|
||||
drawHorizLine(currentCanvas, s, e, y, h_origin, v_origin) |
|
||||
if j == len(ls.chords)-1: |
|
||||
s = charpos+(currentCanvas.stringWidth(chordList[i][j])/2+string_hz_gap) |
|
||||
e = charpos+string_hz_sp/2 |
|
||||
y = v_origin+(string_height*i)+string_height/2 |
|
||||
drawHorizLine(currentCanvas, s, e, y, h_origin, v_origin) |
|
||||
|
|
||||
writeText(chordList[i][j], size=fontsize, hpos=h_origin+charpos, vpos=v_origin+(i*string_height)) |
|
||||
|
|
||||
lastWidth = currentCanvas.stringWidth(chordList[i][j]) |
|
||||
|
|
||||
cur_pos += (string_height*(nstrings+2)) |
|
@ -1,4 +0,0 @@ |
|||||
def header(): |
|
||||
writeText(ls.title.cdata, size=24) |
|
||||
writeText("Composer: {c}".format(c = ls.composer.cdata), size=12) |
|
||||
writeText("Arranger: {a}".format(a = ls.arranger.cdata), size=12) |
|
@ -1,24 +1,32 @@ |
|||||
# -*- coding: utf-8 -*- |
# -*- coding: utf-8 -*- |
||||
|
|
||||
from sys import exit |
|
||||
|
|
||||
def parseFingering(fingering, instrument): |
def parseFingering(fingering, instrument): |
||||
|
""" |
||||
|
Converts fingerings into the list format that Chord objects understand. |
||||
|
""" |
||||
if instrument == 'guitar': |
if instrument == 'guitar': |
||||
numStrings = 6 |
numStrings = 6 |
||||
if len(fingering) == numStrings: |
|
||||
|
if "," not in fingering and len(fingering) == numStrings: # if the fingering is entered in concise format e.g. xx4455 |
||||
output = list(fingering) |
output = list(fingering) |
||||
else: |
|
||||
output = [x for x in fingering.split(',')] |
|
||||
if len(output) == numStrings: |
|
||||
|
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: |
||||
|
print("Voicing <{}> is malformed.".format(fingering)) |
||||
return output |
return output |
||||
else: |
|
||||
exit("Voicing <{v}> is malformed.".format(v=fingering)) |
|
||||
|
elif instrument == 'piano': |
||||
|
return [parseName(note).upper().strip() for note in fingering.split(",")] |
||||
else: |
else: |
||||
return [fingering] |
return [fingering] |
||||
|
|
||||
|
|
||||
|
# dictionary holding text to be replaced in chord names |
||||
nameReplacements = {"b": "♭", "#": "♯"} |
nameReplacements = {"b": "♭", "#": "♯"} |
||||
|
|
||||
def parseName(chordName): |
def parseName(chordName): |
||||
|
""" |
||||
|
Replaces symbols in chord names. |
||||
|
""" |
||||
parsedName = chordName |
parsedName = chordName |
||||
for i, j in nameReplacements.items(): |
for i, j in nameReplacements.items(): |
||||
parsedName = parsedName.replace(i, j) |
parsedName = parsedName.replace(i, j) |
@ -1,39 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from reportlab.pdfgen import canvas |
|
||||
from reportlab.lib.units import mm |
|
||||
from reportlab.graphics.shapes import * |
|
||||
|
|
||||
def writeText(currentCanvas, style, string, size, vpos, **kwargs): |
|
||||
margin = style.leftMargin*style.unit |
|
||||
|
|
||||
align = kwargs.get('align', 'centre') |
|
||||
if align == 'centre' or align == 'center': |
|
||||
hpos = kwargs.get('hpos', style.pageSize[0]/2) |
|
||||
elif align == 'left': |
|
||||
hpos = kwargs.get('hpos', margin) |
|
||||
elif align == 'right': |
|
||||
hpos = kwargs.get('hpos', style.pageSize[0]-margin) |
|
||||
spacing = kwargs.get('spacing', style.lineSpacing) |
|
||||
|
|
||||
currentCanvas.setFont(style.font, size) |
|
||||
|
|
||||
if align == 'centre' or align == 'center': |
|
||||
currentCanvas.drawCentredString(hpos, vpos+(0.75*size*spacing),string) |
|
||||
elif align == 'left': |
|
||||
currentCanvas.drawString(hpos, vpos+(0.75*size*spacing),string) |
|
||||
elif align == 'right': |
|
||||
currentCanvas.drawString(hpos-currentCanvas.stringWidth(string), vpos+(0.75*size*spacing),string) |
|
||||
|
|
||||
return size*style.lineSpacing |
|
||||
|
|
||||
def drawHorizLine(currentCanvas, startpoint, endpoint, v_pos, h_origin, v_origin): |
|
||||
x1 = h_origin+startpoint |
|
||||
x2 = h_origin+endpoint |
|
||||
currentCanvas.line(x1, v_pos, x2, v_pos) |
|
||||
|
|
||||
def drawVertLine(currentCanvas, startpoint, endpoint, h_pos, h_origin, v_origin): |
|
||||
y1 = v_origin+startpoint |
|
||||
y2 = v_origin+endpoint |
|
||||
currentCanvas.line(h_pos, y1, h_pos, y2) |
|
||||
|
|
@ -0,0 +1,51 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from reportlab.lib.styles import StyleSheet1, ParagraphStyle |
||||
|
from reportlab.lib.enums import * |
||||
|
from reportlab.lib.units import mm |
||||
|
from reportlab.lib.colors import black |
||||
|
|
||||
|
def getStyleSheet(csStyle): |
||||
|
"""Returns a stylesheet object""" |
||||
|
stylesheet = StyleSheet1() |
||||
|
|
||||
|
stylesheet.add(ParagraphStyle(name='Master', |
||||
|
fontName=csStyle.font)) |
||||
|
|
||||
|
stylesheet.add(ParagraphStyle(name='Title', |
||||
|
leading=csStyle.lineSpacing*csStyle.titleFontSize, |
||||
|
fontSize=csStyle.titleFontSize, |
||||
|
alignment=TA_CENTER, |
||||
|
parent=stylesheet['Master']) |
||||
|
) |
||||
|
|
||||
|
stylesheet.add(ParagraphStyle(name='Subtitle', |
||||
|
leading=csStyle.lineSpacing*csStyle.subtitleFontSize, |
||||
|
fontSize=csStyle.subtitleFontSize, |
||||
|
alignment=TA_CENTER, |
||||
|
parent=stylesheet['Master']) |
||||
|
) |
||||
|
stylesheet.add(ParagraphStyle(name='Credits', |
||||
|
leading=csStyle.lineSpacing*csStyle.creditsFontSize, |
||||
|
fontSize=csStyle.creditsFontSize, |
||||
|
alignment=TA_CENTER, |
||||
|
parent=stylesheet['Master']) |
||||
|
) |
||||
|
|
||||
|
stylesheet.add(ParagraphStyle(name='Tempo', |
||||
|
leading=csStyle.lineSpacing*csStyle.tempoFontSize, |
||||
|
fontSize=csStyle.tempoFontSize, |
||||
|
alignment=TA_LEFT, |
||||
|
parent=stylesheet['Master']) |
||||
|
) |
||||
|
|
||||
|
stylesheet.add(ParagraphStyle(name='Heading', |
||||
|
leading=csStyle.lineSpacing*csStyle.headingFontSize, |
||||
|
fontSize=csStyle.headingFontSize, |
||||
|
alignment=TA_LEFT, |
||||
|
parent=stylesheet['Master'], |
||||
|
spaceAfter=2*mm, |
||||
|
keepWithNext=1) |
||||
|
) |
||||
|
|
||||
|
return stylesheet |
@ -1,78 +0,0 @@ |
|||||
import sys |
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore |
|
||||
|
|
||||
class MItemModel(QtGui.QStandardItemModel): |
|
||||
|
|
||||
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) |
|
||||
|
|
||||
class MProxyStyle(QtWidgets.QProxyStyle): |
|
||||
|
|
||||
def drawPrimitive(self, element, option, painter, widget=None): |
|
||||
""" |
|
||||
Draw a line across the entire row rather than just the column |
|
||||
we're hovering over. This may not always work depending on global |
|
||||
style. |
|
||||
""" |
|
||||
if element == self.PE_IndicatorItemViewItemDrop and not option.rect.isNull(): |
|
||||
option_new = QtWidgets.QStyleOption(option) |
|
||||
option_new.rect.setLeft(0) |
|
||||
if widget: |
|
||||
option_new.rect.setRight(widget.width()) |
|
||||
option = option_new |
|
||||
super().drawPrimitive(element, option, painter, widget) |
|
||||
|
|
||||
class MTableView(QtWidgets.QTableView): |
|
||||
|
|
||||
def __init__(self, parent): |
|
||||
super().__init__(parent) |
|
||||
|
|
||||
self.verticalHeader().hide() |
|
||||
self.horizontalHeader().show() |
|
||||
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) |
|
||||
self.setShowGrid(False) |
|
||||
#self.setDragDropMode(self.InternalMove) |
|
||||
#self.setDragDropOverwriteMode(False) |
|
||||
|
|
||||
# Set our custom style - this draws the drop indicator across the whole row |
|
||||
self.setStyle(MProxyStyle()) |
|
||||
|
|
||||
self.model = MItemModel() |
|
||||
self.setModel(self.model) |
|
||||
|
|
||||
class ChordTableView(MTableView): |
|
||||
|
|
||||
def __init__(self, parent): |
|
||||
super().__init__(parent) |
|
||||
|
|
||||
self.model.setHorizontalHeaderLabels(['Chord', 'Voicing']) |
|
||||
|
|
||||
def populate(self, cList): |
|
||||
self.model.removeRows(0, self.model.rowCount()) |
|
||||
for c in cList: |
|
||||
rowList = [QtGui.QStandardItem(c.name), QtGui.QStandardItem(",".join(c.guitar if hasattr(c, 'guitar') else ""))] |
|
||||
for item in rowList: |
|
||||
item.setEditable(False) |
|
||||
item.setDropEnabled(False) |
|
||||
|
|
||||
self.model.appendRow(rowList) |
|
||||
|
|
||||
class BlockTableView(MTableView): |
|
||||
|
|
||||
def __init__(self, parent): |
|
||||
super().__init__(parent) |
|
||||
|
|
||||
self.model.setHorizontalHeaderLabels(['Chord', 'Length', 'Notes']) |
|
||||
|
|
||||
def populate(self, bList): |
|
||||
self.model.removeRows(0, self.model.rowCount()) |
|
||||
for b in bList: |
|
||||
rowList = [QtGui.QStandardItem((b.chord.name if b.chord else "")), QtGui.QStandardItem(str(b.length)), QtGui.QStandardItem(b.notes)] |
|
||||
for item in rowList: |
|
||||
item.setEditable(False) |
|
||||
item.setDropEnabled(False) |
|
||||
|
|
||||
self.model.appendRow(rowList) |
|
@ -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,0 +1,12 @@ |
|||||
|
from PyQt5.QtWidgets import QComboBox |
||||
|
from PyQt5.QtCore import pyqtSignal |
||||
|
|
||||
|
class MComboBox(QComboBox): |
||||
|
""" |
||||
|
Modified version of combobox that emits a signal with the current item when clicked. |
||||
|
""" |
||||
|
clicked = pyqtSignal(str) |
||||
|
|
||||
|
def showPopup(self): |
||||
|
self.clicked.emit(self.currentText()) |
||||
|
super().showPopup() |
@ -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() |
@ -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) |
@ -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") |
@ -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) |
@ -0,0 +1,153 @@ |
|||||
|
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" |
||||
|
""" |
||||
|
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): |
||||
|
""" |
||||
|
Proxy style to change the appearance of the TableView. |
||||
|
""" |
||||
|
|
||||
|
def drawPrimitive(self, element, option, painter, widget=None): |
||||
|
""" |
||||
|
Draw a line across the entire row rather than just the column |
||||
|
we're hovering over. |
||||
|
""" |
||||
|
if element == self.PE_IndicatorItemViewItemDrop and not option.rect.isNull(): |
||||
|
option_new = QtWidgets.QStyleOption(option) |
||||
|
option_new.rect.setLeft(0) |
||||
|
if widget: |
||||
|
option_new.rect.setRight(widget.width()) |
||||
|
option = option_new |
||||
|
super().drawPrimitive(element, option, painter, widget) |
||||
|
|
||||
|
|
||||
|
class MTableView(QtWidgets.QTableView): |
||||
|
""" |
||||
|
Subclass the built in TableView to customise it. |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, parent): |
||||
|
super().__init__(parent) |
||||
|
|
||||
|
self.model = MItemModel() |
||||
|
self.setModel(self.model) |
||||
|
|
||||
|
self.verticalHeader().hide() |
||||
|
self.horizontalHeader().show() |
||||
|
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Interactive) |
||||
|
self.horizontalHeader().setStretchLastSection(True) |
||||
|
|
||||
|
self.setShowGrid(False) |
||||
|
# self.setDragDropMode(self.InternalMove) |
||||
|
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): |
||||
|
""" |
||||
|
Subclass MTableView to add properties just for the chord table. |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, parent): |
||||
|
super().__init__(parent) |
||||
|
|
||||
|
self.model.setHorizontalHeaderLabels(['Chord', 'Guitar voicing', 'Piano voicing']) |
||||
|
|
||||
|
def populate(self, cList): |
||||
|
""" |
||||
|
Fill the table from a list of Chord objects. |
||||
|
""" |
||||
|
self.model.removeRows(0, self.model.rowCount()) |
||||
|
for c in cList: |
||||
|
rowList = [QtGui.QStandardItem(c.name), QtGui.QStandardItem( |
||||
|
",".join(c.voicings['guitar'] if 'guitar' in c.voicings.keys() else "")), |
||||
|
QtGui.QStandardItem( |
||||
|
",".join(c.voicings['piano'] if 'piano' in c.voicings.keys() else ""))] |
||||
|
for item in rowList: |
||||
|
item.setEditable(False) |
||||
|
item.setDropEnabled(False) |
||||
|
|
||||
|
self.model.appendRow(rowList) |
||||
|
|
||||
|
|
||||
|
class SectionTableView(MTableView): |
||||
|
""" |
||||
|
Subclass MTableView to add properties just for the section table. |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, parent): |
||||
|
super().__init__(parent) |
||||
|
|
||||
|
self.model.setHorizontalHeaderLabels(['Name']) |
||||
|
|
||||
|
def populate(self, sList): |
||||
|
""" |
||||
|
Fill the table from a list of Section objects. |
||||
|
""" |
||||
|
self.model.removeRows(0, self.model.rowCount()) |
||||
|
for s in sList: |
||||
|
rowList = [QtGui.QStandardItem(s.name)] |
||||
|
for item in rowList: |
||||
|
item.setEditable(False) |
||||
|
item.setDropEnabled(False) |
||||
|
|
||||
|
self.model.appendRow(rowList) |
||||
|
|
||||
|
|
||||
|
class BlockTableView(MTableView): |
||||
|
""" |
||||
|
Subclass MTableView to add properties just for the block table. |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, parent): |
||||
|
super().__init__(parent) |
||||
|
|
||||
|
self.model.setHorizontalHeaderLabels(['Chord', 'Length', 'Notes']) |
||||
|
|
||||
|
def populate(self, bList): |
||||
|
""" |
||||
|
Fill the table from a list of Block objects. |
||||
|
""" |
||||
|
self.model.removeRows(0, self.model.rowCount()) |
||||
|
for b in bList: |
||||
|
rowList = [QtGui.QStandardItem((b.chord.name if b.chord else "")), QtGui.QStandardItem( |
||||
|
str(b.length)), QtGui.QStandardItem(b.notes)] |
||||
|
for item in rowList: |
||||
|
item.setEditable(False) |
||||
|
item.setDropEnabled(False) |
||||
|
|
||||
|
self.model.appendRow(rowList) |
@ -0,0 +1,309 @@ |
|||||
|
<chordsheet> |
||||
|
<title>"African Heritage"</title> |
||||
|
<subtitle>A corroboration</subtitle> |
||||
|
<composer>Ivan Holmes</composer> |
||||
|
<arranger>Ivan Holmes and Joe Buckley</arranger> |
||||
|
<tempo>120</tempo> |
||||
|
<timesignature>6</timesignature> |
||||
|
<chords> |
||||
|
<chord> |
||||
|
<name>Gm9</name> |
||||
|
<voicing instrument="guitar">x,10,8,10,10,x</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>Abm9</name> |
||||
|
<voicing instrument="guitar">x,11,9,11,11,x</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>Cm9</name> |
||||
|
<voicing instrument="guitar">x,x,8,8,8,10</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>D7#5#9</name> |
||||
|
<voicing instrument="guitar">x58565</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>Eb7#5#9</name> |
||||
|
<voicing instrument="guitar">x69676</voicing> |
||||
|
</chord> |
||||
|
</chords> |
||||
|
<section name="A section"> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
<notes>over Ab</notes> |
||||
|
</block> |
||||
|
</section> |
||||
|
<section name="B section"> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
</section> |
||||
|
<section name="C section"> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
<notes>over Ab</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
<notes>over Ab</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
<notes>over Ab</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>Abm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>9</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>12</length> |
||||
|
<chord>Gm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Eb7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>6</length> |
||||
|
<chord>Cm9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>3</length> |
||||
|
<chord>D7#5#9</chord> |
||||
|
<notes>over Ab</notes> |
||||
|
</block> |
||||
|
</section> |
||||
|
</chordsheet> |
@ -0,0 +1 @@ |
|||||
|
<chordsheet><title>Angela</title><subtitle>Theme from 'Taxi'</subtitle><arranger>Max</arranger><composer>Bob James</composer><timesignature>4</timesignature><chords><chord><name>E♭maj7</name><voicing instrument="guitar">x,x,1,3,3,3</voicing></chord><chord><name>A♭ma7</name><voicing instrument="guitar">x,x,1,1,1,3</voicing></chord><chord><name>Gm7</name><voicing instrument="guitar">3,x,3,3,3,x</voicing></chord><chord><name>B♭/D</name><voicing instrument="guitar">x,x,0,3,3,1</voicing></chord><chord><name>A♭maj7/C</name><voicing instrument="guitar">x,3,1,1,1,3</voicing></chord><chord><name>B♭</name><voicing instrument="guitar">x,1,3,3,3,1</voicing></chord><chord><name>A♭</name><voicing instrument="guitar">4,6,6,5,4,4</voicing></chord><chord><name>E♭/G</name><voicing instrument="guitar">x,x,5,3,4,3</voicing></chord><chord><name>Fm</name><voicing instrument="guitar">x,x,3,1,1,1</voicing></chord><chord><name>A♭/B♭</name><voicing instrument="guitar">6,x,6,5,4,4</voicing></chord><chord><name>E♭</name><voicing instrument="guitar">x,6,5,3,4,3</voicing></chord><chord><name>E♭7</name><voicing instrument="guitar">x,x,1,3,2,3</voicing></chord><chord><name>A♭maj9</name><voicing instrument="guitar">4,x,5,3,4,3</voicing></chord><chord><name>Fm7</name><voicing instrument="guitar">1,x,1,1,1,x</voicing></chord></chords><section name="Intro"><block><length>2.0</length><chord>E♭maj7</chord></block><block><length>2.0</length><chord>A♭ma7</chord></block><block><length>2.0</length><chord>Gm7</chord></block><block><length>2.0</length><chord>B♭/D</chord></block><block><length>2.0</length><chord>A♭maj7/C</chord></block><block><length>2.0</length><chord>B♭</chord></block><block><length>1.0</length><chord>A♭</chord></block><block><length>1.0</length><chord>E♭/G</chord></block><block><length>1.0</length><chord>Fm</chord></block><block><length>1.0</length><chord>A♭/B♭</chord></block><block><length>2.0</length><chord>E♭</chord></block><block><length>2.0</length><chord>E♭7</chord></block><block><length>2.0</length><chord>A♭maj9</chord></block><block><length>2.0</length><chord>E♭/G</chord></block><block><length>2.0</length><chord>Fm7</chord></block><block><length>2.0</length><chord>B♭</chord></block><block><length>1.0</length><chord>A♭</chord></block><block><length>1.0</length><chord>E♭/G</chord></block><block><length>1.0</length><chord>Fm</chord></block><block><length>1.0</length><chord>A♭/B♭</chord></block></section></chordsheet> |
@ -1,46 +1,93 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
<chordsheet> |
<chordsheet> |
||||
<title>Composition</title> |
|
||||
<composer>A. Person</composer> |
|
||||
|
<title>Example Song</title> |
||||
|
<composer>Ivan Holmes</composer> |
||||
<timesignature>4</timesignature> |
<timesignature>4</timesignature> |
||||
<chords> |
<chords> |
||||
<chord> |
<chord> |
||||
<name>B</name> |
|
||||
<voicing instrument="guitar">xx2341</voicing> |
|
||||
<voicing instrument="piano">abcdefg</voicing> |
|
||||
|
<name>C7</name> |
||||
|
<voicing instrument="guitar">x,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">Bb,E,C,G</voicing> |
||||
</chord> |
</chord> |
||||
<chord> |
<chord> |
||||
<name>E</name> |
|
||||
<voicing instrument="guitar">022100</voicing> |
|
||||
|
<name>F</name> |
||||
|
<voicing instrument="guitar">1,3,3,2,1,1</voicing> |
||||
|
<voicing instrument="piano">A,C,F</voicing> |
||||
</chord> |
</chord> |
||||
<chord> |
<chord> |
||||
<name>Cm9</name> |
|
||||
<voicing instrument="guitar">x,x,8,8,8,10</voicing> |
|
||||
|
<name>G</name> |
||||
|
<voicing instrument="guitar">3,2,0,0,0,3</voicing> |
||||
|
<voicing instrument="piano">B,D,G</voicing> |
||||
</chord> |
</chord> |
||||
<chord> |
<chord> |
||||
<name>D7b5#9</name> |
|
||||
|
<name>C/G</name> |
||||
|
<voicing instrument="guitar">3,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">G,C,E</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>Dm</name> |
||||
|
<voicing instrument="guitar">x,x,0,2,3,1</voicing> |
||||
|
<voicing instrument="piano">A,D,F</voicing> |
||||
</chord> |
</chord> |
||||
</chords> |
</chords> |
||||
<progression> |
|
||||
|
<section name="Example section"> |
||||
|
<block> |
||||
|
<length>16</length> |
||||
|
<chord>C7</chord> |
||||
|
<notes>Intro, strum lightly</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>F</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>8</length> |
||||
|
<chord>G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>F</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>8</length> |
||||
|
<chord>G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
<block> |
<block> |
||||
<length>4</length> |
<length>4</length> |
||||
<chord>B</chord> |
|
||||
<notes>These are notes</notes> |
|
||||
|
<chord>Dm</chord> |
||||
</block> |
</block> |
||||
<block> |
<block> |
||||
<length>4</length> |
<length>4</length> |
||||
<chord>E</chord> |
|
||||
|
<chord>C/G</chord> |
||||
</block> |
</block> |
||||
<block> |
<block> |
||||
<length>12</length> |
|
||||
<chord>Cm9</chord> |
|
||||
|
<length>4</length> |
||||
|
<chord>G</chord> |
||||
</block> |
</block> |
||||
<block> |
<block> |
||||
<length>6</length> |
|
||||
<chord>D7b5#9</chord> |
|
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<notes>Contemplation time</notes> |
||||
</block> |
</block> |
||||
<block> |
<block> |
||||
<length>6</length> |
|
||||
<notes>For quiet contemplation.</notes> |
|
||||
|
<length>8</length> |
||||
|
<chord>C7</chord> |
||||
|
<notes>Crescendo until end</notes> |
||||
</block> |
</block> |
||||
</progression> |
|
||||
|
</section> |
||||
</chordsheet> |
</chordsheet> |
@ -0,0 +1,143 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<chordsheet> |
||||
|
<title>Example Song</title> |
||||
|
<composer>Ivan Holmes</composer> |
||||
|
<timesignature>4</timesignature> |
||||
|
<chords> |
||||
|
<chord> |
||||
|
<name>C7</name> |
||||
|
<voicing instrument="guitar">x,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">Bb,E,C,G</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>F</name> |
||||
|
<voicing instrument="guitar">1,3,3,2,1,1</voicing> |
||||
|
<voicing instrument="piano">A,C,F</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>G</name> |
||||
|
<voicing instrument="guitar">3,2,0,0,0,3</voicing> |
||||
|
<voicing instrument="piano">B,D,G</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>C/G</name> |
||||
|
<voicing instrument="guitar">3,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">G,C,E</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>Dm</name> |
||||
|
<voicing instrument="guitar">x,x,0,2,3,1</voicing> |
||||
|
<voicing instrument="piano">A,D,F</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>q7</name> |
||||
|
<voicing instrument="guitar">x,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">Bb,E,C,G</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>q3</name> |
||||
|
<voicing instrument="guitar">1,3,3,2,1,1</voicing> |
||||
|
<voicing instrument="piano">A,C,F</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>q5</name> |
||||
|
<voicing instrument="guitar">3,2,0,0,0,3</voicing> |
||||
|
<voicing instrument="piano">B,D,G</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>q/G</name> |
||||
|
<voicing instrument="guitar">3,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">G,C,E</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>q</name> |
||||
|
<voicing instrument="guitar">x,x,0,2,3,1</voicing> |
||||
|
<voicing instrument="piano">A,D,F</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>yeeq</name> |
||||
|
<voicing instrument="guitar">x,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">Bb,E,C,G</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>quu</name> |
||||
|
<voicing instrument="guitar">1,3,3,2,1,1</voicing> |
||||
|
<voicing instrument="piano">A,C,F</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>b3</name> |
||||
|
<voicing instrument="guitar">3,2,0,0,0,3</voicing> |
||||
|
<voicing instrument="piano">B,D</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>aa</name> |
||||
|
<voicing instrument="guitar">3,3,2,0,1,0</voicing> |
||||
|
<voicing instrument="piano">G,C,E</voicing> |
||||
|
</chord> |
||||
|
<chord> |
||||
|
<name>z</name> |
||||
|
<voicing instrument="guitar">x,x,0,2,3,1</voicing> |
||||
|
<voicing instrument="piano">A,D,F,G,E,B,C</voicing> |
||||
|
</chord> |
||||
|
</chords> |
||||
|
<section name="Example section"> |
||||
|
<block> |
||||
|
<length>16</length> |
||||
|
<chord>C7</chord> |
||||
|
<notes>Intro, strum lightly</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>F</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>8</length> |
||||
|
<chord>G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>F</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>8</length> |
||||
|
<chord>G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>Dm</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C/G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>G</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<chord>C7</chord> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>4</length> |
||||
|
<notes>Contemplation time</notes> |
||||
|
</block> |
||||
|
<block> |
||||
|
<length>8</length> |
||||
|
<chord>C7</chord> |
||||
|
<notes>Crescendo until end</notes> |
||||
|
</block> |
||||
|
</section> |
||||
|
</chordsheet> |
@ -0,0 +1,24 @@ |
|||||
|
\chordsheet 1 |
||||
|
\rem This is a comment to say that the first line isn't really needed (as there's only one version of Chordsheet Macro so far) |
||||
|
|
||||
|
\title Kiss of Life |
||||
|
\subtitle Sade |
||||
|
\arranger Ivan Holmes |
||||
|
\composer Sade Adu, Paul S. Denman, Andrew Hale, Stuart Matthewman |
||||
|
\timesig 4 |
||||
|
\tempo 120 |
||||
|
|
||||
|
\chord AM9 piano A,B,C#,E |
||||
|
\chord F#m11 alias F piano A,B,C#,E |
||||
|
\chord DM7 piano A,C#,F# |
||||
|
\chord C#m7 piano G#,B,E |
||||
|
\chord Bm7 piano A,D,F# |
||||
|
|
||||
|
\section Intro and verse |
||||
|
AM9,8 F#m11,8 DM7,1.5 |
||||
|
C#m7,2 Bm7,4.5 F#m11,8 |
||||
|
|
||||
|
\! This is another comment. Comments may not exist in the middle of other statements. |
||||
|
|
||||
|
\section Chorus and bridge |
||||
|
Bm7,3.5 F,4.5 Bm7,3.5 F#m11,4.5 |
@ -0,0 +1 @@ |
|||||
|
<chordsheet><title>Kiss of Life</title><subtitle>Sade</subtitle><arranger>Ivan Holmes</arranger><composer>Sade Adu, Paul S. Denman, Andrew Hale, Stuart Matthewman</composer><timesignature>4</timesignature><tempo>120</tempo><chords><chord><name>AM9</name><voicing instrument="piano">A,B,C♯,E</voicing></chord><chord><name>F♯m11</name><voicing instrument="piano">A,B,C♯,E</voicing></chord><chord><name>DM7</name><voicing instrument="piano">A,C♯,F♯</voicing></chord><chord><name>C♯m7</name><voicing instrument="piano">G♯,B,E</voicing></chord><chord><name>Bm7</name><voicing instrument="piano">A,D,F♯</voicing></chord></chords><section name="Intro and verse"><block><length>8.0</length><chord>AM9</chord></block><block><length>8.0</length><chord>F♯m11</chord></block><block><length>1.5</length><chord>DM7</chord></block><block><length>2.0</length><chord>C♯m7</chord></block><block><length>4.5</length><chord>Bm7</chord></block><block><length>8.0</length><chord>F♯m11</chord></block></section><section name="Chorus and bridge"><block><length>3.5</length><chord>Bm7</chord></block><block><length>4.5</length><chord>F♯m11</chord></block><block><length>3.5</length><chord>Bm7</chord></block><block><length>4.5</length><chord>F♯m11</chord></block></section></chordsheet> |
@ -0,0 +1 @@ |
|||||
|
<chordsheet><title>Composition</title><composer>A. Person</composer><timesignature>4</timesignature><chords><chord><name>B</name><voicing instrument="guitar">x,x,2,3,4,1</voicing></chord><chord><name>E</name><voicing instrument="guitar">0,2,2,1,0,0</voicing></chord><chord><name>Cm9</name><voicing instrument="guitar">x,x,8,8,8,10</voicing></chord><chord><name>D7♭5♯9</name></chord></chords><section name="Test section"><block><length>4</length><chord>B</chord><notes>These are notes.</notes></block><block><length>4</length><chord>E</chord></block><block><length>12</length><chord>Cm9</chord></block><block><length>6</length><chord>D7♭5♯9</chord></block><block><length>6</length><notes>For quiet contemplation.</notes></block><block><length>46</length><chord>D7♭5♯9</chord><notes>A very long block to test wrapping!</notes></block></section></chordsheet> |
@ -0,0 +1,15 @@ |
|||||
|
import _version |
||||
|
|
||||
|
with open('version.rc.template', 'r') as verstf: |
||||
|
verstemp = verstf.read() |
||||
|
|
||||
|
major, minor, patch = _version.version.split(".") |
||||
|
|
||||
|
verstemp = verstemp.replace("%APPNAME%", _version.appName) |
||||
|
verstemp = verstemp.replace("%VERSION%", _version.version) |
||||
|
verstemp = verstemp.replace("%MAJOR_VERSION%", major) |
||||
|
verstemp = verstemp.replace("%MINOR_VERSION%", minor) |
||||
|
verstemp = verstemp.replace("%PATCH_VERSION%", patch) |
||||
|
|
||||
|
with open('version.rc', 'w') as versf: |
||||
|
versf.write(verstemp) |
1235
gui.py
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,47 @@ |
|||||
|
# -*- mode: python ; coding: utf-8 -*- |
||||
|
|
||||
|
block_cipher = None |
||||
|
|
||||
|
with open('_version.py', 'r') as versinfo: |
||||
|
exec(versinfo.read()) |
||||
|
|
||||
|
a = Analysis(['gui.py'], |
||||
|
pathex=['/home/ivan/Code/chordsheet'], |
||||
|
binaries=[], |
||||
|
datas=[ |
||||
|
('fonts', 'fonts'), |
||||
|
('ui', 'ui') |
||||
|
], |
||||
|
hiddenimports=['PyQt5.sip'], |
||||
|
hookspath=[], |
||||
|
runtime_hooks=[], |
||||
|
excludes=[], |
||||
|
win_no_prefer_redirects=False, |
||||
|
win_private_assemblies=False, |
||||
|
cipher=block_cipher, |
||||
|
noarchive=False) |
||||
|
pyz = PYZ(a.pure, a.zipped_data, |
||||
|
cipher=block_cipher) |
||||
|
exe = EXE(pyz, |
||||
|
a.scripts, |
||||
|
[], |
||||
|
exclude_binaries=True, |
||||
|
name='chordsheet', |
||||
|
icon='ui/icon.png', |
||||
|
debug=False, |
||||
|
bootloader_ignore_signals=False, |
||||
|
strip=False, |
||||
|
upx=True, |
||||
|
upx_exclude=[], |
||||
|
runtime_tmpdir=None, |
||||
|
console=False, |
||||
|
version='version.rc') |
||||
|
|
||||
|
coll = COLLECT(exe, |
||||
|
a.binaries, |
||||
|
a.zipfiles, |
||||
|
a.datas, |
||||
|
strip=False, |
||||
|
upx=True, |
||||
|
upx_exclude=[], |
||||
|
name='chordsheet-'+version) |
@ -0,0 +1,4 @@ |
|||||
|
reportlab>=3.5.67 |
||||
|
PyMuPDF>=1.18.13 |
||||
|
PyQt5>=5.15.4 |
||||
|
PyQt5.Sip |
@ -0,0 +1,142 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<ui version="4.0"> |
||||
|
<class>Dialog</class> |
||||
|
<widget class="QDialog" name="Dialog"> |
||||
|
<property name="enabled"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
<property name="geometry"> |
||||
|
<rect> |
||||
|
<x>0</x> |
||||
|
<y>0</y> |
||||
|
<width>400</width> |
||||
|
<height>200</height> |
||||
|
</rect> |
||||
|
</property> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="minimumSize"> |
||||
|
<size> |
||||
|
<width>400</width> |
||||
|
<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> |
||||
|
<widget class="QLabel" name="iconLabel"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="minimumSize"> |
||||
|
<size> |
||||
|
<width>128</width> |
||||
|
<height>128</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string/> |
||||
|
</property> |
||||
|
<property name="scaledContents"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<spacer name="verticalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Vertical</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>20</width> |
||||
|
<height>40</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="Line" name="line"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Vertical</enum> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<layout class="QVBoxLayout" name="rightPane"> |
||||
|
<item> |
||||
|
<widget class="QLabel" name="label"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string><html><head/><body><p><span style=" font-size:24pt; font-weight:600;">Chordsheet</span><br/>by Ivan Holmes</p><p>Chordsheet is a piece of software that generates a chord sheet with a simple GUI. </p><p><a href="https://git.radivan.net/ivan/chordsheet"><span style=" text-decoration: underline; color:#0000ff;">Git repository</span></a></p></body></html></string> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
||||
|
</property> |
||||
|
<property name="wordWrap"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
<property name="openExternalLinks"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QLabel" name="versionLabel"> |
||||
|
<property name="sizePolicy"> |
||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum"> |
||||
|
<horstretch>0</horstretch> |
||||
|
<verstretch>0</verstretch> |
||||
|
</sizepolicy> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string>Version not set</string> |
||||
|
</property> |
||||
|
<property name="alignment"> |
||||
|
<set>Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing</set> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
<resources/> |
||||
|
<connections/> |
||||
|
</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> |
@ -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> |
@ -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> |
@ -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> |
After Width: 1024 | Height: 1024 | Size: 236 KiB |
@ -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> |
@ -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> |
@ -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> |
@ -0,0 +1,43 @@ |
|||||
|
# UTF-8 |
||||
|
# |
||||
|
# For more details about fixed file info 'ffi' see: |
||||
|
# http://msdn.microsoft.com/en-us/library/ms646997.aspx |
||||
|
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, 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. |
||||
|
flags=0x0, |
||||
|
# The operating system for which this file was designed. |
||||
|
# 0x4 - NT and there is no need to change it. |
||||
|
OS=0x4, |
||||
|
# The general type of file. |
||||
|
# 0x1 - the file is an application. |
||||
|
fileType=0x1, |
||||
|
# The function of the file. |
||||
|
# 0x0 - the function is not defined for this fileType |
||||
|
subtype=0x0, |
||||
|
# Creation date and time stamp. |
||||
|
date=(0, 0) |
||||
|
), |
||||
|
kids=[ |
||||
|
StringFileInfo( |
||||
|
[ |
||||
|
StringTable( |
||||
|
u'040904B0', |
||||
|
[StringStruct(u'CompanyName', u'Ivan Holmes'), |
||||
|
StringStruct(u'FileDescription', u'Chordsheet'), |
||||
|
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.5.0')]) |
||||
|
]), |
||||
|
VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) |
||||
|
] |
||||
|
) |
@ -0,0 +1,43 @@ |
|||||
|
# UTF-8 |
||||
|
# |
||||
|
# For more details about fixed file info 'ffi' see: |
||||
|
# http://msdn.microsoft.com/en-us/library/ms646997.aspx |
||||
|
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=(%MAJOR_VERSION%, %MINOR_VERSION%, %PATCH_VERSION%, 0), |
||||
|
prodvers=(%MAJOR_VERSION%, %MINOR_VERSION%, %PATCH_VERSION%, 0), |
||||
|
# Contains a bitmask that specifies the valid bits 'flags'r |
||||
|
mask=0x3f, |
||||
|
# Contains a bitmask that specifies the Boolean attributes of the file. |
||||
|
flags=0x0, |
||||
|
# The operating system for which this file was designed. |
||||
|
# 0x4 - NT and there is no need to change it. |
||||
|
OS=0x4, |
||||
|
# The general type of file. |
||||
|
# 0x1 - the file is an application. |
||||
|
fileType=0x1, |
||||
|
# The function of the file. |
||||
|
# 0x0 - the function is not defined for this fileType |
||||
|
subtype=0x0, |
||||
|
# Creation date and time stamp. |
||||
|
date=(0, 0) |
||||
|
), |
||||
|
kids=[ |
||||
|
StringFileInfo( |
||||
|
[ |
||||
|
StringTable( |
||||
|
u'040904B0', |
||||
|
[StringStruct(u'CompanyName', u'Ivan Holmes'), |
||||
|
StringStruct(u'FileDescription', u'%APPNAME%'), |
||||
|
StringStruct(u'FileVersion', u'%VERSION%'), |
||||
|
StringStruct(u'InternalName', u'%APPNAME%'), |
||||
|
StringStruct(u'LegalCopyright', u'Copyright (c) Ivan Holmes, 2020. Some rights reserved.'), |
||||
|
StringStruct(u'OriginalFilename', u'chordsheet.exe'), |
||||
|
StringStruct(u'ProductName', u'%APPNAME%'), |
||||
|
StringStruct(u'ProductVersion', u'%VERSION%')]) |
||||
|
]), |
||||
|
VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) |
||||
|
] |
||||
|
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue