1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2002-2011 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12
13 #include "box.h"
14 #include "textframe.h"
15 #include "text.h"
16 #include "score.h"
17 #include "barline.h"
18 #include "repeat.h"
19 #include "symbol.h"
20 #include "system.h"
21 #include "image.h"
22 #include "layoutbreak.h"
23 #include "fret.h"
24 #include "mscore.h"
25 #include "stafftext.h"
26 #include "icon.h"
27 #include "xml.h"
28 #include "measure.h"
29 #include "undo.h"
30
31 namespace Ms {
32
33 static const ElementStyle boxStyle {
34 { Sid::systemFrameDistance, Pid::TOP_GAP },
35 { Sid::frameSystemDistance, Pid::BOTTOM_GAP },
36 };
37
38 static const ElementStyle hBoxStyle {
39 };
40
41 //---------------------------------------------------------
42 // Box
43 //---------------------------------------------------------
44
Box(Score * score)45 Box::Box(Score* score)
46 : MeasureBase(score)
47 {
48 }
49
50 //---------------------------------------------------------
51 // layout
52 //---------------------------------------------------------
53
layout()54 void Box::layout()
55 {
56 MeasureBase::layout();
57 for (Element* e : el()) {
58 if (!e->isLayoutBreak())
59 e->layout();
60 }
61 }
62
63 //---------------------------------------------------------
64 // computeMinWidth
65 //---------------------------------------------------------
66
computeMinWidth()67 void HBox::computeMinWidth()
68 {
69 setWidth(point(boxWidth()) + topGap() + bottomGap()); // top/bottom is really left/right
70 }
71
72 //---------------------------------------------------------
73 // draw
74 //---------------------------------------------------------
75
draw(QPainter * painter) const76 void Box::draw(QPainter* painter) const
77 {
78 if (score() && score()->printing())
79 return;
80 if (selected() || editMode || dropTarget() || score()->showFrames()) {
81 qreal w = spatium() * .15;
82 QPainterPathStroker stroker;
83 stroker.setWidth(w);
84 stroker.setJoinStyle(Qt::MiterJoin);
85 stroker.setCapStyle(Qt::SquareCap);
86
87 QVector<qreal> dashes ;
88 dashes.append(1);
89 dashes.append(3);
90 stroker.setDashPattern(dashes);
91 QPainterPath path;
92 w *= .5;
93 path.addRect(bbox().adjusted(w, w, -w, -w));
94 QPainterPath stroke = stroker.createStroke(path);
95 painter->setBrush(Qt::NoBrush);
96 painter->fillPath(stroke, (selected() || editMode || dropTarget()) ? MScore::selectColor[0] : MScore::frameMarginColor);
97 }
98 }
99
100 //---------------------------------------------------------
101 // startEdit
102 //---------------------------------------------------------
103
startEdit(EditData & ed)104 void Box::startEdit(EditData& ed)
105 {
106 Element::startEdit(ed);
107 editMode = true;
108 }
109
110 //---------------------------------------------------------
111 // edit
112 //---------------------------------------------------------
113
edit(EditData &)114 bool Box::edit(EditData&)
115 {
116 return false;
117 }
118
119 //---------------------------------------------------------
120 // startEditDrag
121 //---------------------------------------------------------
122
startEditDrag(EditData & ed)123 void Box::startEditDrag(EditData& ed)
124 {
125 ElementEditData* eed = ed.getData(this);
126 if (isHBox())
127 eed->pushProperty(Pid::BOX_WIDTH);
128 else
129 eed->pushProperty(Pid::BOX_HEIGHT);
130 }
131
132 //---------------------------------------------------------
133 // editDrag
134 //---------------------------------------------------------
135
editDrag(EditData & ed)136 void Box::editDrag(EditData& ed)
137 {
138 if (isVBox()) {
139 _boxHeight += Spatium(ed.delta.y() / spatium());
140 if (ed.vRaster) {
141 qreal vRaster = 1.0 / MScore::vRaster();
142 int n = lrint(_boxHeight.val() / vRaster);
143 _boxHeight = Spatium(vRaster * n);
144 }
145 bbox().setRect(0.0, 0.0, system()->width(), point(boxHeight()));
146 system()->setHeight(height());
147 triggerLayout();
148 }
149 else {
150 _boxWidth += Spatium(ed.delta.x() / spatium());
151 if (ed.hRaster) {
152 qreal hRaster = 1.0 / MScore::hRaster();
153 int n = lrint(_boxWidth.val() / hRaster);
154 _boxWidth = Spatium(hRaster * n);
155 }
156 triggerLayout();
157 }
158 layout();
159 }
160
161 //---------------------------------------------------------
162 // endEdit
163 //---------------------------------------------------------
164
endEdit(EditData &)165 void Box::endEdit(EditData&)
166 {
167 editMode = false;
168 layout();
169 }
170
171 //---------------------------------------------------------
172 // gripsPositions
173 //---------------------------------------------------------
174
gripsPositions(const EditData &) const175 std::vector<QPointF> HBox::gripsPositions(const EditData&) const
176 {
177 QRectF r(abbox());
178 return { QPointF(r.right(), r.top() + r.height() * .5) };
179 }
180
gripsPositions(const EditData &) const181 std::vector<QPointF> VBox::gripsPositions(const EditData&) const
182 {
183 QRectF r(abbox());
184 return { QPointF(r.x() + r.width() * .5, r.bottom()) };
185 }
186
187 //---------------------------------------------------------
188 // write
189 //---------------------------------------------------------
190
write(XmlWriter & xml) const191 void Box::write(XmlWriter& xml) const
192 {
193 xml.stag(this);
194 writeProperties(xml);
195 xml.etag();
196 }
197
198 //---------------------------------------------------------
199 // writeProperties
200 //---------------------------------------------------------
201
writeProperties(XmlWriter & xml) const202 void Box::writeProperties(XmlWriter& xml) const
203 {
204 for (Pid id : {
205 Pid::BOX_HEIGHT, Pid::BOX_WIDTH, Pid::TOP_GAP, Pid::BOTTOM_GAP,
206 Pid::LEFT_MARGIN, Pid::RIGHT_MARGIN, Pid::TOP_MARGIN, Pid::BOTTOM_MARGIN, Pid::BOX_AUTOSIZE }) {
207 writeProperty(xml, id);
208 }
209 Element::writeProperties(xml);
210 for (const Element* e : el())
211 e->write(xml);
212 }
213
214 //---------------------------------------------------------
215 // read
216 //---------------------------------------------------------
217
read(XmlReader & e)218 void Box::read(XmlReader& e)
219 {
220 _leftMargin = 0.0;
221 _rightMargin = 0.0;
222 _topMargin = 0.0;
223 _bottomMargin = 0.0;
224 _boxHeight = Spatium(0); // override default set in constructor
225 _boxWidth = Spatium(0);
226 MeasureBase::read(e);
227 if (score()->mscVersion() < 302)
228 _isAutoSizeEnabled = false; // disable auto-size for older scores by default.
229 }
230
231 //---------------------------------------------------------
232 // readProperties
233 //---------------------------------------------------------
234
readProperties(XmlReader & e)235 bool Box::readProperties(XmlReader& e)
236 {
237 const QStringRef& tag(e.name());
238 if (tag == "height")
239 _boxHeight = Spatium(e.readDouble());
240 else if (tag == "width")
241 _boxWidth = Spatium(e.readDouble());
242 else if (tag == "topGap") {
243 _topGap = e.readDouble();
244 if (score()->mscVersion() >= 206)
245 _topGap *= score()->spatium();
246 setPropertyFlags(Pid::TOP_GAP, PropertyFlags::UNSTYLED);
247 }
248 else if (tag == "bottomGap") {
249 _bottomGap = e.readDouble();
250 if (score()->mscVersion() >= 206)
251 _bottomGap *= score()->spatium();
252 setPropertyFlags(Pid::BOTTOM_GAP, PropertyFlags::UNSTYLED);
253 }
254 else if (tag == "leftMargin")
255 _leftMargin = e.readDouble();
256 else if (tag == "rightMargin")
257 _rightMargin = e.readDouble();
258 else if (tag == "topMargin")
259 _topMargin = e.readDouble();
260 else if (tag == "bottomMargin")
261 _bottomMargin = e.readDouble();
262 else if (tag == "boxAutoSize")
263 _isAutoSizeEnabled = e.readBool();
264 else if (tag == "Text") {
265 Text* t;
266 if (isTBox()) {
267 t = toTBox(this)->text();
268 t->read(e);
269 }
270 else {
271 t = new Text(score());
272 t->read(e);
273 if (t->empty())
274 qDebug("read empty text");
275 else
276 add(t);
277 }
278 }
279 else if (tag == "Symbol") {
280 Symbol* s = new Symbol(score());
281 s->read(e);
282 add(s);
283 }
284 else if (tag == "Image") {
285 if (MScore::noImages)
286 e.skipCurrentElement();
287 else {
288 Image* image = new Image(score());
289 image->setTrack(e.track());
290 image->read(e);
291 add(image);
292 }
293 }
294 else if (tag == "FretDiagram") {
295 FretDiagram* f = new FretDiagram(score());
296 f->read(e);
297 add(f);
298 }
299 else if (tag == "HBox") {
300 HBox* hb = new HBox(score());
301 hb->read(e);
302 add(hb);
303 }
304 else if (tag == "VBox") {
305 VBox* vb = new VBox(score());
306 vb->read(e);
307 add(vb);
308 }
309 else if (MeasureBase::readProperties(e))
310 ;
311 else
312 return false;
313 return true;
314 }
315
316 //---------------------------------------------------------
317 // add
318 /// Add new Element \a el to Box
319 //---------------------------------------------------------
320
add(Element * e)321 void Box::add(Element* e)
322 {
323 if (e->isText())
324 toText(e)->setLayoutToParentWidth(true);
325 MeasureBase::add(e);
326 }
327
contentRect() const328 QRectF Box::contentRect() const
329 {
330 QRectF result;
331
332 for (const Element* element : el())
333 result = result.united(element->bbox());
334
335 return result;
336 }
337
338 //---------------------------------------------------------
339 // getProperty
340 //---------------------------------------------------------
341
getProperty(Pid propertyId) const342 QVariant Box::getProperty(Pid propertyId) const
343 {
344 switch(propertyId) {
345 case Pid::BOX_HEIGHT:
346 return _boxHeight;
347 case Pid::BOX_WIDTH:
348 return _boxWidth;
349 case Pid::TOP_GAP:
350 return _topGap;
351 case Pid::BOTTOM_GAP:
352 return _bottomGap;
353 case Pid::LEFT_MARGIN:
354 return _leftMargin;
355 case Pid::RIGHT_MARGIN:
356 return _rightMargin;
357 case Pid::TOP_MARGIN:
358 return _topMargin;
359 case Pid::BOTTOM_MARGIN:
360 return _bottomMargin;
361 case Pid::BOX_AUTOSIZE:
362 return (score()->mscVersion() >= 302) ? _isAutoSizeEnabled : false;
363 default:
364 return MeasureBase::getProperty(propertyId);
365 }
366 }
367
368 //---------------------------------------------------------
369 // setProperty
370 //---------------------------------------------------------
371
setProperty(Pid propertyId,const QVariant & v)372 bool Box::setProperty(Pid propertyId, const QVariant& v)
373 {
374 score()->addRefresh(canvasBoundingRect());
375 switch (propertyId) {
376 case Pid::BOX_HEIGHT:
377 _boxHeight = v.value<Spatium>();
378 break;
379 case Pid::BOX_WIDTH:
380 _boxWidth = v.value<Spatium>();
381 break;
382 case Pid::TOP_GAP:
383 _topGap = v.toDouble();
384 break;
385 case Pid::BOTTOM_GAP:
386 _bottomGap = v.toDouble();
387 break;
388 case Pid::LEFT_MARGIN:
389 _leftMargin = v.toDouble();
390 break;
391 case Pid::RIGHT_MARGIN:
392 _rightMargin = v.toDouble();
393 break;
394 case Pid::TOP_MARGIN:
395 _topMargin = v.toDouble();
396 break;
397 case Pid::BOTTOM_MARGIN:
398 _bottomMargin = v.toDouble();
399 break;
400 case Pid::BOX_AUTOSIZE:
401 _isAutoSizeEnabled = v.toBool();
402 break;
403 default:
404 return MeasureBase::setProperty(propertyId, v);
405 }
406 triggerLayout();
407 return true;
408 }
409
410 //---------------------------------------------------------
411 // propertyDefault
412 //---------------------------------------------------------
413
propertyDefault(Pid id) const414 QVariant Box::propertyDefault(Pid id) const
415 {
416 switch(id) {
417 case Pid::BOX_HEIGHT:
418 case Pid::BOX_WIDTH:
419 return Spatium(0.0);
420
421 case Pid::TOP_GAP:
422 return isHBox() ? 0.0 : score()->styleP(Sid::systemFrameDistance);
423 case Pid::BOTTOM_GAP:
424 return isHBox() ? 0.0 : score()->styleP(Sid::frameSystemDistance);
425
426 case Pid::LEFT_MARGIN:
427 case Pid::RIGHT_MARGIN:
428 case Pid::TOP_MARGIN:
429 case Pid::BOTTOM_MARGIN:
430 return 0.0;
431 case Pid::BOX_AUTOSIZE:
432 return true;
433 default:
434 return MeasureBase::propertyDefault(id);
435 }
436 }
437
438 //---------------------------------------------------------
439 // copyValues
440 //---------------------------------------------------------
441
copyValues(Box * origin)442 void Box::copyValues(Box* origin)
443 {
444 _boxHeight = origin->boxHeight();
445 _boxWidth = origin->boxWidth();
446
447 qreal factor = magS() / origin->magS();
448 _bottomGap = origin->bottomGap() * factor;
449 _topGap = origin->topGap() * factor;
450 _bottomMargin = origin->bottomMargin() * factor;
451 _topMargin = origin->topMargin() * factor;
452 _leftMargin = origin->leftMargin() * factor;
453 _rightMargin = origin->rightMargin() * factor;
454 }
455
456 //---------------------------------------------------------
457 // HBox
458 //---------------------------------------------------------
459
HBox(Score * score)460 HBox::HBox(Score* score)
461 : Box(score)
462 {
463 initElementStyle(&hBoxStyle);
464 setBoxWidth(Spatium(5.0));
465 }
466
467 //---------------------------------------------------------
468 // layout
469 //---------------------------------------------------------
470
layout()471 void HBox::layout()
472 {
473 if (parent() && parent()->isVBox()) {
474 VBox* vb = toVBox(parent());
475 qreal x = vb->leftMargin() * DPMM;
476 qreal y = vb->topMargin() * DPMM;
477 qreal w = point(boxWidth());
478 qreal h = vb->height() - (vb->topMargin() + vb->bottomMargin()) * DPMM;
479 setPos(x, y);
480 bbox().setRect(0.0, 0.0, w, h);
481 }
482 else if (system()) {
483 bbox().setRect(0.0, 0.0, point(boxWidth()), system()->height());
484 }
485 else {
486 bbox().setRect(0.0, 0.0, 50, 50);
487 }
488 Box::layout();
489 }
490
491 //---------------------------------------------------------
492 // layout2
493 // height (bbox) is defined now
494 //---------------------------------------------------------
495
layout2()496 void HBox::layout2()
497 {
498 Box::layout();
499 }
500
501 //---------------------------------------------------------
502 // acceptDrop
503 //---------------------------------------------------------
504
acceptDrop(EditData & data) const505 bool Box::acceptDrop(EditData& data) const
506 {
507 if (data.dropElement->flag(ElementFlag::ON_STAFF))
508 return false;
509 if (MScore::debugMode)
510 qDebug("<%s>", data.dropElement->name());
511 ElementType t = data.dropElement->type();
512 switch (t) {
513 case ElementType::LAYOUT_BREAK:
514 case ElementType::TEXT:
515 case ElementType::STAFF_TEXT:
516 case ElementType::IMAGE:
517 case ElementType::SYMBOL:
518 return true;
519 case ElementType::ICON:
520 switch (toIcon(data.dropElement)->iconType()) {
521 case IconType::VFRAME:
522 case IconType::TFRAME:
523 case IconType::FFRAME:
524 case IconType::HFRAME:
525 case IconType::MEASURE:
526 return true;
527 default:
528 break;
529 }
530 break;
531 case ElementType::BAR_LINE:
532 return isHBox();
533 default:
534 break;
535 }
536 return false;
537 }
538
539 //---------------------------------------------------------
540 // drop
541 //---------------------------------------------------------
542
drop(EditData & data)543 Element* Box::drop(EditData& data)
544 {
545 Element* e = data.dropElement;
546 if (e->flag(ElementFlag::ON_STAFF))
547 return 0;
548 if (MScore::debugMode)
549 qDebug("<%s>", e->name());
550 switch (e->type()) {
551 case ElementType::LAYOUT_BREAK:
552 {
553 LayoutBreak* lb = toLayoutBreak(e);
554 if (pageBreak() || lineBreak()) {
555 if (
556 (lb->isPageBreak() && pageBreak())
557 || (lb->isLineBreak() && lineBreak())
558 || (lb->isSectionBreak() && sectionBreak())
559 ) {
560 //
561 // if break already set
562 //
563 delete lb;
564 break;
565 }
566 for (Element* elem : el()) {
567 if (elem->type() == ElementType::LAYOUT_BREAK) {
568 score()->undoChangeElement(elem, e);
569 break;
570 }
571 }
572 break;
573 }
574 lb->setTrack(-1); // these are system elements
575 lb->setParent(this);
576 score()->undoAddElement(lb);
577 return lb;
578 }
579
580 case ElementType::STAFF_TEXT:
581 {
582 Text* text = new Text(score(), Tid::FRAME);
583 text->setParent(this);
584 text->setXmlText(toStaffText(e)->xmlText());
585 score()->undoAddElement(text);
586 delete e;
587 return text;
588 }
589
590 case ElementType::ICON:
591 switch (toIcon(e)->iconType()) {
592 case IconType::VFRAME:
593 score()->insertMeasure(ElementType::VBOX, this);
594 break;
595 case IconType::TFRAME:
596 score()->insertMeasure(ElementType::TBOX, this);
597 break;
598 case IconType::FFRAME:
599 score()->insertMeasure(ElementType::FBOX, this);
600 break;
601 case IconType::HFRAME:
602 score()->insertMeasure(ElementType::HBOX, this);
603 break;
604 case IconType::MEASURE:
605 score()->insertMeasure(ElementType::MEASURE, this);
606 break;
607 default:
608 break;
609 }
610 break;
611
612 case ElementType::TEXT:
613 case ElementType::IMAGE:
614 case ElementType::SYMBOL:
615 e->setParent(this);
616 score()->undoAddElement(e);
617 return e;
618 default:
619 return 0;
620 }
621 return 0;
622 }
623
624 //---------------------------------------------------------
625 // drag
626 //---------------------------------------------------------
627
drag(EditData & data)628 QRectF HBox::drag(EditData& data)
629 {
630 QRectF r(canvasBoundingRect());
631 qreal diff = data.evtDelta.x();
632 qreal x1 = offset().x() + diff;
633 if (parent()->type() == ElementType::VBOX) {
634 VBox* vb = toVBox(parent());
635 qreal x2 = parent()->width() - width() - (vb->leftMargin() + vb->rightMargin()) * DPMM;
636 if (x1 < 0.0)
637 x1 = 0.0;
638 else if (x1 > x2)
639 x1 = x2;
640 }
641 setOffset(QPointF(x1, 0.0));
642 // setStartDragPosition(data.delta);
643 return canvasBoundingRect() | r;
644 }
645
646 //---------------------------------------------------------
647 // endEditDrag
648 //---------------------------------------------------------
649
endEditDrag(EditData &)650 void HBox::endEditDrag(EditData&)
651 {
652 triggerLayout();
653 score()->update();
654 }
655
656 //---------------------------------------------------------
657 // isMovable
658 //---------------------------------------------------------
659
isMovable() const660 bool HBox::isMovable() const
661 {
662 return parent() && (parent()->isHBox() || parent()->isVBox());
663 }
664
665 //---------------------------------------------------------
666 // writeProperties
667 //---------------------------------------------------------
668
writeProperties(XmlWriter & xml) const669 void HBox::writeProperties(XmlWriter& xml) const
670 {
671 writeProperty(xml, Pid::CREATE_SYSTEM_HEADER);
672 Box::writeProperties(xml);
673 }
674
675 //---------------------------------------------------------
676 // readProperties
677 //---------------------------------------------------------
678
readProperties(XmlReader & e)679 bool HBox::readProperties(XmlReader& e)
680 {
681 const QStringRef& tag(e.name());
682 if (readProperty(tag, e, Pid::CREATE_SYSTEM_HEADER))
683 ;
684 else if (Box::readProperties(e))
685 ;
686 else
687 return false;
688 return true;
689 }
690
691 //---------------------------------------------------------
692 // getProperty
693 //---------------------------------------------------------
694
getProperty(Pid propertyId) const695 QVariant HBox::getProperty(Pid propertyId) const
696 {
697 switch (propertyId) {
698 case Pid::CREATE_SYSTEM_HEADER:
699 return createSystemHeader();
700 default:
701 return Box::getProperty(propertyId);
702 }
703 }
704
705 //---------------------------------------------------------
706 // setProperty
707 //---------------------------------------------------------
708
setProperty(Pid propertyId,const QVariant & v)709 bool HBox::setProperty(Pid propertyId, const QVariant& v)
710 {
711 switch (propertyId) {
712 case Pid::CREATE_SYSTEM_HEADER:
713 setCreateSystemHeader(v.toBool());
714 triggerLayout();
715 break;
716 default:
717 return Box::setProperty(propertyId, v);
718 }
719 return true;
720 }
721
722 //---------------------------------------------------------
723 // propertyDefault
724 //---------------------------------------------------------
725
propertyDefault(Pid id) const726 QVariant HBox::propertyDefault(Pid id) const
727 {
728 switch(id) {
729 case Pid::CREATE_SYSTEM_HEADER:
730 return true;
731 default:
732 return Box::propertyDefault(id);
733 }
734 }
735
736 //---------------------------------------------------------
737 // VBox
738 //---------------------------------------------------------
739
VBox(Score * score)740 VBox::VBox(Score* score)
741 : Box(score)
742 {
743 initElementStyle(&boxStyle);
744 setBoxHeight(Spatium(10.0));
745 setLineBreak(true);
746 }
747
minHeight() const748 qreal VBox::minHeight() const
749 {
750 return point(Spatium(10));
751 }
752
maxHeight() const753 qreal VBox::maxHeight() const
754 {
755 return point(Spatium(30));
756 }
757
getProperty(Pid propertyId) const758 QVariant VBox::getProperty(Pid propertyId) const
759 {
760 switch (propertyId) {
761 case Pid::BOX_AUTOSIZE:
762 return isAutoSizeEnabled();
763 default:
764 return Box::getProperty(propertyId);
765 }
766 }
767
768 //---------------------------------------------------------
769 // layout
770 //---------------------------------------------------------
771
layout()772 void VBox::layout()
773 {
774 setPos(QPointF());
775
776 if (system())
777 bbox().setRect(0.0, 0.0, system()->width(), point(boxHeight()));
778 else
779 bbox().setRect(0.0, 0.0, 50, 50);
780
781 for (Element* e : el()) {
782 if (!e->isLayoutBreak())
783 e->layout();
784 }
785
786 if (getProperty(Pid::BOX_AUTOSIZE).toBool()) {
787 qreal contentHeight = contentRect().height();
788
789 if (contentHeight < minHeight())
790 contentHeight = minHeight();
791
792 setHeight(contentHeight);
793 }
794
795 MeasureBase::layout();
796 }
797
798 //---------------------------------------------------------
799 // layout
800 //---------------------------------------------------------
801
layout()802 void FBox::layout()
803 {
804 // setPos(QPointF()); // !?
805 bbox().setRect(0.0, 0.0, system()->width(), point(boxHeight()));
806 Box::layout();
807 }
808
809 //---------------------------------------------------------
810 // add
811 /// Add new Element \a e to fret diagram box
812 //---------------------------------------------------------
813
add(Element * e)814 void FBox::add(Element* e)
815 {
816 e->setParent(this);
817 if (e->isFretDiagram()) {
818 // FretDiagram* fd = toFretDiagram(e);
819 // fd->setFlag(ElementFlag::MOVABLE, false);
820 }
821 else {
822 qDebug("FBox::add: element not allowed");
823 return;
824 }
825 el().push_back(e);
826 }
827
828 //---------------------------------------------------------
829 // accessibleExtraInfo
830 //---------------------------------------------------------
831
accessibleExtraInfo() const832 QString Box::accessibleExtraInfo() const
833 {
834 QString rez = "";
835 for (Element* e : el())
836 rez += " " + e->screenReaderInfo();
837 return rez;
838 }
839
840 //---------------------------------------------------------
841 // accessibleExtraInfo
842 //---------------------------------------------------------
843
accessibleExtraInfo() const844 QString TBox::accessibleExtraInfo() const
845 {
846 QString rez = _text->screenReaderInfo();
847 return rez;
848 }
849
850 }
851
852