34#include <QApplication>
36#include <QKeySequence>
39#include <QInputMethodEvent>
54 if (s == QTextCharFormat::DotLine) {
56 }
else if (s == QTextCharFormat::DashUnderline) {
58 }
else if (s == QTextCharFormat::WaveUnderline) {
60 }
else if (s == QTextCharFormat::SpellCheckUnderline) {
71 if (format.hasProperty(QTextFormat::FontUnderline)) {
74 if (format.hasProperty(QTextFormat::FontOverline)) {
77 if (format.hasProperty(QTextFormat::FontStrikeOut)) {
81 if (format.hasProperty(QTextFormat::TextUnderlineStyle)) {
90 if (format.hasProperty(QTextFormat::BackgroundBrush)) {
91 thick = format.background().isOpaque();
108 bool isAddingCommand =
false;
115 bool cursorVisible =
false;
131 bool visualNavigation =
true;
132 bool pasteRichText =
true;
135 int preEditStart = -1;
136 int preEditLength = -1;
140 bool blockQueryUpdates =
false;
151 if (
d->canvas->canvasController()) {
163 d->cursorFlash.stop();
164 d->cursorFlashLimit.stop();
177 d->shape->removeShapeChangeListener(
this);
179 d->shape = textShape;
183 d->pos =
d->shape->posForIndex(
d->shape->plainText().size());
203 d->visualNavigation = visualMode;
232 int pos =
d->shape->posForPointLineSensitive(
d->shape->documentToShape(point));
233 if (
d->preEditCommand) {
234 int start =
d->shape->indexForPos(
d->preEditStart);
235 int end = start +
d->preEditLength;
238 qApp->inputMethod()->invokeAction(QInputMethod::Click,
posIndex - start);
245 const int finalPos =
d->shape->posForIndex(
d->shape->plainText().size());
246 d->pos = qBound(0,
pos, finalPos);
247 if (moveAnchor ||
d->anchor < 0 ||
d->anchor > finalPos) {
259 const int finalPos =
d->shape->posForIndex(
d->shape->plainText().size());
312 int posStart = qMin(posA, posB);
313 int posEnd = qMax(posA, posB);
314 int indexEnd =
d->shape->indexForPos(posEnd);
315 int length = indexEnd -
d->shape->indexForPos(posStart);
331 int lastIndex =
d->shape->indexForPos(
d->pos);
341 return QPair<KoSvgTextProperties, KoSvgTextProperties>(
d->shape->propertiesForPos(
d->pos),
d->shape->propertiesForPos(
d->pos,
true));
343 return QPair<KoSvgTextProperties, KoSvgTextProperties>();
351 if (
d->pos !=
d->anchor) {
352 start = qMin(
d->pos,
d->anchor);
353 end = qMax(
d->pos,
d->anchor);
355 return d->shape->propertiesForRange(start, end);
382 if (
d->anchor !=
d->pos) {
383 int end =
d->shape->indexForPos(qMax(
d->anchor,
d->pos));
384 int length =
d->shape->indexForPos(qMax(
d->anchor,
d->pos)) -
d->shape->indexForPos(qMin(
d->anchor,
d->pos));
394 int start =
d->shape->indexForPos(qMin(
d->anchor,
d->pos));
395 int length =
d->shape->indexForPos(qMax(
d->anchor,
d->pos)) - start;
396 QString copied =
d->shape->plainText().mid(start,
length);
397 std::unique_ptr<KoSvgTextShape> copy =
d->shape->copyRange(start,
length);
398 QClipboard *cb = QApplication::clipboard();
405 QMimeData *svgData =
new QMimeData();
407 QString svgDoc = QString(
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"2.0\">%1\n%2</svg>").arg(styles).arg(svg);
408 svgData->setData(QLatin1String(
"image/svg+xml"), svgDoc.toUtf8());
410 svgData->setText(copied);
412 svgData->setHtml(html);
413 cb->setMimeData(svgData);
429 bool success =
false;
431 QClipboard *cb = QApplication::clipboard();
432 const QMimeData *mimeData = cb->mimeData();
436 while (shapes.size() > 0) {
443 }
else if (mimeData->hasHtml()) {
444 QString html = mimeData->html();
449 if (converter.convertFromHtml(html, &svg, &styles)
450 && converter.convertFromSvg(svg, styles,
d->shape->boundingRect(), 72.0) ) {
465 bool success =
false;
466 QClipboard *cb = QApplication::clipboard();
467 const QMimeData *mimeData = cb->mimeData();
468 if (mimeData->hasText()) {
489 gc.setTransform(
d->shape->absoluteTransformation(),
true);
490 if (
d->pos !=
d->anchor) {
493 QBrush brush(selectionColor);
494 gc.fillPath(
d->selection, brush);
497 if (
d->cursorVisible) {
499 pen.setCosmetic(
true);
500 QColor c =
d->cursorColor.isValid()?
d->cursorColor: Qt::black;
502 pen.setWidth((
d->cursorWidth + 2) * decorationThickness);
504 gc.drawPath(
d->cursorShape);
506 pen.setWidth(
d->cursorWidth * decorationThickness);
508 gc.drawPath(
d->cursorShape);
512 if (
d->preEditCommand) {
514 QBrush brush(selectionColor);
516 gc.fillPath(
d->IMEDecoration, brush);
525 dbgTools <<
"receiving inputmethod query" << query;
531 return d->shape?
true:
false;
533 case Qt::ImCursorRectangle:
536 QPointF caret1(
d->cursorCaret.p1());
537 QPointF caret2(
d->cursorCaret.p2());
540 QRectF
rect = QRectF(caret1, caret2).normalized();
541 if (!
rect.isValid()) {
542 if (
rect.height() < 1) {
543 rect.adjust(0, -1, 0, 0);
545 if (
rect.width() < 1) {
546 rect.adjust(0, 0, 1, 0);
550 return rect.toAlignedRect();
553 case Qt::ImAnchorRectangle:
556 QPointF caret1(
d->anchorCaret.p1());
557 QPointF caret2(
d->anchorCaret.p2());
558 QRectF
rect = QRectF(caret1, caret2).normalized();
559 if (
rect.isEmpty()) {
560 if (
rect.height() < 1) {
561 rect.adjust(0, -1, 0, 0);
563 if (
rect.width() < 1) {
564 rect =
rect.adjusted(-1, 0, 0, 0).normalized();
567 return rect.toAlignedRect();
571 case Qt::ImAbsolutePosition:
572 case Qt::ImCursorPosition:
574 return d->shape->indexForPos(
d->pos);
577 case Qt::ImSurroundingText:
579 QString surroundingText =
d->shape->plainText();
580 int preEditIndex =
d->preEditCommand?
d->shape->indexForPos(
d->preEditStart): 0;
581 surroundingText.remove(preEditIndex,
d->preEditLength);
582 return surroundingText;
585 case Qt::ImCurrentSelection:
587 QString surroundingText =
d->shape->plainText();
588 int preEditIndex =
d->preEditCommand?
d->shape->indexForPos(
d->preEditStart): 0;
589 surroundingText.remove(preEditIndex,
d->preEditLength);
590 int start =
d->shape->indexForPos(qMin(
d->anchor,
d->pos));
591 int length =
d->shape->indexForPos(qMax(
d->anchor,
d->pos)) - start;
592 return surroundingText.mid(start,
length);
595 case Qt::ImTextBeforeCursor:
597 int start =
d->shape->indexForPos(
d->pos);
598 QString surroundingText =
d->shape->plainText();
599 int preEditIndex =
d->preEditCommand?
d->shape->indexForPos(
d->preEditStart): 0;
600 surroundingText.remove(preEditIndex,
d->preEditLength);
601 return surroundingText.left(start);
604 case Qt::ImTextAfterCursor:
606 int start =
d->shape->indexForPos(
d->pos);
607 QString surroundingText =
d->shape->plainText();
608 int preEditIndex =
d->preEditCommand?
d->shape->indexForPos(
d->preEditStart): 0;
609 surroundingText.remove(preEditIndex,
d->preEditLength);
610 return surroundingText.right(start);
613 case Qt::ImMaximumTextLength:
616 case Qt::ImAnchorPosition:
618 return d->shape->indexForPos(
d->anchor);
624 return Qt::ImhMultiLine;
628 case Qt::ImEnterKeyType:
630 return Qt::EnterKeyDefault;
642 dbgTools <<
"Commit:"<<
event->commitString() <<
"predit:"<<
event->preeditString();
643 dbgTools <<
"Replacement:"<<
event->replacementStart() <<
event->replacementLength();
645 QRectF updateRect =
d->shape?
d->shape->boundingRect(): QRectF();
646 d->blockQueryUpdates =
true;
647 SvgTextShapeManagerBlocker blocker(
d->canvas->shapeManager());
649 bool isGettingInput = !
event->commitString().isEmpty() || !
event->preeditString().isEmpty()
650 ||
event->replacementLength() > 0;
653 if (
d->preEditCommand) {
654 d->preEditCommand->undo();
655 d->preEditCommand = 0;
656 d->preEditStart = -1;
657 d->preEditLength = -1;
658 updateRect |=
d->shape?
d->shape->boundingRect(): QRectF();
661 if (!
d->shape || !isGettingInput) {
663 d->canvas->shapeManager()->update(updateRect);
673 int originalPos =
d->pos;
674 int index =
d->shape->indexForPos(
d->pos) +
event->replacementStart();
675 d->pos =
d->shape->posForIndex(index);
676 if (event->replacementLength() > 0) {
678 index + event->replacementLength(),
681 event->replacementLength(),
687 if (!event->commitString().isEmpty()) {
692 Q_FOREACH(
const QInputMethodEvent::Attribute attribute, event->attributes()) {
693 if (attribute.type == QInputMethodEvent::Selection) {
694 d->pos =
d->shape->posForIndex(attribute.start);
695 int index =
d->shape->indexForPos(
d->pos);
696 d->anchor =
d->shape->posForIndex(index + attribute.length);
702 if (!event->preeditString().isEmpty()) {
703 int index =
d->shape->indexForPos(
d->pos);
705 d->preEditCommand->redo();
706 d->preEditLength =
event->preeditString().size();
707 d->preEditStart =
d->shape->posForIndex(index,
true);
709 d->preEditCommand = 0;
714 Q_FOREACH(
const QInputMethodEvent::Attribute attribute, event->attributes()) {
715 dbgTools <<
"attribute: "<< attribute.type <<
"start: " << attribute.start
716 <<
"length: " << attribute.length <<
"val: " << attribute.value;
722 if (attribute.type == QInputMethodEvent::TextFormat) {
723 QVariant val = attribute.value;
724 QTextCharFormat form = val.value<QTextFormat>().toCharFormat();
726 if (attribute.length == 0 || attribute.start < 0 || !attribute.value.isValid()) {
733 for (
int i = 0; i <
styleMap.size(); i++) {
734 if (attribute.start >=
styleMap.at(i).start
738 if (attribute.start + attribute.length >
styleMap.at(i).start
739 && attribute.start + attribute.length <=
styleMap.at(i).start +
styleMap.at(i).length) {
744 if (positionA > -1 && positionA == positionB) {
748 decoration3.
start = (attribute.start+attribute.length);
750 decoration1.
length = attribute.start - decoration1.
start;
751 decoration2.
start = attribute.start;
752 decoration2.
length = attribute.length;
753 if (decoration1.
length > 0) {
755 if (decoration2.
length > 0) {
757 styleMap.insert(positionA, decoration2);
762 if (decoration3.
length > 0) {
763 styleMap.insert(positionA + 1, decoration3);
765 }
else if (positionA > -1 && positionB > -1
766 && positionA != positionB) {
772 decoration1.
length = attribute.start - decoration1.
start;
773 decoration2.
start = attribute.start;
775 decoration4.
start = (attribute.start+attribute.length);
778 if (decoration1.
length > 0) {
780 if (decoration2.
length > 0) {
782 styleMap.insert(positionA, decoration2);
788 if (decoration3.
length > 0) {
790 if (decoration4.
length > 0) {
791 styleMap.insert(positionB + 1, decoration4);
799 if (positionA > -1 && !
styleMap.isEmpty()) {
801 for(
int i = positionA; i <= positionB; i++) {
809 decoration.
start = attribute.start;
810 decoration.
length = attribute.length;
818 }
else if (attribute.type == QInputMethodEvent::Cursor) {
819 if (
d->preEditStart < 0) {
822 int index =
d->shape->indexForPos(
d->preEditStart);
823 d->pos =
d->shape->posForIndex(index + attribute.start);
833 d->blockQueryUpdates =
false;
834 qApp->inputMethod()->update(Qt::ImQueryInput);
835 updateRect |=
d->shape->boundingRect();
836 d->shape->updateAbsolute(updateRect);
848 d->cursorVisible = !
d->cursorVisible;
854 d->cursorFlash.stop();
855 d->cursorFlashLimit.stop();
856 d->cursorVisible =
true;
865 if (!
d->canvas->canvasWidget()) {
868 QPoint
pos =
d->canvas->canvasWidget()->mapTo(
d->canvas->canvasWidget()->window(), QPoint());
869 QTransform widgetToWindow = QTransform::fromTranslate(
pos.x(),
pos.y());
870 QTransform inputItemTransform = widgetToWindow;
871 QRectF inputRect =
d->canvas->canvasWidget()->geometry();
873 inputRect =
d->shape->outlineRect().normalized();
874 QTransform shapeTransform =
d->shape->absoluteTransformation();
875 QTransform docToView =
d->canvas->viewConverter()->documentToView();
876 QTransform viewToWidget =
d->canvas->viewConverter()->viewToWidget();
877 inputItemTransform = shapeTransform * docToView * viewToWidget * widgetToWindow;
879 qApp->inputMethod()->setInputItemTransform(inputItemTransform);
880 qApp->inputMethod()->setInputItemRectangle(inputRect);
881 if (!
d->blockQueryUpdates) {
882 qApp->inputMethod()->update(Qt::ImQueryInput);
901 if (shapeProps.
stroke()) {
902 stroke = qSharedPointerDynamicCast<KoShapeStroke>(shapeProps.
stroke());
905 if (stroke != shapeProps.
stroke()) {
920 for(
auto it =
p.begin(); it !=
p.end(); it++) {
922 int value = it->property(property, QVariant(400)).toInt();
923 newVal =
value == 400? QVariant(700): QVariant(400);
924 if (
value == 400)
break;
928 if (
value.style == QFont::StyleNormal) {
929 newSlant.
style = QFont::StyleItalic;
931 newSlant.style = QFont::StyleNormal;
932 newSlant.slantValue.customValue = 0;
933 newSlant.slantValue.isAuto =
true;
935 newVal = QVariant::fromValue(newSlant);
936 if (
value.style == QFont::StyleNormal)
break;
939 KoSvgText::TextDecorations newDecor;
942 newVal = QVariant::fromValue(newDecor);
945 newVal = QVariant::fromValue(newDecor);
958 QAction *action =
dynamic_cast<QAction*
>(QObject::sender());
959 if (!action || !
d->shape)
return;
963 if (properties.
isEmpty())
return;
969 return d->pos !=
d->anchor;
976 d->pos =
d->shape->posForIndex(
d->posIndex);
977 d->anchor =
d->shape->posForIndex(
d->anchorIndex);
993 d->interface->emitSelectionChange();
1000 if (
d->preEditCommand) {
1006 bool select =
event->modifiers().testFlag(Qt::ShiftModifier);
1008 if (!((Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier) & event->modifiers())) {
1010 switch (event->key()) {
1027 case Qt::Key_Delete:
1031 case Qt::Key_Backspace:
1035 case Qt::Key_Return:
1044 if (event->isAccepted()) {
1062 int newKey =
event->key();
1067 newKey = Qt::Key_Right;
1070 newKey = Qt::Key_Left;
1080 newKey = Qt::Key_Down;
1083 newKey = Qt::Key_Up;
1086 newKey = Qt::Key_Left;
1089 newKey = Qt::Key_Right;
1097 newKey = Qt::Key_Up;
1100 newKey = Qt::Key_Down;
1103 newKey = Qt::Key_Left;
1106 newKey = Qt::Key_Right;
1113 QKeySequence testSequence(event->modifiers() | newKey);
1121 Q_FOREACH(QAction *action,
d->actions) {
1122 if (action->shortcut() == testSequence) {
1128 if (event->isAccepted())
return;
1134 if (testSequence == QKeySequence::MoveToNextChar) {
1137 }
else if (testSequence == QKeySequence::SelectNextChar) {
1140 }
else if (testSequence == QKeySequence::MoveToPreviousChar) {
1143 }
else if (testSequence == QKeySequence::SelectPreviousChar) {
1146 }
else if (testSequence == QKeySequence::MoveToNextLine) {
1149 }
else if (testSequence == QKeySequence::SelectNextLine) {
1152 }
else if (testSequence == QKeySequence::MoveToPreviousLine) {
1155 }
else if (testSequence == QKeySequence::SelectPreviousLine) {
1159 }
else if (testSequence == QKeySequence::MoveToNextWord) {
1162 }
else if (testSequence == QKeySequence::SelectNextWord) {
1165 }
else if (testSequence == QKeySequence::MoveToPreviousWord) {
1168 }
else if (testSequence == QKeySequence::SelectPreviousWord) {
1172 }
else if (testSequence == QKeySequence::MoveToStartOfLine) {
1175 }
else if (testSequence == QKeySequence::SelectStartOfLine) {
1178 }
else if (testSequence == QKeySequence::MoveToEndOfLine) {
1181 }
else if (testSequence == QKeySequence::SelectEndOfLine) {
1185 }
else if (testSequence == QKeySequence::MoveToStartOfBlock
1186 || testSequence == QKeySequence::MoveToStartOfDocument) {
1189 }
else if (testSequence == QKeySequence::SelectStartOfBlock
1190 || testSequence == QKeySequence::SelectStartOfDocument) {
1194 }
else if (testSequence == QKeySequence::MoveToEndOfBlock
1195 || testSequence == QKeySequence::MoveToEndOfDocument) {
1198 }
else if (testSequence == QKeySequence::SelectEndOfBlock
1199 || testSequence == QKeySequence::SelectEndOfDocument) {
1203 }
else if (testSequence == QKeySequence::DeleteStartOfWord) {
1206 }
else if (testSequence == QKeySequence::DeleteEndOfWord) {
1209 }
else if (testSequence == QKeySequence::DeleteEndOfLine) {
1212 }
else if (testSequence == QKeySequence::DeleteCompleteLine) {
1215 }
else if (testSequence == QKeySequence::Backspace) {
1218 }
else if (testSequence == QKeySequence::Delete) {
1222 }
else if (testSequence == QKeySequence::InsertLineSeparator
1223 || testSequence == QKeySequence::InsertParagraphSeparator) {
1233 return d->isAddingCommand;
1238 d->cursorFlash.start();
1239 d->cursorFlashLimit.start();
1240 d->cursorVisible =
false;
1252 d->actions.append(action);
1255 }
else if (name ==
"svg_insert_special_character") {
1256 d->actions.append(action);
1259 }
else if (name ==
"svg_paste_rich_text") {
1260 d->actions.append(action);
1263 }
else if (name ==
"svg_paste_plain_text") {
1264 d->actions.append(action);
1273 return d->interface;
1279 d->oldCursorRect =
d->shape->shapeToDocument(
d->cursorShape.boundingRect());
1280 d->posIndex =
d->shape->indexForPos(
d->pos);
1281 d->anchorIndex =
d->shape->indexForPos(
d->anchor);
1284 d->cursorColor = QColor();
1285 d->cursorShape =
d->shape?
d->shape->cursorForPos(
d->pos,
d->cursorCaret,
d->cursorColor): QPainterPath();
1287 if (!
d->blockQueryUpdates) {
1288 qApp->inputMethod()->update(Qt::ImQueryInput);
1291 d->interface->emitSelectionChange();
1292 if (!(
d->canvas->canvasWidget() &&
d->canvas->canvasController())) {
1296 if (
d->shape && !firstUpdate) {
1297 QRectF
rect =
d->shape->shapeToDocument(
d->cursorShape.boundingRect());
1298 d->canvas->canvasController()->ensureVisibleDoc(
rect,
false);
1300 if (
d->canvas->canvasWidget()->hasFocus()) {
1301 d->cursorFlash.start();
1302 d->cursorFlashLimit.start();
1303 d->cursorVisible =
false;
1311 d->oldSelectionRect =
d->shape->shapeToDocument(
d->selection.boundingRect());
1312 d->shape->cursorForPos(
d->anchor,
d->anchorCaret,
d->cursorColor);
1313 d->selection =
d->shape->selectionBoxes(
d->pos,
d->anchor);
1321 d->oldIMEDecorationRect =
d->shape->shapeToDocument(
d->IMEDecoration.boundingRect());
1322 KoSvgText::TextDecorations decor;
1324 d->IMEDecoration = QPainterPath();
1325 if (
d->preEditCommand) {
1328 int startIndex =
d->shape->indexForPos(
d->preEditStart) + info.
start;
1329 int endIndex = startIndex + info.
length;
1330 qreal minimum =
d->canvas->viewToDocument(QPointF(1, 1)).x();
1331 d->IMEDecoration.addPath(
d->shape->underlines(
d->shape->posForIndex(startIndex),
1332 d->shape->posForIndex(endIndex),
1337 d->IMEDecoration.setFillRule(Qt::WindingFill);
1349 d->isAddingCommand =
true;
1350 d->canvas->addCommand(cmd);
1351 d->isAddingCommand =
false;
1363 newPos =
d->shape->posLeft(
pos, visual);
1366 newPos =
d->shape->posRight(
pos, visual);
1369 newPos =
d->shape->posUp(
pos, visual);
1372 newPos =
d->shape->posDown(
pos, visual);
1375 newPos =
d->shape->previousIndex(
pos);
1378 newPos =
d->shape->nextIndex(
pos);
1381 newPos =
d->shape->previousLine(
pos);
1384 newPos =
d->shape->nextLine(
pos);
1387 newPos =
d->shape->wordLeft(
pos, visual);
1388 if (newPos ==
pos) {
1389 newPos =
d->shape->posLeft(
pos, visual);
1390 newPos =
d->shape->wordLeft(newPos, visual);
1394 newPos =
d->shape->wordRight(
pos, visual);
1395 if (newPos ==
pos) {
1396 newPos =
d->shape->posRight(
pos, visual);
1397 newPos =
d->shape->wordRight(newPos, visual);
1401 newPos =
d->shape->wordStart(
pos);
1402 if (newPos ==
pos) {
1403 newPos =
d->shape->previousIndex(
pos);
1404 newPos =
d->shape->wordStart(newPos);
1408 newPos =
d->shape->wordEnd(
pos);
1409 if (newPos ==
pos) {
1410 newPos =
d->shape->nextIndex(
pos);
1411 newPos =
d->shape->wordEnd(newPos);
1415 newPos =
d->shape->lineStart(
pos);
1418 newPos =
d->shape->lineEnd(
pos);
1424 newPos =
d->shape->posForIndex(
d->shape->plainText().size());
1433 const QString text =
event->text();
1436 const QChar c = text.at(0);
1439 if (c.category() == QChar::Other_Format)
1442 if (event->modifiers() == Qt::ControlModifier
1443 || event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) {
1448 if (c.category() == QChar::Other_PrivateUse)
1450 if (c == QLatin1Char(
'\t'))
1457 if (!
d->preEditCommand) {
1461 qApp->inputMethod()->commit();
1463 if (!
d->preEditCommand) {
1467 d->preEditCommand->undo();
1468 d->preEditCommand =
nullptr;
1469 d->preEditStart = -1;
1470 d->preEditLength = 0;
1479 if (
d->shape &&
d->canvas->resourceManager() &&
d->pos ==
d->anchor) {
1486 if (c !=
d->canvas->resourceManager()->foregroundColor()) {
1487 d->canvas->resourceManager()->setForegroundColor(c);
1491 if (stroke && stroke->
color().isValid()) {
1495 if (c !=
d->canvas->resourceManager()->backgroundColor()) {
1496 d->canvas->resourceManager()->setBackgroundColor(c);
1499 Q_FOREACH (QAction *action,
d->actions) {
1500 if (action->isCheckable()) {
1527 return d->parent->propertiesForRange();
1539 d->parent->mergePropertiesIntoSelection(properties, removeProperties);
1544 return d->parent->hasSelection();
1551 if (!
d->parent->shape())
return;
1552 d->compressor.start();
qreal length(const QPointF &vec)
float value(const T *src, size_t ch)
static QColor bgColorForCaret(QColor c)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
A simple solid color shape background.
QColor color() const
Returns the background color.
void setOpacity(quint8 alpha)
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
void toQColor(QColor *c) const
a convenience method for the above.
void addShapeChangeListener(ShapeChangeListener *listener)
KoShapeAnchor * anchor() const
ChangeType
Used by shapeChanged() to select which change was made.
QList< KoShape * > fetchShapes(QRectF viewportInPx, qreal resolutionPPI, QSizeF *fragmentSize=nullptr)
The KoSvgTextPropertiesInterface class.
void textSelectionChanged()
@ StrokeId
KoSvgText::StrokeProperty.
@ FillId
KoSvgText::BackgroundProperty.
@ FontStyleId
KoSvgText::CssSlantData.
@ WritingModeId
KoSvgText::WritingMode.
@ DirectionId
KoSvgText::Direction.
@ TextDecorationLineId
Flags, KoSvgText::TextDecorations.
QSharedPointer< KoShapeBackground > background() const
KoShapeStrokeModelSP stroke() const
void setProperty(PropertyId id, const QVariant &value)
QVariant propertyOrDefault(PropertyId id) const
bool convertToSvg(QString *svgText, QString *stylesText)
bool convertToHtml(QString *htmlText)
convertToHtml convert the text in the text shape to html
Interface to interact with the text property manager.
const QScopedPointer< Private > d
virtual bool spanSelection() override
Whether the tool is currently selecting a set of characters instead of whole paragraphs.
SvgTextCursorPropertyInterface(SvgTextCursor *parent)
virtual KoSvgTextProperties getInheritedProperties() override
getInheritedProperties The properties that should be visible when a given property isn't available in...
virtual QList< KoSvgTextProperties > getSelectedProperties() override
getSelectedProperties
virtual void setPropertiesOnSelected(KoSvgTextProperties properties, QSet< KoSvgTextProperties::PropertyId > removeProperties=QSet< KoSvgTextProperties::PropertyId >()) override
setPropertiesOnSelected This sets the properties on the selection. The implementation is responsible ...
~SvgTextCursorPropertyInterface()
void emitSelectionChange()
The SvgTextMergePropertiesRangeCommand class This sets properties on a specific range in a single tex...
static bool actionEnabled(QAction *action, const QList< KoSvgTextProperties > currentProperties)
static KoSvgTextProperties getModifiedProperties(const QAction *action, QList< KoSvgTextProperties > currentProperties)
static bool configureAction(QAction *action, const QString &name)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
qreal luminosityCoarse(const QColor &c, bool sRGBtrc)
luminosityCoarse This calculates the luminosity of the given QColor. It uses a very coarse (10 step) ...
@ BackgroundColor
The active background color selected for this canvas.
@ ForegroundColor
The active foreground color selected for this canvas.
TextDecorationStyle
Style of the text-decoration.
@ Solid
Draw a solid line.Ex: --—.
@ Dashed
Draw a dashed line. Ex: - - - - -.
@ Wavy
Draw a wavy line. We currently make a zigzag, ex: ^^^^^.
@ Dotted
Draw a dotted line. Ex: .....
Direction
Base direction used by Bidi algorithm.
int start
The startPos from the attribute.
void setDecorationFromQTextCharFormat(QTextCharFormat format)
void setDecorationFromQStyle(QTextCharFormat::UnderlineStyle s)
bool thick
Whether the decoration needs to be doubled in size.
int length
The length from the attribute.
KoSvgText::TextDecorationStyle style
The style.
KoSvgText::TextDecorations decor
Which sides get decorated.
BackgroundProperty is a special wrapper around KoShapeBackground for managing it in KoSvgTextProperti...
When style is oblique, a custom slant value can be specified for variable fonts.
StrokeProperty is a special wrapper around KoShapeStrokeModel for managing it in KoSvgTextProperties.
KisSignalCompressor compressor
Private(SvgTextCursor *parent)
void setVisualMode(const bool visualMode=true)
setVisualMode set whether the navigation mode is visual or logical. This right now primarily affects ...
void keyPressEvent(QKeyEvent *event)
Handle the cursor-related key events.
KoSvgTextPropertiesInterface * textPropertyInterface()
QList< QAction * > actions
int getAnchor()
Get the current selection anchor. This is the same as position, unless there's a selection.
void setCaretSetting(int cursorWidth=1, int cursorFlash=1000, int cursorFlashLimit=5000)
setCaretSetting Set the caret settings for the cursor. Qt has some standard functionality associated,...
void insertText(QString text)
Insert text at getPos()
QPair< KoSvgTextProperties, KoSvgTextProperties > currentTextProperties() const
currentTextProperties
void updateIMEDecoration()
QVector< IMEDecorationInfo > styleMap
Decoration info (underlines) for the preEdit string to differentiate it from regular text.
const QScopedPointer< Private > d
bool hasSelection() override
return true if the tool currently has something selected that can be copied or deleted.
void setPos(int pos, int anchor)
Set the pos and the anchor.
void addCommandToUndoAdapter(KUndo2Command *cmd)
void notifyShapeChanged(KoShape::ChangeType type, KoShape *shape) override
QRectF oldIMEDecorationRect
Update Rectangle of previous decoration.
void sigOpenGlyphPalette()
void updateCanvasResources()
void insertRichText(KoSvgTextShape *insert)
Insert rich text at getPos();.
SvgTextCursor(KoCanvasBase *canvas)
void inputMethodEvent(QInputMethodEvent *event)
void canvasResourceChanged(int key, const QVariant &value)
void setPosToPoint(QPointF point, bool moveAnchor=true)
Set the pos from a point. This currently does a search inside the text shape.
void moveCursor(MoveMode mode, bool moveAnchor=true)
Move the cursor, and, if you don't want a selection, move the anchor.
void setPasteRichTextByDefault(const bool pasteRichText=true)
setPasteRichText
void mergePropertiesIntoSelection(const KoSvgTextProperties props, const QSet< KoSvgTextProperties::PropertyId > removeProperties=QSet< KoSvgTextProperties::PropertyId >())
bool acceptableInput(const QKeyEvent *event) const
More or less copied from bool QInputControl::isAcceptableInput(const QKeyEvent *event) const.
QList< KoSvgTextProperties > propertiesForRange() const
QVariant inputMethodQuery(Qt::InputMethodQuery query) const
void removeSelection()
removeSelection if there's a selection, creates a text-removal command.
void removeText(MoveMode first, MoveMode second)
removeText remove text relative to the current position. This will move the cursor according to the m...
int getPos()
Get the current position.
void focusOut()
Stops blinking cursor.
void removeLastCodePoint()
void notifyMarkupChanged() override
bool pastePlainText()
pastePlainText Explicitely paste plaintext at pos.
bool registerPropertyAction(QAction *action, const QString &name)
Register an action.
void focusIn()
Turns on blinking cursor.
void updateCursorDecoration(QRectF updateRect)
void paintDecorations(QPainter &gc, QColor selectionColor, int decorationThickness=1)
void toggleProperty(KoSvgTextProperties::PropertyId property)
bool paste()
paste pastes plain text in the clipboard at pos. Uses pasteRichTextByDefault to determine whether to ...
QPainterPath IMEDecoration
The decorations for the current preedit string.
void setShape(KoSvgTextShape *textShape)
setShape
void updateInputMethodItemTransform()
int moveModeResult(MoveMode &mode, int &pos, bool visual=false) const
SvgTextRemoveCommand * removeSelectionImpl(bool allowCleanUp, KUndo2Command *parent=0)
removeSelection if there's a selection, creates a text-removal command.
void notifyCursorPosChanged(int pos, int anchor) override
void copy() const
copy copies plain text into the clipboard between anchor and pos.
void updateCursor(bool firstUpdate=false)
update the cursor shape. First update will block ensuring the canvas is visible so setShape won't cau...