-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #423 from PeterBjuhr/svg-edit
Svg edit - multiple improvements, and start of transferring edits to the source
- Loading branch information
Showing
11 changed files
with
1,006 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/ | ||
# | ||
# Copyright (c) 2008 - 2014 by Wilbert Berendsen | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
# See http://www.gnu.org/licenses/ for more information. | ||
|
||
""" | ||
An Object Editor | ||
""" | ||
|
||
# Note: This is only a very first stub | ||
|
||
from __future__ import unicode_literals | ||
|
||
import sys | ||
|
||
from PyQt4.QtCore import Qt | ||
from PyQt4.QtGui import QKeySequence | ||
|
||
import panel | ||
|
||
class ObjectEditor(panel.Panel): | ||
def __init__(self, mainwindow): | ||
super(ObjectEditor, self).__init__(mainwindow) | ||
self.hide() | ||
self.toggleViewAction().setShortcut(QKeySequence("Meta+Alt+E")) | ||
mainwindow.addDockWidget(Qt.LeftDockWidgetArea, self) | ||
|
||
def translateUI(self): | ||
self.setWindowTitle(_("Object Editor")) | ||
self.toggleViewAction().setText(_("O&bject Editor")) | ||
|
||
def createWidget(self): | ||
from . import widget | ||
w = widget.Widget(self) | ||
return w | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/ | ||
# | ||
# Copyright (c) 2008 - 2014 by Wilbert Berendsen | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
# See http://www.gnu.org/licenses/ for more information. | ||
|
||
""" | ||
Finds out which type of LilyPond object the offset will be applied to | ||
using ly.music, stores this data and creates and inserts an override command. | ||
""" | ||
|
||
from __future__ import unicode_literals | ||
|
||
from PyQt4 import QtGui | ||
|
||
import documentinfo | ||
import lydocument | ||
import reformat | ||
|
||
|
||
class DefineOffset(): | ||
|
||
def __init__(self, doc): | ||
self.doc = doc | ||
self.docinfo = documentinfo.music(doc) | ||
self.node = None | ||
self.lilyObject = None | ||
self.lilyContext = "" | ||
self.pos = 0 | ||
|
||
def getCurrentLilyObject(self, cursor): | ||
""" Use cursor from textedit link to get type of object being edited.""" | ||
lycursor = lydocument.cursor(cursor) | ||
self.pos = lycursor.start | ||
node = self.docinfo.node(self.pos) | ||
self.node = node | ||
child = self.docinfo.iter_music(node) | ||
for c in child: | ||
name = c.__class__.__name__ #get instance name | ||
return self.item2object(name) | ||
name = node.__class__.__name__ | ||
return self.item2object(name) | ||
|
||
def item2object(self, item): | ||
""" Translate item type into name of | ||
LilyPond object. | ||
""" | ||
item2objectDict = { | ||
"String": { "GrobType": "TextScript" }, | ||
"Markup": { "GrobType": "TextScript" }, | ||
"Tempo": { "GrobType": "MetronomeMark", | ||
"Context" : "Score" }, | ||
"Articulation": { "GrobType": "Script" } | ||
} | ||
try: | ||
obj = item2objectDict[item] | ||
except KeyError: | ||
obj = { "GrobType": "still testing!" } | ||
self.lilyObject = obj["GrobType"] | ||
if "Context" in obj: | ||
self.lilyContext = obj["Context"] | ||
return obj["GrobType"] | ||
|
||
def insertOverride(self, x, y): | ||
""" Insert the override command. """ | ||
doc = lydocument.Document(self.doc) | ||
block = doc.block(self.pos) | ||
p = block.position() | ||
cursor = QtGui.QTextCursor(self.doc) | ||
cursor.setPosition(p) | ||
cursor.beginEditBlock() | ||
cursor.insertText(self.createOffsetOverride(x, y)) | ||
cursor.insertBlock() | ||
cursor.endEditBlock() | ||
reformat.reformat(cursor) | ||
|
||
def createOffsetOverride(self, x, y): | ||
""" Create the override command. | ||
Can this be created as a node? | ||
""" | ||
objToOverride = self.lilyContext | ||
if len(objToOverride) > 0: | ||
objToOverride += "." | ||
objToOverride += self.lilyObject | ||
return "\once \override " + objToOverride + ".extra-offset = #'(" + str(x) + " . " + str(y) + ")" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/ | ||
# | ||
# Copyright (c) 2008 - 2014 by Wilbert Berendsen | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
# See http://www.gnu.org/licenses/ for more information. | ||
|
||
""" | ||
An Object Editor widget. | ||
""" | ||
|
||
from __future__ import unicode_literals | ||
|
||
import sys | ||
|
||
from PyQt4 import QtCore | ||
from PyQt4.QtCore import * | ||
from PyQt4.QtGui import * | ||
|
||
import app | ||
import objecteditor | ||
|
||
from . import defineoffset | ||
|
||
|
||
class Widget(QWidget): | ||
|
||
# I think we will work with individual editor objects for different types of objects. | ||
# Each one will be shown/hidden on demand, i.e. when an element is activated | ||
# through the SVG view, the music view or the cursor in the source. | ||
# Each editor object handles its own connections to signals. | ||
# (PS: The object editor will also work with the source code directly, | ||
# i.e. independently of graphical SVG editing.) | ||
|
||
def __init__(self, tool): | ||
super(Widget, self).__init__(tool) | ||
self.mainwindow = tool.mainwindow() | ||
self.define = None | ||
|
||
import panelmanager | ||
self.svgview = panelmanager.manager(tool.mainwindow()).svgview.widget().view | ||
|
||
layout = QVBoxLayout(spacing=1) | ||
self.setLayout(layout) | ||
|
||
self.elemLabel = QLabel() | ||
|
||
self.XOffsetBox = QDoubleSpinBox() | ||
self.XOffsetBox.setRange(-99,99) | ||
self.XOffsetBox.setSingleStep(0.1) | ||
self.XOffsetLabel = l = QLabel() | ||
l.setBuddy(self.XOffsetBox) | ||
|
||
self.YOffsetBox = QDoubleSpinBox() | ||
self.YOffsetBox.setRange(-99,99) | ||
self.YOffsetBox.setSingleStep(0.1) | ||
self.YOffsetLabel = l = QLabel() | ||
l.setBuddy(self.YOffsetBox) | ||
|
||
self.insertButton = QPushButton("insert offset in source", self) | ||
self.insertButton.clicked.connect(self.callInsert) | ||
|
||
layout.addWidget(self.elemLabel) | ||
layout.addWidget(self.XOffsetBox) | ||
layout.addWidget(self.XOffsetLabel) | ||
layout.addWidget(self.YOffsetBox) | ||
layout.addWidget(self.YOffsetLabel) | ||
layout.addWidget(self.insertButton) | ||
|
||
layout.addStretch(1) | ||
|
||
app.translateUI(self) | ||
self.loadSettings() | ||
|
||
self.connectSlots() | ||
|
||
def connectSlots(self): | ||
# On creation we connect to all available signals | ||
self.connectToSvgView() | ||
|
||
def connectToSvgView(self): | ||
"""Register with signals emitted by the | ||
SVG viewer for processing graphical editing. | ||
""" | ||
self.svgview.objectStartDragging.connect(self.startDragging) | ||
self.svgview.objectDragging.connect(self.Dragging) | ||
self.svgview.objectDragged.connect(self.Dragged) | ||
self.svgview.cursor.connect(self.setObjectFromCursor) | ||
|
||
def disconnectFromSvgView(self): | ||
"""Do not process graphical edits when the | ||
Object Editor isn't visible.""" | ||
self.svgview.objectStartDragging.disconnect() | ||
self.svgview.objectDragging.disconnect() | ||
self.svgview.objectDragged.disconnect() | ||
self.svgview.cursor.disconnect() | ||
|
||
def translateUI(self): | ||
self.XOffsetLabel.setText(_("X Offset")) | ||
self.XOffsetBox.setToolTip(_("Display the X Offset")) | ||
self.YOffsetLabel.setText(_("Y Offset")) | ||
self.YOffsetBox.setToolTip(_("Display the Y Offset")) | ||
self.insertButton.setEnabled(False) | ||
|
||
def hideEvent(self, event): | ||
"""Disconnect from all graphical editing signals | ||
when the panel isn't visible | ||
""" | ||
self.disconnectFromSvgView() | ||
event.accept() | ||
|
||
def showEvent(self, event): | ||
"""Connect to the graphical editing signals | ||
when the panel becomes visible | ||
""" | ||
self.connectToSvgView() | ||
event.accept() | ||
|
||
def callInsert(self): | ||
""" Insert the override command in the source.""" | ||
if self.define: | ||
self.define.insertOverride(self.XOffsetBox.value(), self.YOffsetBox.value()) | ||
|
||
@QtCore.pyqtSlot(float, float) | ||
def setOffset(self, x, y): | ||
"""Display the updated offset.""" | ||
self.XOffsetBox.setValue(x) | ||
self.YOffsetBox.setValue(y) | ||
|
||
@QtCore.pyqtSlot(float, float) | ||
def startDragging(self, x, y): | ||
"""Set the value of the offset externally.""" | ||
# temporary debug output | ||
#print "Start dragging with offset", x, y | ||
self.setOffset(x, y) | ||
|
||
@QtCore.pyqtSlot(float, float) | ||
def Dragging(self, x, y): | ||
"""Set the value of the offset externally.""" | ||
# temporary debug output | ||
# print "Dragging with offset", x, y | ||
self.setOffset(x, y) | ||
|
||
@QtCore.pyqtSlot(float, float) | ||
def Dragged(self, x, y): | ||
"""Set the value of the offset externally.""" | ||
# temporary debug output | ||
#print "Dragged to", x, y | ||
self.setOffset(x, y) | ||
|
||
@QtCore.pyqtSlot(QTextCursor) | ||
def setObjectFromCursor(self, cursor): | ||
"""Set selected element.""" | ||
self.define = defineoffset.DefineOffset(self.mainwindow.currentDocument()) | ||
self.elemLabel.setText(self.define.getCurrentLilyObject(cursor)) | ||
self.insertButton.setEnabled(True) | ||
|
||
def loadSettings(self): | ||
"""Called on construction. Load settings and set checkboxes state.""" | ||
s = QSettings() | ||
s.beginGroup('object_editor') | ||
|
||
def saveSettings(self): | ||
"""Called on close. Save settings and checkboxes state.""" | ||
s = QSettings() | ||
s.beginGroup('object_editor') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.