X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=src%2Fheadingobj.cpp;fp=src%2Fheadingobj.cpp;h=ed12672b354c822810b1bd0e80137ed2590dbcb2;hb=d483bd8e6523c23c6f1d8908a2e0611c2bc9ff4f;hp=0000000000000000000000000000000000000000;hpb=7dfa3fe589d1722d49681f42cdb0bf1e6efb5223;p=sven%2Fvym.git diff --git a/src/headingobj.cpp b/src/headingobj.cpp new file mode 100644 index 0000000..ed12672 --- /dev/null +++ b/src/headingobj.cpp @@ -0,0 +1,262 @@ +#include +#include +#include + +#include "headingobj.h" + +extern bool debug; + +///////////////////////////////////////////////////////////////// +// HeadingObj +///////////////////////////////////////////////////////////////// +HeadingObj::HeadingObj(QGraphicsItem *parent) : MapObj(parent) +{ + // qDebug() << "Const HeadingObj (s) "; + init(); +} + +HeadingObj::~HeadingObj() +{ + // qDebug() << "Destr. HeadingObj "<textwidth; + color = other->color; + font = other->font; + setText(other->text()); +} + +void HeadingObj::move(double x, double y) +{ + MapObj::move(x, y); + + qreal h; // height of a textline + qreal ho; // offset of height while drawing all lines + + if (!textline.isEmpty()) + h = textline.first()->boundingRect().height(); + else + h = 2; + ho = 0; + for (int i = 0; i < textline.size(); ++i) { + textline.at(i)->setPos(x, y + ho); + ho = ho + h; + } +} + +void HeadingObj::moveBy(double x, double y) +{ + move(x + absPos.x(), y + absPos.y()); +} + +void HeadingObj::positionBBox() +{ + bbox.setX(absPos.x()); + bbox.setY(absPos.y()); +} + +void HeadingObj::calcBBoxSize() +{ + qreal w = 0; + qreal h = 0; + // Using Backspace an empty heading might easily be created, then there + // would be textline.first()==NULL This can be worked around by the + // following, but then no selection would be visible, thus we prevent it in + // ::setText() + if (!textline.isEmpty()) { + for (int i = 0; i < textline.size(); i++) { + h += textline.at(i)->boundingRect().height(); + if (w < textline.at(i)->boundingRect().width()) + w = textline.at(i)->boundingRect().width(); + } + } + bbox.setSize(QSizeF(w, h)); +} + +QGraphicsTextItem *HeadingObj::newLine(QString s) +{ + QGraphicsTextItem *t = new QGraphicsTextItem(s, parentItem()); + t->setFont(font); + t->setZValue(dZ_TEXT); + t->setDefaultTextColor(color); + t->setRotation(angle); + return t; +} + +void HeadingObj::setTransformOriginPoint(const QPointF &p) +{ + for (int i = 0; i < textline.size(); i++) { + textline.at(i)->setTransformOriginPoint(p); + } +} + +void HeadingObj::setRotation(const qreal &a) +{ + angle = a; + for (int i = 0; i < textline.size(); i++) + textline.at(i)->setRotation(angle); +} + +qreal HeadingObj::getRotation() { return angle; } + +void HeadingObj::setText(QString s) +{ + heading = s; + + // remove old textlines and prepare generating new ones + while (!textline.isEmpty()) + delete textline.takeFirst(); + + if (s.startsWith("") || + s.startsWith("")) { + QGraphicsTextItem *t = new QGraphicsTextItem(); + t->setFont(font); + t->setZValue(dZ_TEXT); + t->setHtml(s); + t->setDefaultTextColor(color); + t->setRotation(angle); + scene()->addItem(t); + textline.append(t); + } + else { + // prevent empty textline, so at least a small selection stays + // visible for this heading + if (s.length() == 0) + s = " "; + + int i = 0; // index for actual search for ws + int j = 0; // index of last ws + int k = 0; // index of "
" or similar linebreak + int br = 0; // width of found break, e.g. for
it is 4 + QRegExp re(""); + re.setMinimal(true); + + // set the text and wrap lines + while (s.length() > 0) { + // ok, some people wanted manual linebreaks, here we go + k = re.indexIn(s, i); + if (k >= 0) { + br = re.cap(0).length(); + i = k; + } + else + i = s.indexOf(" ", i); + if (i < 0 && j == 0) { // no ws found at all in s + // append whole s + textline.append(newLine(s)); + s = ""; + } + else { + if (i < 0 && j > 0) { // no ws found in actual search + if (s.length() <= textwidth) { + textline.append(newLine(s)); + s = ""; + } + else { + textline.append(newLine(s.left(j))); + s = s.mid(j + 1, s.length()); + j = 0; + } + } + else { + if (i >= 0 && + i <= static_cast( + textwidth)) { // there is a ws in textwidth + if (br > 0) { + // here is a linebreak + textline.append(newLine(s.left(i))); + s = s.mid(i + br, s.length()); + i = 0; + j = 0; + br = 0; + } + else { + j = i; + i++; + } + } + else { + if (i > static_cast(textwidth)) { + if (j > 0) { // a ws out of textwidth, but we have + // also one in + textline.append(newLine(s.left(j))); + s = s.mid(j + 1, s.length()); + i = 0; + j = 0; + } + else { // a ws out of text, but none in + textline.append(newLine(s.left(i))); + s = s.mid(i + 1, s.length()); + i = 0; + } + } + } + } + } + } + } // ASCII heading with multiple lines + setVisibility(visible); + move(absPos.x(), absPos.y()); + calcBBoxSize(); +} + +QString HeadingObj::text() { return heading; } + +void HeadingObj::setFont(QFont f) +{ + if (font != f) { + font = f; + setText(text()); + } +} + +QFont HeadingObj::getFont() { return font; } + +void HeadingObj::setColor(QColor c) +{ + if (color != c) { + color = c; + for (int i = 0; i < textline.size(); ++i) + // TextItem + textline.at(i)->setDefaultTextColor(c); + // SimpleTextItem + // textline.at(i)->setBrush(c); + } +} + +QColor HeadingObj::getColor() { return color; } + +void HeadingObj::setZValue(double z) +{ + for (int i = 0; i < textline.size(); ++i) + textline.at(i)->setZValue(z); +} + +void HeadingObj::setVisibility(bool v) +{ + MapObj::setVisibility(v); + for (int i = 0; i < textline.size(); ++i) + if (v) + textline.at(i)->show(); + else + textline.at(i)->hide(); +} + +qreal HeadingObj::getHeight() { return bbox.height(); } + +qreal HeadingObj::getWidth() { return bbox.width(); }