mirror of
https://github.com/fergalmoran/flameshot.git
synced 2025-12-22 09:51:06 +00:00
NC/Optimisations and bug fixes for objects editing (#1600)
* 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>
This commit is contained in:
@@ -9,7 +9,7 @@ set(GIT_API_URL "https://api.github.com/repos/flameshot-org/flameshot/releases/l
|
|||||||
# set(GIT_API_URL "https://api.github.com/repos/namecheap/flameshot/releases/latest")
|
# set(GIT_API_URL "https://api.github.com/repos/namecheap/flameshot/releases/latest")
|
||||||
|
|
||||||
# TODO - fix it for all linux distros
|
# TODO - fix it for all linux distros
|
||||||
# find_package (Git)
|
#find_package (Git)
|
||||||
#if (GIT_FOUND)
|
#if (GIT_FOUND)
|
||||||
# message("git found: ${GIT_EXECUTABLE} in version ${GIT_VERSION_STRING}")
|
# message("git found: ${GIT_EXECUTABLE} in version ${GIT_VERSION_STRING}")
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -197,6 +197,17 @@ if (WIN32)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
find_package (Git)
|
||||||
|
if (GIT_FOUND)
|
||||||
|
message("git found: ${GIT_EXECUTABLE} in version ${GIT_VERSION_STRING}")
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD OUTPUT_VARIABLE FLAMESHOT_GIT_HASH)
|
||||||
|
string(REGEX REPLACE "\r*\n$" "" FLAMESHOT_GIT_HASH "${FLAMESHOT_GIT_HASH}")
|
||||||
|
target_compile_definitions(flameshot PRIVATE FLAMESHOT_GIT_HASH="${FLAMESHOT_GIT_HASH}")
|
||||||
|
message("FLAMESHOT_GIT_HASH: ${FLAMESHOT_GIT_HASH}")
|
||||||
|
else()
|
||||||
|
target_compile_definitions(flameshot PRIVATE FLAMESHOT_GIT_HASH="-")
|
||||||
|
message("git command is not found")
|
||||||
|
endif ()
|
||||||
target_compile_definitions(flameshot PRIVATE APP_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
target_compile_definitions(flameshot PRIVATE APP_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||||
target_compile_definitions(flameshot PRIVATE APP_VERSION="v${PROJECT_VERSION}")
|
target_compile_definitions(flameshot PRIVATE APP_VERSION="v${PROJECT_VERSION}")
|
||||||
target_compile_definitions(flameshot PRIVATE IMGUR_CLIENT_ID="313baf0c7b4d3ff")
|
target_compile_definitions(flameshot PRIVATE IMGUR_CLIENT_ID="313baf0c7b4d3ff")
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
GeneralConf::GeneralConf(QWidget* parent)
|
GeneralConf::GeneralConf(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_historyConfirmationToDelete(nullptr)
|
, m_historyConfirmationToDelete(nullptr)
|
||||||
|
, m_undoLimit(nullptr)
|
||||||
{
|
{
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
m_layout->setAlignment(Qt::AlignTop);
|
m_layout->setAlignment(Qt::AlignTop);
|
||||||
@@ -35,6 +36,7 @@ GeneralConf::GeneralConf(QWidget* parent)
|
|||||||
initUseJpgForClipboard();
|
initUseJpgForClipboard();
|
||||||
initSaveAfterCopy();
|
initSaveAfterCopy();
|
||||||
initUploadHistoryMaxSize();
|
initUploadHistoryMaxSize();
|
||||||
|
initUndoLimit();
|
||||||
|
|
||||||
// this has to be at the end
|
// this has to be at the end
|
||||||
initConfigButtons();
|
initConfigButtons();
|
||||||
@@ -54,6 +56,7 @@ void GeneralConf::updateComponents()
|
|||||||
m_copyPathAfterSave->setChecked(config.copyPathAfterSaveEnabled());
|
m_copyPathAfterSave->setChecked(config.copyPathAfterSaveEnabled());
|
||||||
m_useJpgForClipboard->setChecked(config.useJpgForClipboard());
|
m_useJpgForClipboard->setChecked(config.useJpgForClipboard());
|
||||||
m_uploadHistoryMaxSize->setValue(config.uploadHistoryMaxSizeValue());
|
m_uploadHistoryMaxSize->setValue(config.uploadHistoryMaxSizeValue());
|
||||||
|
m_undoLimit->setValue(config.undoLimit());
|
||||||
|
|
||||||
if (!config.savePath().isEmpty()) {
|
if (!config.savePath().isEmpty()) {
|
||||||
m_savePath->setText(config.savePath());
|
m_savePath->setText(config.savePath());
|
||||||
@@ -182,6 +185,7 @@ void GeneralConf::setActualFormData()
|
|||||||
m_historyConfirmationToDelete->setChecked(
|
m_historyConfirmationToDelete->setChecked(
|
||||||
config.historyConfirmationToDelete());
|
config.historyConfirmationToDelete());
|
||||||
m_uploadHistoryMaxSize->setValue(config.uploadHistoryMaxSizeValue());
|
m_uploadHistoryMaxSize->setValue(config.uploadHistoryMaxSizeValue());
|
||||||
|
m_undoLimit->setValue(config.undoLimit());
|
||||||
m_useJpgForClipboard->setChecked(config.useJpgForClipboard());
|
m_useJpgForClipboard->setChecked(config.useJpgForClipboard());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +432,6 @@ void GeneralConf::initUploadHistoryMaxSize()
|
|||||||
SIGNAL(valueChanged(int)),
|
SIGNAL(valueChanged(int)),
|
||||||
this,
|
this,
|
||||||
SLOT(uploadHistoryMaxSizeChanged(int)));
|
SLOT(uploadHistoryMaxSizeChanged(int)));
|
||||||
|
|
||||||
vboxLayout->addWidget(m_uploadHistoryMaxSize);
|
vboxLayout->addWidget(m_uploadHistoryMaxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,6 +440,35 @@ void GeneralConf::uploadHistoryMaxSizeChanged(int max)
|
|||||||
ConfigHandler().setUploadHistoryMaxSize(max);
|
ConfigHandler().setUploadHistoryMaxSize(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneralConf::initUndoLimit()
|
||||||
|
{
|
||||||
|
QGroupBox* box = new QGroupBox(tr("Undo limit"));
|
||||||
|
box->setFlat(true);
|
||||||
|
m_layout->addWidget(box);
|
||||||
|
m_layout->addStretch();
|
||||||
|
|
||||||
|
QVBoxLayout* vboxLayout = new QVBoxLayout();
|
||||||
|
box->setLayout(vboxLayout);
|
||||||
|
|
||||||
|
int limit = ConfigHandler().undoLimit();
|
||||||
|
|
||||||
|
m_undoLimit = new QSpinBox(this);
|
||||||
|
m_undoLimit->setMinimum(1);
|
||||||
|
m_undoLimit->setMaximum(999);
|
||||||
|
m_undoLimit->setValue(limit);
|
||||||
|
QString foreground = this->palette().windowText().color().name();
|
||||||
|
m_undoLimit->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||||
|
|
||||||
|
connect(m_undoLimit, SIGNAL(valueChanged(int)), this, SLOT(undoLimit(int)));
|
||||||
|
|
||||||
|
vboxLayout->addWidget(m_undoLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralConf::undoLimit(int limit)
|
||||||
|
{
|
||||||
|
ConfigHandler().setUndoLimit(limit);
|
||||||
|
}
|
||||||
|
|
||||||
void GeneralConf::initUseJpgForClipboard()
|
void GeneralConf::initUseJpgForClipboard()
|
||||||
{
|
{
|
||||||
m_useJpgForClipboard =
|
m_useJpgForClipboard =
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ private slots:
|
|||||||
void autostartChanged(bool checked);
|
void autostartChanged(bool checked);
|
||||||
void historyConfirmationToDelete(bool checked);
|
void historyConfirmationToDelete(bool checked);
|
||||||
void uploadHistoryMaxSizeChanged(int max);
|
void uploadHistoryMaxSizeChanged(int max);
|
||||||
|
void undoLimit(int limit);
|
||||||
void saveAfterCopyChanged(bool checked);
|
void saveAfterCopyChanged(bool checked);
|
||||||
void changeSavePath();
|
void changeSavePath();
|
||||||
void importConfiguration();
|
void importConfiguration();
|
||||||
@@ -47,6 +48,7 @@ private:
|
|||||||
void initShowTrayIcon();
|
void initShowTrayIcon();
|
||||||
void initHistoryConfirmationToDelete();
|
void initHistoryConfirmationToDelete();
|
||||||
void initUploadHistoryMaxSize();
|
void initUploadHistoryMaxSize();
|
||||||
|
void initUndoLimit();
|
||||||
void initConfigButtons();
|
void initConfigButtons();
|
||||||
void initCheckForUpdates();
|
void initCheckForUpdates();
|
||||||
void initAutostart();
|
void initAutostart();
|
||||||
@@ -79,4 +81,5 @@ private:
|
|||||||
QCheckBox* m_historyConfirmationToDelete;
|
QCheckBox* m_historyConfirmationToDelete;
|
||||||
QCheckBox* m_useJpgForClipboard;
|
QCheckBox* m_useJpgForClipboard;
|
||||||
QSpinBox* m_uploadHistoryMaxSize;
|
QSpinBox* m_uploadHistoryMaxSize;
|
||||||
|
QSpinBox* m_undoLimit;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2021 Yuriy Puchkov <yuriy.puchkov@namecheap.com>
|
// SPDX-FileCopyrightText: 2021 Yuriy Puchkov <yuriy.puchkov@namecheap.com>
|
||||||
//
|
|
||||||
// Created by yuriypuchkov on 09.02.2021.
|
|
||||||
|
|
||||||
#include "qguiappcurrentscreen.h"
|
#include "qguiappcurrentscreen.h"
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2021 Yuriy Puchkov <yuriy.puchkov@namecheap.com>
|
// SPDX-FileCopyrightText: 2021 Yuriy Puchkov <yuriy.puchkov@namecheap.com>
|
||||||
//
|
|
||||||
// Created by yuriypuchkov on 09.02.2021.
|
|
||||||
|
|
||||||
#ifndef FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
#ifndef FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
||||||
#define FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
#define FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# Use default Imgur client_id if user did not pass
|
|
||||||
# this variable to qmake
|
|
||||||
isEmpty(IMGUR_CLIENT_ID) {
|
|
||||||
IMGUR_CLIENT_ID = "313baf0c7b4d3ff"
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINES += IMGUR_CLIENT_ID=\\\"$${IMGUR_CLIENT_ID}\\\"
|
|
||||||
@@ -72,9 +72,6 @@ public:
|
|||||||
REQ_CAPTURE_DONE_OK,
|
REQ_CAPTURE_DONE_OK,
|
||||||
// Instance this->widget()'s widget inside the editor under the mouse.
|
// Instance this->widget()'s widget inside the editor under the mouse.
|
||||||
REQ_ADD_CHILD_WIDGET,
|
REQ_ADD_CHILD_WIDGET,
|
||||||
// Instance this->widget()'s widget as a window which closes after
|
|
||||||
// closing the editor.
|
|
||||||
REQ_ADD_CHILD_WINDOW,
|
|
||||||
// Instance this->widget()'s widget which handles its own lifetime.
|
// Instance this->widget()'s widget which handles its own lifetime.
|
||||||
REQ_ADD_EXTERNAL_WIDGETS,
|
REQ_ADD_EXTERNAL_WIDGETS,
|
||||||
// increase tool size for all tools
|
// increase tool size for all tools
|
||||||
@@ -129,6 +126,9 @@ public:
|
|||||||
virtual void setEditMode(bool b) { m_editMode = b; };
|
virtual void setEditMode(bool b) { m_editMode = b; };
|
||||||
virtual bool editMode() { return m_editMode; };
|
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
|
// Counter for all object types (currently is used for the CircleCounter
|
||||||
// only)
|
// only)
|
||||||
virtual void setCount(int count) { m_count = count; };
|
virtual void setCount(int count) { m_count = count; };
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ void TextTool::process(QPainter& painter, const QPixmap& pixmap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int val = 5;
|
const int val = 5;
|
||||||
|
QFont orig_font = painter.font();
|
||||||
|
QPen orig_pen = painter.pen();
|
||||||
QFontMetrics fm(m_font);
|
QFontMetrics fm(m_font);
|
||||||
QSize size(fm.boundingRect(QRect(), 0, m_text).size());
|
QSize size(fm.boundingRect(QRect(), 0, m_text).size());
|
||||||
size.setWidth(size.width() + val * 2);
|
size.setWidth(size.width() + val * 2);
|
||||||
@@ -185,6 +187,8 @@ void TextTool::process(QPainter& painter, const QPixmap& pixmap)
|
|||||||
if (!editMode()) {
|
if (!editMode()) {
|
||||||
painter.drawText(m_textArea + QMargins(-val, -val, val, val), m_text);
|
painter.drawText(m_textArea + QMargins(-val, -val, val, val), m_text);
|
||||||
}
|
}
|
||||||
|
painter.setFont(orig_font);
|
||||||
|
painter.setPen(orig_pen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextTool::drawObjectSelection(QPainter& painter)
|
void TextTool::drawObjectSelection(QPainter& painter)
|
||||||
@@ -296,3 +300,16 @@ const QPoint* TextTool::pos()
|
|||||||
m_currentPos = m_textArea.topLeft();
|
m_currentPos = m_textArea.topLeft();
|
||||||
return &m_currentPos;
|
return &m_currentPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextTool::setEditMode(bool b)
|
||||||
|
{
|
||||||
|
if (b) {
|
||||||
|
m_textOld = m_text;
|
||||||
|
}
|
||||||
|
CaptureTool::setEditMode(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextTool::isChanged()
|
||||||
|
{
|
||||||
|
return QString::compare(m_text, m_textOld, Qt::CaseInsensitive) != 0;
|
||||||
|
}
|
||||||
@@ -38,6 +38,9 @@ public:
|
|||||||
const QPoint* pos() override;
|
const QPoint* pos() override;
|
||||||
void drawObjectSelection(QPainter& painter) override;
|
void drawObjectSelection(QPainter& painter) override;
|
||||||
|
|
||||||
|
void setEditMode(bool b) override;
|
||||||
|
bool isChanged() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void copyParams(const TextTool* from, TextTool* to);
|
void copyParams(const TextTool* from, TextTool* to);
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
@@ -64,6 +67,7 @@ private:
|
|||||||
|
|
||||||
QFont m_font;
|
QFont m_font;
|
||||||
QString m_text;
|
QString m_text;
|
||||||
|
QString m_textOld;
|
||||||
int m_size;
|
int m_size;
|
||||||
QColor m_color;
|
QColor m_color;
|
||||||
QRect m_textArea;
|
QRect m_textArea;
|
||||||
|
|||||||
@@ -222,6 +222,21 @@ QString ConfigHandler::ignoreUpdateToVersion()
|
|||||||
return m_settings.value(QStringLiteral("ignoreUpdateToVersion")).toString();
|
return m_settings.value(QStringLiteral("ignoreUpdateToVersion")).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigHandler::setUndoLimit(int value)
|
||||||
|
{
|
||||||
|
m_settings.setValue(QStringLiteral("undoLimit"), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConfigHandler::undoLimit()
|
||||||
|
{
|
||||||
|
int limit = 100;
|
||||||
|
if (m_settings.contains(QStringLiteral("undoLimit"))) {
|
||||||
|
limit = m_settings.value(QStringLiteral("undoLimit")).toInt();
|
||||||
|
limit = qBound(1, limit, 999);
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
bool ConfigHandler::desktopNotificationValue()
|
bool ConfigHandler::desktopNotificationValue()
|
||||||
{
|
{
|
||||||
bool res = true;
|
bool res = true;
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ public:
|
|||||||
void setIgnoreUpdateToVersion(const QString& text);
|
void setIgnoreUpdateToVersion(const QString& text);
|
||||||
QString ignoreUpdateToVersion();
|
QString ignoreUpdateToVersion();
|
||||||
|
|
||||||
|
void setUndoLimit(int value);
|
||||||
|
int undoLimit();
|
||||||
|
|
||||||
QVector<QStringList> shortcuts();
|
QVector<QStringList> shortcuts();
|
||||||
void setShortcutsDefault();
|
void setShortcutsDefault();
|
||||||
bool setShortcut(const QString&, const QString&);
|
bool setShortcut(const QString&, const QString&);
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ CaptureToolButton::~CaptureToolButton()
|
|||||||
|
|
||||||
void CaptureToolButton::initButton()
|
void CaptureToolButton::initButton()
|
||||||
{
|
{
|
||||||
|
if (m_tool) {
|
||||||
|
delete m_tool;
|
||||||
|
m_tool = nullptr;
|
||||||
|
}
|
||||||
m_tool = ToolFactory().CreateTool(m_buttonType, this);
|
m_tool = ToolFactory().CreateTool(m_buttonType, this);
|
||||||
|
|
||||||
resize(GlobalValues::buttonBaseSize(), GlobalValues::buttonBaseSize());
|
resize(GlobalValues::buttonBaseSize(), GlobalValues::buttonBaseSize());
|
||||||
|
|||||||
@@ -31,12 +31,13 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QUndoView>
|
|
||||||
#include <draggablewidgetmaker.h>
|
#include <draggablewidgetmaker.h>
|
||||||
|
|
||||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
#define MOUSE_DISTANCE_TO_START_MOVING 3
|
||||||
|
|
||||||
// CaptureWidget is the main component used to capture the screen. It contains
|
// CaptureWidget is the main component used to capture the screen. It contains
|
||||||
// an area of selection with its respective buttons.
|
// an area of selection with its respective buttons.
|
||||||
|
|
||||||
@@ -65,7 +66,11 @@ CaptureWidget::CaptureWidget(uint id,
|
|||||||
, m_lastPressedRedo(false)
|
, m_lastPressedRedo(false)
|
||||||
, m_panel(nullptr)
|
, m_panel(nullptr)
|
||||||
, m_selection(nullptr)
|
, m_selection(nullptr)
|
||||||
|
, m_existingObjectIsChanged(false)
|
||||||
|
, m_startMove(false)
|
||||||
{
|
{
|
||||||
|
m_undoStack.setUndoLimit(ConfigHandler().undoLimit() + 1);
|
||||||
|
|
||||||
// Base config of the widget
|
// Base config of the widget
|
||||||
m_eventFilter = new HoverEventFilter(this);
|
m_eventFilter = new HoverEventFilter(this);
|
||||||
connect(m_eventFilter,
|
connect(m_eventFilter,
|
||||||
@@ -272,9 +277,6 @@ bool CaptureWidget::commitCurrentTool()
|
|||||||
m_toolWidget) {
|
m_toolWidget) {
|
||||||
pushToolToStack();
|
pushToolToStack();
|
||||||
}
|
}
|
||||||
if (m_activeTool) {
|
|
||||||
m_activeTool->setEditMode(false);
|
|
||||||
}
|
|
||||||
releaseActiveTool();
|
releaseActiveTool();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -297,6 +299,8 @@ void CaptureWidget::deleteToolWidgetOrClose()
|
|||||||
m_toolWidget->close();
|
m_toolWidget->close();
|
||||||
delete m_toolWidget;
|
delete m_toolWidget;
|
||||||
m_toolWidget = nullptr;
|
m_toolWidget = nullptr;
|
||||||
|
} else if (m_colorPicker && m_colorPicker->isVisible()) {
|
||||||
|
m_colorPicker->hide();
|
||||||
} else {
|
} else {
|
||||||
// close CaptureWidget
|
// close CaptureWidget
|
||||||
close();
|
close();
|
||||||
@@ -306,6 +310,12 @@ void CaptureWidget::deleteToolWidgetOrClose()
|
|||||||
void CaptureWidget::releaseActiveTool()
|
void CaptureWidget::releaseActiveTool()
|
||||||
{
|
{
|
||||||
if (m_activeTool) {
|
if (m_activeTool) {
|
||||||
|
if (m_activeTool->editMode()) {
|
||||||
|
m_activeTool->setEditMode(false);
|
||||||
|
if (m_activeTool->isChanged()) {
|
||||||
|
pushObjectsStateToUndoStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (-1 == m_panel->activeLayerIndex() && m_activeButton) {
|
if (-1 == m_panel->activeLayerIndex() && m_activeButton) {
|
||||||
// delete tool if no active selection, otherwise object shouldn't be
|
// delete tool if no active selection, otherwise object shouldn't be
|
||||||
// deleted, because it is in undo/redo stack
|
// deleted, because it is in undo/redo stack
|
||||||
@@ -400,8 +410,7 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos)
|
|||||||
// point and shouldn't wait for second point and move event
|
// point and shouldn't wait for second point and move event
|
||||||
m_activeTool->drawEnd(m_context.mousePos);
|
m_activeTool->drawEnd(m_context.mousePos);
|
||||||
m_captureToolObjects.append(m_activeTool);
|
m_captureToolObjects.append(m_activeTool);
|
||||||
m_undoStack.push(
|
pushObjectsStateToUndoStack();
|
||||||
new ModificationCommand(this, m_captureToolObjects));
|
|
||||||
releaseActiveTool();
|
releaseActiveTool();
|
||||||
m_mouseIsClicked = false;
|
m_mouseIsClicked = false;
|
||||||
}
|
}
|
||||||
@@ -410,6 +419,16 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CaptureWidget::pushObjectsStateToUndoStack()
|
||||||
|
{
|
||||||
|
m_existingObjectIsChanged = false;
|
||||||
|
// push zero state to be able to do a complete undo
|
||||||
|
if (m_undoStack.count() == 0 || m_undoStack.index() == 0) {
|
||||||
|
m_undoStack.push(new ModificationCommand(this, m_captureToolObjects));
|
||||||
|
}
|
||||||
|
m_undoStack.push(new ModificationCommand(this, m_captureToolObjects));
|
||||||
|
}
|
||||||
|
|
||||||
int CaptureWidget::selectToolItemAtPos(const QPoint& pos)
|
int CaptureWidget::selectToolItemAtPos(const QPoint& pos)
|
||||||
{
|
{
|
||||||
// Try to select existing tool, "-1" - no active tool
|
// Try to select existing tool, "-1" - no active tool
|
||||||
@@ -434,8 +453,14 @@ int CaptureWidget::selectToolItemAtPos(const QPoint& pos)
|
|||||||
|
|
||||||
void CaptureWidget::mousePressEvent(QMouseEvent* e)
|
void CaptureWidget::mousePressEvent(QMouseEvent* e)
|
||||||
{
|
{
|
||||||
|
m_startMove = false;
|
||||||
|
m_startMovePos = QPoint();
|
||||||
m_dragStartPoint = m_mousePressedPos = e->pos();
|
m_dragStartPoint = m_mousePressedPos = e->pos();
|
||||||
m_activeToolOffsetToMouseOnStart = QPoint();
|
m_activeToolOffsetToMouseOnStart = QPoint();
|
||||||
|
if (m_colorPicker->isVisible()) {
|
||||||
|
updateCursor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// reset object selection if capture area selection is active
|
// reset object selection if capture area selection is active
|
||||||
if (m_selection->getMouseSide(e->pos()) != SelectionWidget::NO_SIDE) {
|
if (m_selection->getMouseSide(e->pos()) != SelectionWidget::NO_SIDE) {
|
||||||
@@ -443,6 +468,9 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e->button() == Qt::RightButton) {
|
if (e->button() == Qt::RightButton) {
|
||||||
|
if (m_activeTool && m_activeTool->editMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
showColorPicker(m_mousePressedPos);
|
showColorPicker(m_mousePressedPos);
|
||||||
} else if (e->button() == Qt::LeftButton) {
|
} else if (e->button() == Qt::LeftButton) {
|
||||||
m_showInitialMsg = false;
|
m_showInitialMsg = false;
|
||||||
@@ -471,8 +499,8 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit current tool if it has edit widget and mouse click is outside of
|
// Commit current tool if it has edit widget and mouse click is outside
|
||||||
// it
|
// of it
|
||||||
if (m_toolWidget && !m_toolWidget->geometry().contains(e->pos())) {
|
if (m_toolWidget && !m_toolWidget->geometry().contains(e->pos())) {
|
||||||
commitCurrentTool();
|
commitCurrentTool();
|
||||||
m_panel->setToolWidget(nullptr);
|
m_panel->setToolWidget(nullptr);
|
||||||
@@ -508,18 +536,34 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e)
|
|||||||
m_context.mousePos = e->pos();
|
m_context.mousePos = e->pos();
|
||||||
bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier;
|
bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier;
|
||||||
|
|
||||||
int activeLayerIndex = m_panel->activeLayerIndex();
|
int activeLayerIndex = -1;
|
||||||
|
if (m_mouseIsClicked) {
|
||||||
|
activeLayerIndex = m_panel->activeLayerIndex();
|
||||||
|
}
|
||||||
if (m_mouseIsClicked && !m_activeButton && activeLayerIndex >= 0) {
|
if (m_mouseIsClicked && !m_activeButton && activeLayerIndex >= 0) {
|
||||||
// Move existing object
|
// Move existing object
|
||||||
QPointer<CaptureTool> activeTool =
|
if (!m_startMove) {
|
||||||
m_captureToolObjects.at(activeLayerIndex);
|
// Check for the minimal offset to start moving an object
|
||||||
if (m_activeToolOffsetToMouseOnStart.isNull()) {
|
if (m_startMovePos.isNull()) {
|
||||||
setCursor(Qt::OpenHandCursor);
|
m_startMovePos = e->pos();
|
||||||
m_activeToolOffsetToMouseOnStart = e->pos() - *activeTool->pos();
|
}
|
||||||
|
if ((e->pos() - m_startMovePos).manhattanLength() >
|
||||||
|
MOUSE_DISTANCE_TO_START_MOVING) {
|
||||||
|
m_startMove = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_startMove) {
|
||||||
|
QPointer<CaptureTool> activeTool =
|
||||||
|
m_captureToolObjects.at(activeLayerIndex);
|
||||||
|
if (m_activeToolOffsetToMouseOnStart.isNull()) {
|
||||||
|
setCursor(Qt::OpenHandCursor);
|
||||||
|
m_activeToolOffsetToMouseOnStart =
|
||||||
|
e->pos() - *activeTool->pos();
|
||||||
|
}
|
||||||
|
activeTool->move(e->pos() - m_activeToolOffsetToMouseOnStart);
|
||||||
|
m_activeToolIsMoved = true;
|
||||||
|
drawToolsData(false);
|
||||||
}
|
}
|
||||||
activeTool->move(e->pos() - m_activeToolOffsetToMouseOnStart);
|
|
||||||
m_activeToolIsMoved = true;
|
|
||||||
drawToolsData(false);
|
|
||||||
} else if (m_mouseIsClicked &&
|
} else if (m_mouseIsClicked &&
|
||||||
(!m_activeButton ||
|
(!m_activeButton ||
|
||||||
(m_activeButton && m_activeButton->tool() &&
|
(m_activeButton && m_activeButton->tool() &&
|
||||||
@@ -627,16 +671,14 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e)
|
|||||||
|
|
||||||
void CaptureWidget::mouseReleaseEvent(QMouseEvent* e)
|
void CaptureWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||||
{
|
{
|
||||||
if (e->button() == Qt::RightButton || m_colorPicker->isVisible()) {
|
if (e->button() == Qt::LeftButton && m_colorPicker->isVisible()) {
|
||||||
// Color picker
|
// Color picker
|
||||||
m_colorPicker->hide();
|
m_colorPicker->hide();
|
||||||
if (!m_context.color.isValid()) {
|
if (!m_context.color.isValid()) {
|
||||||
m_context.color = ConfigHandler().drawColorValue();
|
m_context.color = ConfigHandler().drawColorValue();
|
||||||
m_panel->show();
|
m_panel->show();
|
||||||
} else {
|
} else if (m_panel->activeLayerIndex() >= 0) {
|
||||||
// push current state to the undo stack
|
pushObjectsStateToUndoStack();
|
||||||
m_undoStack.push(
|
|
||||||
new ModificationCommand(this, m_captureToolObjects));
|
|
||||||
}
|
}
|
||||||
} else if (m_mouseIsClicked) {
|
} else if (m_mouseIsClicked) {
|
||||||
if (m_activeTool) {
|
if (m_activeTool) {
|
||||||
@@ -649,9 +691,7 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent* e)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_activeToolIsMoved) {
|
if (m_activeToolIsMoved) {
|
||||||
// push current state to the undo stack
|
pushObjectsStateToUndoStack();
|
||||||
m_undoStack.push(
|
|
||||||
new ModificationCommand(this, m_captureToolObjects));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to select existing tool if it was in the selection area but
|
// Try to select existing tool if it was in the selection area but
|
||||||
@@ -786,17 +826,15 @@ void CaptureWidget::wheelEvent(QWheelEvent* e)
|
|||||||
m_activeButton->tool()->showMousePreview()) {
|
m_activeButton->tool()->showMousePreview()) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
emit thicknessChanged(m_context.thickness);
|
|
||||||
|
|
||||||
// update selected object thickness
|
// update selected object thickness
|
||||||
// Reset selection if mouse pos is not in selection area
|
// Reset selection if mouse pos is not in selection area
|
||||||
auto toolItem = activeToolObject();
|
auto toolItem = activeToolObject();
|
||||||
if (toolItem) {
|
if (toolItem) {
|
||||||
toolItem->thicknessChanged(m_context.thickness);
|
toolItem->thicknessChanged(m_context.thickness);
|
||||||
|
m_existingObjectIsChanged = true;
|
||||||
// TODO - save thickness update, but not immediately
|
|
||||||
m_undoStack.push(new ModificationCommand(this, m_captureToolObjects));
|
|
||||||
}
|
}
|
||||||
|
emit thicknessChanged(m_context.thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureWidget::resizeEvent(QResizeEvent* e)
|
void CaptureWidget::resizeEvent(QResizeEvent* e)
|
||||||
@@ -965,8 +1003,12 @@ void CaptureWidget::setState(CaptureToolButton* b)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_toolWidget && m_activeTool && m_activeTool->isValid()) {
|
if (m_toolWidget && m_activeTool) {
|
||||||
pushToolToStack();
|
if (m_activeTool->isValid()) {
|
||||||
|
pushToolToStack();
|
||||||
|
} else {
|
||||||
|
releaseActiveTool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_activeButton != b) {
|
if (m_activeButton != b) {
|
||||||
processTool(b->tool());
|
processTool(b->tool());
|
||||||
@@ -1072,16 +1114,6 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r)
|
|||||||
m_toolWidget->setFocus();
|
m_toolWidget->setFocus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CaptureTool::REQ_ADD_CHILD_WINDOW:
|
|
||||||
if (!m_activeTool) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
QWidget* w = m_activeTool->widget();
|
|
||||||
connect(
|
|
||||||
this, &CaptureWidget::destroyed, w, &QWidget::deleteLater);
|
|
||||||
w->show();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CaptureTool::REQ_ADD_EXTERNAL_WIDGETS:
|
case CaptureTool::REQ_ADD_EXTERNAL_WIDGETS:
|
||||||
if (!m_activeTool) {
|
if (!m_activeTool) {
|
||||||
break;
|
break;
|
||||||
@@ -1133,6 +1165,15 @@ void CaptureWidget::setDrawColor(const QColor& c)
|
|||||||
|
|
||||||
void CaptureWidget::updateActiveLayer(const int& layer)
|
void CaptureWidget::updateActiveLayer(const int& layer)
|
||||||
{
|
{
|
||||||
|
// TODO - refactor this part, make all objects to work with
|
||||||
|
// m_activeTool->isChanged() and remove m_existingObjectIsChanged
|
||||||
|
if (m_activeTool && m_activeTool->nameID() == ToolType::TEXT &&
|
||||||
|
m_activeTool->isChanged()) {
|
||||||
|
commitCurrentTool();
|
||||||
|
}
|
||||||
|
if (m_existingObjectIsChanged) {
|
||||||
|
pushObjectsStateToUndoStack();
|
||||||
|
}
|
||||||
drawToolsData(false, true);
|
drawToolsData(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1158,6 +1199,7 @@ void CaptureWidget::removeToolObject(int index)
|
|||||||
}
|
}
|
||||||
m_context.circleCount = circleCount;
|
m_context.circleCount = circleCount;
|
||||||
}
|
}
|
||||||
|
pushObjectsStateToUndoStack();
|
||||||
drawToolsData();
|
drawToolsData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1166,13 +1208,14 @@ void CaptureWidget::setDrawThickness(const int& t)
|
|||||||
{
|
{
|
||||||
m_context.thickness = qBound(1, t, 100);
|
m_context.thickness = qBound(1, t, 100);
|
||||||
ConfigHandler().setDrawThickness(m_context.thickness);
|
ConfigHandler().setDrawThickness(m_context.thickness);
|
||||||
emit thicknessChanged(m_context.thickness);
|
|
||||||
|
|
||||||
auto toolItem = activeToolObject();
|
auto toolItem = activeToolObject();
|
||||||
if (toolItem) {
|
if (toolItem) {
|
||||||
// Change thickness
|
// Change thickness
|
||||||
emit toolItem->thicknessChanged(t);
|
emit toolItem->thicknessChanged(t);
|
||||||
drawToolsData(false, true);
|
drawToolsData(false, true);
|
||||||
|
} else {
|
||||||
|
emit thicknessChanged(m_context.thickness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1375,12 +1418,12 @@ void CaptureWidget::updateCursor()
|
|||||||
|
|
||||||
void CaptureWidget::pushToolToStack()
|
void CaptureWidget::pushToolToStack()
|
||||||
{
|
{
|
||||||
// push zero state to be able to do a complete undo
|
|
||||||
if (m_undoStack.count() == 0) {
|
|
||||||
m_undoStack.push(new ModificationCommand(this, m_captureToolObjects));
|
|
||||||
}
|
|
||||||
|
|
||||||
// append current tool to the new state
|
// append current tool to the new state
|
||||||
|
bool isChanged = true;
|
||||||
|
if (m_activeTool && m_activeTool->editMode()) {
|
||||||
|
m_activeTool->setEditMode(false);
|
||||||
|
isChanged = m_activeTool->isChanged();
|
||||||
|
}
|
||||||
if (m_activeTool && m_activeButton) {
|
if (m_activeTool && m_activeButton) {
|
||||||
disconnect(this,
|
disconnect(this,
|
||||||
&CaptureWidget::colorChanged,
|
&CaptureWidget::colorChanged,
|
||||||
@@ -1394,13 +1437,13 @@ void CaptureWidget::pushToolToStack()
|
|||||||
disconnect(m_panel->toolWidget(), nullptr, m_activeTool, nullptr);
|
disconnect(m_panel->toolWidget(), nullptr, m_activeTool, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_activeTool->setEditMode(false);
|
|
||||||
m_captureToolObjects.append(m_activeTool);
|
m_captureToolObjects.append(m_activeTool);
|
||||||
releaseActiveTool();
|
releaseActiveTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
// push current state to the undo stack
|
if (isChanged) {
|
||||||
m_undoStack.push(new ModificationCommand(this, m_captureToolObjects));
|
pushObjectsStateToUndoStack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureWidget::drawToolsData(bool updateLayersPanel, bool drawSelection)
|
void CaptureWidget::drawToolsData(bool updateLayersPanel, bool drawSelection)
|
||||||
@@ -1530,6 +1573,11 @@ void CaptureWidget::undo()
|
|||||||
m_lastPressedUndo = true;
|
m_lastPressedUndo = true;
|
||||||
m_lastPressedRedo = false;
|
m_lastPressedRedo = false;
|
||||||
m_undoStack.undo();
|
m_undoStack.undo();
|
||||||
|
if (m_undoStack.index() == 0 && m_captureToolObjects.size() > 0) {
|
||||||
|
m_lastPressedUndo = false;
|
||||||
|
m_captureToolObjects.clear();
|
||||||
|
drawToolsData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureWidget::redo()
|
void CaptureWidget::redo()
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ protected:
|
|||||||
void moveEvent(QMoveEvent* moveEvent) override;
|
void moveEvent(QMoveEvent* moveEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void pushObjectsStateToUndoStack();
|
||||||
void releaseActiveTool();
|
void releaseActiveTool();
|
||||||
void uncheckActiveTool();
|
void uncheckActiveTool();
|
||||||
int selectToolItemAtPos(const QPoint& pos);
|
int selectToolItemAtPos(const QPoint& pos);
|
||||||
@@ -185,6 +186,12 @@ private:
|
|||||||
|
|
||||||
QUndoStack m_undoStack;
|
QUndoStack m_undoStack;
|
||||||
|
|
||||||
|
bool m_existingObjectIsChanged;
|
||||||
|
|
||||||
|
// For start moving after more than X offset
|
||||||
|
QPoint m_startMovePos;
|
||||||
|
bool m_startMove;
|
||||||
|
|
||||||
// TODO - should be remove after fixing undo()/redo() functions
|
// TODO - should be remove after fixing undo()/redo() functions
|
||||||
bool m_lastPressedUndo;
|
bool m_lastPressedUndo;
|
||||||
bool m_lastPressedRedo;
|
bool m_lastPressedRedo;
|
||||||
|
|||||||
@@ -55,8 +55,9 @@ void InfoWindow::initLabels()
|
|||||||
QLabel* versionTitleLabel = new QLabel(tr("<u><b>Version</b></u>"), this);
|
QLabel* versionTitleLabel = new QLabel(tr("<u><b>Version</b></u>"), this);
|
||||||
versionTitleLabel->setAlignment(Qt::AlignHCenter);
|
versionTitleLabel->setAlignment(Qt::AlignHCenter);
|
||||||
m_layout->addWidget(versionTitleLabel);
|
m_layout->addWidget(versionTitleLabel);
|
||||||
QString versionMsg = "Flameshot " + QStringLiteral(APP_VERSION) +
|
QString versionMsg = "Flameshot " + QStringLiteral(APP_VERSION) + " (" +
|
||||||
"\nCompiled with Qt " + QT_VERSION_STR;
|
QStringLiteral(FLAMESHOT_GIT_HASH) +
|
||||||
|
")\nCompiled with Qt " + QT_VERSION_STR;
|
||||||
QLabel* versionLabel = new QLabel(versionMsg, this);
|
QLabel* versionLabel = new QLabel(versionMsg, this);
|
||||||
versionLabel->setAlignment(Qt::AlignHCenter);
|
versionLabel->setAlignment(Qt::AlignHCenter);
|
||||||
m_layout->addWidget(versionLabel);
|
m_layout->addWidget(versionLabel);
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ SidePanelWidget::SidePanelWidget(QPixmap* p, QWidget* parent)
|
|||||||
|
|
||||||
QFormLayout* colorForm = new QFormLayout();
|
QFormLayout* colorForm = new QFormLayout();
|
||||||
m_thicknessSlider = new QSlider(Qt::Horizontal);
|
m_thicknessSlider = new QSlider(Qt::Horizontal);
|
||||||
|
m_thicknessSlider->setRange(1, 100);
|
||||||
m_thicknessSlider->setValue(m_thickness);
|
m_thicknessSlider->setValue(m_thickness);
|
||||||
m_colorLabel = new QLabel();
|
m_colorLabel = new QLabel();
|
||||||
m_colorLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
m_colorLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
|||||||
Reference in New Issue
Block a user