Fix #25060 - Fix FiguredBass creating, editing and displaying.
After the recent changes to Text styling and editing, FiguredBass has been broken. This patch attempts to fix it. As the current Text in-place editor insists in inserting spurious (and sometime wrong) HTML markup and styling which jeopardize the parsing of FiguredBassItem's, I have modified the FiguredBass endEdit() callback function to discard all HTML and keep only the plain text. This may reduce the flexibility of entering extra indications in FiguredBass elements, but ensure that properly structured texts are parsed and recognized. The patch also corrects two points in text.cpp which forced extra HTML formatting to be inserted.
This commit is contained in:
parent
4a780b308e
commit
0a05faddb5
3 changed files with 63 additions and 50 deletions
|
@ -989,70 +989,65 @@ void FiguredBass::read(XmlReader& e)
|
|||
|
||||
void FiguredBass::layout()
|
||||
{
|
||||
// qreal y;
|
||||
|
||||
qreal yOff = score()->styleD(ST_figuredBassYOffset);
|
||||
qreal _sp = spatium();
|
||||
// if 'our' style, force 'our' style data from FiguredBass parameters
|
||||
if(textStyleType() == TEXT_STYLE_FIGURED_BASS) {
|
||||
TextStyle st("Figured Bass", g_FBFonts[0].family, score()->styleD(ST_figuredBassFontSize),
|
||||
false, false, false, ALIGN_LEFT | ALIGN_TOP, QPointF(0, score()->styleD(ST_figuredBassYOffset)),
|
||||
false, false, false, ALIGN_LEFT | ALIGN_TOP, QPointF(0, yOff),
|
||||
OFFSET_SPATIUM);
|
||||
st.setSizeIsSpatiumDependent(true);
|
||||
setTextStyle(st);
|
||||
}
|
||||
Text::layout(); // Text and/or SimpleText may expect some internal data to be setup
|
||||
|
||||
// if style has been changed (or text not styled), do nothing else, keeping default laying out and formatting
|
||||
if(textStyleType() != TEXT_STYLE_FIGURED_BASS)
|
||||
// if in edit mode or if style has been changed,
|
||||
// do nothing else, keeping default laying out and formatting
|
||||
if(editMode() || textStyleType() != TEXT_STYLE_FIGURED_BASS) {
|
||||
Text::layout();
|
||||
return;
|
||||
}
|
||||
|
||||
// bounding box
|
||||
if(editMode()) {
|
||||
qreal h, w, w1;
|
||||
QFontMetricsF fm(textStyle().font(spatium()));
|
||||
// box width
|
||||
w = 0;
|
||||
QStringList list = text().split('\n');
|
||||
foreach(QString str, list) {
|
||||
w1 = fm.width(str);
|
||||
if(w1 > w)
|
||||
w = w1;
|
||||
}
|
||||
// bbox height
|
||||
h = fm.lineSpacing();
|
||||
h *= score()->styleD(ST_figuredBassLineHeight);
|
||||
h *= (list.size() > 1 ? list.size() : 1); // at least 1 line
|
||||
// ready to set position and bbox
|
||||
// setPos(0, y);
|
||||
bbox().setRect(0-2, 0-2, w+4, h+4);
|
||||
}
|
||||
else {
|
||||
// if element could be parsed into items, layout each element
|
||||
if(items.size() > 0) {
|
||||
layoutLines();
|
||||
bbox().setRect(0, 0, _lineLenghts.at(0), 0);
|
||||
// layout each item and enlarge bbox to include items bboxes
|
||||
for(int i=0; i < items.size(); i++) {
|
||||
items[i].layout();
|
||||
addbbox(items[i].bbox().translated(items[i].pos()));
|
||||
}
|
||||
// VERTICAL POSITION:
|
||||
yOff *= _sp; // convert spatium value to raster units
|
||||
// if any staff, add staff y-offset
|
||||
if (parent() && parent()->type() == SEGMENT) {
|
||||
Segment* s = static_cast<Segment*>(parent());
|
||||
System* system = s->measure()->system();
|
||||
if (system) {
|
||||
SysStaff* sstaff = system->staff(staffIdx());
|
||||
yOff += sstaff->y();
|
||||
}
|
||||
}
|
||||
setPos(QPointF(0.0, yOff));
|
||||
|
||||
// adjustReadPos(); // already taken into account by Text::layout()
|
||||
// BOUNDING BOX and individual item layout (if requried)
|
||||
createLayout(); // prepare structs and data expected by Text methods
|
||||
// if element could be parsed into items, layout each element
|
||||
if(items.size() > 0) {
|
||||
layoutLines();
|
||||
bbox().setRect(0, 0, _lineLenghts.at(0), 0);
|
||||
// layout each item and enlarge bbox to include items bboxes
|
||||
for(int i=0; i < items.size(); i++) {
|
||||
items[i].layout();
|
||||
addbbox(items[i].bbox().translated(items[i].pos()));
|
||||
}
|
||||
}
|
||||
adjustReadPos();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// layoutLines
|
||||
//
|
||||
// lays out the duration indicator line(s), filling the _lineLengths array
|
||||
// and the length of printed lines (used by continuation lines)
|
||||
//---------------------------------------------------------
|
||||
|
||||
void FiguredBass::layoutLines()
|
||||
{
|
||||
if(_ticks <= 0) {
|
||||
NoLen:
|
||||
_lineLenghts.resize(1);
|
||||
_lineLenghts[0] = 0;
|
||||
_lineLenghts.resize(1); // be sure to always have
|
||||
_lineLenghts[0] = 0; // at least 1 item in array
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1131,23 +1126,24 @@ qDebug("FiguredBass: duration indicator end line not implemented");
|
|||
|
||||
void FiguredBass::draw(QPainter* painter) const
|
||||
{
|
||||
// if not printing, draw duration line(s)
|
||||
if( !score()->printing() ) {
|
||||
// if neither edit mode or printing, draw duration line(s)
|
||||
if( !editMode() && !score()->printing() ) {
|
||||
foreach(qreal len, _lineLenghts)
|
||||
if(len > 0) {
|
||||
painter->setPen(QPen(Qt::lightGray, 1));
|
||||
painter->drawLine(0.0, -2, len, -2); // -2: 2 rast. un. above digits
|
||||
}
|
||||
}
|
||||
// if in edit mode or with custom style, use default drawing
|
||||
// if in edit mode or with custom style, use standard text drawing
|
||||
if(editMode() || textStyleType() != TEXT_STYLE_FIGURED_BASS)
|
||||
Text::draw(painter);
|
||||
// not edit mode:
|
||||
else {
|
||||
if(items.size() < 1)
|
||||
Text::draw(painter);
|
||||
if(items.size() < 1) // if not parseable into f.b. items
|
||||
Text::draw(painter); // draw as standard text
|
||||
else
|
||||
foreach(FiguredBassItem item, items) {
|
||||
painter->translate(item.pos());
|
||||
foreach(FiguredBassItem item, items) { // if parseable into f.b. items
|
||||
painter->translate(item.pos()); // draw each item in its proper position
|
||||
item.draw(painter);
|
||||
painter->translate(-item.pos());
|
||||
}
|
||||
|
@ -1160,16 +1156,25 @@ void FiguredBass::draw(QPainter* painter) const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// endEdit
|
||||
// startEdit / edit / endEdit
|
||||
//---------------------------------------------------------
|
||||
|
||||
void FiguredBass::startEdit(MuseScoreView * msv, const QPointF & pt)
|
||||
{
|
||||
Text::layout(); // convert layout to standard Text conventions
|
||||
Text::startEdit(msv, pt);
|
||||
}
|
||||
|
||||
void FiguredBass::endEdit()
|
||||
{
|
||||
int idx;
|
||||
|
||||
Text::endEdit();
|
||||
QString txt = text();
|
||||
// as the standard text editor keeps inserting spurious HTML formatting and styles
|
||||
// retrieve and work only on the plain text
|
||||
QString txt = plainText();
|
||||
if(txt.isEmpty()) { // if no text, nothing to do
|
||||
setText(txt); // clear the stored text: the empty f.b. element will be deleted
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -278,11 +278,13 @@ class FiguredBass : public Text {
|
|||
virtual FiguredBass* clone() const { return new FiguredBass(*this); }
|
||||
virtual ElementType type() const { return FIGURED_BASS; }
|
||||
virtual void draw(QPainter* painter) const;
|
||||
// virtual bool edit(MuseScoreView*msv, int currGrip, int key, Qt::KeyboardModifiers modifiers, const QString& _s);
|
||||
virtual void endEdit();
|
||||
virtual void layout();
|
||||
virtual void read(XmlReader&);
|
||||
virtual void setSelected(bool f);
|
||||
virtual void setVisible(bool f);
|
||||
virtual void startEdit(MuseScoreView *msv, const QPointF &pt);
|
||||
virtual void write(Xml& xml) const;
|
||||
|
||||
// read / write MusicXML
|
||||
|
|
|
@ -1335,6 +1335,8 @@ void Text::genText()
|
|||
|
||||
for (const TextBlock& block : _layout) {
|
||||
for (const TextFragment& f : block.fragments()) {
|
||||
if (f.text.isEmpty()) // skip empty fragments, not to
|
||||
continue; // insert extra HTML formatting
|
||||
const CharFormat& format = f.format;
|
||||
if (format.type() == CharFormatType::TEXT) {
|
||||
if (cursor.format()->bold() != format.bold()) {
|
||||
|
@ -1467,16 +1469,20 @@ bool Text::edit(MuseScoreView*, int, int key, Qt::KeyboardModifiers modifiers, c
|
|||
switch (key) {
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
{
|
||||
if (_cursor.hasSelection())
|
||||
deleteSelectedText();
|
||||
|
||||
CharFormat* charFmt = _cursor.format(); // take current format
|
||||
_layout.insert(_cursor.line() + 1, curLine().split(_cursor.column()));
|
||||
_layout[_cursor.line()].setEol(true);
|
||||
_cursor.setLine(_cursor.line() + 1);
|
||||
_cursor.setColumn(0);
|
||||
_cursor.setFormat(*charFmt); // restore orig. format at new line
|
||||
s.clear();
|
||||
_cursor.clearSelection();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Backspace:
|
||||
if (_cursor.hasSelection())
|
||||
|
@ -1495,13 +1501,13 @@ bool Text::edit(MuseScoreView*, int, int key, Qt::KeyboardModifiers modifiers, c
|
|||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
if (!movePosition(ctrlPressed ? QTextCursor::StartOfLine : QTextCursor::Left, mm) && (type() == LYRICS || type() == FIGURED_BASS))
|
||||
if (!movePosition(ctrlPressed ? QTextCursor::StartOfLine : QTextCursor::Left, mm) && type() == LYRICS)
|
||||
return false;
|
||||
s.clear();
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
if (!movePosition(ctrlPressed ? QTextCursor::EndOfLine : QTextCursor::Right, mm) && (type() == LYRICS || type() == FIGURED_BASS))
|
||||
if (!movePosition(ctrlPressed ? QTextCursor::EndOfLine : QTextCursor::Right, mm) && type() == LYRICS)
|
||||
return false;
|
||||
s.clear();
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue