* Optimise undo/redo for thickness, do not save every change on mouse wheel, save just the result (cherry picked from commit c0bd74790e086dcde1c242a31e27f992a04c07e2) * fix - In some cases undo/redo stack has excess steps (root cause is in the start move object event on a small not noticeable mouse move) (cherry picked from commit 912f39f38083e368979f34ef14821979c34482bb) * fix - It is impossible to remove an object using the "Undo the latest modification" button on second attempt (full undo, draw something, full undo again) (cherry picked from commit a7f77a130a497ac6fdecd59eb43c889dcc6cbe1a) * fix - Picked font family in the text editing tool is applied to the autoincrement tool (cherry picked from commit 11c5eb29b1078bd6aba91fe7a74c2682767ad47c) * Add git hash to version in the about dialog (cherry picked from commit b4dbf52b3217b51614100bd307046772a37dc484) * Add configuration option to limit undo steps (cherry picked from commit f13cbecabb172060b196a535348f145457ad2f0f) * Object delete operation is not registered on the undo stack (cherry picked from commit 5c966cb5d3702a4d735dd542ad03a80899250b4a) * fix - Unable to draw an object from second attempt after ColorPicker was called (cherry picked from commit 49a119886fec253376703e8aa2386e16bc23cbcf) * fix - App freezes and then crashes when changing object line thickness via Active thickness slider in the tool settings (cherry picked from commit 26fd64f1c333f70c67282630362cbc5fc8427a39) * fix - set min and max values for thickness slider to 1-100 (cherry picked from commit 6d8661666e4e199a3c29f991d52bef73ec36129c) * fix - Crash on Move Tool button with an active Text editor (cherry picked from commit 461f95da3afda56c0e9693e768e86b18d056eecc) * fix - Text is not modified when picking it as object in the list (cherry picked from commit 366bb0928b430d442dc67299353f7dc5ceb743b4) * fix - Text modification cannot be undone fix - Object that was created after the text object disappears after undo editing text (cherry picked from commit 79b2fb92aca65b177cffb386db141d30551a2b1c) * fix - Text is not saved if picking any object in the objects list without clicking at the empty space (cherry picked from commit 4679a744a3d2498fe27379f89d48b347a34ae0dc) * Last available undo step reset everything to the beginning (cherry picked from commit 4af7423d00cfaa9feabc905400aa3ac30fc4a3ea) * Missed changes (cherry-pick) for switching ColorPicker behaviour (right mouse click and hold to right mouse click and left click) Co-authored-by: Yuriy Puchkov <yuriy.puchkov@namecheap.com>
207 lines
6.7 KiB
C++
207 lines
6.7 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// SPDX-FileCopyrightText: 2017-2019 Alejandro Sirgo Rica & Contributors
|
|
|
|
#pragma once
|
|
|
|
#include "src/tools/capturecontext.h"
|
|
#include "src/utils/colorutils.h"
|
|
#include "src/utils/pathinfo.h"
|
|
#include <QIcon>
|
|
#include <QPainter>
|
|
|
|
enum class ToolType
|
|
{
|
|
ARROW,
|
|
CIRCLE,
|
|
CIRCLECOUNT,
|
|
COPY,
|
|
EXIT,
|
|
IMGUR,
|
|
LAUNCHER,
|
|
LINE,
|
|
MARKER,
|
|
MOVE,
|
|
PENCIL,
|
|
PIN,
|
|
PIXELATE,
|
|
RECTANGLE,
|
|
REDO,
|
|
SAVE,
|
|
SELECTION,
|
|
SIZEINDICATOR,
|
|
TEXT,
|
|
UNDO,
|
|
UPLOAD,
|
|
SIZEINCREASE,
|
|
SIZEDECREASE
|
|
};
|
|
|
|
class CaptureTool : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
// Request actions on the main widget
|
|
enum Request
|
|
{
|
|
// Call close() in the editor.
|
|
REQ_CLOSE_GUI,
|
|
// Call hide() in the editor.
|
|
REQ_HIDE_GUI,
|
|
// Select the whole screen.
|
|
REQ_SELECT_ALL,
|
|
// Disable the selection.
|
|
REQ_HIDE_SELECTION,
|
|
// Undo the last active modification in the stack.
|
|
REQ_UNDO_MODIFICATION,
|
|
// Redo the next modification in the stack.
|
|
REQ_REDO_MODIFICATION,
|
|
// Remove all the modifications.
|
|
REQ_CLEAR_MODIFICATIONS,
|
|
// Disable the active tool.
|
|
REQ_MOVE_MODE,
|
|
// Open the color picker under the mouse.
|
|
REQ_SHOW_COLOR_PICKER,
|
|
// Open/Close the side-panel.
|
|
REQ_TOGGLE_SIDEBAR,
|
|
// Call update() in the editor.
|
|
REQ_REDRAW,
|
|
// Notify to redraw screenshot with tools without object selection.
|
|
REQ_CLEAR_SELECTION,
|
|
// Notify is the screenshot has been saved.
|
|
REQ_CAPTURE_DONE_OK,
|
|
// Instance this->widget()'s widget inside the editor under the mouse.
|
|
REQ_ADD_CHILD_WIDGET,
|
|
// Instance this->widget()'s widget which handles its own lifetime.
|
|
REQ_ADD_EXTERNAL_WIDGETS,
|
|
// increase tool size for all tools
|
|
REQ_INCREASE_TOOL_SIZE,
|
|
// decrease tool size for all tools
|
|
REQ_DECREASE_TOOL_SIZE
|
|
};
|
|
|
|
explicit CaptureTool(QObject* parent = nullptr)
|
|
: QObject(parent)
|
|
, m_count(0)
|
|
, m_editMode(false)
|
|
{}
|
|
|
|
virtual void setCapture(const QPixmap& pixmap){};
|
|
|
|
// Returns false when the tool is in an inconsistent state and shouldn't
|
|
// be included in the tool undo/redo stack.
|
|
virtual bool isValid() const = 0;
|
|
// Close the capture after the process() call if the tool was activated
|
|
// from a button press.
|
|
virtual bool closeOnButtonPressed() const = 0;
|
|
// If the tool keeps active after the selection.
|
|
virtual bool isSelectable() const = 0;
|
|
// Enable mouse preview.
|
|
virtual bool showMousePreview() const = 0;
|
|
|
|
// The icon of the tool.
|
|
// inEditor is true when the icon is requested inside the editor
|
|
// and false otherwise.
|
|
virtual QIcon icon(const QColor& background, bool inEditor) const = 0;
|
|
// Name displayed for the tool, this could be translated with tr()
|
|
virtual QString name() const = 0;
|
|
// Codename for the tool, this shouldn't change as it is used as ID
|
|
// for the tool in the internals of Flameshot
|
|
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
|
|
// individual widget.
|
|
virtual QWidget* widget() { return nullptr; }
|
|
// When the tool is selected this method is called and the widget is added
|
|
// to the configuration panel inside the main widget.
|
|
virtual QWidget* configurationWidget() { return nullptr; }
|
|
// 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; };
|
|
|
|
// return true if object was change after editMode
|
|
virtual bool isChanged() { return true; };
|
|
|
|
// Counter for all object types (currently is used for the CircleCounter
|
|
// only)
|
|
virtual void setCount(int count) { m_count = count; };
|
|
virtual int count() { return m_count; };
|
|
|
|
// Called every time the tool has to draw
|
|
// recordUndo indicates when the tool should save the information
|
|
// for the undo(), if the value is false calling undo() after
|
|
// that process should not modify revert the changes.
|
|
virtual void process(QPainter& painter, const QPixmap& pixmap) = 0;
|
|
virtual void drawSearchArea(QPainter& painter, const QPixmap& pixmap)
|
|
{
|
|
process(painter, pixmap);
|
|
};
|
|
virtual void drawObjectSelection(QPainter& painter) { Q_UNUSED(painter) };
|
|
// When the tool is selected, this is called when the mouse moves
|
|
virtual void paintMousePreview(QPainter& painter,
|
|
const CaptureContext& context) = 0;
|
|
|
|
// Move tool objects
|
|
virtual void move(const QPoint& pos) { Q_UNUSED(pos) };
|
|
virtual const QPoint* pos() { return nullptr; };
|
|
|
|
// get selection region
|
|
const QRect& selectionRect() { return m_selectionRect; };
|
|
|
|
signals:
|
|
void requestAction(Request r);
|
|
|
|
protected:
|
|
void copyParams(const CaptureTool* from, CaptureTool* to)
|
|
{
|
|
to->m_count = from->m_count;
|
|
}
|
|
|
|
QString iconPath(const QColor& c) const
|
|
{
|
|
return ColorUtils::colorIsDark(c) ? PathInfo::whiteIconPath()
|
|
: PathInfo::blackIconPath();
|
|
}
|
|
|
|
void drawObjectSelectionRect(QPainter& painter, QRect rect)
|
|
{
|
|
QPen orig_pen = painter.pen();
|
|
painter.setPen(QPen(Qt::black, 3));
|
|
painter.drawRect(rect);
|
|
painter.setPen(QPen(Qt::white, 1, Qt::DotLine));
|
|
painter.drawRect(rect);
|
|
painter.setPen(orig_pen);
|
|
m_selectionRect = rect;
|
|
}
|
|
|
|
public slots:
|
|
// On mouse release.
|
|
virtual void drawEnd(const QPoint& p) = 0;
|
|
// Mouse pressed and moving, called once a pixel.
|
|
virtual void drawMove(const QPoint& p) = 0;
|
|
// Called when drawMove is needed with an adjustment;
|
|
// should be overridden in case an adjustment is applicable.
|
|
virtual void drawMoveWithAdjustment(const QPoint& p) { drawMove(p); }
|
|
// Called when the tool is activated.
|
|
virtual void drawStart(const CaptureContext& context) = 0;
|
|
// Called right after pressign the button which activates the tool.
|
|
virtual void pressed(const CaptureContext& context) = 0;
|
|
// Called when the color is changed in the editor.
|
|
virtual void colorChanged(const QColor& c) = 0;
|
|
// Called when the thickness of the tool is updated in the editor.
|
|
virtual void thicknessChanged(int th) = 0;
|
|
virtual int thickness() { return -1; };
|
|
|
|
private:
|
|
unsigned int m_count;
|
|
bool m_editMode;
|
|
QRect m_selectionRect;
|
|
};
|