From 63045e4b02df1754e760957a233567c5b83d5d9b Mon Sep 17 00:00:00 2001 From: Yurii Puchkov Date: Mon, 26 Apr 2021 21:31:11 +0300 Subject: [PATCH] NC/Edit text objects on double click (#1578) * Edit existing text objects (cherry picked from commit 3d6edca21b5615481d0ab409801baeafb523ce72) * Add 'info' to the panel for the text tool object (cherry picked from commit 2b633f560e46a0112d70653f6c55da5e97ce4cc8) * Add 'info' to the panel for the CircleCount tool object (cherry picked from commit 5ff5b667c1d6c534fe447618f9938a4581f0c9f2) * Set text settings active in the Tool Settings panel on edit text (cherry picked from commit a020a3504c0d02bbca4bb870e12e80ee87d64f75) * Set font family in the Tool Settings panel on edit text object (cherry picked from commit 70fe9bd5e79f39d544ed2d7848d05492da9b52bd) Co-authored-by: Yuriy Puchkov --- src/tools/capturetool.h | 7 ++ src/tools/circlecount/circlecounttool.cpp | 7 ++ src/tools/circlecount/circlecounttool.h | 4 + src/tools/text/textconfig.cpp | 22 +++-- src/tools/text/textconfig.h | 3 + src/tools/text/texttool.cpp | 22 ++++- src/tools/text/texttool.h | 3 + src/widgets/capture/capturewidget.cpp | 104 ++++++++++++++-------- src/widgets/capture/capturewidget.h | 4 +- src/widgets/panel/utilitypanel.cpp | 8 +- src/widgets/panel/utilitypanel.h | 2 +- 11 files changed, 139 insertions(+), 47 deletions(-) diff --git a/src/tools/capturetool.h b/src/tools/capturetool.h index 71da66c5..584f255f 100644 --- a/src/tools/capturetool.h +++ b/src/tools/capturetool.h @@ -86,6 +86,7 @@ public: explicit CaptureTool(QObject* parent = nullptr) : QObject(parent) , m_count(0) + , m_editMode(false) {} virtual void setCapture(const QPixmap& pixmap){}; @@ -112,6 +113,8 @@ public: virtual ToolType nameID() const = 0; // Short description of the tool. virtual QString description() const = 0; + // Short tool item info + virtual QString info() { return name(); }; // if the type is TYPE_WIDGET the widget is loaded in the main widget. // If the type is TYPE_EXTERNAL_WIDGET it is created outside as an @@ -123,6 +126,9 @@ public: // Return a copy of the tool virtual CaptureTool* copy(QObject* parent = nullptr) = 0; + virtual void setEditMode(bool b) { m_editMode = b; }; + virtual bool editMode() { return m_editMode; }; + // Counter for all object types (currently is used for the CircleCounter // only) virtual void setCount(int count) { m_count = count; }; @@ -195,5 +201,6 @@ public slots: private: unsigned int m_count; + bool m_editMode; QRect m_selectionRect; }; diff --git a/src/tools/circlecount/circlecounttool.cpp b/src/tools/circlecount/circlecounttool.cpp index 646ca4a5..108f5181 100644 --- a/src/tools/circlecount/circlecounttool.cpp +++ b/src/tools/circlecount/circlecounttool.cpp @@ -21,6 +21,13 @@ QIcon CircleCountTool::icon(const QColor& background, bool inEditor) const Q_UNUSED(inEditor) return QIcon(iconPath(background) + "circlecount-outline.svg"); } + +QString CircleCountTool::info() +{ + m_tempString = QString("%1 - %2").arg(name()).arg(count()); + return m_tempString; +} + QString CircleCountTool::name() const { return tr("Circle Counter"); diff --git a/src/tools/circlecount/circlecounttool.h b/src/tools/circlecount/circlecounttool.h index 2b852119..d907418d 100644 --- a/src/tools/circlecount/circlecounttool.h +++ b/src/tools/circlecount/circlecounttool.h @@ -14,6 +14,7 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QString info() override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; @@ -27,4 +28,7 @@ protected: public slots: void drawStart(const CaptureContext& context) override; void pressed(const CaptureContext& context) override; + +private: + QString m_tempString; }; diff --git a/src/tools/text/textconfig.cpp b/src/tools/text/textconfig.cpp index e4cdfae5..e9bc1ae2 100644 --- a/src/tools/text/textconfig.cpp +++ b/src/tools/text/textconfig.cpp @@ -12,19 +12,24 @@ TextConfig::TextConfig(QWidget* parent) : QWidget(parent) + , m_layout(nullptr) + , m_fontsCB(nullptr) + , m_strikeOutButton(nullptr) + , m_underlineButton(nullptr) + , m_weightButton(nullptr) + , m_italicButton(nullptr) { m_layout = new QVBoxLayout(this); QFontDatabase fontDB; - QComboBox* fontsCB = new QComboBox(); - connect(fontsCB, + m_fontsCB = new QComboBox(); + connect(m_fontsCB, &QComboBox::currentTextChanged, this, &TextConfig::fontFamilyChanged); - fontsCB->addItems(fontDB.families()); + m_fontsCB->addItems(fontDB.families()); // TODO save family in config - int index = fontsCB->findText(font().family()); - fontsCB->setCurrentIndex(index); + setFontFamily(font().family()); QString iconPrefix = ColorUtils::colorIsDark(palette().windowText().color()) ? PathInfo::blackIconPath() @@ -67,7 +72,7 @@ TextConfig::TextConfig(QWidget* parent) m_italicButton->setToolTip(tr("Italic")); QHBoxLayout* modifiersLayout = new QHBoxLayout(); - m_layout->addWidget(fontsCB); + m_layout->addWidget(m_fontsCB); modifiersLayout->addWidget(m_strikeOutButton); modifiersLayout->addWidget(m_underlineButton); modifiersLayout->addWidget(m_weightButton); @@ -75,6 +80,11 @@ TextConfig::TextConfig(QWidget* parent) m_layout->addLayout(modifiersLayout); } +void TextConfig::setFontFamily(const QString& fontFamily) +{ + m_fontsCB->setCurrentIndex(m_fontsCB->findText(fontFamily)); +} + void TextConfig::setUnderline(const bool u) { m_underlineButton->setChecked(u); diff --git a/src/tools/text/textconfig.h b/src/tools/text/textconfig.h index 2195a85c..841e573e 100644 --- a/src/tools/text/textconfig.h +++ b/src/tools/text/textconfig.h @@ -7,6 +7,7 @@ class QVBoxLayout; class QPushButton; +class QComboBox; class TextConfig : public QWidget { @@ -14,6 +15,7 @@ class TextConfig : public QWidget public: explicit TextConfig(QWidget* parent = nullptr); + void setFontFamily(const QString& fontFamily); void setUnderline(const bool u); void setStrikeOut(const bool s); void setWeight(const int w); @@ -33,6 +35,7 @@ private slots: private: QVBoxLayout* m_layout; + QComboBox* m_fontsCB; QPushButton* m_strikeOutButton; QPushButton* m_underlineButton; QPushButton* m_weightButton; diff --git a/src/tools/text/texttool.cpp b/src/tools/text/texttool.cpp index 62548209..b33a36b8 100644 --- a/src/tools/text/texttool.cpp +++ b/src/tools/text/texttool.cpp @@ -6,6 +6,7 @@ #include "textwidget.h" #define BASE_POINT_SIZE 8 +#define MAX_INFO_LENGTH 24 TextTool::TextTool(QObject* parent) : CaptureTool(parent) @@ -59,6 +60,20 @@ QString TextTool::name() const return tr("Text"); } +QString TextTool::info() +{ + if (m_text.length() > 0) { + m_tempString = QString("%1 - %2").arg(name()).arg(m_text.trimmed()); + m_tempString = m_tempString.split("\n").at(0); + if (m_tempString.length() > MAX_INFO_LENGTH) { + m_tempString.truncate(MAX_INFO_LENGTH); + m_tempString += "…"; + } + return m_tempString; + } + return name(); +} + ToolType TextTool::nameID() const { return ToolType::TEXT; @@ -76,6 +91,8 @@ QWidget* TextTool::widget() m_widget->setTextColor(m_color); m_font.setPointSize(m_size + BASE_POINT_SIZE); m_widget->setFont(m_font); + m_widget->setText(m_text); + m_widget->selectAll(); connect(m_widget, &TextWidget::textUpdated, this, &TextTool::updateText); return m_widget; } @@ -115,6 +132,7 @@ QWidget* TextTool::configurationWidget() &TextConfig::fontWeightChanged, this, &TextTool::updateFontWeight); + m_confW->setFontFamily(m_font.family()); m_confW->setItalic(m_font.italic()); m_confW->setUnderline(m_font.underline()); m_confW->setStrikeOut(m_font.strikeOut()); @@ -164,7 +182,9 @@ void TextTool::process(QPainter& painter, const QPixmap& pixmap) // draw text painter.setFont(m_font); painter.setPen(m_color); - painter.drawText(m_textArea + QMargins(-val, -val, val, val), m_text); + if (!editMode()) { + painter.drawText(m_textArea + QMargins(-val, -val, val, val), m_text); + } } void TextTool::drawObjectSelection(QPainter& painter) diff --git a/src/tools/text/texttool.h b/src/tools/text/texttool.h index 67150411..816596b7 100644 --- a/src/tools/text/texttool.h +++ b/src/tools/text/texttool.h @@ -25,6 +25,7 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QString info() override; QWidget* widget() override; QWidget* configurationWidget() override; @@ -69,4 +70,6 @@ private: QPointer m_widget; QPointer m_confW; QPoint m_currentPos; + + QString m_tempString; }; diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 53f8b256..a30eb5f7 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -267,19 +267,16 @@ QPixmap CaptureWidget::pixmap() // tool. bool CaptureWidget::commitCurrentTool() { - if (m_activeButton && m_activeTool) { - if (m_activeTool->isValid() && m_toolWidget) { + if (m_activeTool) { + if (m_activeTool->isValid() && !m_activeTool->editMode() && + m_toolWidget) { pushToolToStack(); - } else { - m_activeTool->deleteLater(); - m_activeTool = nullptr; } - if (m_toolWidget) { - m_toolWidget->close(); - delete m_toolWidget; - m_toolWidget = nullptr; - return true; + if (m_activeTool) { + m_activeTool->setEditMode(false); } + releaseActiveTool(); + return true; } return false; } @@ -306,13 +303,29 @@ void CaptureWidget::deleteToolWidgetOrClose() } } +void CaptureWidget::releaseActiveTool() +{ + if (m_activeTool) { + if (-1 == m_panel->activeLayerIndex() && m_activeButton) { + // delete tool if no active selection, otherwise object shouldn't be + // deleted, because it is in undo/redo stack + m_activeTool->deleteLater(); + } + m_activeTool = nullptr; + } + if (m_toolWidget) { + m_toolWidget->close(); + delete m_toolWidget; + m_toolWidget = nullptr; + } +} + void CaptureWidget::uncheckActiveTool() { // uncheck active tool m_activeButton->setColor(m_uiColor); m_activeButton = nullptr; - m_activeTool->deleteLater(); - m_activeTool = nullptr; + releaseActiveTool(); updateCursor(); update(); // clear mouse preview } @@ -389,8 +402,7 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos) m_captureToolObjects.append(m_activeTool); m_undoStack.push( new ModificationCommand(this, m_captureToolObjects)); - m_activeTool->deleteLater(); - m_activeTool = nullptr; + releaseActiveTool(); m_mouseIsClicked = false; } return true; @@ -398,16 +410,17 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos) return false; } -void CaptureWidget::selectToolItemAtPos(const QPoint& pos) +int CaptureWidget::selectToolItemAtPos(const QPoint& pos) { - // Try to select existing tool + // Try to select existing tool, "-1" - no active tool + int activeLayerIndex = -1; if (m_activeButton.isNull() && m_captureToolObjects.captureToolObjects().size() > 0 && m_selection->getMouseSide(pos) == SelectionWidget::NO_SIDE) { auto toolItem = activeToolObject(); if (!toolItem || (toolItem && !toolItem->selectionRect().contains(pos))) { - int activeLayerIndex = m_captureToolObjects.find(pos, size()); + activeLayerIndex = m_captureToolObjects.find(pos, size()); int thickness_old = m_context.thickness; m_panel->setActiveLayer(activeLayerIndex); drawObjectSelection(); @@ -416,6 +429,7 @@ void CaptureWidget::selectToolItemAtPos(const QPoint& pos) } } } + return activeLayerIndex; } void CaptureWidget::mousePressEvent(QMouseEvent* e) @@ -457,12 +471,38 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) } } - // Try to select existing tool + // Commit current tool if it has edit widget and mouse click is outside of + // it + if (m_toolWidget && !m_toolWidget->geometry().contains(e->pos())) { + commitCurrentTool(); + m_panel->setToolWidget(nullptr); + drawToolsData(); + update(); + } + selectToolItemAtPos(m_mousePressedPos); updateCursor(); } +void CaptureWidget::mouseDoubleClickEvent(QMouseEvent* event) +{ + int activeLayerIndex = m_panel->activeLayerIndex(); + if (activeLayerIndex != -1) { + // Start object editing + m_activeTool = m_captureToolObjects.at(activeLayerIndex); + if (m_activeTool && m_activeTool->nameID() == ToolType::TEXT) { + m_mouseIsClicked = false; + m_context.mousePos = *m_activeTool->pos(); + m_activeTool->setEditMode(true); + drawToolsData(true, false); + m_mouseIsClicked = false; + handleButtonSignal(CaptureTool::REQ_ADD_CHILD_WIDGET); + m_panel->setToolWidget(m_activeTool->configurationWidget()); + } + } +} + void CaptureWidget::mouseMoveEvent(QMouseEvent* e) { m_context.mousePos = e->pos(); @@ -588,6 +628,7 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) { if (e->button() == Qt::RightButton || m_colorPicker->isVisible()) { + // Color picker m_colorPicker->hide(); if (!m_context.color.isValid()) { m_context.color = ConfigHandler().drawColorValue(); @@ -604,8 +645,7 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) if (m_activeTool->isValid()) { pushToolToStack(); } else if (!m_toolWidget) { - m_activeTool->deleteLater(); - m_activeTool = nullptr; + releaseActiveTool(); } } else { if (m_activeToolIsMoved) { @@ -625,9 +665,10 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) } } - // Show the buttons after the resize of the selection or the creation - // of a new one. if (!m_buttonHandler->isVisible() && m_selection->isVisible()) { + // Show the buttons after the resize of the selection or the creation + // of a new one. + // Don't go outside QRect newGeometry = m_selection->geometry().intersected(rect()); // normalize @@ -924,15 +965,8 @@ void CaptureWidget::setState(CaptureToolButton* b) return; } - if (m_toolWidget) { - m_toolWidget->close(); - delete m_toolWidget; - m_toolWidget = nullptr; - if (m_activeTool != nullptr) { - if (m_activeTool->isValid()) { - pushToolToStack(); - } - } + if (m_toolWidget && m_activeTool && m_activeTool->isValid()) { + pushToolToStack(); } if (m_activeButton != b) { processTool(b->tool()); @@ -946,7 +980,7 @@ void CaptureWidget::setState(CaptureToolButton* b) if (b->tool()->isSelectable()) { if (m_activeButton != b) { QWidget* confW = b->tool()->configurationWidget(); - m_panel->addToolWidget(confW); + m_panel->setToolWidget(confW); if (m_activeButton) { m_activeButton->setColor(m_uiColor); } @@ -1360,9 +1394,9 @@ void CaptureWidget::pushToolToStack() disconnect(m_panel->toolWidget(), nullptr, m_activeTool, nullptr); } + m_activeTool->setEditMode(false); m_captureToolObjects.append(m_activeTool); - m_activeTool->deleteLater(); - m_activeTool = nullptr; + releaseActiveTool(); } // push current state to the undo stack @@ -1402,7 +1436,7 @@ void CaptureWidget::drawToolsData(bool updateLayersPanel, bool drawSelection) void CaptureWidget::drawObjectSelection() { auto toolItem = activeToolObject(); - if (toolItem) { + if (toolItem && !toolItem->editMode()) { QPainter painter(&m_context.screenshot); toolItem->drawObjectSelection(painter); if (m_context.thickness != toolItem->thickness()) { diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index 8a02ac1d..35700d64 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -99,6 +99,7 @@ protected: void mousePressEvent(QMouseEvent* mouseEvent) override; void mouseMoveEvent(QMouseEvent* mouseEvent) override; void mouseReleaseEvent(QMouseEvent* mouseEvent) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; void keyPressEvent(QKeyEvent* keyEvent) override; void keyReleaseEvent(QKeyEvent* keyEvent) override; void wheelEvent(QWheelEvent* wheelEvent) override; @@ -106,8 +107,9 @@ protected: void moveEvent(QMoveEvent* moveEvent) override; private: + void releaseActiveTool(); void uncheckActiveTool(); - void selectToolItemAtPos(const QPoint& pos); + int selectToolItemAtPos(const QPoint& pos); void showColorPicker(const QPoint& pos); bool startDrawObjectTool(const QPoint& pos); QPointer activeToolObject(); diff --git a/src/widgets/panel/utilitypanel.cpp b/src/widgets/panel/utilitypanel.cpp index 07bc5e5e..b0bbd23d 100644 --- a/src/widgets/panel/utilitypanel.cpp +++ b/src/widgets/panel/utilitypanel.cpp @@ -51,10 +51,12 @@ QWidget* UtilityPanel::toolWidget() const return m_toolWidget; } -void UtilityPanel::addToolWidget(QWidget* w) +void UtilityPanel::setToolWidget(QWidget* w) { if (m_toolWidget) { - m_toolWidget->deleteLater(); + m_toolWidget->close(); + delete m_toolWidget; + m_toolWidget = nullptr; } if (w) { m_toolWidget = w; @@ -168,7 +170,7 @@ void UtilityPanel::fillCaptureTools( for (auto toolItem : captureToolObjects) { QListWidgetItem* item = new QListWidgetItem( - toolItem->icon(QColor(Qt::white), false), toolItem->name()); + toolItem->icon(QColor(Qt::white), false), toolItem->info()); m_captureTools->addItem(item); } if (currentSelection >= 0 && currentSelection < m_captureTools->count()) { diff --git a/src/widgets/panel/utilitypanel.h b/src/widgets/panel/utilitypanel.h index f26cab33..afa1a239 100644 --- a/src/widgets/panel/utilitypanel.h +++ b/src/widgets/panel/utilitypanel.h @@ -23,7 +23,7 @@ public: explicit UtilityPanel(CaptureWidget* captureWidget); QWidget* toolWidget() const; - void addToolWidget(QWidget* w); + void setToolWidget(QWidget* w); void clearToolWidget(); void pushWidget(QWidget* w); void hide();