File indexing completed on 2025-01-19 03:51:07

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2005-02-14
0007  * Description : a widget to insert a text over an image.
0008  *
0009  * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2006-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "inserttextwidget.h"
0017 
0018 // Qt includes
0019 
0020 #include <QFontMetrics>
0021 #include <QPainter>
0022 
0023 namespace DigikamEditorInsertTextToolPlugin
0024 {
0025 
0026 class Q_DECL_HIDDEN InsertTextWidget::Private
0027 {
0028 public:
0029 
0030     explicit Private()
0031       : currentMoving   (false),
0032         textBorder      (false),
0033         textTransparent (false),
0034         alignMode       (0),
0035         textOpacity     (0),
0036         h               (0),
0037         textRotation    (0),
0038         transparency    (0),
0039         w               (0),
0040         xpos            (0),
0041         ypos            (0),
0042         pixmap          (nullptr),
0043         iface           (nullptr)
0044     {
0045     }
0046 
0047     bool        currentMoving;
0048     bool        textBorder;
0049     bool        textTransparent;
0050 
0051     int         alignMode;
0052     int         textOpacity;
0053     int         h;
0054     int         textRotation;
0055     int         transparency;
0056     int         w;
0057     int         xpos;
0058     int         ypos;
0059 
0060     QColor      backgroundColor;   // For text
0061     QColor      bgColor;           // For Pixmap
0062     QColor      textColor;
0063 
0064     QFont       textFont;
0065 
0066     QPixmap*    pixmap;
0067 
0068     QRect       positionHint;
0069     QRect       rect;
0070     QRect       textRect;
0071 
0072     QString     textString;
0073 
0074     ImageIface* iface;
0075 };
0076 
0077 InsertTextWidget::InsertTextWidget(int w, int h, QWidget* const parent)
0078     : QWidget(parent),
0079       d      (new Private)
0080 {
0081     d->currentMoving   = false;
0082     d->bgColor         = palette().color(QPalette::Window);
0083     d->backgroundColor = QColor(0xCC, 0xCC, 0xCC);
0084     d->transparency    = 210;
0085 
0086     d->iface  = new ImageIface(QSize(w, h));
0087     d->w      = d->iface->previewSize().width();
0088     d->h      = d->iface->previewSize().height();
0089     d->pixmap = new QPixmap(w, h);
0090     d->pixmap->fill(d->bgColor);
0091 
0092     setMinimumSize(w, h);
0093     setMouseTracking(true);
0094     setAttribute(Qt::WA_DeleteOnClose);
0095 
0096     d->rect     = QRect(width()/2-d->w/2, height()/2-d->h/2, d->w, d->h);
0097     d->textRect = QRect();
0098 }
0099 
0100 InsertTextWidget::~InsertTextWidget()
0101 {
0102     delete d->iface;
0103     delete d->pixmap;
0104     delete d;
0105 }
0106 
0107 ImageIface* InsertTextWidget::imageIface() const
0108 {
0109     return d->iface;
0110 }
0111 
0112 void InsertTextWidget::resetEdit()
0113 {
0114     // signal this needs to be filled by makePixmap
0115 
0116     d->textRect = QRect();
0117     makePixmap();
0118     repaint();
0119 }
0120 
0121 void InsertTextWidget::setText(const QString& text, const QFont& font, const QColor& color, int opacity,
0122                                int alignMode, bool border, bool transparent, int rotation)
0123 {
0124     d->textString      = text;
0125     d->textColor       = color;
0126     d->textOpacity     = opacity;
0127     d->textBorder      = border;
0128     d->textTransparent = transparent;
0129     d->textRotation    = rotation;
0130 
0131     switch (alignMode)
0132     {
0133         case ALIGN_LEFT:
0134             d->alignMode = Qt::AlignLeft;
0135             break;
0136 
0137         case ALIGN_RIGHT:
0138             d->alignMode = Qt::AlignRight;
0139             break;
0140 
0141         case ALIGN_CENTER:
0142             d->alignMode = Qt::AlignHCenter;
0143             break;
0144 
0145         case ALIGN_BLOCK:
0146             d->alignMode = Qt::AlignJustify;
0147             break;
0148     }
0149 
0150     // Center text if top left corner text area is not visible.
0151 
0152 /*
0153     if (d->textFont.pointSize() != font.pointSize() &&
0154         !rect().contains( d->textRect.x(), d->textRect.y()))
0155     {
0156         d->textFont = font;
0157         resetEdit();
0158         return;
0159     }
0160 */
0161 
0162     d->textFont = font;
0163 
0164     makePixmap();
0165     repaint();
0166 }
0167 
0168 void InsertTextWidget::setBackgroundColor(const QColor& bg)
0169 {
0170     d->bgColor = bg;
0171     makePixmap();
0172     repaint();
0173 }
0174 
0175 void InsertTextWidget::setPositionHint(const QRect& hint)
0176 {
0177     // interpreted by composeImage
0178 
0179     d->positionHint = hint;
0180 
0181     if (d->textRect.isValid())
0182     {
0183         // invalidate current position so that hint is certainly interpreted
0184 
0185         d->textRect = QRect();
0186         makePixmap();
0187         repaint();
0188     }
0189 }
0190 
0191 QRect InsertTextWidget::getPositionHint() const
0192 {
0193     QRect hint;
0194 
0195     if (d->textRect.isValid())
0196     {
0197         // We normalize on the size of the image, but we store as int. Precision loss is no problem.
0198 
0199         hint.setX(     (int) ((float)(d->textRect.x() - d->rect.x())     / (float)d->rect.width()  * 10000.0));
0200         hint.setY(     (int) ((float)(d->textRect.y() - d->rect.y())     / (float)d->rect.height() * 10000.0));
0201         hint.setWidth( (int) ((float)d->textRect.width()  / (float)d->rect.width()  * 10000.0));
0202         hint.setHeight((int) ((float)d->textRect.height() / (float)d->rect.height() * 10000.0));
0203     }
0204 
0205     return hint;
0206 }
0207 
0208 DImg InsertTextWidget::makeInsertText()
0209 {
0210     int orgW     = d->iface->originalSize().width();
0211     int orgH     = d->iface->originalSize().height();
0212     float ratioW = (float)orgW/(float)d->w;
0213     float ratioH = (float)orgH/(float)d->h;
0214 
0215     int x, y;
0216 
0217     if (d->textRect.isValid())
0218     {
0219         // convert from widget to image coordinates, then to original size
0220 
0221         x = qRound((d->textRect.x() - d->rect.x()) * ratioW);
0222         y = qRound((d->textRect.y() - d->rect.y()) * ratioH);
0223     }
0224     else
0225     {
0226         x = -1;
0227         y = -1;
0228     }
0229 
0230     // Get original image
0231 
0232     DImg image      = d->iface->original()->copy();
0233     int borderWidth = qMax(1, qRound(ratioW));
0234 
0235     // compose and draw result on image
0236 
0237     composeImage(&image, nullptr, x, y,
0238                  d->textFont, d->textFont.pointSizeF(),
0239                  d->textRotation, d->textColor, d->textOpacity,
0240                  d->alignMode, d->textString, d->textTransparent, d->backgroundColor,
0241                  d->textBorder ? BORDER_NORMAL : BORDER_NONE, borderWidth, borderWidth);
0242 
0243     return image;
0244 }
0245 
0246 void InsertTextWidget::makePixmap()
0247 {
0248     int orgW = d->iface->originalSize().width();
0249     int orgH = d->iface->originalSize().height();
0250     float ratioW = (float)d->w / (float)orgW;
0251     float ratioH = (float)d->h / (float)orgH;
0252 
0253     int x, y;
0254 
0255     if (d->textRect.isValid())
0256     {
0257         // convert from widget to image coordinates
0258 
0259         x = d->textRect.x() - d->rect.x();
0260         y = d->textRect.y() - d->rect.y();
0261     }
0262     else
0263     {
0264         x = -1;
0265         y = -1;
0266     }
0267 
0268     // get preview image data
0269 
0270     DImg image = d->iface->preview();
0271     image.setIccProfile(d->iface->original()->getIccProfile());
0272 
0273     // paint pixmap for drawing this widget
0274     // First, fill with background color
0275 
0276     d->pixmap->fill(d->bgColor);
0277     QPainter p(d->pixmap);
0278 
0279     // Convert image to pixmap and draw it
0280 
0281     QPixmap imagePixmap = d->iface->convertToPixmap(image);
0282     p.drawPixmap(d->rect.x(), d->rect.y(),
0283                  imagePixmap, 0, 0, imagePixmap.width(), imagePixmap.height());
0284 
0285     // prepare painter for use by compose image
0286 
0287     p.setClipRect(d->rect);
0288     p.translate(d->rect.x(), d->rect.y());
0289 
0290     int borderWidth = qMax(1, qRound(ratioW));
0291 
0292     // compose image and draw result directly on pixmap, with correct offset
0293 
0294     QRect textRect = composeImage(&image, &p, x, y,
0295                                   d->textFont, d->textFont.pointSizeF(),
0296                                   d->textRotation, d->textColor, d->textOpacity,
0297                                   d->alignMode, d->textString, d->textTransparent, d->backgroundColor,
0298                                   d->textBorder ? BORDER_NORMAL : BORDER_SUPPORT, borderWidth, borderWidth,
0299                                   (ratioW > ratioH) ? ratioW : ratioH);
0300 
0301     p.end();
0302 
0303     // store new text rectangle
0304     // convert from image to widget coordinates
0305 
0306     d->textRect.setX(textRect.x() + d->rect.x());
0307     d->textRect.setY(textRect.y() + d->rect.y());
0308     d->textRect.setSize(textRect.size());
0309 }
0310 
0311 /**
0312    Take data from image, draw text at x|y with specified parameters.
0313    If destPainter is null, draw to image,
0314    if destPainter is not null, draw directly using the painter.
0315    Returns modified area of image.
0316 */
0317 QRect InsertTextWidget::composeImage(DImg* const image, QPainter* const destPainter,
0318                                      int x, int y,
0319                                      QFont font, float pointSize, int textRotation, QColor textColor,
0320                                      int textOpacity, int alignMode, const QString& textString,
0321                                      bool transparentBackground, QColor backgroundColor,
0322                                      BorderMode borderMode, int borderWidth, int spacing, float fontScale)
0323 {
0324     /*
0325         The problem we have to solve is that we have no pixel access to font rendering,
0326         we have to let Qt do the drawing. On the other hand we need to support 16 bit, which
0327         cannot be done with QPixmap.
0328         The current solution cuts out the text area, lets Qt do its drawing, converts back and blits to original.
0329     */
0330 
0331     int maxWidth, maxHeight;
0332 
0333     if (x == -1 && y == -1)
0334     {
0335         maxWidth  = image->width();
0336         maxHeight = image->height();
0337     }
0338     else
0339     {
0340         maxWidth  = image->width()  - x;
0341         maxHeight = image->height() - y;
0342     }
0343 
0344     fontScale = qMax(0.01f, fontScale);
0345 
0346     // find out size of the area that we are drawing to
0347 
0348     font.setPointSizeF(pointSize);
0349     QFontMetrics fontMt(font);
0350     QRect fontRect = fontMt.boundingRect(0, 0,
0351                                          qRound(maxWidth  / fontScale),
0352                                          qRound(maxHeight / fontScale),
0353                                          alignMode, textString);
0354 
0355     fontRect.setWidth(qRound(fontRect.width()   * fontScale));
0356     fontRect.setHeight(qRound(fontRect.height() * fontScale));
0357 
0358     if (!fontRect.isValid())
0359     {
0360         return QRect();
0361     }
0362 
0363     int fontWidth, fontHeight;
0364 
0365     switch (textRotation)
0366     {
0367         case ROTATION_NONE:
0368         case ROTATION_180:
0369         default:
0370             fontWidth = fontRect.width();
0371             fontHeight = fontRect.height();
0372             break;
0373 
0374         case ROTATION_90:
0375         case ROTATION_270:
0376             fontWidth = fontRect.height();
0377             fontHeight = fontRect.width();
0378             break;
0379     }
0380 
0381     // x, y == -1 means that we have to find a good initial position for the text here
0382 
0383     if ((x == -1) && (y == -1))
0384     {
0385         int boxWidth  = fontWidth  + 2 * borderWidth + 2 * spacing;
0386         int boxHeight = fontHeight + 2 * borderWidth + 2 * spacing;
0387 
0388         // was a valid position hint stored from last use?
0389 
0390         if (d->positionHint.isValid())
0391         {
0392             // We assume that people tend to orient text along the edges,
0393             // so we do some guessing so that positions such as "in the lower right corner"
0394             // will be remembered across different image sizes.
0395 
0396             // get relative positions
0397 
0398             float fromTop    =       (float)d->positionHint.top()    / 10000.0;
0399             float fromBottom = 1.0 - (float)d->positionHint.bottom() / 10000.0;
0400             float fromLeft   =       (float)d->positionHint.left()   / 10000.0;
0401             float fromRight  = 1.0 - (float)d->positionHint.right()  / 10000.0;
0402 
0403             // calculate horizontal position
0404 
0405             if (fromLeft < fromRight)
0406             {
0407                 x = qRound(fromLeft * maxWidth);
0408 
0409                 // we are placing from the smaller distance,
0410                 // so if now the larger distance is actually too small,
0411                 // fall back to standard placement, nothing to lose.
0412 
0413                 if ((x + boxWidth) > maxWidth)
0414                 {
0415                     x = qMax( (maxWidth - boxWidth) / 2, 0);
0416                 }
0417             }
0418             else
0419             {
0420                 x = maxWidth - qRound(fromRight * maxWidth) - boxWidth;
0421 
0422                 if (x < 0)
0423                 {
0424                     x = qMax( (maxWidth - boxWidth) / 2, 0);
0425                 }
0426             }
0427 
0428             // calculate vertical position
0429 
0430             if (fromTop < fromBottom)
0431             {
0432                 y = qRound(fromTop * maxHeight);
0433 
0434                 if (y + boxHeight > maxHeight)
0435                 {
0436                     y = qMax( (maxHeight - boxHeight) / 2, 0);
0437                 }
0438             }
0439             else
0440             {
0441                 y = maxHeight - qRound(fromBottom * maxHeight) - boxHeight;
0442 
0443                 if (y < 0)
0444                 {
0445                     y = qMax( (maxHeight - boxHeight) / 2, 0);
0446                 }
0447             }
0448 
0449             if (!QRect(x, y, boxWidth, boxHeight).
0450                  intersects(QRect(0, 0, maxWidth, maxHeight)))
0451             {
0452                 // emergency fallback - nothing is visible
0453 
0454                 x = qMax( (maxWidth - boxWidth)   / 2, 0);
0455                 y = qMax( (maxHeight - boxHeight) / 2, 0);
0456             }
0457 
0458             // invalidate position hint, use only once
0459 
0460             d->positionHint = QRect();
0461         }
0462         else
0463         {
0464             // use standard position
0465 
0466             x = qMax( (maxWidth - boxWidth)   / 2, 0);
0467             y = qMax( (maxHeight - boxHeight) / 2, 0);
0468         }
0469     }
0470 
0471     // create a rectangle relative to image
0472 
0473     QRect drawRect(x, y, fontWidth + 2 * borderWidth + 2 * spacing, fontHeight + 2 * borderWidth  + 2 * spacing);
0474 
0475     // create a rectangle relative to textArea, excluding the border
0476 
0477     QRect textAreaBackgroundRect(borderWidth, borderWidth, fontWidth + 2 * spacing, fontHeight + 2 * spacing);
0478 
0479     // create a rectangle relative to textArea, excluding the border and spacing
0480 
0481     QRect textAreaTextRect(borderWidth + spacing, borderWidth + spacing, fontWidth, fontHeight);
0482 
0483     // create a rectangle relative to textArea, including the border,
0484     // for drawing the rectangle, taking into account that the width of the QPen goes in and out in equal parts
0485 
0486     QRect textAreaDrawRect(borderWidth / 2, borderWidth / 2, fontWidth + borderWidth + 2 * spacing,
0487                            fontHeight + borderWidth + 2 * spacing);
0488 
0489     // cut out the text area
0490 
0491     DImg textArea = image->copy(drawRect);
0492 
0493     if (textArea.isNull())
0494     {
0495         return QRect();
0496     }
0497 
0498     // compose semi-transparent background over textArea
0499 
0500     DColorComposer* const composer = DColorComposer::getComposer(DColorComposer::PorterDuffNone);
0501 
0502     if (transparentBackground)
0503     {
0504         DImg transparentLayer(textAreaBackgroundRect.width(), textAreaBackgroundRect.height(), textArea.sixteenBit(), true);
0505         DColor transparent(backgroundColor);
0506         transparent.setAlpha(d->transparency);
0507 
0508         if (image->sixteenBit())
0509         {
0510             transparent.convertToSixteenBit();
0511         }
0512 
0513         transparentLayer.fill(transparent);
0514         textArea.bitBlendImage(composer, &transparentLayer, 0, 0, transparentLayer.width(), transparentLayer.height(),
0515                                textAreaBackgroundRect.x(), textAreaBackgroundRect.y());
0516     }
0517 
0518     DImg textNotDrawn;
0519 
0520     if (textArea.sixteenBit())
0521     {
0522         textNotDrawn = textArea.copy();
0523         textNotDrawn.convertToEightBit();
0524     }
0525     else
0526     {
0527         textNotDrawn = textArea;
0528     }
0529 
0530     // We have no direct pixel access to font rendering, so now we need to use Qt/X11 for the drawing
0531 
0532     // convert text area to pixmap
0533 
0534     QPixmap pixmap;
0535 
0536     if (destPainter)
0537     {
0538         // We working on tool preview, deal with CM as well
0539 
0540         pixmap = d->iface->convertToPixmap(textNotDrawn);
0541     }
0542     else
0543     {
0544         // We working on target image. Do no apply double CM adjustment here.
0545 
0546         pixmap = textNotDrawn.convertToPixmap();
0547     }
0548 
0549     int fontScaleWidth  = qRound(fontWidth  / fontScale);
0550     int fontScaleHeight = qRound(fontHeight / fontScale);
0551 
0552     QPixmap textPixmap(fontScaleWidth, fontScaleHeight);
0553     textPixmap.fill(Qt::transparent);
0554 
0555     QPainter tp(&textPixmap);
0556     tp.setOpacity((qreal)textOpacity / 100.0);
0557     tp.setPen(QPen(textColor, 1));
0558     tp.setFont(font);
0559 
0560     switch (textRotation)
0561     {
0562         case ROTATION_NONE:
0563             tp.drawText(0, 0, fontScaleWidth, fontScaleHeight,
0564                          alignMode, textString);
0565             break;
0566         case ROTATION_90:
0567             tp.translate(fontScaleWidth, 0);
0568             tp.rotate(90.0);
0569             tp.drawText(0, 0, fontScaleHeight, fontScaleWidth,
0570                         alignMode, textString);
0571             break;
0572         case ROTATION_180:
0573             tp.translate(fontScaleWidth, fontScaleHeight);
0574             tp.rotate(180.0);
0575             tp.drawText(0, 0, fontScaleWidth, fontScaleHeight,
0576                         alignMode, textString);
0577             break;
0578         case ROTATION_270:
0579             tp.translate(0, fontScaleHeight);
0580             tp.rotate(270.0);
0581             tp.drawText(0, 0, fontScaleHeight, fontScaleWidth,
0582                         alignMode, textString);
0583             break;
0584     }
0585 
0586     tp.end();
0587 
0588     // paint on pixmap
0589 
0590     QPainter p(&pixmap);
0591 
0592     p.drawPixmap(textAreaTextRect, textPixmap.scaled(fontWidth,
0593                                                      fontHeight,
0594                                                      Qt::IgnoreAspectRatio,
0595                                                      Qt::SmoothTransformation));
0596     // Drawing rectangle around text.
0597 
0598     if (borderMode == BORDER_NORMAL)      // Decorative border using text color.
0599     {
0600         p.setOpacity((qreal)textOpacity / 100.0);
0601         p.setPen(QPen(textColor, borderWidth, Qt::SolidLine,
0602                       Qt::SquareCap, Qt::RoundJoin));
0603         p.drawRect(textAreaDrawRect);
0604     }
0605     else if (borderMode == BORDER_SUPPORT)  // Make simple dot line border to help user.
0606     {
0607         p.setPen(QPen(Qt::white, 1, Qt::SolidLine));
0608         p.drawRect(textAreaDrawRect);
0609         p.setPen(QPen(Qt::red, 1, Qt::DotLine));
0610         p.drawRect(textAreaDrawRect);
0611     }
0612 
0613     p.end();
0614 
0615     if (!destPainter)
0616     {
0617         // convert to QImage, then to DImg
0618 
0619         QImage pixmapImage = pixmap.toImage();
0620         DImg textDrawn(pixmapImage.width(), pixmapImage.height(), false, true, pixmapImage.bits());
0621 
0622         // This does not work: during the conversion, colors are altered significantly (diffs of 1 to 10 in each component),
0623         // so we cannot find out which pixels have actually been touched.
0624 /*
0625         // Compare the result of drawing with the previous version.
0626         // Set all unchanged pixels to transparent
0627         DColor color, ncolor;
0628         uchar *ptr, *nptr;
0629         ptr = textDrawn.bits();
0630         nptr = textNotDrawn.bits();
0631         int bytesDepth = textDrawn.bytesDepth();
0632         int numPixels = textDrawn.width() * textDrawn.height();
0633         for (int i = 0; i < numPixels; ++i, ptr+= bytesDepth, nptr += bytesDepth)
0634         {
0635             color.setColor(ptr, false);
0636             ncolor.setColor(nptr, false);
0637             if (color.red()   == ncolor.red()   &&
0638                 color.green() == ncolor.green() &&
0639                 color.blue()  == ncolor.blue())
0640             {
0641                 color.setAlpha(0);
0642                 color.setPixel(ptr);
0643             }
0644         }
0645         // convert to 16 bit if needed
0646 */
0647         textDrawn.convertToDepthOfImage(&textArea);
0648 
0649         // now compose to original: only pixels affected by drawing text and border are changed, not whole area
0650 
0651         textArea.bitBlendImage(composer, &textDrawn, 0, 0, textDrawn.width(), textDrawn.height(), 0, 0);
0652 
0653         // copy result to original image
0654 
0655         image->bitBltImage(&textArea, drawRect.x(), drawRect.y());
0656     }
0657     else
0658     {
0659         destPainter->drawPixmap(drawRect.x(), drawRect.y(), pixmap, 0, 0, pixmap.width(), pixmap.height());
0660     }
0661 
0662     delete composer;
0663 
0664     return drawRect;
0665 }
0666 
0667 void InsertTextWidget::paintEvent(QPaintEvent*)
0668 {
0669     QPainter p(this);
0670     p.drawPixmap(0, 0, *d->pixmap);
0671     p.end();
0672 }
0673 
0674 void InsertTextWidget::resizeEvent(QResizeEvent* e)
0675 {
0676     blockSignals(true);
0677     delete d->pixmap;
0678 
0679     int w     = e->size().width();
0680     int h     = e->size().height();
0681 
0682     int textX = d->textRect.x() - d->rect.x();
0683     int textY = d->textRect.y() - d->rect.y();
0684     int old_w = d->w;
0685     int old_h = d->h;
0686     d->iface->setPreviewSize(QSize(w, h));
0687     d->w      = d->iface->previewSize().width();
0688     d->h      = d->iface->previewSize().height();
0689 
0690     d->pixmap = new QPixmap(w, h);
0691     d->rect   = QRect(w/2-d->w/2, h/2-d->h/2, d->w, d->h);
0692 
0693     if (d->textRect.isValid())
0694     {
0695         int textWidth  = d->textRect.width();
0696         int textHeight = d->textRect.height();
0697 
0698         textX      = qRound(textX      * (float)d->w / (float)old_w);
0699         textY      = qRound(textY      * (float)d->h / (float)old_h);
0700         textWidth  = qRound(textWidth  * (float)d->w / (float)old_w);
0701         textHeight = qRound(textHeight * (float)d->h / (float)old_h);
0702 
0703         d->textRect.setX(textX + d->rect.x());
0704         d->textRect.setY(textY + d->rect.y());
0705         d->textRect.setWidth(textWidth);
0706         d->textRect.setHeight(textHeight);
0707         makePixmap();
0708     }
0709 
0710     blockSignals(false);
0711 }
0712 
0713 void InsertTextWidget::mousePressEvent(QMouseEvent* e)
0714 {
0715     if (e->button() == Qt::LeftButton &&
0716 
0717 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0718 
0719         d->textRect.contains(e->position().toPoint().x(), e->position().toPoint().y()))
0720     {
0721         d->xpos = e->position().toPoint().x();
0722         d->ypos = e->position().toPoint().y();
0723 
0724 #else
0725 
0726         d->textRect.contains(e->x(), e->y()))
0727     {
0728         d->xpos = e->x();
0729         d->ypos = e->y();
0730 
0731 #endif
0732 
0733         setCursor(Qt::SizeAllCursor);
0734         d->currentMoving = true;
0735     }
0736 }
0737 
0738 void InsertTextWidget::mouseReleaseEvent(QMouseEvent*)
0739 {
0740     setCursor(Qt::ArrowCursor);
0741     d->currentMoving = false;
0742 }
0743 
0744 void InsertTextWidget::mouseMoveEvent(QMouseEvent* e)
0745 {
0746 
0747 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0748 
0749     if (rect().contains(e->position().toPoint().x(), e->position().toPoint().y()))
0750 
0751 #else
0752 
0753     if (rect().contains(e->x(), e->y()))
0754 
0755 #endif
0756 
0757     {
0758         if      (e->buttons() == Qt::LeftButton && d->currentMoving)
0759         {
0760 
0761 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0762 
0763             uint newxpos = e->position().toPoint().x();
0764             uint newypos = e->position().toPoint().y();
0765 
0766 #else
0767             uint newxpos = e->x();
0768             uint newypos = e->y();
0769 
0770 #endif
0771 
0772             d->textRect.translate(newxpos - d->xpos, newypos - d->ypos);
0773 
0774             if (d->textRect.x() - d->rect.x() < 0)
0775             {
0776                 d->textRect.setX(d->rect.x());
0777             }
0778 
0779             if (d->textRect.y() - d->rect.y() < 0)
0780             {
0781                 d->textRect.setY(d->rect.y());
0782             }
0783 
0784             makePixmap();
0785             repaint();
0786 
0787             d->xpos = newxpos;
0788             d->ypos = newypos;
0789             setCursor(Qt::PointingHandCursor);
0790         }
0791 
0792 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0793 
0794         else if (d->textRect.contains(e->position().toPoint().x(), e->position().toPoint().y()))
0795 
0796 #else
0797 
0798         else if (d->textRect.contains(e->x(), e->y()))
0799 
0800 #endif
0801 
0802         {
0803             setCursor(Qt::SizeAllCursor);
0804         }
0805         else
0806         {
0807             setCursor(Qt::ArrowCursor);
0808         }
0809     }
0810 }
0811 
0812 } // namespace DigikamEditorInsertTextToolPlugin
0813 
0814 #include "moc_inserttextwidget.cpp"