mirror of
https://github.com/fergalmoran/flameshot.git
synced 2025-12-22 09:51:06 +00:00
Changed clang format to new agreement
This commit is contained in:
committed by
borgmanJeremy
parent
2cbccc3d0a
commit
0d5386edd4
@@ -1,2 +1,6 @@
|
|||||||
Language: Cpp
|
Language: Cpp
|
||||||
BasedOnStyle: Mozilla
|
BasedOnStyle: Mozilla
|
||||||
|
IndentWidth: 4
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
|||||||
2
.github/workflows/clang-format.yml
vendored
2
.github/workflows/clang-format.yml
vendored
@@ -14,4 +14,4 @@ jobs:
|
|||||||
#exclude: './third_party ./external'
|
#exclude: './third_party ./external'
|
||||||
extensions: 'h,cpp'
|
extensions: 'h,cpp'
|
||||||
clangFormatVersion: 11
|
clangFormatVersion: 11
|
||||||
style: mozilla
|
style: file
|
||||||
|
|||||||
88
external/Qt-Color-Widgets/src/color_utils.cpp
vendored
88
external/Qt-Color-Widgets/src/color_utils.cpp
vendored
@@ -24,59 +24,57 @@
|
|||||||
namespace color_widgets {
|
namespace color_widgets {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
QColor
|
QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha)
|
||||||
color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha)
|
|
||||||
{
|
{
|
||||||
qreal h1 = hue * 6;
|
qreal h1 = hue * 6;
|
||||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||||
QColor col;
|
QColor col;
|
||||||
if (h1 >= 0 && h1 < 1)
|
if (h1 >= 0 && h1 < 1)
|
||||||
col = QColor::fromRgbF(chroma, x, 0);
|
col = QColor::fromRgbF(chroma, x, 0);
|
||||||
else if (h1 < 2)
|
else if (h1 < 2)
|
||||||
col = QColor::fromRgbF(x, chroma, 0);
|
col = QColor::fromRgbF(x, chroma, 0);
|
||||||
else if (h1 < 3)
|
else if (h1 < 3)
|
||||||
col = QColor::fromRgbF(0, chroma, x);
|
col = QColor::fromRgbF(0, chroma, x);
|
||||||
else if (h1 < 4)
|
else if (h1 < 4)
|
||||||
col = QColor::fromRgbF(0, x, chroma);
|
col = QColor::fromRgbF(0, x, chroma);
|
||||||
else if (h1 < 5)
|
else if (h1 < 5)
|
||||||
col = QColor::fromRgbF(x, 0, chroma);
|
col = QColor::fromRgbF(x, 0, chroma);
|
||||||
else if (h1 < 6)
|
else if (h1 < 6)
|
||||||
col = QColor::fromRgbF(chroma, 0, x);
|
col = QColor::fromRgbF(chroma, 0, x);
|
||||||
|
|
||||||
qreal m = luma - color_lumaF(col);
|
qreal m = luma - color_lumaF(col);
|
||||||
|
|
||||||
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
||||||
qBound(0.0, col.greenF() + m, 1.0),
|
qBound(0.0, col.greenF() + m, 1.0),
|
||||||
qBound(0.0, col.blueF() + m, 1.0),
|
qBound(0.0, col.blueF() + m, 1.0),
|
||||||
alpha);
|
alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor
|
QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha)
|
||||||
color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha)
|
|
||||||
{
|
{
|
||||||
qreal chroma = (1 - qAbs(2 * lig - 1)) * sat;
|
qreal chroma = (1 - qAbs(2 * lig - 1)) * sat;
|
||||||
qreal h1 = hue * 6;
|
qreal h1 = hue * 6;
|
||||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||||
QColor col;
|
QColor col;
|
||||||
if (h1 >= 0 && h1 < 1)
|
if (h1 >= 0 && h1 < 1)
|
||||||
col = QColor::fromRgbF(chroma, x, 0);
|
col = QColor::fromRgbF(chroma, x, 0);
|
||||||
else if (h1 < 2)
|
else if (h1 < 2)
|
||||||
col = QColor::fromRgbF(x, chroma, 0);
|
col = QColor::fromRgbF(x, chroma, 0);
|
||||||
else if (h1 < 3)
|
else if (h1 < 3)
|
||||||
col = QColor::fromRgbF(0, chroma, x);
|
col = QColor::fromRgbF(0, chroma, x);
|
||||||
else if (h1 < 4)
|
else if (h1 < 4)
|
||||||
col = QColor::fromRgbF(0, x, chroma);
|
col = QColor::fromRgbF(0, x, chroma);
|
||||||
else if (h1 < 5)
|
else if (h1 < 5)
|
||||||
col = QColor::fromRgbF(x, 0, chroma);
|
col = QColor::fromRgbF(x, 0, chroma);
|
||||||
else if (h1 < 6)
|
else if (h1 < 6)
|
||||||
col = QColor::fromRgbF(chroma, 0, x);
|
col = QColor::fromRgbF(chroma, 0, x);
|
||||||
|
|
||||||
qreal m = lig - chroma / 2;
|
qreal m = lig - chroma / 2;
|
||||||
|
|
||||||
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
||||||
qBound(0.0, col.greenF() + m, 1.0),
|
qBound(0.0, col.greenF() + m, 1.0),
|
||||||
qBound(0.0, col.blueF() + m, 1.0),
|
qBound(0.0, col.blueF() + m, 1.0),
|
||||||
alpha);
|
alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
866
external/Qt-Color-Widgets/src/color_wheel.cpp
vendored
866
external/Qt-Color-Widgets/src/color_wheel.cpp
vendored
@@ -34,9 +34,9 @@ namespace color_widgets {
|
|||||||
|
|
||||||
enum MouseStatus
|
enum MouseStatus
|
||||||
{
|
{
|
||||||
Nothing,
|
Nothing,
|
||||||
DragCircle,
|
DragCircle,
|
||||||
DragSquare
|
DragSquare
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ColorWheel::DisplayFlags hard_default_flags =
|
static const ColorWheel::DisplayFlags hard_default_flags =
|
||||||
@@ -48,517 +48,499 @@ static const double selector_radius = 6;
|
|||||||
class ColorWheel::Private
|
class ColorWheel::Private
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ColorWheel* const w;
|
ColorWheel* const w;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qreal hue, sat, val;
|
qreal hue, sat, val;
|
||||||
qreal bgBrightness;
|
qreal bgBrightness;
|
||||||
unsigned int wheel_width;
|
unsigned int wheel_width;
|
||||||
MouseStatus mouse_status;
|
MouseStatus mouse_status;
|
||||||
QPixmap hue_ring;
|
QPixmap hue_ring;
|
||||||
QImage inner_selector;
|
QImage inner_selector;
|
||||||
DisplayFlags display_flags;
|
DisplayFlags display_flags;
|
||||||
QColor (*color_from)(qreal, qreal, qreal, qreal);
|
QColor (*color_from)(qreal, qreal, qreal, qreal);
|
||||||
QColor (*rainbow_from_hue)(qreal);
|
QColor (*rainbow_from_hue)(qreal);
|
||||||
int max_size = 128;
|
int max_size = 128;
|
||||||
|
|
||||||
explicit Private(ColorWheel* widget)
|
explicit Private(ColorWheel* widget)
|
||||||
: w(widget)
|
: w(widget)
|
||||||
, hue(0)
|
, hue(0)
|
||||||
, sat(0)
|
, sat(0)
|
||||||
, val(0)
|
, val(0)
|
||||||
, wheel_width(20)
|
, wheel_width(20)
|
||||||
, mouse_status(Nothing)
|
, mouse_status(Nothing)
|
||||||
, display_flags(FLAGS_DEFAULT)
|
, display_flags(FLAGS_DEFAULT)
|
||||||
, color_from(&QColor::fromHsvF)
|
, color_from(&QColor::fromHsvF)
|
||||||
, rainbow_from_hue(&detail::rainbow_hsv)
|
, rainbow_from_hue(&detail::rainbow_hsv)
|
||||||
{
|
{
|
||||||
QColor bgColor = widget->palette().window().color();
|
QColor bgColor = widget->palette().window().color();
|
||||||
bgBrightness = color_widgets::detail::color_lumaF(bgColor);
|
bgBrightness = color_widgets::detail::color_lumaF(bgColor);
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate outer wheel radius from idget center
|
|
||||||
qreal outer_radius() const
|
|
||||||
{
|
|
||||||
return qMin(w->geometry().width(), w->geometry().height()) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate inner wheel radius from idget center
|
|
||||||
qreal inner_radius() const { return outer_radius() - wheel_width; }
|
|
||||||
|
|
||||||
/// Calculate the edge length of the inner square
|
|
||||||
qreal square_size() const { return inner_radius() * qSqrt(2); }
|
|
||||||
|
|
||||||
/// Calculate the height of the inner triangle
|
|
||||||
qreal triangle_height() const { return inner_radius() * 3 / 2; }
|
|
||||||
|
|
||||||
/// Calculate the side of the inner triangle
|
|
||||||
qreal triangle_side() const { return inner_radius() * qSqrt(3); }
|
|
||||||
|
|
||||||
/// return line from center to given point
|
|
||||||
QLineF line_to_point(const QPoint& p) const
|
|
||||||
{
|
|
||||||
return QLineF(
|
|
||||||
w->geometry().width() / 2, w->geometry().height() / 2, p.x(), p.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
void render_square()
|
|
||||||
{
|
|
||||||
int width = qMin<int>(square_size(), max_size);
|
|
||||||
QSize size(width, width);
|
|
||||||
inner_selector = QImage(size, QImage::Format_RGB32);
|
|
||||||
|
|
||||||
for (int y = 0; y < width; ++y) {
|
|
||||||
for (int x = 0; x < width; ++x) {
|
|
||||||
inner_selector.setPixel(
|
|
||||||
x, y, color_from(hue, double(x) / width, double(y) / width, 1).rgb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief renders the selector as a triangle
|
|
||||||
* \note It's the same as a square with the edge with value=0 collapsed to a
|
|
||||||
* single point
|
|
||||||
*/
|
|
||||||
void render_triangle()
|
|
||||||
{
|
|
||||||
QSizeF size = selector_size();
|
|
||||||
if (size.height() > max_size)
|
|
||||||
size *= max_size / size.height();
|
|
||||||
|
|
||||||
qreal ycenter = size.height() / 2;
|
|
||||||
inner_selector = QImage(size.toSize(), QImage::Format_RGB32);
|
|
||||||
|
|
||||||
for (int x = 0; x < inner_selector.width(); x++) {
|
|
||||||
qreal pval = x / size.height();
|
|
||||||
qreal slice_h = size.height() * pval;
|
|
||||||
for (int y = 0; y < inner_selector.height(); y++) {
|
|
||||||
qreal ymin = ycenter - slice_h / 2;
|
|
||||||
qreal psat = qBound(0.0, (y - ymin) / slice_h, 1.0);
|
|
||||||
|
|
||||||
inner_selector.setPixel(x, y, color_from(hue, psat, pval, 1).rgb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Updates the inner image that displays the saturation-value selector
|
|
||||||
void render_inner_selector()
|
|
||||||
{
|
|
||||||
if (display_flags & ColorWheel::SHAPE_TRIANGLE)
|
|
||||||
render_triangle();
|
|
||||||
else
|
|
||||||
render_square();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Offset of the selector image
|
|
||||||
QPointF selector_image_offset()
|
|
||||||
{
|
|
||||||
if (display_flags & SHAPE_TRIANGLE)
|
|
||||||
return QPointF(-inner_radius(), -triangle_side() / 2);
|
|
||||||
return QPointF(-square_size() / 2, -square_size() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Size of the selector when rendered to the screen
|
|
||||||
*/
|
|
||||||
QSizeF selector_size()
|
|
||||||
{
|
|
||||||
if (display_flags & SHAPE_TRIANGLE)
|
|
||||||
return QSizeF(triangle_height(), triangle_side());
|
|
||||||
return QSizeF(square_size(), square_size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rotation of the selector image
|
|
||||||
qreal selector_image_angle()
|
|
||||||
{
|
|
||||||
if (display_flags & SHAPE_TRIANGLE) {
|
|
||||||
if (display_flags & ANGLE_ROTATING)
|
|
||||||
return -hue * 360 - 60;
|
|
||||||
return -150;
|
|
||||||
} else {
|
|
||||||
if (display_flags & ANGLE_ROTATING)
|
|
||||||
return -hue * 360 - 45;
|
|
||||||
else
|
|
||||||
return 180;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Updates the outer ring that displays the hue selector
|
|
||||||
void render_ring()
|
|
||||||
{
|
|
||||||
hue_ring = QPixmap(outer_radius() * 2, outer_radius() * 2);
|
|
||||||
hue_ring.fill(Qt::transparent);
|
|
||||||
QPainter painter(&hue_ring);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
|
|
||||||
const int hue_stops = 24;
|
|
||||||
QConicalGradient gradient_hue(0, 0, 0);
|
|
||||||
if (gradient_hue.stops().size() < hue_stops) {
|
|
||||||
for (double a = 0; a < 1.0; a += 1.0 / (hue_stops - 1)) {
|
|
||||||
gradient_hue.setColorAt(a, rainbow_from_hue(a));
|
|
||||||
}
|
|
||||||
gradient_hue.setColorAt(1, rainbow_from_hue(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.translate(outer_radius(), outer_radius());
|
/// Calculate outer wheel radius from idget center
|
||||||
|
qreal outer_radius() const
|
||||||
painter.setPen(Qt::NoPen);
|
{
|
||||||
painter.setBrush(QBrush(gradient_hue));
|
return qMin(w->geometry().width(), w->geometry().height()) / 2;
|
||||||
painter.drawEllipse(QPointF(0, 0), outer_radius(), outer_radius());
|
}
|
||||||
|
|
||||||
painter.setBrush(Qt::transparent); // palette().background());
|
/// Calculate inner wheel radius from idget center
|
||||||
painter.drawEllipse(QPointF(0, 0), inner_radius(), inner_radius());
|
qreal inner_radius() const { return outer_radius() - wheel_width; }
|
||||||
}
|
|
||||||
|
/// Calculate the edge length of the inner square
|
||||||
void set_color(const QColor& c)
|
qreal square_size() const { return inner_radius() * qSqrt(2); }
|
||||||
{
|
|
||||||
if (display_flags & ColorWheel::COLOR_HSV) {
|
/// Calculate the height of the inner triangle
|
||||||
hue = qMax(0.0, c.hsvHueF());
|
qreal triangle_height() const { return inner_radius() * 3 / 2; }
|
||||||
sat = c.hsvSaturationF();
|
|
||||||
val = c.valueF();
|
/// Calculate the side of the inner triangle
|
||||||
} else if (display_flags & ColorWheel::COLOR_HSL) {
|
qreal triangle_side() const { return inner_radius() * qSqrt(3); }
|
||||||
hue = qMax(0.0, c.hueF());
|
|
||||||
sat = detail::color_HSL_saturationF(c);
|
/// return line from center to given point
|
||||||
val = detail::color_lightnessF(c);
|
QLineF line_to_point(const QPoint& p) const
|
||||||
} else if (display_flags & ColorWheel::COLOR_LCH) {
|
{
|
||||||
hue = qMax(0.0, c.hsvHueF());
|
return QLineF(
|
||||||
sat = detail::color_chromaF(c);
|
w->geometry().width() / 2, w->geometry().height() / 2, p.x(), p.y());
|
||||||
val = detail::color_lumaF(c);
|
}
|
||||||
|
|
||||||
|
void render_square()
|
||||||
|
{
|
||||||
|
int width = qMin<int>(square_size(), max_size);
|
||||||
|
QSize size(width, width);
|
||||||
|
inner_selector = QImage(size, QImage::Format_RGB32);
|
||||||
|
|
||||||
|
for (int y = 0; y < width; ++y) {
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
inner_selector.setPixel(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
color_from(hue, double(x) / width, double(y) / width, 1)
|
||||||
|
.rgb());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief renders the selector as a triangle
|
||||||
|
* \note It's the same as a square with the edge with value=0 collapsed to a
|
||||||
|
* single point
|
||||||
|
*/
|
||||||
|
void render_triangle()
|
||||||
|
{
|
||||||
|
QSizeF size = selector_size();
|
||||||
|
if (size.height() > max_size)
|
||||||
|
size *= max_size / size.height();
|
||||||
|
|
||||||
|
qreal ycenter = size.height() / 2;
|
||||||
|
inner_selector = QImage(size.toSize(), QImage::Format_RGB32);
|
||||||
|
|
||||||
|
for (int x = 0; x < inner_selector.width(); x++) {
|
||||||
|
qreal pval = x / size.height();
|
||||||
|
qreal slice_h = size.height() * pval;
|
||||||
|
for (int y = 0; y < inner_selector.height(); y++) {
|
||||||
|
qreal ymin = ycenter - slice_h / 2;
|
||||||
|
qreal psat = qBound(0.0, (y - ymin) / slice_h, 1.0);
|
||||||
|
|
||||||
|
inner_selector.setPixel(
|
||||||
|
x, y, color_from(hue, psat, pval, 1).rgb());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the inner image that displays the saturation-value selector
|
||||||
|
void render_inner_selector()
|
||||||
|
{
|
||||||
|
if (display_flags & ColorWheel::SHAPE_TRIANGLE)
|
||||||
|
render_triangle();
|
||||||
|
else
|
||||||
|
render_square();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Offset of the selector image
|
||||||
|
QPointF selector_image_offset()
|
||||||
|
{
|
||||||
|
if (display_flags & SHAPE_TRIANGLE)
|
||||||
|
return QPointF(-inner_radius(), -triangle_side() / 2);
|
||||||
|
return QPointF(-square_size() / 2, -square_size() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Size of the selector when rendered to the screen
|
||||||
|
*/
|
||||||
|
QSizeF selector_size()
|
||||||
|
{
|
||||||
|
if (display_flags & SHAPE_TRIANGLE)
|
||||||
|
return QSizeF(triangle_height(), triangle_side());
|
||||||
|
return QSizeF(square_size(), square_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rotation of the selector image
|
||||||
|
qreal selector_image_angle()
|
||||||
|
{
|
||||||
|
if (display_flags & SHAPE_TRIANGLE) {
|
||||||
|
if (display_flags & ANGLE_ROTATING)
|
||||||
|
return -hue * 360 - 60;
|
||||||
|
return -150;
|
||||||
|
} else {
|
||||||
|
if (display_flags & ANGLE_ROTATING)
|
||||||
|
return -hue * 360 - 45;
|
||||||
|
else
|
||||||
|
return 180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the outer ring that displays the hue selector
|
||||||
|
void render_ring()
|
||||||
|
{
|
||||||
|
hue_ring = QPixmap(outer_radius() * 2, outer_radius() * 2);
|
||||||
|
hue_ring.fill(Qt::transparent);
|
||||||
|
QPainter painter(&hue_ring);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
|
const int hue_stops = 24;
|
||||||
|
QConicalGradient gradient_hue(0, 0, 0);
|
||||||
|
if (gradient_hue.stops().size() < hue_stops) {
|
||||||
|
for (double a = 0; a < 1.0; a += 1.0 / (hue_stops - 1)) {
|
||||||
|
gradient_hue.setColorAt(a, rainbow_from_hue(a));
|
||||||
|
}
|
||||||
|
gradient_hue.setColorAt(1, rainbow_from_hue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.translate(outer_radius(), outer_radius());
|
||||||
|
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.setBrush(QBrush(gradient_hue));
|
||||||
|
painter.drawEllipse(QPointF(0, 0), outer_radius(), outer_radius());
|
||||||
|
|
||||||
|
painter.setBrush(Qt::transparent); // palette().background());
|
||||||
|
painter.drawEllipse(QPointF(0, 0), inner_radius(), inner_radius());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_color(const QColor& c)
|
||||||
|
{
|
||||||
|
if (display_flags & ColorWheel::COLOR_HSV) {
|
||||||
|
hue = qMax(0.0, c.hsvHueF());
|
||||||
|
sat = c.hsvSaturationF();
|
||||||
|
val = c.valueF();
|
||||||
|
} else if (display_flags & ColorWheel::COLOR_HSL) {
|
||||||
|
hue = qMax(0.0, c.hueF());
|
||||||
|
sat = detail::color_HSL_saturationF(c);
|
||||||
|
val = detail::color_lightnessF(c);
|
||||||
|
} else if (display_flags & ColorWheel::COLOR_LCH) {
|
||||||
|
hue = qMax(0.0, c.hsvHueF());
|
||||||
|
sat = detail::color_chromaF(c);
|
||||||
|
val = detail::color_lumaF(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ColorWheel::ColorWheel(QWidget* parent)
|
ColorWheel::ColorWheel(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, p(new Private(this))
|
, p(new Private(this))
|
||||||
{
|
{
|
||||||
setDisplayFlags(FLAGS_DEFAULT);
|
setDisplayFlags(FLAGS_DEFAULT);
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorWheel::~ColorWheel()
|
ColorWheel::~ColorWheel()
|
||||||
{
|
{
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor
|
QColor ColorWheel::color() const
|
||||||
ColorWheel::color() const
|
|
||||||
{
|
{
|
||||||
return p->color_from(p->hue, p->sat, p->val, 1);
|
return p->color_from(p->hue, p->sat, p->val, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize
|
QSize ColorWheel::sizeHint() const
|
||||||
ColorWheel::sizeHint() const
|
|
||||||
{
|
{
|
||||||
return QSize(p->wheel_width * 5, p->wheel_width * 5);
|
return QSize(p->wheel_width * 5, p->wheel_width * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal
|
qreal ColorWheel::hue() const
|
||||||
ColorWheel::hue() const
|
|
||||||
{
|
{
|
||||||
if ((p->display_flags & COLOR_LCH) && p->sat > 0.01)
|
if ((p->display_flags & COLOR_LCH) && p->sat > 0.01)
|
||||||
return color().hueF();
|
return color().hueF();
|
||||||
return p->hue;
|
return p->hue;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal
|
qreal ColorWheel::saturation() const
|
||||||
ColorWheel::saturation() const
|
|
||||||
{
|
{
|
||||||
return color().hsvSaturationF();
|
return color().hsvSaturationF();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal
|
qreal ColorWheel::value() const
|
||||||
ColorWheel::value() const
|
|
||||||
{
|
{
|
||||||
return color().valueF();
|
return color().valueF();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int ColorWheel::wheelWidth() const
|
||||||
ColorWheel::wheelWidth() const
|
|
||||||
{
|
{
|
||||||
return p->wheel_width;
|
return p->wheel_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::setWheelWidth(unsigned int w)
|
||||||
ColorWheel::setWheelWidth(unsigned int w)
|
|
||||||
{
|
{
|
||||||
p->wheel_width = w;
|
p->wheel_width = w;
|
||||||
p->render_inner_selector();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::paintEvent(QPaintEvent*)
|
|
||||||
{
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter.translate(geometry().width() / 2, geometry().height() / 2);
|
|
||||||
|
|
||||||
// hue wheel
|
|
||||||
if (p->hue_ring.isNull())
|
|
||||||
p->render_ring();
|
|
||||||
|
|
||||||
painter.drawPixmap(-p->outer_radius(), -p->outer_radius(), p->hue_ring);
|
|
||||||
|
|
||||||
// hue selector
|
|
||||||
QColor penColor = p->bgBrightness < 0.6 ? Qt::white : Qt::black;
|
|
||||||
painter.setPen(QPen(penColor, 3));
|
|
||||||
painter.setBrush(Qt::NoBrush);
|
|
||||||
QLineF ray(0, 0, p->outer_radius(), 0);
|
|
||||||
ray.setAngle(p->hue * 360);
|
|
||||||
QPointF h1 = ray.p2();
|
|
||||||
ray.setLength(p->inner_radius());
|
|
||||||
QPointF h2 = ray.p2();
|
|
||||||
painter.drawLine(h1, h2);
|
|
||||||
|
|
||||||
// lum-sat square
|
|
||||||
if (p->inner_selector.isNull())
|
|
||||||
p->render_inner_selector();
|
p->render_inner_selector();
|
||||||
|
|
||||||
painter.rotate(p->selector_image_angle());
|
|
||||||
painter.translate(p->selector_image_offset());
|
|
||||||
|
|
||||||
QPointF selector_position;
|
|
||||||
if (p->display_flags & SHAPE_SQUARE) {
|
|
||||||
qreal side = p->square_size();
|
|
||||||
selector_position = QPointF(p->sat * side, p->val * side);
|
|
||||||
} else if (p->display_flags & SHAPE_TRIANGLE) {
|
|
||||||
qreal side = p->triangle_side();
|
|
||||||
qreal height = p->triangle_height();
|
|
||||||
qreal slice_h = side * p->val;
|
|
||||||
qreal ymin = side / 2 - slice_h / 2;
|
|
||||||
|
|
||||||
selector_position = QPointF(p->val * height, ymin + p->sat * slice_h);
|
|
||||||
QPolygonF triangle;
|
|
||||||
triangle.append(QPointF(0, side / 2));
|
|
||||||
triangle.append(QPointF(height, 0));
|
|
||||||
triangle.append(QPointF(height, side));
|
|
||||||
QPainterPath clip;
|
|
||||||
clip.addPolygon(triangle);
|
|
||||||
painter.setClipPath(clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.drawImage(QRectF(QPointF(0, 0), p->selector_size()),
|
|
||||||
p->inner_selector);
|
|
||||||
painter.setClipping(false);
|
|
||||||
|
|
||||||
// lum-sat selector
|
|
||||||
// we define the color of the selecto based on the background color of the
|
|
||||||
// widget in order to improve the contrast
|
|
||||||
qreal colorBrightness = color_widgets::detail::color_lumaF(color());
|
|
||||||
if (p->bgBrightness < 0.6) // dark theme
|
|
||||||
{
|
|
||||||
bool isWhite = (colorBrightness < 0.7);
|
|
||||||
painter.setPen(QPen(isWhite ? Qt::white : Qt::black, 3));
|
|
||||||
} else // light theme
|
|
||||||
{
|
|
||||||
bool isWhite = (colorBrightness < 0.4 && p->val < 0.3);
|
|
||||||
painter.setPen(QPen(isWhite ? Qt::white : Qt::black, 3));
|
|
||||||
}
|
|
||||||
painter.setBrush(Qt::NoBrush);
|
|
||||||
painter.drawEllipse(selector_position, selector_radius, selector_radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::mouseMoveEvent(QMouseEvent* ev)
|
|
||||||
{
|
|
||||||
if (p->mouse_status == DragCircle) {
|
|
||||||
p->hue = p->line_to_point(ev->pos()).angle() / 360.0;
|
|
||||||
p->render_inner_selector();
|
|
||||||
|
|
||||||
emit colorSelected(color());
|
|
||||||
emit colorChanged(color());
|
|
||||||
update();
|
update();
|
||||||
} else if (p->mouse_status == DragSquare) {
|
}
|
||||||
QLineF glob_mouse_ln = p->line_to_point(ev->pos());
|
|
||||||
QLineF center_mouse_ln(QPointF(0, 0),
|
|
||||||
glob_mouse_ln.p2() - glob_mouse_ln.p1());
|
|
||||||
|
|
||||||
center_mouse_ln.setAngle(center_mouse_ln.angle() +
|
void ColorWheel::paintEvent(QPaintEvent*)
|
||||||
p->selector_image_angle());
|
{
|
||||||
center_mouse_ln.setP2(center_mouse_ln.p2() - p->selector_image_offset());
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.translate(geometry().width() / 2, geometry().height() / 2);
|
||||||
|
|
||||||
|
// hue wheel
|
||||||
|
if (p->hue_ring.isNull())
|
||||||
|
p->render_ring();
|
||||||
|
|
||||||
|
painter.drawPixmap(-p->outer_radius(), -p->outer_radius(), p->hue_ring);
|
||||||
|
|
||||||
|
// hue selector
|
||||||
|
QColor penColor = p->bgBrightness < 0.6 ? Qt::white : Qt::black;
|
||||||
|
painter.setPen(QPen(penColor, 3));
|
||||||
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
QLineF ray(0, 0, p->outer_radius(), 0);
|
||||||
|
ray.setAngle(p->hue * 360);
|
||||||
|
QPointF h1 = ray.p2();
|
||||||
|
ray.setLength(p->inner_radius());
|
||||||
|
QPointF h2 = ray.p2();
|
||||||
|
painter.drawLine(h1, h2);
|
||||||
|
|
||||||
|
// lum-sat square
|
||||||
|
if (p->inner_selector.isNull())
|
||||||
|
p->render_inner_selector();
|
||||||
|
|
||||||
|
painter.rotate(p->selector_image_angle());
|
||||||
|
painter.translate(p->selector_image_offset());
|
||||||
|
|
||||||
|
QPointF selector_position;
|
||||||
if (p->display_flags & SHAPE_SQUARE) {
|
if (p->display_flags & SHAPE_SQUARE) {
|
||||||
p->sat = qBound(0.0, center_mouse_ln.x2() / p->square_size(), 1.0);
|
qreal side = p->square_size();
|
||||||
p->val = qBound(0.0, center_mouse_ln.y2() / p->square_size(), 1.0);
|
selector_position = QPointF(p->sat * side, p->val * side);
|
||||||
} else if (p->display_flags & SHAPE_TRIANGLE) {
|
} else if (p->display_flags & SHAPE_TRIANGLE) {
|
||||||
QPointF pt = center_mouse_ln.p2();
|
qreal side = p->triangle_side();
|
||||||
|
qreal height = p->triangle_height();
|
||||||
|
qreal slice_h = side * p->val;
|
||||||
|
qreal ymin = side / 2 - slice_h / 2;
|
||||||
|
|
||||||
qreal side = p->triangle_side();
|
selector_position = QPointF(p->val * height, ymin + p->sat * slice_h);
|
||||||
p->val = qBound(0.0, pt.x() / p->triangle_height(), 1.0);
|
QPolygonF triangle;
|
||||||
qreal slice_h = side * p->val;
|
triangle.append(QPointF(0, side / 2));
|
||||||
|
triangle.append(QPointF(height, 0));
|
||||||
qreal ycenter = side / 2;
|
triangle.append(QPointF(height, side));
|
||||||
qreal ymin = ycenter - slice_h / 2;
|
QPainterPath clip;
|
||||||
|
clip.addPolygon(triangle);
|
||||||
if (slice_h > 0)
|
painter.setClipPath(clip);
|
||||||
p->sat = qBound(0.0, (pt.y() - ymin) / slice_h, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit colorSelected(color());
|
painter.drawImage(QRectF(QPointF(0, 0), p->selector_size()),
|
||||||
emit colorChanged(color());
|
p->inner_selector);
|
||||||
update();
|
painter.setClipping(false);
|
||||||
}
|
|
||||||
|
// lum-sat selector
|
||||||
|
// we define the color of the selecto based on the background color of the
|
||||||
|
// widget in order to improve the contrast
|
||||||
|
qreal colorBrightness = color_widgets::detail::color_lumaF(color());
|
||||||
|
if (p->bgBrightness < 0.6) // dark theme
|
||||||
|
{
|
||||||
|
bool isWhite = (colorBrightness < 0.7);
|
||||||
|
painter.setPen(QPen(isWhite ? Qt::white : Qt::black, 3));
|
||||||
|
} else // light theme
|
||||||
|
{
|
||||||
|
bool isWhite = (colorBrightness < 0.4 && p->val < 0.3);
|
||||||
|
painter.setPen(QPen(isWhite ? Qt::white : Qt::black, 3));
|
||||||
|
}
|
||||||
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
painter.drawEllipse(selector_position, selector_radius, selector_radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::mouseMoveEvent(QMouseEvent* ev)
|
||||||
ColorWheel::mousePressEvent(QMouseEvent* ev)
|
|
||||||
{
|
{
|
||||||
if (ev->buttons() & Qt::LeftButton) {
|
if (p->mouse_status == DragCircle) {
|
||||||
setFocus();
|
p->hue = p->line_to_point(ev->pos()).angle() / 360.0;
|
||||||
QLineF ray = p->line_to_point(ev->pos());
|
p->render_inner_selector();
|
||||||
if (ray.length() <= p->inner_radius())
|
|
||||||
p->mouse_status = DragSquare;
|
|
||||||
else if (ray.length() <= p->outer_radius())
|
|
||||||
p->mouse_status = DragCircle;
|
|
||||||
|
|
||||||
// Update the color
|
emit colorSelected(color());
|
||||||
|
emit colorChanged(color());
|
||||||
|
update();
|
||||||
|
} else if (p->mouse_status == DragSquare) {
|
||||||
|
QLineF glob_mouse_ln = p->line_to_point(ev->pos());
|
||||||
|
QLineF center_mouse_ln(QPointF(0, 0),
|
||||||
|
glob_mouse_ln.p2() - glob_mouse_ln.p1());
|
||||||
|
|
||||||
|
center_mouse_ln.setAngle(center_mouse_ln.angle() +
|
||||||
|
p->selector_image_angle());
|
||||||
|
center_mouse_ln.setP2(center_mouse_ln.p2() -
|
||||||
|
p->selector_image_offset());
|
||||||
|
|
||||||
|
if (p->display_flags & SHAPE_SQUARE) {
|
||||||
|
p->sat = qBound(0.0, center_mouse_ln.x2() / p->square_size(), 1.0);
|
||||||
|
p->val = qBound(0.0, center_mouse_ln.y2() / p->square_size(), 1.0);
|
||||||
|
} else if (p->display_flags & SHAPE_TRIANGLE) {
|
||||||
|
QPointF pt = center_mouse_ln.p2();
|
||||||
|
|
||||||
|
qreal side = p->triangle_side();
|
||||||
|
p->val = qBound(0.0, pt.x() / p->triangle_height(), 1.0);
|
||||||
|
qreal slice_h = side * p->val;
|
||||||
|
|
||||||
|
qreal ycenter = side / 2;
|
||||||
|
qreal ymin = ycenter - slice_h / 2;
|
||||||
|
|
||||||
|
if (slice_h > 0)
|
||||||
|
p->sat = qBound(0.0, (pt.y() - ymin) / slice_h, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit colorSelected(color());
|
||||||
|
emit colorChanged(color());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::mousePressEvent(QMouseEvent* ev)
|
||||||
|
{
|
||||||
|
if (ev->buttons() & Qt::LeftButton) {
|
||||||
|
setFocus();
|
||||||
|
QLineF ray = p->line_to_point(ev->pos());
|
||||||
|
if (ray.length() <= p->inner_radius())
|
||||||
|
p->mouse_status = DragSquare;
|
||||||
|
else if (ray.length() <= p->outer_radius())
|
||||||
|
p->mouse_status = DragCircle;
|
||||||
|
|
||||||
|
// Update the color
|
||||||
|
mouseMoveEvent(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::mouseReleaseEvent(QMouseEvent* ev)
|
||||||
|
{
|
||||||
mouseMoveEvent(ev);
|
mouseMoveEvent(ev);
|
||||||
}
|
p->mouse_status = Nothing;
|
||||||
|
emit mouseReleaseOnColor(color());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::resizeEvent(QResizeEvent*)
|
||||||
ColorWheel::mouseReleaseEvent(QMouseEvent* ev)
|
|
||||||
{
|
{
|
||||||
mouseMoveEvent(ev);
|
|
||||||
p->mouse_status = Nothing;
|
|
||||||
emit mouseReleaseOnColor(color());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::resizeEvent(QResizeEvent*)
|
|
||||||
{
|
|
||||||
p->render_ring();
|
|
||||||
p->render_inner_selector();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::setColor(QColor c)
|
|
||||||
{
|
|
||||||
qreal oldh = p->hue;
|
|
||||||
p->set_color(c);
|
|
||||||
if (!qFuzzyCompare(oldh + 1, p->hue + 1))
|
|
||||||
p->render_inner_selector();
|
|
||||||
update();
|
|
||||||
emit colorChanged(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::setHue(qreal h)
|
|
||||||
{
|
|
||||||
p->hue = qBound(0.0, h, 1.0);
|
|
||||||
p->render_inner_selector();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::setSaturation(qreal s)
|
|
||||||
{
|
|
||||||
p->sat = qBound(0.0, s, 1.0);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::setValue(qreal v)
|
|
||||||
{
|
|
||||||
p->val = qBound(0.0, v, 1.0);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorWheel::setDisplayFlags(DisplayFlags flags)
|
|
||||||
{
|
|
||||||
if (!(flags & COLOR_FLAGS))
|
|
||||||
flags |= default_flags & COLOR_FLAGS;
|
|
||||||
if (!(flags & ANGLE_FLAGS))
|
|
||||||
flags |= default_flags & ANGLE_FLAGS;
|
|
||||||
if (!(flags & SHAPE_FLAGS))
|
|
||||||
flags |= default_flags & SHAPE_FLAGS;
|
|
||||||
|
|
||||||
if ((flags & COLOR_FLAGS) != (p->display_flags & COLOR_FLAGS)) {
|
|
||||||
QColor old_col = color();
|
|
||||||
if (flags & ColorWheel::COLOR_HSL) {
|
|
||||||
p->hue = old_col.hueF();
|
|
||||||
p->sat = detail::color_HSL_saturationF(old_col);
|
|
||||||
p->val = detail::color_lightnessF(old_col);
|
|
||||||
p->color_from = &detail::color_from_hsl;
|
|
||||||
p->rainbow_from_hue = &detail::rainbow_hsv;
|
|
||||||
} else if (flags & ColorWheel::COLOR_LCH) {
|
|
||||||
p->hue = old_col.hueF();
|
|
||||||
p->sat = detail::color_chromaF(old_col);
|
|
||||||
p->val = detail::color_lumaF(old_col);
|
|
||||||
p->color_from = &detail::color_from_lch;
|
|
||||||
p->rainbow_from_hue = &detail::rainbow_lch;
|
|
||||||
} else {
|
|
||||||
p->hue = old_col.hsvHueF();
|
|
||||||
p->sat = old_col.hsvSaturationF();
|
|
||||||
p->val = old_col.valueF();
|
|
||||||
p->color_from = &QColor::fromHsvF;
|
|
||||||
p->rainbow_from_hue = &detail::rainbow_hsv;
|
|
||||||
}
|
|
||||||
p->render_ring();
|
p->render_ring();
|
||||||
}
|
p->render_inner_selector();
|
||||||
|
|
||||||
p->display_flags = flags;
|
|
||||||
p->render_inner_selector();
|
|
||||||
update();
|
|
||||||
emit displayFlagsChanged(flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorWheel::DisplayFlags
|
void ColorWheel::setColor(QColor c)
|
||||||
ColorWheel::displayFlags(DisplayFlags mask) const
|
|
||||||
{
|
{
|
||||||
return p->display_flags & mask;
|
qreal oldh = p->hue;
|
||||||
|
p->set_color(c);
|
||||||
|
if (!qFuzzyCompare(oldh + 1, p->hue + 1))
|
||||||
|
p->render_inner_selector();
|
||||||
|
update();
|
||||||
|
emit colorChanged(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::setHue(qreal h)
|
||||||
ColorWheel::setDefaultDisplayFlags(DisplayFlags flags)
|
|
||||||
{
|
{
|
||||||
if (!(flags & COLOR_FLAGS))
|
p->hue = qBound(0.0, h, 1.0);
|
||||||
flags |= hard_default_flags & COLOR_FLAGS;
|
p->render_inner_selector();
|
||||||
if (!(flags & ANGLE_FLAGS))
|
update();
|
||||||
flags |= hard_default_flags & ANGLE_FLAGS;
|
|
||||||
if (!(flags & SHAPE_FLAGS))
|
|
||||||
flags |= hard_default_flags & SHAPE_FLAGS;
|
|
||||||
default_flags = flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorWheel::DisplayFlags
|
void ColorWheel::setSaturation(qreal s)
|
||||||
ColorWheel::defaultDisplayFlags(DisplayFlags mask)
|
|
||||||
{
|
{
|
||||||
return default_flags & mask;
|
p->sat = qBound(0.0, s, 1.0);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::setValue(qreal v)
|
||||||
ColorWheel::setDisplayFlag(DisplayFlags flag, DisplayFlags mask)
|
|
||||||
{
|
{
|
||||||
setDisplayFlags((p->display_flags & ~mask) | flag);
|
p->val = qBound(0.0, v, 1.0);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ColorWheel::setDisplayFlags(DisplayFlags flags)
|
||||||
ColorWheel::dragEnterEvent(QDragEnterEvent* event)
|
|
||||||
{
|
{
|
||||||
if (event->mimeData()->hasColor() ||
|
if (!(flags & COLOR_FLAGS))
|
||||||
(event->mimeData()->hasText() &&
|
flags |= default_flags & COLOR_FLAGS;
|
||||||
QColor(event->mimeData()->text()).isValid()))
|
if (!(flags & ANGLE_FLAGS))
|
||||||
event->acceptProposedAction();
|
flags |= default_flags & ANGLE_FLAGS;
|
||||||
}
|
if (!(flags & SHAPE_FLAGS))
|
||||||
|
flags |= default_flags & SHAPE_FLAGS;
|
||||||
|
|
||||||
void
|
if ((flags & COLOR_FLAGS) != (p->display_flags & COLOR_FLAGS)) {
|
||||||
ColorWheel::dropEvent(QDropEvent* event)
|
QColor old_col = color();
|
||||||
{
|
if (flags & ColorWheel::COLOR_HSL) {
|
||||||
if (event->mimeData()->hasColor()) {
|
p->hue = old_col.hueF();
|
||||||
setColor(event->mimeData()->colorData().value<QColor>());
|
p->sat = detail::color_HSL_saturationF(old_col);
|
||||||
event->accept();
|
p->val = detail::color_lightnessF(old_col);
|
||||||
} else if (event->mimeData()->hasText()) {
|
p->color_from = &detail::color_from_hsl;
|
||||||
QColor col(event->mimeData()->text());
|
p->rainbow_from_hue = &detail::rainbow_hsv;
|
||||||
if (col.isValid()) {
|
} else if (flags & ColorWheel::COLOR_LCH) {
|
||||||
setColor(col);
|
p->hue = old_col.hueF();
|
||||||
event->accept();
|
p->sat = detail::color_chromaF(old_col);
|
||||||
|
p->val = detail::color_lumaF(old_col);
|
||||||
|
p->color_from = &detail::color_from_lch;
|
||||||
|
p->rainbow_from_hue = &detail::rainbow_lch;
|
||||||
|
} else {
|
||||||
|
p->hue = old_col.hsvHueF();
|
||||||
|
p->sat = old_col.hsvSaturationF();
|
||||||
|
p->val = old_col.valueF();
|
||||||
|
p->color_from = &QColor::fromHsvF;
|
||||||
|
p->rainbow_from_hue = &detail::rainbow_hsv;
|
||||||
|
}
|
||||||
|
p->render_ring();
|
||||||
|
}
|
||||||
|
|
||||||
|
p->display_flags = flags;
|
||||||
|
p->render_inner_selector();
|
||||||
|
update();
|
||||||
|
emit displayFlagsChanged(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorWheel::DisplayFlags ColorWheel::displayFlags(DisplayFlags mask) const
|
||||||
|
{
|
||||||
|
return p->display_flags & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::setDefaultDisplayFlags(DisplayFlags flags)
|
||||||
|
{
|
||||||
|
if (!(flags & COLOR_FLAGS))
|
||||||
|
flags |= hard_default_flags & COLOR_FLAGS;
|
||||||
|
if (!(flags & ANGLE_FLAGS))
|
||||||
|
flags |= hard_default_flags & ANGLE_FLAGS;
|
||||||
|
if (!(flags & SHAPE_FLAGS))
|
||||||
|
flags |= hard_default_flags & SHAPE_FLAGS;
|
||||||
|
default_flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorWheel::DisplayFlags ColorWheel::defaultDisplayFlags(DisplayFlags mask)
|
||||||
|
{
|
||||||
|
return default_flags & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::setDisplayFlag(DisplayFlags flag, DisplayFlags mask)
|
||||||
|
{
|
||||||
|
setDisplayFlags((p->display_flags & ~mask) | flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::dragEnterEvent(QDragEnterEvent* event)
|
||||||
|
{
|
||||||
|
if (event->mimeData()->hasColor() ||
|
||||||
|
(event->mimeData()->hasText() &&
|
||||||
|
QColor(event->mimeData()->text()).isValid()))
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorWheel::dropEvent(QDropEvent* event)
|
||||||
|
{
|
||||||
|
if (event->mimeData()->hasColor()) {
|
||||||
|
setColor(event->mimeData()->colorData().value<QColor>());
|
||||||
|
event->accept();
|
||||||
|
} else if (event->mimeData()->hasText()) {
|
||||||
|
QColor col(event->mimeData()->text());
|
||||||
|
if (col.isValid()) {
|
||||||
|
setColor(col);
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace color_widgets
|
} // namespace color_widgets
|
||||||
|
|||||||
635
external/singleapplication/singleapplication.cpp
vendored
635
external/singleapplication/singleapplication.cpp
vendored
@@ -49,324 +49,319 @@
|
|||||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication* q_ptr)
|
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication* q_ptr)
|
||||||
: q_ptr(q_ptr)
|
: q_ptr(q_ptr)
|
||||||
{
|
{
|
||||||
server = nullptr;
|
server = nullptr;
|
||||||
socket = nullptr;
|
socket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleApplicationPrivate::~SingleApplicationPrivate()
|
SingleApplicationPrivate::~SingleApplicationPrivate()
|
||||||
{
|
{
|
||||||
if (socket != nullptr) {
|
if (socket != nullptr) {
|
||||||
socket->close();
|
socket->close();
|
||||||
delete socket;
|
delete socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory->lock();
|
memory->lock();
|
||||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||||
if (server != nullptr) {
|
if (server != nullptr) {
|
||||||
server->close();
|
server->close();
|
||||||
delete server;
|
delete server;
|
||||||
inst->primary = false;
|
inst->primary = false;
|
||||||
inst->primaryPid = -1;
|
inst->primaryPid = -1;
|
||||||
}
|
}
|
||||||
memory->unlock();
|
memory->unlock();
|
||||||
|
|
||||||
delete memory;
|
delete memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::genBlockServerName(int timeout)
|
||||||
SingleApplicationPrivate::genBlockServerName(int timeout)
|
|
||||||
{
|
{
|
||||||
QCryptographicHash appData(QCryptographicHash::Sha256);
|
QCryptographicHash appData(QCryptographicHash::Sha256);
|
||||||
appData.addData("SingleApplication", 17);
|
appData.addData("SingleApplication", 17);
|
||||||
appData.addData(SingleApplication::app_t::applicationName().toUtf8());
|
appData.addData(SingleApplication::app_t::applicationName().toUtf8());
|
||||||
appData.addData(SingleApplication::app_t::organizationName().toUtf8());
|
appData.addData(SingleApplication::app_t::organizationName().toUtf8());
|
||||||
appData.addData(SingleApplication::app_t::organizationDomain().toUtf8());
|
appData.addData(SingleApplication::app_t::organizationDomain().toUtf8());
|
||||||
|
|
||||||
if (!(options & SingleApplication::Mode::ExcludeAppVersion)) {
|
if (!(options & SingleApplication::Mode::ExcludeAppVersion)) {
|
||||||
appData.addData(SingleApplication::app_t::applicationVersion().toUtf8());
|
appData.addData(
|
||||||
}
|
SingleApplication::app_t::applicationVersion().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
if (!(options & SingleApplication::Mode::ExcludeAppPath)) {
|
if (!(options & SingleApplication::Mode::ExcludeAppPath)) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
appData.addData(
|
appData.addData(
|
||||||
SingleApplication::app_t::applicationFilePath().toLower().toUtf8());
|
SingleApplication::app_t::applicationFilePath().toLower().toUtf8());
|
||||||
#else
|
#else
|
||||||
appData.addData(SingleApplication::app_t::applicationFilePath().toUtf8());
|
appData.addData(
|
||||||
|
SingleApplication::app_t::applicationFilePath().toUtf8());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// User level block requires a user specific data in the hash
|
// User level block requires a user specific data in the hash
|
||||||
if (options & SingleApplication::Mode::User) {
|
if (options & SingleApplication::Mode::User) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
Q_UNUSED(timeout);
|
Q_UNUSED(timeout);
|
||||||
wchar_t username[UNLEN + 1];
|
wchar_t username[UNLEN + 1];
|
||||||
// Specifies size of the buffer on input
|
// Specifies size of the buffer on input
|
||||||
DWORD usernameLength = UNLEN + 1;
|
DWORD usernameLength = UNLEN + 1;
|
||||||
if (GetUserNameW(username, &usernameLength)) {
|
if (GetUserNameW(username, &usernameLength)) {
|
||||||
appData.addData(QString::fromWCharArray(username).toUtf8());
|
appData.addData(QString::fromWCharArray(username).toUtf8());
|
||||||
} else {
|
} else {
|
||||||
appData.addData(
|
appData.addData(
|
||||||
QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||||
.join("")
|
.join("")
|
||||||
.toUtf8());
|
.toUtf8());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
QProcess process;
|
||||||
|
process.start(QStringLiteral("whoami"), QStringList{});
|
||||||
|
|
||||||
|
if (process.waitForFinished(timeout) &&
|
||||||
|
process.exitCode() == QProcess::NormalExit) {
|
||||||
|
appData.addData(process.readLine());
|
||||||
|
} else {
|
||||||
|
appData.addData(QDir(QStandardPaths::standardLocations(
|
||||||
|
QStandardPaths::HomeLocation)
|
||||||
|
.first())
|
||||||
|
.absolutePath()
|
||||||
|
.toUtf8());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
QProcess process;
|
|
||||||
process.start(QStringLiteral("whoami"), QStringList{});
|
|
||||||
|
|
||||||
if (process.waitForFinished(timeout) &&
|
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||||
process.exitCode() == QProcess::NormalExit) {
|
// server naming requirements.
|
||||||
appData.addData(process.readLine());
|
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleApplicationPrivate::startPrimary(bool resetMemory)
|
||||||
|
{
|
||||||
|
Q_Q(SingleApplication);
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
// Handle any further termination signals to ensure the
|
||||||
|
// QSharedMemory block is deleted even if the process crashes
|
||||||
|
crashHandler();
|
||||||
|
#endif
|
||||||
|
// Successful creation means that no main process exists
|
||||||
|
// So we start a QLocalServer to listen for connections
|
||||||
|
QLocalServer::removeServer(blockServerName);
|
||||||
|
server = new QLocalServer();
|
||||||
|
|
||||||
|
// Restrict access to the socket according to the
|
||||||
|
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||||
|
if (options & SingleApplication::Mode::User) {
|
||||||
|
server->setSocketOptions(QLocalServer::UserAccessOption);
|
||||||
} else {
|
} else {
|
||||||
appData.addData(
|
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||||
QDir(QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
|
||||||
.first())
|
|
||||||
.absolutePath()
|
|
||||||
.toUtf8());
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
server->listen(blockServerName);
|
||||||
// server naming requirements.
|
QObject::connect(server,
|
||||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
&QLocalServer::newConnection,
|
||||||
|
this,
|
||||||
|
&SingleApplicationPrivate::slotConnectionEstablished);
|
||||||
|
|
||||||
|
// Reset the number of connections
|
||||||
|
memory->lock();
|
||||||
|
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||||
|
|
||||||
|
if (resetMemory) {
|
||||||
|
inst->secondary = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->primary = true;
|
||||||
|
inst->primaryPid = q->applicationPid();
|
||||||
|
|
||||||
|
memory->unlock();
|
||||||
|
|
||||||
|
instanceNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::startSecondary()
|
||||||
SingleApplicationPrivate::startPrimary(bool resetMemory)
|
|
||||||
{
|
|
||||||
Q_Q(SingleApplication);
|
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
// Handle any further termination signals to ensure the
|
|
||||||
// QSharedMemory block is deleted even if the process crashes
|
|
||||||
crashHandler();
|
|
||||||
#endif
|
|
||||||
// Successful creation means that no main process exists
|
|
||||||
// So we start a QLocalServer to listen for connections
|
|
||||||
QLocalServer::removeServer(blockServerName);
|
|
||||||
server = new QLocalServer();
|
|
||||||
|
|
||||||
// Restrict access to the socket according to the
|
|
||||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
|
||||||
if (options & SingleApplication::Mode::User) {
|
|
||||||
server->setSocketOptions(QLocalServer::UserAccessOption);
|
|
||||||
} else {
|
|
||||||
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
|
||||||
}
|
|
||||||
|
|
||||||
server->listen(blockServerName);
|
|
||||||
QObject::connect(server,
|
|
||||||
&QLocalServer::newConnection,
|
|
||||||
this,
|
|
||||||
&SingleApplicationPrivate::slotConnectionEstablished);
|
|
||||||
|
|
||||||
// Reset the number of connections
|
|
||||||
memory->lock();
|
|
||||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
|
||||||
|
|
||||||
if (resetMemory) {
|
|
||||||
inst->secondary = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inst->primary = true;
|
|
||||||
inst->primaryPid = q->applicationPid();
|
|
||||||
|
|
||||||
memory->unlock();
|
|
||||||
|
|
||||||
instanceNumber = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SingleApplicationPrivate::startSecondary()
|
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
// Handle any further termination signals to ensure the
|
// Handle any further termination signals to ensure the
|
||||||
// QSharedMemory block is deleted even if the process crashes
|
// QSharedMemory block is deleted even if the process crashes
|
||||||
crashHandler();
|
crashHandler();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::connectToPrimary(int msecs,
|
||||||
SingleApplicationPrivate::connectToPrimary(int msecs,
|
ConnectionType connectionType)
|
||||||
ConnectionType connectionType)
|
|
||||||
{
|
{
|
||||||
// Connect to the Local Server of the Primary Instance if not already
|
// Connect to the Local Server of the Primary Instance if not already
|
||||||
// connected.
|
// connected.
|
||||||
if (socket == nullptr) {
|
if (socket == nullptr) {
|
||||||
socket = new QLocalSocket();
|
socket = new QLocalSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If already connected - we are done;
|
// If already connected - we are done;
|
||||||
if (socket->state() == QLocalSocket::ConnectedState)
|
if (socket->state() == QLocalSocket::ConnectedState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If not connect
|
// If not connect
|
||||||
if (socket->state() == QLocalSocket::UnconnectedState ||
|
if (socket->state() == QLocalSocket::UnconnectedState ||
|
||||||
socket->state() == QLocalSocket::ClosingState) {
|
socket->state() == QLocalSocket::ClosingState) {
|
||||||
socket->connectToServer(blockServerName);
|
socket->connectToServer(blockServerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for being connected
|
// Wait for being connected
|
||||||
if (socket->state() == QLocalSocket::ConnectingState) {
|
if (socket->state() == QLocalSocket::ConnectingState) {
|
||||||
socket->waitForConnected(msecs);
|
socket->waitForConnected(msecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialisation message according to the SingleApplication protocol
|
// Initialisation message according to the SingleApplication protocol
|
||||||
if (socket->state() == QLocalSocket::ConnectedState) {
|
if (socket->state() == QLocalSocket::ConnectedState) {
|
||||||
// Notify the parent that a new instance had been started;
|
// Notify the parent that a new instance had been started;
|
||||||
QByteArray initMsg;
|
QByteArray initMsg;
|
||||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||||
writeStream.setVersion(QDataStream::Qt_5_2);
|
writeStream.setVersion(QDataStream::Qt_5_2);
|
||||||
writeStream << blockServerName.toLatin1();
|
writeStream << blockServerName.toLatin1();
|
||||||
writeStream << static_cast<quint8>(connectionType);
|
writeStream << static_cast<quint8>(connectionType);
|
||||||
writeStream << instanceNumber;
|
writeStream << instanceNumber;
|
||||||
quint16 checksum =
|
quint16 checksum = qChecksum(initMsg.constData(),
|
||||||
qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
static_cast<quint32>(initMsg.length()));
|
||||||
writeStream << checksum;
|
writeStream << checksum;
|
||||||
|
|
||||||
socket->write(initMsg);
|
socket->write(initMsg);
|
||||||
socket->flush();
|
socket->flush();
|
||||||
socket->waitForBytesWritten(msecs);
|
socket->waitForBytesWritten(msecs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64
|
qint64 SingleApplicationPrivate::primaryPid()
|
||||||
SingleApplicationPrivate::primaryPid()
|
|
||||||
{
|
{
|
||||||
qint64 pid;
|
qint64 pid;
|
||||||
|
|
||||||
memory->lock();
|
memory->lock();
|
||||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||||
pid = inst->primaryPid;
|
pid = inst->primaryPid;
|
||||||
memory->unlock();
|
memory->unlock();
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
void
|
void SingleApplicationPrivate::crashHandler()
|
||||||
SingleApplicationPrivate::crashHandler()
|
|
||||||
{
|
{
|
||||||
// Handle any further termination signals to ensure the
|
// Handle any further termination signals to ensure the
|
||||||
// QSharedMemory block is deleted even if the process crashes
|
// QSharedMemory block is deleted even if the process crashes
|
||||||
signal(SIGHUP, SingleApplicationPrivate::terminate); // 1
|
signal(SIGHUP, SingleApplicationPrivate::terminate); // 1
|
||||||
signal(SIGINT, SingleApplicationPrivate::terminate); // 2
|
signal(SIGINT, SingleApplicationPrivate::terminate); // 2
|
||||||
signal(SIGQUIT, SingleApplicationPrivate::terminate); // 3
|
signal(SIGQUIT, SingleApplicationPrivate::terminate); // 3
|
||||||
signal(SIGILL, SingleApplicationPrivate::terminate); // 4
|
signal(SIGILL, SingleApplicationPrivate::terminate); // 4
|
||||||
signal(SIGABRT, SingleApplicationPrivate::terminate); // 6
|
signal(SIGABRT, SingleApplicationPrivate::terminate); // 6
|
||||||
signal(SIGFPE, SingleApplicationPrivate::terminate); // 8
|
signal(SIGFPE, SingleApplicationPrivate::terminate); // 8
|
||||||
signal(SIGBUS, SingleApplicationPrivate::terminate); // 10
|
signal(SIGBUS, SingleApplicationPrivate::terminate); // 10
|
||||||
signal(SIGSEGV, SingleApplicationPrivate::terminate); // 11
|
signal(SIGSEGV, SingleApplicationPrivate::terminate); // 11
|
||||||
signal(SIGSYS, SingleApplicationPrivate::terminate); // 12
|
signal(SIGSYS, SingleApplicationPrivate::terminate); // 12
|
||||||
signal(SIGPIPE, SingleApplicationPrivate::terminate); // 13
|
signal(SIGPIPE, SingleApplicationPrivate::terminate); // 13
|
||||||
signal(SIGALRM, SingleApplicationPrivate::terminate); // 14
|
signal(SIGALRM, SingleApplicationPrivate::terminate); // 14
|
||||||
signal(SIGTERM, SingleApplicationPrivate::terminate); // 15
|
signal(SIGTERM, SingleApplicationPrivate::terminate); // 15
|
||||||
signal(SIGXCPU, SingleApplicationPrivate::terminate); // 24
|
signal(SIGXCPU, SingleApplicationPrivate::terminate); // 24
|
||||||
signal(SIGXFSZ, SingleApplicationPrivate::terminate); // 25
|
signal(SIGXFSZ, SingleApplicationPrivate::terminate); // 25
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::terminate(int signum)
|
||||||
SingleApplicationPrivate::terminate(int signum)
|
|
||||||
{
|
{
|
||||||
delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
|
delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
|
||||||
::exit(128 + signum);
|
::exit(128 + signum);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Executed when a connection has been made to the LocalServer
|
* @brief Executed when a connection has been made to the LocalServer
|
||||||
*/
|
*/
|
||||||
void
|
void SingleApplicationPrivate::slotConnectionEstablished()
|
||||||
SingleApplicationPrivate::slotConnectionEstablished()
|
|
||||||
{
|
{
|
||||||
Q_Q(SingleApplication);
|
Q_Q(SingleApplication);
|
||||||
|
|
||||||
QLocalSocket* nextConnSocket = server->nextPendingConnection();
|
QLocalSocket* nextConnSocket = server->nextPendingConnection();
|
||||||
|
|
||||||
quint32 instanceId = 0;
|
quint32 instanceId = 0;
|
||||||
ConnectionType connectionType = InvalidConnection;
|
ConnectionType connectionType = InvalidConnection;
|
||||||
if (nextConnSocket->waitForReadyRead(100)) {
|
if (nextConnSocket->waitForReadyRead(100)) {
|
||||||
// read all data from message in same order/format as written
|
// read all data from message in same order/format as written
|
||||||
QByteArray msgBytes = nextConnSocket->read(
|
QByteArray msgBytes =
|
||||||
nextConnSocket->bytesAvailable() - static_cast<qint64>(sizeof(quint16)));
|
nextConnSocket->read(nextConnSocket->bytesAvailable() -
|
||||||
QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
|
static_cast<qint64>(sizeof(quint16)));
|
||||||
QDataStream readStream(msgBytes);
|
QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
|
||||||
readStream.setVersion(QDataStream::Qt_5_2);
|
QDataStream readStream(msgBytes);
|
||||||
|
readStream.setVersion(QDataStream::Qt_5_2);
|
||||||
|
|
||||||
// server name
|
// server name
|
||||||
QByteArray latin1Name;
|
QByteArray latin1Name;
|
||||||
readStream >> latin1Name;
|
readStream >> latin1Name;
|
||||||
// connectioon type
|
// connectioon type
|
||||||
quint8 connType = InvalidConnection;
|
quint8 connType = InvalidConnection;
|
||||||
readStream >> connType;
|
readStream >> connType;
|
||||||
connectionType = static_cast<ConnectionType>(connType);
|
connectionType = static_cast<ConnectionType>(connType);
|
||||||
// instance id
|
// instance id
|
||||||
readStream >> instanceId;
|
readStream >> instanceId;
|
||||||
// checksum
|
// checksum
|
||||||
quint16 msgChecksum = 0;
|
quint16 msgChecksum = 0;
|
||||||
QDataStream checksumStream(checksumBytes);
|
QDataStream checksumStream(checksumBytes);
|
||||||
checksumStream.setVersion(QDataStream::Qt_5_2);
|
checksumStream.setVersion(QDataStream::Qt_5_2);
|
||||||
checksumStream >> msgChecksum;
|
checksumStream >> msgChecksum;
|
||||||
|
|
||||||
const quint16 actualChecksum =
|
const quint16 actualChecksum = qChecksum(
|
||||||
qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
|
msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
|
||||||
|
|
||||||
if (readStream.status() != QDataStream::Ok ||
|
if (readStream.status() != QDataStream::Ok ||
|
||||||
QLatin1String(latin1Name) != blockServerName ||
|
QLatin1String(latin1Name) != blockServerName ||
|
||||||
msgChecksum != actualChecksum) {
|
msgChecksum != actualChecksum) {
|
||||||
connectionType = InvalidConnection;
|
connectionType = InvalidConnection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionType == InvalidConnection) {
|
if (connectionType == InvalidConnection) {
|
||||||
nextConnSocket->close();
|
nextConnSocket->close();
|
||||||
delete nextConnSocket;
|
delete nextConnSocket;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(nextConnSocket,
|
QObject::connect(nextConnSocket,
|
||||||
&QLocalSocket::aboutToClose,
|
&QLocalSocket::aboutToClose,
|
||||||
this,
|
this,
|
||||||
[nextConnSocket, instanceId, this]() {
|
[nextConnSocket, instanceId, this]() {
|
||||||
emit this->slotClientConnectionClosed(nextConnSocket,
|
emit this->slotClientConnectionClosed(nextConnSocket,
|
||||||
instanceId);
|
instanceId);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(nextConnSocket,
|
QObject::connect(nextConnSocket,
|
||||||
&QLocalSocket::readyRead,
|
&QLocalSocket::readyRead,
|
||||||
this,
|
this,
|
||||||
[nextConnSocket, instanceId, this]() {
|
[nextConnSocket, instanceId, this]() {
|
||||||
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
emit this->slotDataAvailable(nextConnSocket,
|
||||||
});
|
instanceId);
|
||||||
|
});
|
||||||
|
|
||||||
if (connectionType == NewInstance ||
|
if (connectionType == NewInstance ||
|
||||||
(connectionType == SecondaryInstance &&
|
(connectionType == SecondaryInstance &&
|
||||||
options & SingleApplication::Mode::SecondaryNotification)) {
|
options & SingleApplication::Mode::SecondaryNotification)) {
|
||||||
emit q->instanceStarted();
|
emit q->instanceStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextConnSocket->bytesAvailable() > 0) {
|
if (nextConnSocket->bytesAvailable() > 0) {
|
||||||
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket* dataSocket,
|
||||||
SingleApplicationPrivate::slotDataAvailable(QLocalSocket* dataSocket,
|
quint32 instanceId)
|
||||||
quint32 instanceId)
|
|
||||||
{
|
{
|
||||||
Q_Q(SingleApplication);
|
Q_Q(SingleApplication);
|
||||||
emit q->receivedMessage(instanceId, dataSocket->readAll());
|
emit q->receivedMessage(instanceId, dataSocket->readAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SingleApplicationPrivate::slotClientConnectionClosed(
|
||||||
SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket* closedSocket,
|
QLocalSocket* closedSocket,
|
||||||
quint32 instanceId)
|
quint32 instanceId)
|
||||||
{
|
{
|
||||||
if (closedSocket->bytesAvailable() > 0)
|
if (closedSocket->bytesAvailable() > 0)
|
||||||
emit slotDataAvailable(closedSocket, instanceId);
|
emit slotDataAvailable(closedSocket, instanceId);
|
||||||
closedSocket->deleteLater();
|
closedSocket->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -384,61 +379,62 @@ SingleApplication::SingleApplication(int& argc,
|
|||||||
: app_t(argc, argv)
|
: app_t(argc, argv)
|
||||||
, d_ptr(new SingleApplicationPrivate(this))
|
, d_ptr(new SingleApplicationPrivate(this))
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
|
|
||||||
// Store the current mode of the program
|
// Store the current mode of the program
|
||||||
d->options = options;
|
d->options = options;
|
||||||
|
|
||||||
// Generating an application ID used for identifying the shared memory
|
// Generating an application ID used for identifying the shared memory
|
||||||
// block and QLocalServer
|
// block and QLocalServer
|
||||||
d->genBlockServerName(timeout);
|
d->genBlockServerName(timeout);
|
||||||
|
|
||||||
// Guarantee thread safe behaviour with a shared memory block. Also by
|
// Guarantee thread safe behaviour with a shared memory block. Also by
|
||||||
// explicitly attaching it and then deleting it we make sure that the
|
// explicitly attaching it and then deleting it we make sure that the
|
||||||
// memory is deleted even if the process had crashed on Unix.
|
// memory is deleted even if the process had crashed on Unix.
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
d->memory = new QSharedMemory(d->blockServerName);
|
d->memory = new QSharedMemory(d->blockServerName);
|
||||||
d->memory->attach();
|
d->memory->attach();
|
||||||
delete d->memory;
|
delete d->memory;
|
||||||
#endif
|
#endif
|
||||||
d->memory = new QSharedMemory(d->blockServerName);
|
d->memory = new QSharedMemory(d->blockServerName);
|
||||||
|
|
||||||
// Create a shared memory block
|
// Create a shared memory block
|
||||||
if (d->memory->create(sizeof(InstancesInfo))) {
|
if (d->memory->create(sizeof(InstancesInfo))) {
|
||||||
d->startPrimary(true);
|
d->startPrimary(true);
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Attempt to attach to the memory segment
|
|
||||||
if (d->memory->attach()) {
|
|
||||||
d->memory->lock();
|
|
||||||
InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
|
|
||||||
|
|
||||||
if (!inst->primary) {
|
|
||||||
d->startPrimary(false);
|
|
||||||
d->memory->unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
|
// Attempt to attach to the memory segment
|
||||||
|
if (d->memory->attach()) {
|
||||||
|
d->memory->lock();
|
||||||
|
InstancesInfo* inst =
|
||||||
|
static_cast<InstancesInfo*>(d->memory->data());
|
||||||
|
|
||||||
// Check if another instance can be started
|
if (!inst->primary) {
|
||||||
if (allowSecondary) {
|
d->startPrimary(false);
|
||||||
inst->secondary += 1;
|
d->memory->unlock();
|
||||||
d->instanceNumber = inst->secondary;
|
return;
|
||||||
d->startSecondary();
|
}
|
||||||
if (d->options & Mode::SecondaryNotification) {
|
|
||||||
d->connectToPrimary(timeout,
|
// Check if another instance can be started
|
||||||
SingleApplicationPrivate::SecondaryInstance);
|
if (allowSecondary) {
|
||||||
|
inst->secondary += 1;
|
||||||
|
d->instanceNumber = inst->secondary;
|
||||||
|
d->startSecondary();
|
||||||
|
if (d->options & Mode::SecondaryNotification) {
|
||||||
|
d->connectToPrimary(
|
||||||
|
timeout, SingleApplicationPrivate::SecondaryInstance);
|
||||||
|
}
|
||||||
|
d->memory->unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->memory->unlock();
|
||||||
}
|
}
|
||||||
d->memory->unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->memory->unlock();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
d->connectToPrimary(timeout, SingleApplicationPrivate::NewInstance);
|
d->connectToPrimary(timeout, SingleApplicationPrivate::NewInstance);
|
||||||
delete d;
|
delete d;
|
||||||
::exit(EXIT_SUCCESS);
|
::exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,52 +442,47 @@ SingleApplication::SingleApplication(int& argc,
|
|||||||
*/
|
*/
|
||||||
SingleApplication::~SingleApplication()
|
SingleApplication::~SingleApplication()
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool SingleApplication::isPrimary()
|
||||||
SingleApplication::isPrimary()
|
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
return d->server != nullptr;
|
return d->server != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool SingleApplication::isSecondary()
|
||||||
SingleApplication::isSecondary()
|
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
return d->server == nullptr;
|
return d->server == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32
|
quint32 SingleApplication::instanceId()
|
||||||
SingleApplication::instanceId()
|
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
return d->instanceNumber;
|
return d->instanceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64
|
qint64 SingleApplication::primaryPid()
|
||||||
SingleApplication::primaryPid()
|
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
return d->primaryPid();
|
return d->primaryPid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool SingleApplication::sendMessage(QByteArray message, int timeout)
|
||||||
SingleApplication::sendMessage(QByteArray message, int timeout)
|
|
||||||
{
|
{
|
||||||
Q_D(SingleApplication);
|
Q_D(SingleApplication);
|
||||||
|
|
||||||
// Nobody to connect to
|
// Nobody to connect to
|
||||||
if (isPrimary())
|
if (isPrimary())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure the socket is connected
|
// Make sure the socket is connected
|
||||||
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
|
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
|
||||||
|
|
||||||
d->socket->write(message);
|
d->socket->write(message);
|
||||||
bool dataWritten = d->socket->flush();
|
bool dataWritten = d->socket->flush();
|
||||||
d->socket->waitForBytesWritten(timeout);
|
d->socket->waitForBytesWritten(timeout);
|
||||||
return dataWritten;
|
return dataWritten;
|
||||||
}
|
}
|
||||||
|
|||||||
158
external/singleapplication/singleapplication.h
vendored
158
external/singleapplication/singleapplication.h
vendored
@@ -41,98 +41,98 @@ class SingleApplicationPrivate;
|
|||||||
*/
|
*/
|
||||||
class SingleApplication : public QAPPLICATION_CLASS
|
class SingleApplication : public QAPPLICATION_CLASS
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
typedef QAPPLICATION_CLASS app_t;
|
typedef QAPPLICATION_CLASS app_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Mode of operation of SingleApplication.
|
* @brief Mode of operation of SingleApplication.
|
||||||
* Whether the block should be user-wide or system-wide and whether the
|
* Whether the block should be user-wide or system-wide and whether the
|
||||||
* primary instance should be notified when a secondary instance had been
|
* primary instance should be notified when a secondary instance had been
|
||||||
* started.
|
* started.
|
||||||
* @note Operating system can restrict the shared memory blocks to the same
|
* @note Operating system can restrict the shared memory blocks to the same
|
||||||
* user, in which case the User/System modes will have no effect and the
|
* user, in which case the User/System modes will have no effect and the
|
||||||
* block will be user wide.
|
* block will be user wide.
|
||||||
* @enum
|
* @enum
|
||||||
*/
|
*/
|
||||||
enum Mode
|
enum Mode
|
||||||
{
|
{
|
||||||
User = 1 << 0,
|
User = 1 << 0,
|
||||||
System = 1 << 1,
|
System = 1 << 1,
|
||||||
SecondaryNotification = 1 << 2,
|
SecondaryNotification = 1 << 2,
|
||||||
ExcludeAppVersion = 1 << 3,
|
ExcludeAppVersion = 1 << 3,
|
||||||
ExcludeAppPath = 1 << 4
|
ExcludeAppPath = 1 << 4
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Options, Mode)
|
Q_DECLARE_FLAGS(Options, Mode)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Intitializes a SingleApplication instance with argc command line
|
* @brief Intitializes a SingleApplication instance with argc command line
|
||||||
* arguments in argv
|
* arguments in argv
|
||||||
* @arg {int &} argc - Number of arguments in argv
|
* @arg {int &} argc - Number of arguments in argv
|
||||||
* @arg {const char *[]} argv - Supplied command line arguments
|
* @arg {const char *[]} argv - Supplied command line arguments
|
||||||
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||||
* if there is already a primary instance.
|
* if there is already a primary instance.
|
||||||
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||||
* User wide or System wide.
|
* User wide or System wide.
|
||||||
* @arg {int} timeout - Timeout to wait in miliseconds.
|
* @arg {int} timeout - Timeout to wait in miliseconds.
|
||||||
* @note argc and argv may be changed as Qt removes arguments that it
|
* @note argc and argv may be changed as Qt removes arguments that it
|
||||||
* recognizes
|
* recognizes
|
||||||
* @note Mode::SecondaryNotification only works if set on both the primary
|
* @note Mode::SecondaryNotification only works if set on both the primary
|
||||||
* instance and the secondary instance.
|
* instance and the secondary instance.
|
||||||
* @note The timeout is just a hint for the maximum time of blocking
|
* @note The timeout is just a hint for the maximum time of blocking
|
||||||
* operations. It does not guarantee that the SingleApplication
|
* operations. It does not guarantee that the SingleApplication
|
||||||
* initialisation will be completed in given time, though is a good hint.
|
* initialisation will be completed in given time, though is a good hint.
|
||||||
* Usually 4*timeout would be the worst case (fail) scenario.
|
* Usually 4*timeout would be the worst case (fail) scenario.
|
||||||
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||||
*/
|
*/
|
||||||
explicit SingleApplication(int& argc,
|
explicit SingleApplication(int& argc,
|
||||||
char* argv[],
|
char* argv[],
|
||||||
bool allowSecondary = false,
|
bool allowSecondary = false,
|
||||||
Options options = Mode::User,
|
Options options = Mode::User,
|
||||||
int timeout = 100);
|
int timeout = 100);
|
||||||
~SingleApplication();
|
~SingleApplication();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns if the instance is the primary instance
|
* @brief Returns if the instance is the primary instance
|
||||||
* @returns {bool}
|
* @returns {bool}
|
||||||
*/
|
*/
|
||||||
bool isPrimary();
|
bool isPrimary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns if the instance is a secondary instance
|
* @brief Returns if the instance is a secondary instance
|
||||||
* @returns {bool}
|
* @returns {bool}
|
||||||
*/
|
*/
|
||||||
bool isSecondary();
|
bool isSecondary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a unique identifier for the current instance
|
* @brief Returns a unique identifier for the current instance
|
||||||
* @returns {qint32}
|
* @returns {qint32}
|
||||||
*/
|
*/
|
||||||
quint32 instanceId();
|
quint32 instanceId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the process ID (PID) of the primary instance
|
* @brief Returns the process ID (PID) of the primary instance
|
||||||
* @returns {qint64}
|
* @returns {qint64}
|
||||||
*/
|
*/
|
||||||
qint64 primaryPid();
|
qint64 primaryPid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a message to the primary instance. Returns true on success.
|
* @brief Sends a message to the primary instance. Returns true on success.
|
||||||
* @param {int} timeout - Timeout for connecting
|
* @param {int} timeout - Timeout for connecting
|
||||||
* @returns {bool}
|
* @returns {bool}
|
||||||
* @note sendMessage() will return false if invoked from the primary
|
* @note sendMessage() will return false if invoked from the primary
|
||||||
* instance.
|
* instance.
|
||||||
*/
|
*/
|
||||||
bool sendMessage(QByteArray message, int timeout = 100);
|
bool sendMessage(QByteArray message, int timeout = 100);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void instanceStarted();
|
void instanceStarted();
|
||||||
void receivedMessage(quint32 instanceId, QByteArray message);
|
void receivedMessage(quint32 instanceId, QByteArray message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SingleApplicationPrivate* d_ptr;
|
SingleApplicationPrivate* d_ptr;
|
||||||
Q_DECLARE_PRIVATE(SingleApplication)
|
Q_DECLARE_PRIVATE(SingleApplication)
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
|
||||||
|
|||||||
62
external/singleapplication/singleapplication_p.h
vendored
62
external/singleapplication/singleapplication_p.h
vendored
@@ -39,50 +39,50 @@
|
|||||||
|
|
||||||
struct InstancesInfo
|
struct InstancesInfo
|
||||||
{
|
{
|
||||||
bool primary;
|
bool primary;
|
||||||
quint32 secondary;
|
quint32 secondary;
|
||||||
qint64 primaryPid;
|
qint64 primaryPid;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleApplicationPrivate : public QObject
|
class SingleApplicationPrivate : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum ConnectionType : quint8
|
enum ConnectionType : quint8
|
||||||
{
|
{
|
||||||
InvalidConnection = 0,
|
InvalidConnection = 0,
|
||||||
NewInstance = 1,
|
NewInstance = 1,
|
||||||
SecondaryInstance = 2,
|
SecondaryInstance = 2,
|
||||||
Reconnect = 3
|
Reconnect = 3
|
||||||
};
|
};
|
||||||
Q_DECLARE_PUBLIC(SingleApplication)
|
Q_DECLARE_PUBLIC(SingleApplication)
|
||||||
|
|
||||||
SingleApplicationPrivate(SingleApplication* q_ptr);
|
SingleApplicationPrivate(SingleApplication* q_ptr);
|
||||||
~SingleApplicationPrivate();
|
~SingleApplicationPrivate();
|
||||||
|
|
||||||
void genBlockServerName(int msecs);
|
void genBlockServerName(int msecs);
|
||||||
void startPrimary(bool resetMemory);
|
void startPrimary(bool resetMemory);
|
||||||
void startSecondary();
|
void startSecondary();
|
||||||
void connectToPrimary(int msecs, ConnectionType connectionType);
|
void connectToPrimary(int msecs, ConnectionType connectionType);
|
||||||
qint64 primaryPid();
|
qint64 primaryPid();
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
void crashHandler();
|
void crashHandler();
|
||||||
static void terminate(int signum);
|
static void terminate(int signum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QSharedMemory* memory;
|
QSharedMemory* memory;
|
||||||
SingleApplication* q_ptr;
|
SingleApplication* q_ptr;
|
||||||
QLocalSocket* socket;
|
QLocalSocket* socket;
|
||||||
QLocalServer* server;
|
QLocalServer* server;
|
||||||
quint32 instanceNumber;
|
quint32 instanceNumber;
|
||||||
QString blockServerName;
|
QString blockServerName;
|
||||||
SingleApplication::Options options;
|
SingleApplication::Options options;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void slotConnectionEstablished();
|
void slotConnectionEstablished();
|
||||||
void slotDataAvailable(QLocalSocket*, quint32);
|
void slotDataAvailable(QLocalSocket*, quint32);
|
||||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SINGLEAPPLICATION_P_H
|
#endif // SINGLEAPPLICATION_P_H
|
||||||
|
|||||||
@@ -25,38 +25,32 @@ CommandArgument::CommandArgument(const QString& name,
|
|||||||
, m_description(description)
|
, m_description(description)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
void CommandArgument::setName(const QString& name)
|
||||||
CommandArgument::setName(const QString& name)
|
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandArgument::name() const
|
||||||
CommandArgument::name() const
|
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandArgument::setDescription(const QString& description)
|
||||||
CommandArgument::setDescription(const QString& description)
|
|
||||||
{
|
{
|
||||||
m_description = description;
|
m_description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandArgument::description() const
|
||||||
CommandArgument::description() const
|
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandArgument::isRoot() const
|
||||||
CommandArgument::isRoot() const
|
|
||||||
{
|
{
|
||||||
return m_name.isEmpty() && m_description.isEmpty();
|
return m_name.isEmpty() && m_description.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandArgument::operator==(const CommandArgument& arg) const
|
||||||
CommandArgument::operator==(const CommandArgument& arg) const
|
|
||||||
{
|
{
|
||||||
return m_description == arg.m_description && m_name == arg.m_name;
|
return m_description == arg.m_description && m_name == arg.m_name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,20 +22,20 @@
|
|||||||
class CommandArgument
|
class CommandArgument
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CommandArgument();
|
CommandArgument();
|
||||||
explicit CommandArgument(const QString& name, const QString& description);
|
explicit CommandArgument(const QString& name, const QString& description);
|
||||||
|
|
||||||
void setName(const QString& name);
|
void setName(const QString& name);
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
|
||||||
void setDescription(const QString& description);
|
void setDescription(const QString& description);
|
||||||
QString description() const;
|
QString description() const;
|
||||||
|
|
||||||
bool isRoot() const;
|
bool isRoot() const;
|
||||||
|
|
||||||
bool operator==(const CommandArgument& arg) const;
|
bool operator==(const CommandArgument& arg) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,399 +34,386 @@ auto versionOption =
|
|||||||
auto helpOption =
|
auto helpOption =
|
||||||
CommandOption({ "h", "help" }, QStringLiteral("Displays this help"));
|
CommandOption({ "h", "help" }, QStringLiteral("Displays this help"));
|
||||||
|
|
||||||
QString
|
QString optionsToString(const QList<CommandOption>& options,
|
||||||
optionsToString(const QList<CommandOption>& options,
|
const QList<CommandArgument>& arguments)
|
||||||
const QList<CommandArgument>& arguments)
|
|
||||||
{
|
{
|
||||||
int size = 0; // track the largest size
|
int size = 0; // track the largest size
|
||||||
QStringList dashedOptionList;
|
QStringList dashedOptionList;
|
||||||
// save the dashed options and its size in order to print the description
|
// save the dashed options and its size in order to print the description
|
||||||
// of every option at the same horizontal character position.
|
// of every option at the same horizontal character position.
|
||||||
for (auto const& option : options) {
|
for (auto const& option : options) {
|
||||||
QStringList dashedOptions = option.dashedNames();
|
QStringList dashedOptions = option.dashedNames();
|
||||||
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
||||||
if (!option.valueName().isEmpty()) {
|
if (!option.valueName().isEmpty()) {
|
||||||
joinedDashedOptions += QStringLiteral(" <%1>").arg(option.valueName());
|
joinedDashedOptions +=
|
||||||
|
QStringLiteral(" <%1>").arg(option.valueName());
|
||||||
|
}
|
||||||
|
if (joinedDashedOptions.length() > size) {
|
||||||
|
size = joinedDashedOptions.length();
|
||||||
|
}
|
||||||
|
dashedOptionList << joinedDashedOptions;
|
||||||
}
|
}
|
||||||
if (joinedDashedOptions.length() > size) {
|
// check the length of the arguments
|
||||||
size = joinedDashedOptions.length();
|
for (auto const& arg : arguments) {
|
||||||
|
if (arg.name().length() > size)
|
||||||
|
size = arg.name().length();
|
||||||
}
|
}
|
||||||
dashedOptionList << joinedDashedOptions;
|
// generate the text
|
||||||
}
|
QString result;
|
||||||
// check the length of the arguments
|
if (!dashedOptionList.isEmpty()) {
|
||||||
for (auto const& arg : arguments) {
|
result += QObject::tr("Options") + ":\n";
|
||||||
if (arg.name().length() > size)
|
QString linePadding =
|
||||||
size = arg.name().length();
|
QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
||||||
}
|
for (int i = 0; i < options.length(); ++i) {
|
||||||
// generate the text
|
result += QStringLiteral(" %1 %2\n")
|
||||||
QString result;
|
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
||||||
if (!dashedOptionList.isEmpty()) {
|
.arg(options.at(i).description().replace(
|
||||||
result += QObject::tr("Options") + ":\n";
|
QLatin1String("\n"), linePadding));
|
||||||
QString linePadding = QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
}
|
||||||
for (int i = 0; i < options.length(); ++i) {
|
if (!arguments.isEmpty()) {
|
||||||
result += QStringLiteral(" %1 %2\n")
|
result += QLatin1String("\n");
|
||||||
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
}
|
||||||
.arg(options.at(i).description().replace(QLatin1String("\n"),
|
|
||||||
linePadding));
|
|
||||||
}
|
}
|
||||||
if (!arguments.isEmpty()) {
|
if (!arguments.isEmpty()) {
|
||||||
result += QLatin1String("\n");
|
result += QObject::tr("Arguments") + ":\n";
|
||||||
}
|
}
|
||||||
}
|
for (int i = 0; i < arguments.length(); ++i) {
|
||||||
if (!arguments.isEmpty()) {
|
result += QStringLiteral(" %1 %2\n")
|
||||||
result += QObject::tr("Arguments") + ":\n";
|
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
||||||
}
|
.arg(arguments.at(i).description());
|
||||||
for (int i = 0; i < arguments.length(); ++i) {
|
}
|
||||||
result += QStringLiteral(" %1 %2\n")
|
return result;
|
||||||
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
|
||||||
.arg(arguments.at(i).description());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
bool
|
bool CommandLineParser::processArgs(const QStringList& args,
|
||||||
CommandLineParser::processArgs(const QStringList& args,
|
QStringList::const_iterator& actualIt,
|
||||||
QStringList::const_iterator& actualIt,
|
Node*& actualNode)
|
||||||
Node*& actualNode)
|
|
||||||
{
|
{
|
||||||
QString argument = *actualIt;
|
QString argument = *actualIt;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
bool isValidArg = false;
|
bool isValidArg = false;
|
||||||
for (Node& n : actualNode->subNodes) {
|
for (Node& n : actualNode->subNodes) {
|
||||||
if (n.argument.name() == argument) {
|
if (n.argument.name() == argument) {
|
||||||
actualNode = &n;
|
actualNode = &n;
|
||||||
isValidArg = true;
|
isValidArg = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (isValidArg) {
|
||||||
if (isValidArg) {
|
auto nextArg = actualNode->argument;
|
||||||
auto nextArg = actualNode->argument;
|
m_foundArgs.append(nextArg);
|
||||||
m_foundArgs.append(nextArg);
|
// check next is help
|
||||||
// check next is help
|
++actualIt;
|
||||||
++actualIt;
|
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
||||||
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
--actualIt;
|
||||||
--actualIt;
|
} else {
|
||||||
} else {
|
ok = false;
|
||||||
ok = false;
|
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
||||||
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
}
|
||||||
}
|
return ok;
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandLineParser::processOptions(const QStringList& args,
|
||||||
CommandLineParser::processOptions(const QStringList& args,
|
QStringList::const_iterator& actualIt,
|
||||||
QStringList::const_iterator& actualIt,
|
Node* const actualNode)
|
||||||
Node* const actualNode)
|
|
||||||
{
|
{
|
||||||
QString arg = *actualIt;
|
QString arg = *actualIt;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
// track values
|
// track values
|
||||||
int equalsPos = arg.indexOf(QLatin1String("="));
|
int equalsPos = arg.indexOf(QLatin1String("="));
|
||||||
QString valueStr;
|
QString valueStr;
|
||||||
if (equalsPos != -1) {
|
if (equalsPos != -1) {
|
||||||
valueStr = arg.mid(equalsPos + 1); // right
|
valueStr = arg.mid(equalsPos + 1); // right
|
||||||
arg = arg.mid(0, equalsPos); // left
|
arg = arg.mid(0, equalsPos); // left
|
||||||
}
|
|
||||||
// check format -x --xx...
|
|
||||||
bool isDoubleDashed = arg.startsWith(QLatin1String("--"));
|
|
||||||
ok = isDoubleDashed ? arg.length() > 3 : arg.length() == 2;
|
|
||||||
if (!ok) {
|
|
||||||
out << QStringLiteral("the option %1 has a wrong format.").arg(arg);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
arg = isDoubleDashed ? arg.remove(0, 2) : arg.remove(0, 1);
|
|
||||||
// get option
|
|
||||||
auto endIt = actualNode->options.cend();
|
|
||||||
auto optionIt = endIt;
|
|
||||||
for (auto i = actualNode->options.cbegin(); i != endIt; ++i) {
|
|
||||||
if ((*i).names().contains(arg)) {
|
|
||||||
optionIt = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
// check format -x --xx...
|
||||||
if (optionIt == endIt) {
|
bool isDoubleDashed = arg.startsWith(QLatin1String("--"));
|
||||||
QString argName = actualNode->argument.name();
|
ok = isDoubleDashed ? arg.length() > 3 : arg.length() == 2;
|
||||||
if (argName.isEmpty()) {
|
|
||||||
argName = qApp->applicationName();
|
|
||||||
}
|
|
||||||
out << QStringLiteral("the option '%1' is not a valid option "
|
|
||||||
"for the argument '%2'.")
|
|
||||||
.arg(arg)
|
|
||||||
.arg(argName);
|
|
||||||
ok = false;
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
// check presence of values
|
|
||||||
CommandOption option = *optionIt;
|
|
||||||
bool requiresValue = !(option.valueName().isEmpty());
|
|
||||||
if (!requiresValue && equalsPos != -1) {
|
|
||||||
out << QStringLiteral("the option '%1' contains a '=' and it doesn't "
|
|
||||||
"require a value.")
|
|
||||||
.arg(arg);
|
|
||||||
ok = false;
|
|
||||||
return ok;
|
|
||||||
} else if (requiresValue && valueStr.isEmpty()) {
|
|
||||||
// find in the next
|
|
||||||
if (actualIt + 1 != args.cend()) {
|
|
||||||
++actualIt;
|
|
||||||
} else {
|
|
||||||
out << QStringLiteral("Expected value after the option '%1'.").arg(arg);
|
|
||||||
ok = false;
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
valueStr = *actualIt;
|
|
||||||
}
|
|
||||||
// check the value correctness
|
|
||||||
if (requiresValue) {
|
|
||||||
ok = option.checkValue(valueStr);
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QString err = option.errorMsg();
|
out << QStringLiteral("the option %1 has a wrong format.").arg(arg);
|
||||||
if (!err.endsWith(QLatin1String(".")))
|
return ok;
|
||||||
err += QLatin1String(".");
|
|
||||||
out << err;
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
option.setValue(valueStr);
|
arg = isDoubleDashed ? arg.remove(0, 2) : arg.remove(0, 1);
|
||||||
}
|
// get option
|
||||||
m_foundOptions.append(option);
|
auto endIt = actualNode->options.cend();
|
||||||
return ok;
|
auto optionIt = endIt;
|
||||||
|
for (auto i = actualNode->options.cbegin(); i != endIt; ++i) {
|
||||||
|
if ((*i).names().contains(arg)) {
|
||||||
|
optionIt = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optionIt == endIt) {
|
||||||
|
QString argName = actualNode->argument.name();
|
||||||
|
if (argName.isEmpty()) {
|
||||||
|
argName = qApp->applicationName();
|
||||||
|
}
|
||||||
|
out << QStringLiteral("the option '%1' is not a valid option "
|
||||||
|
"for the argument '%2'.")
|
||||||
|
.arg(arg)
|
||||||
|
.arg(argName);
|
||||||
|
ok = false;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
// check presence of values
|
||||||
|
CommandOption option = *optionIt;
|
||||||
|
bool requiresValue = !(option.valueName().isEmpty());
|
||||||
|
if (!requiresValue && equalsPos != -1) {
|
||||||
|
out << QStringLiteral("the option '%1' contains a '=' and it doesn't "
|
||||||
|
"require a value.")
|
||||||
|
.arg(arg);
|
||||||
|
ok = false;
|
||||||
|
return ok;
|
||||||
|
} else if (requiresValue && valueStr.isEmpty()) {
|
||||||
|
// find in the next
|
||||||
|
if (actualIt + 1 != args.cend()) {
|
||||||
|
++actualIt;
|
||||||
|
} else {
|
||||||
|
out << QStringLiteral("Expected value after the option '%1'.")
|
||||||
|
.arg(arg);
|
||||||
|
ok = false;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
valueStr = *actualIt;
|
||||||
|
}
|
||||||
|
// check the value correctness
|
||||||
|
if (requiresValue) {
|
||||||
|
ok = option.checkValue(valueStr);
|
||||||
|
if (!ok) {
|
||||||
|
QString err = option.errorMsg();
|
||||||
|
if (!err.endsWith(QLatin1String(".")))
|
||||||
|
err += QLatin1String(".");
|
||||||
|
out << err;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
option.setValue(valueStr);
|
||||||
|
}
|
||||||
|
m_foundOptions.append(option);
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandLineParser::parse(const QStringList& args)
|
||||||
CommandLineParser::parse(const QStringList& args)
|
|
||||||
{
|
{
|
||||||
m_foundArgs.clear();
|
m_foundArgs.clear();
|
||||||
m_foundOptions.clear();
|
m_foundOptions.clear();
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
Node* actualNode = &m_parseTree;
|
Node* actualNode = &m_parseTree;
|
||||||
auto it = ++args.cbegin();
|
auto it = ++args.cbegin();
|
||||||
// check version option
|
// check version option
|
||||||
QStringList dashedVersion = versionOption.dashedNames();
|
QStringList dashedVersion = versionOption.dashedNames();
|
||||||
if (m_withVersion && args.length() > 1 &&
|
if (m_withVersion && args.length() > 1 &&
|
||||||
dashedVersion.contains(args.at(1))) {
|
dashedVersion.contains(args.at(1))) {
|
||||||
if (args.length() == 2) {
|
if (args.length() == 2) {
|
||||||
printVersion();
|
printVersion();
|
||||||
m_foundOptions << versionOption;
|
m_foundOptions << versionOption;
|
||||||
} else {
|
} else {
|
||||||
out << "Invalid arguments after the version option.";
|
out << "Invalid arguments after the version option.";
|
||||||
ok = false;
|
ok = false;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
// check help option
|
||||||
|
ok = processIfOptionIsHelp(args, it, actualNode);
|
||||||
|
// process the other args
|
||||||
|
for (; it != args.cend() && ok; ++it) {
|
||||||
|
const QString& value = *it;
|
||||||
|
if (value.startsWith(QLatin1String("-"))) {
|
||||||
|
ok = processOptions(args, it, actualNode);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ok = processArgs(args, it, actualNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ok && !m_generalErrorMessage.isEmpty()) {
|
||||||
|
out << QStringLiteral(" %1\n").arg(m_generalErrorMessage);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
// check help option
|
|
||||||
ok = processIfOptionIsHelp(args, it, actualNode);
|
|
||||||
// process the other args
|
|
||||||
for (; it != args.cend() && ok; ++it) {
|
|
||||||
const QString& value = *it;
|
|
||||||
if (value.startsWith(QLatin1String("-"))) {
|
|
||||||
ok = processOptions(args, it, actualNode);
|
|
||||||
|
|
||||||
|
CommandOption CommandLineParser::addVersionOption()
|
||||||
|
{
|
||||||
|
m_withVersion = true;
|
||||||
|
return versionOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandOption CommandLineParser::addHelpOption()
|
||||||
|
{
|
||||||
|
m_withHelp = true;
|
||||||
|
return helpOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandLineParser::AddArgument(const CommandArgument& arg,
|
||||||
|
const CommandArgument& parent)
|
||||||
|
{
|
||||||
|
bool res = true;
|
||||||
|
Node* n = findParent(parent);
|
||||||
|
if (n == nullptr) {
|
||||||
|
res = false;
|
||||||
} else {
|
} else {
|
||||||
ok = processArgs(args, it, actualNode);
|
Node child;
|
||||||
|
child.argument = arg;
|
||||||
|
n->subNodes.append(child);
|
||||||
}
|
}
|
||||||
}
|
return res;
|
||||||
if (!ok && !m_generalErrorMessage.isEmpty()) {
|
|
||||||
out << QStringLiteral(" %1\n").arg(m_generalErrorMessage);
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandOption
|
bool CommandLineParser::AddOption(const CommandOption& option,
|
||||||
CommandLineParser::addVersionOption()
|
const CommandArgument& parent)
|
||||||
{
|
{
|
||||||
m_withVersion = true;
|
bool res = true;
|
||||||
return versionOption;
|
Node* n = findParent(parent);
|
||||||
}
|
if (n == nullptr) {
|
||||||
|
res = false;
|
||||||
CommandOption
|
} else {
|
||||||
CommandLineParser::addHelpOption()
|
n->options.append(option);
|
||||||
{
|
|
||||||
m_withHelp = true;
|
|
||||||
return helpOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CommandLineParser::AddArgument(const CommandArgument& arg,
|
|
||||||
const CommandArgument& parent)
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
Node* n = findParent(parent);
|
|
||||||
if (n == nullptr) {
|
|
||||||
res = false;
|
|
||||||
} else {
|
|
||||||
Node child;
|
|
||||||
child.argument = arg;
|
|
||||||
n->subNodes.append(child);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CommandLineParser::AddOption(const CommandOption& option,
|
|
||||||
const CommandArgument& parent)
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
Node* n = findParent(parent);
|
|
||||||
if (n == nullptr) {
|
|
||||||
res = false;
|
|
||||||
} else {
|
|
||||||
n->options.append(option);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
|
||||||
const CommandArgument& parent)
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
for (auto const& option : options) {
|
|
||||||
if (!AddOption(option, parent)) {
|
|
||||||
res = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return res;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
||||||
CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
const CommandArgument& parent)
|
||||||
{
|
{
|
||||||
m_generalErrorMessage = msg;
|
bool res = true;
|
||||||
}
|
for (auto const& option : options) {
|
||||||
|
if (!AddOption(option, parent)) {
|
||||||
void
|
res = false;
|
||||||
CommandLineParser::setDescription(const QString& description)
|
break;
|
||||||
{
|
}
|
||||||
m_description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CommandLineParser::isSet(const CommandArgument& arg) const
|
|
||||||
{
|
|
||||||
return m_foundArgs.contains(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CommandLineParser::isSet(const CommandOption& option) const
|
|
||||||
{
|
|
||||||
return m_foundOptions.contains(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString
|
|
||||||
CommandLineParser::value(const CommandOption& option) const
|
|
||||||
{
|
|
||||||
QString value = option.value();
|
|
||||||
for (const CommandOption& fOption : m_foundOptions) {
|
|
||||||
if (option == fOption) {
|
|
||||||
value = fOption.value();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return res;
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||||
CommandLineParser::printVersion()
|
|
||||||
{
|
{
|
||||||
out << "Flameshot " << qApp->applicationVersion() << "\nCompiled with Qt "
|
m_generalErrorMessage = msg;
|
||||||
<< static_cast<QString>(QT_VERSION_STR) << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandLineParser::setDescription(const QString& description)
|
||||||
CommandLineParser::printHelp(QStringList args, const Node* node)
|
|
||||||
{
|
{
|
||||||
args.removeLast(); // remove the help, it's always the last
|
m_description = description;
|
||||||
QString helpText;
|
}
|
||||||
|
|
||||||
// add usage info
|
bool CommandLineParser::isSet(const CommandArgument& arg) const
|
||||||
QString argName = node->argument.name();
|
{
|
||||||
if (argName.isEmpty()) {
|
return m_foundArgs.contains(arg);
|
||||||
argName = qApp->applicationName();
|
}
|
||||||
}
|
|
||||||
QString argText =
|
|
||||||
node->subNodes.isEmpty() ? "" : "[" + QObject::tr("arguments") + "]";
|
|
||||||
helpText += QObject::tr("Usage") + ": %1 [%2-" + QObject::tr("options") +
|
|
||||||
QStringLiteral("] %3\n\n")
|
|
||||||
.arg(args.join(QStringLiteral(" ")))
|
|
||||||
.arg(argName)
|
|
||||||
.arg(argText);
|
|
||||||
|
|
||||||
// short section about default behavior
|
bool CommandLineParser::isSet(const CommandOption& option) const
|
||||||
helpText += QObject::tr("Per default runs Flameshot in the background and \
|
{
|
||||||
|
return m_foundOptions.contains(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CommandLineParser::value(const CommandOption& option) const
|
||||||
|
{
|
||||||
|
QString value = option.value();
|
||||||
|
for (const CommandOption& fOption : m_foundOptions) {
|
||||||
|
if (option == fOption) {
|
||||||
|
value = fOption.value();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandLineParser::printVersion()
|
||||||
|
{
|
||||||
|
out << "Flameshot " << qApp->applicationVersion() << "\nCompiled with Qt "
|
||||||
|
<< static_cast<QString>(QT_VERSION_STR) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandLineParser::printHelp(QStringList args, const Node* node)
|
||||||
|
{
|
||||||
|
args.removeLast(); // remove the help, it's always the last
|
||||||
|
QString helpText;
|
||||||
|
|
||||||
|
// add usage info
|
||||||
|
QString argName = node->argument.name();
|
||||||
|
if (argName.isEmpty()) {
|
||||||
|
argName = qApp->applicationName();
|
||||||
|
}
|
||||||
|
QString argText =
|
||||||
|
node->subNodes.isEmpty() ? "" : "[" + QObject::tr("arguments") + "]";
|
||||||
|
helpText += QObject::tr("Usage") + ": %1 [%2-" + QObject::tr("options") +
|
||||||
|
QStringLiteral("] %3\n\n")
|
||||||
|
.arg(args.join(QStringLiteral(" ")))
|
||||||
|
.arg(argName)
|
||||||
|
.arg(argText);
|
||||||
|
|
||||||
|
// short section about default behavior
|
||||||
|
helpText += QObject::tr("Per default runs Flameshot in the background and \
|
||||||
adds a tray icon for configuration.");
|
adds a tray icon for configuration.");
|
||||||
helpText += "\n\n";
|
helpText += "\n\n";
|
||||||
|
|
||||||
// add command options and subarguments
|
// add command options and subarguments
|
||||||
QList<CommandArgument> subArgs;
|
QList<CommandArgument> subArgs;
|
||||||
for (const Node& n : node->subNodes)
|
for (const Node& n : node->subNodes)
|
||||||
subArgs.append(n.argument);
|
subArgs.append(n.argument);
|
||||||
auto modifiedOptions = node->options;
|
auto modifiedOptions = node->options;
|
||||||
if (m_withHelp)
|
if (m_withHelp)
|
||||||
modifiedOptions << helpOption;
|
modifiedOptions << helpOption;
|
||||||
if (m_withVersion && node == &m_parseTree) {
|
if (m_withVersion && node == &m_parseTree) {
|
||||||
modifiedOptions << versionOption;
|
modifiedOptions << versionOption;
|
||||||
}
|
|
||||||
helpText += optionsToString(modifiedOptions, subArgs);
|
|
||||||
// print it
|
|
||||||
out << helpText;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandLineParser::Node*
|
|
||||||
CommandLineParser::findParent(const CommandArgument& parent)
|
|
||||||
{
|
|
||||||
if (parent == CommandArgument()) {
|
|
||||||
return &m_parseTree;
|
|
||||||
}
|
|
||||||
// find the parent in the subNodes recursively
|
|
||||||
Node* res = nullptr;
|
|
||||||
for (auto i = m_parseTree.subNodes.begin(); i != m_parseTree.subNodes.end();
|
|
||||||
++i) {
|
|
||||||
res = recursiveParentSearch(parent, *i);
|
|
||||||
if (res != nullptr) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
helpText += optionsToString(modifiedOptions, subArgs);
|
||||||
return res;
|
// print it
|
||||||
|
out << helpText;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandLineParser::Node*
|
CommandLineParser::Node* CommandLineParser::findParent(
|
||||||
CommandLineParser::recursiveParentSearch(const CommandArgument& parent,
|
const CommandArgument& parent)
|
||||||
Node& node) const
|
|
||||||
{
|
{
|
||||||
Node* res = nullptr;
|
if (parent == CommandArgument()) {
|
||||||
if (node.argument == parent) {
|
return &m_parseTree;
|
||||||
res = &node;
|
|
||||||
} else {
|
|
||||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
|
||||||
res = recursiveParentSearch(parent, *i);
|
|
||||||
if (res != nullptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
// find the parent in the subNodes recursively
|
||||||
return res;
|
Node* res = nullptr;
|
||||||
|
for (auto i = m_parseTree.subNodes.begin(); i != m_parseTree.subNodes.end();
|
||||||
|
++i) {
|
||||||
|
res = recursiveParentSearch(parent, *i);
|
||||||
|
if (res != nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
CommandLineParser::Node* CommandLineParser::recursiveParentSearch(
|
||||||
CommandLineParser::processIfOptionIsHelp(const QStringList& args,
|
const CommandArgument& parent,
|
||||||
QStringList::const_iterator& actualIt,
|
Node& node) const
|
||||||
Node*& actualNode)
|
|
||||||
{
|
{
|
||||||
bool ok = true;
|
Node* res = nullptr;
|
||||||
auto dashedHelpNames = helpOption.dashedNames();
|
if (node.argument == parent) {
|
||||||
if (m_withHelp && actualIt != args.cend() &&
|
res = &node;
|
||||||
dashedHelpNames.contains(*actualIt)) {
|
|
||||||
if (actualIt + 1 == args.cend()) {
|
|
||||||
m_foundOptions << helpOption;
|
|
||||||
printHelp(args, actualNode);
|
|
||||||
actualIt++;
|
|
||||||
} else {
|
} else {
|
||||||
out << "Invalid arguments after the help option.";
|
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
||||||
ok = false;
|
res = recursiveParentSearch(parent, *i);
|
||||||
|
if (res != nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return res;
|
||||||
return ok;
|
}
|
||||||
|
|
||||||
|
bool CommandLineParser::processIfOptionIsHelp(
|
||||||
|
const QStringList& args,
|
||||||
|
QStringList::const_iterator& actualIt,
|
||||||
|
Node*& actualNode)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
auto dashedHelpNames = helpOption.dashedNames();
|
||||||
|
if (m_withHelp && actualIt != args.cend() &&
|
||||||
|
dashedHelpNames.contains(*actualIt)) {
|
||||||
|
if (actualIt + 1 == args.cend()) {
|
||||||
|
m_foundOptions << helpOption;
|
||||||
|
printHelp(args, actualNode);
|
||||||
|
actualIt++;
|
||||||
|
} else {
|
||||||
|
out << "Invalid arguments after the help option.";
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,69 +24,70 @@
|
|||||||
class CommandLineParser
|
class CommandLineParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CommandLineParser();
|
CommandLineParser();
|
||||||
|
|
||||||
bool parse(const QStringList& args);
|
bool parse(const QStringList& args);
|
||||||
|
|
||||||
CommandArgument rootArgument() const { return CommandArgument(); }
|
CommandArgument rootArgument() const { return CommandArgument(); }
|
||||||
|
|
||||||
CommandOption addVersionOption();
|
CommandOption addVersionOption();
|
||||||
CommandOption addHelpOption();
|
CommandOption addHelpOption();
|
||||||
|
|
||||||
bool AddArgument(const CommandArgument& arg,
|
bool AddArgument(const CommandArgument& arg,
|
||||||
|
const CommandArgument& parent = CommandArgument());
|
||||||
|
|
||||||
|
bool AddOption(const CommandOption& option,
|
||||||
const CommandArgument& parent = CommandArgument());
|
const CommandArgument& parent = CommandArgument());
|
||||||
|
|
||||||
bool AddOption(const CommandOption& option,
|
bool AddOptions(const QList<CommandOption>& options,
|
||||||
const CommandArgument& parent = CommandArgument());
|
const CommandArgument& parent = CommandArgument());
|
||||||
|
|
||||||
bool AddOptions(const QList<CommandOption>& options,
|
void setGeneralErrorMessage(const QString& msg);
|
||||||
const CommandArgument& parent = CommandArgument());
|
void setDescription(const QString& description);
|
||||||
|
|
||||||
void setGeneralErrorMessage(const QString& msg);
|
bool isSet(const CommandArgument& arg) const;
|
||||||
void setDescription(const QString& description);
|
bool isSet(const CommandOption& option) const;
|
||||||
|
QString value(const CommandOption& option) const;
|
||||||
bool isSet(const CommandArgument& arg) const;
|
|
||||||
bool isSet(const CommandOption& option) const;
|
|
||||||
QString value(const CommandOption& option) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_withHelp = false;
|
bool m_withHelp = false;
|
||||||
bool m_withVersion = false;
|
bool m_withVersion = false;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QString m_generalErrorMessage;
|
QString m_generalErrorMessage;
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
|
||||||
explicit Node(const CommandArgument& arg)
|
|
||||||
: argument(arg)
|
|
||||||
{}
|
|
||||||
Node() {}
|
|
||||||
bool operator==(const Node& n) const
|
|
||||||
{
|
{
|
||||||
return argument == n.argument && options == n.options &&
|
explicit Node(const CommandArgument& arg)
|
||||||
subNodes == n.subNodes;
|
: argument(arg)
|
||||||
}
|
{}
|
||||||
CommandArgument argument;
|
Node() {}
|
||||||
QList<CommandOption> options;
|
bool operator==(const Node& n) const
|
||||||
QList<Node> subNodes;
|
{
|
||||||
};
|
return argument == n.argument && options == n.options &&
|
||||||
|
subNodes == n.subNodes;
|
||||||
|
}
|
||||||
|
CommandArgument argument;
|
||||||
|
QList<CommandOption> options;
|
||||||
|
QList<Node> subNodes;
|
||||||
|
};
|
||||||
|
|
||||||
Node m_parseTree;
|
Node m_parseTree;
|
||||||
QList<CommandOption> m_foundOptions;
|
QList<CommandOption> m_foundOptions;
|
||||||
QList<CommandArgument> m_foundArgs;
|
QList<CommandArgument> m_foundArgs;
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
void printVersion();
|
void printVersion();
|
||||||
void printHelp(QStringList args, const Node* node);
|
void printHelp(QStringList args, const Node* node);
|
||||||
Node* findParent(const CommandArgument& parent);
|
Node* findParent(const CommandArgument& parent);
|
||||||
Node* recursiveParentSearch(const CommandArgument& parent, Node& node) const;
|
Node* recursiveParentSearch(const CommandArgument& parent,
|
||||||
bool processIfOptionIsHelp(const QStringList& args,
|
Node& node) const;
|
||||||
QStringList::const_iterator& actualIt,
|
bool processIfOptionIsHelp(const QStringList& args,
|
||||||
Node*& actualNode);
|
QStringList::const_iterator& actualIt,
|
||||||
bool processArgs(const QStringList& args,
|
Node*& actualNode);
|
||||||
QStringList::const_iterator& actualIt,
|
bool processArgs(const QStringList& args,
|
||||||
Node*& actualNode);
|
QStringList::const_iterator& actualIt,
|
||||||
bool processOptions(const QStringList& args,
|
Node*& actualNode);
|
||||||
QStringList::const_iterator& actualIt,
|
bool processOptions(const QStringList& args,
|
||||||
Node* const actualNode);
|
QStringList::const_iterator& actualIt,
|
||||||
|
Node* const actualNode);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ CommandOption::CommandOption(const QString& name,
|
|||||||
, m_valueName(valueName)
|
, m_valueName(valueName)
|
||||||
, m_value(defaultValue)
|
, m_value(defaultValue)
|
||||||
{
|
{
|
||||||
m_checker = [](QString const&) { return true; };
|
m_checker = [](QString const&) { return true; };
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandOption::CommandOption(const QStringList& names,
|
CommandOption::CommandOption(const QStringList& names,
|
||||||
@@ -38,103 +38,89 @@ CommandOption::CommandOption(const QStringList& names,
|
|||||||
, m_valueName(valueName)
|
, m_valueName(valueName)
|
||||||
, m_value(defaultValue)
|
, m_value(defaultValue)
|
||||||
{
|
{
|
||||||
m_checker = [](QString const&) -> bool { return true; };
|
m_checker = [](QString const&) -> bool { return true; };
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::setName(const QString& name)
|
||||||
CommandOption::setName(const QString& name)
|
|
||||||
{
|
{
|
||||||
m_names = QStringList() << name;
|
m_names = QStringList() << name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::setNames(const QStringList& names)
|
||||||
CommandOption::setNames(const QStringList& names)
|
|
||||||
{
|
{
|
||||||
m_names = names;
|
m_names = names;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList CommandOption::names() const
|
||||||
CommandOption::names() const
|
|
||||||
{
|
{
|
||||||
return m_names;
|
return m_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList CommandOption::dashedNames() const
|
||||||
CommandOption::dashedNames() const
|
|
||||||
{
|
{
|
||||||
QStringList dashedNames;
|
QStringList dashedNames;
|
||||||
for (const QString& name : m_names) {
|
for (const QString& name : m_names) {
|
||||||
// prepend "-" to single character options, and "--" to the others
|
// prepend "-" to single character options, and "--" to the others
|
||||||
QString dashedName = (name.length() == 1)
|
QString dashedName = (name.length() == 1)
|
||||||
? QStringLiteral("-%1").arg(name)
|
? QStringLiteral("-%1").arg(name)
|
||||||
: QStringLiteral("--%1").arg(name);
|
: QStringLiteral("--%1").arg(name);
|
||||||
dashedNames << dashedName;
|
dashedNames << dashedName;
|
||||||
}
|
}
|
||||||
return dashedNames;
|
return dashedNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::setValueName(const QString& name)
|
||||||
CommandOption::setValueName(const QString& name)
|
|
||||||
{
|
{
|
||||||
m_valueName = name;
|
m_valueName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandOption::valueName() const
|
||||||
CommandOption::valueName() const
|
|
||||||
{
|
{
|
||||||
return m_valueName;
|
return m_valueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::setValue(const QString& value)
|
||||||
CommandOption::setValue(const QString& value)
|
|
||||||
{
|
{
|
||||||
if (m_valueName.isEmpty()) {
|
if (m_valueName.isEmpty()) {
|
||||||
m_valueName = QLatin1String("value");
|
m_valueName = QLatin1String("value");
|
||||||
}
|
}
|
||||||
m_value = value;
|
m_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandOption::value() const
|
||||||
CommandOption::value() const
|
|
||||||
{
|
{
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||||
CommandOption::addChecker(const function<bool(const QString&)> checker,
|
const QString& errMsg)
|
||||||
const QString& errMsg)
|
|
||||||
{
|
{
|
||||||
m_checker = checker;
|
m_checker = checker;
|
||||||
m_errorMsg = errMsg;
|
m_errorMsg = errMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandOption::checkValue(const QString& value) const
|
||||||
CommandOption::checkValue(const QString& value) const
|
|
||||||
{
|
{
|
||||||
return m_checker(value);
|
return m_checker(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandOption::description() const
|
||||||
CommandOption::description() const
|
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CommandOption::setDescription(const QString& description)
|
||||||
CommandOption::setDescription(const QString& description)
|
|
||||||
{
|
{
|
||||||
m_description = description;
|
m_description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CommandOption::errorMsg() const
|
||||||
CommandOption::errorMsg() const
|
|
||||||
{
|
{
|
||||||
return m_errorMsg;
|
return m_errorMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool CommandOption::operator==(const CommandOption& option) const
|
||||||
CommandOption::operator==(const CommandOption& option) const
|
|
||||||
{
|
{
|
||||||
return m_description == option.m_description && m_names == option.m_names &&
|
return m_description == option.m_description && m_names == option.m_names &&
|
||||||
m_valueName == option.m_valueName;
|
m_valueName == option.m_valueName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,44 +25,44 @@ using std::function;
|
|||||||
class CommandOption
|
class CommandOption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CommandOption(const QString& name,
|
CommandOption(const QString& name,
|
||||||
const QString& description,
|
const QString& description,
|
||||||
const QString& valueName = QString(),
|
const QString& valueName = QString(),
|
||||||
const QString& defaultValue = QString());
|
const QString& defaultValue = QString());
|
||||||
|
|
||||||
CommandOption(const QStringList& names,
|
CommandOption(const QStringList& names,
|
||||||
const QString& description,
|
const QString& description,
|
||||||
const QString& valueName = QString(),
|
const QString& valueName = QString(),
|
||||||
const QString& defaultValue = QString());
|
const QString& defaultValue = QString());
|
||||||
|
|
||||||
void setName(const QString& name);
|
void setName(const QString& name);
|
||||||
void setNames(const QStringList& names);
|
void setNames(const QStringList& names);
|
||||||
QStringList names() const;
|
QStringList names() const;
|
||||||
QStringList dashedNames() const;
|
QStringList dashedNames() const;
|
||||||
|
|
||||||
void setValueName(const QString& name);
|
void setValueName(const QString& name);
|
||||||
QString valueName() const;
|
QString valueName() const;
|
||||||
|
|
||||||
void setValue(const QString& value);
|
void setValue(const QString& value);
|
||||||
QString value() const;
|
QString value() const;
|
||||||
|
|
||||||
void addChecker(const function<bool(QString const&)> checker,
|
void addChecker(const function<bool(QString const&)> checker,
|
||||||
const QString& errMsg);
|
const QString& errMsg);
|
||||||
bool checkValue(const QString& value) const;
|
bool checkValue(const QString& value) const;
|
||||||
|
|
||||||
QString description() const;
|
QString description() const;
|
||||||
void setDescription(const QString& description);
|
void setDescription(const QString& description);
|
||||||
|
|
||||||
QString errorMsg() const;
|
QString errorMsg() const;
|
||||||
|
|
||||||
bool operator==(const CommandOption& option) const;
|
bool operator==(const CommandOption& option) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_names;
|
QStringList m_names;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
QString m_valueName;
|
QString m_valueName;
|
||||||
QString m_value;
|
QString m_value;
|
||||||
|
|
||||||
function<bool(QString const&)> m_checker;
|
function<bool(QString const&)> m_checker;
|
||||||
QString m_errorMsg;
|
QString m_errorMsg;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,94 +24,90 @@
|
|||||||
ButtonListView::ButtonListView(QWidget* parent)
|
ButtonListView::ButtonListView(QWidget* parent)
|
||||||
: QListWidget(parent)
|
: QListWidget(parent)
|
||||||
{
|
{
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setFlow(QListWidget::TopToBottom);
|
setFlow(QListWidget::TopToBottom);
|
||||||
initButtonList();
|
initButtonList();
|
||||||
updateComponents();
|
updateComponents();
|
||||||
connect(
|
connect(
|
||||||
this, &QListWidget::itemClicked, this, &ButtonListView::reverseItemCheck);
|
this, &QListWidget::itemClicked, this, &ButtonListView::reverseItemCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ButtonListView::initButtonList()
|
||||||
ButtonListView::initButtonList()
|
|
||||||
{
|
{
|
||||||
ToolFactory factory;
|
ToolFactory factory;
|
||||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||||
|
|
||||||
for (const CaptureToolButton::ButtonType t : listTypes) {
|
for (const CaptureToolButton::ButtonType t : listTypes) {
|
||||||
CaptureTool* tool = factory.CreateTool(t);
|
CaptureTool* tool = factory.CreateTool(t);
|
||||||
|
|
||||||
// add element to the local map
|
// add element to the local map
|
||||||
m_buttonTypeByName.insert(tool->name(), t);
|
m_buttonTypeByName.insert(tool->name(), t);
|
||||||
|
|
||||||
// init the menu option
|
// init the menu option
|
||||||
QListWidgetItem* m_buttonItem = new QListWidgetItem(this);
|
QListWidgetItem* m_buttonItem = new QListWidgetItem(this);
|
||||||
|
|
||||||
// when the background is lighter than gray, it uses the white icons
|
// when the background is lighter than gray, it uses the white icons
|
||||||
QColor bgColor = this->palette().color(QWidget::backgroundRole());
|
QColor bgColor = this->palette().color(QWidget::backgroundRole());
|
||||||
m_buttonItem->setIcon(tool->icon(bgColor, false));
|
m_buttonItem->setIcon(tool->icon(bgColor, false));
|
||||||
|
|
||||||
m_buttonItem->setFlags(Qt::ItemIsUserCheckable);
|
m_buttonItem->setFlags(Qt::ItemIsUserCheckable);
|
||||||
QColor foregroundColor = this->palette().color(QWidget::foregroundRole());
|
QColor foregroundColor =
|
||||||
m_buttonItem->setForeground(foregroundColor);
|
this->palette().color(QWidget::foregroundRole());
|
||||||
|
m_buttonItem->setForeground(foregroundColor);
|
||||||
|
|
||||||
m_buttonItem->setText(tool->name());
|
m_buttonItem->setText(tool->name());
|
||||||
m_buttonItem->setToolTip(tool->description());
|
m_buttonItem->setToolTip(tool->description());
|
||||||
tool->deleteLater();
|
tool->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ButtonListView::updateActiveButtons(QListWidgetItem* item)
|
||||||
ButtonListView::updateActiveButtons(QListWidgetItem* item)
|
{
|
||||||
{
|
CaptureToolButton::ButtonType bType = m_buttonTypeByName[item->text()];
|
||||||
CaptureToolButton::ButtonType bType = m_buttonTypeByName[item->text()];
|
if (item->checkState() == Qt::Checked) {
|
||||||
if (item->checkState() == Qt::Checked) {
|
m_listButtons.append(bType);
|
||||||
m_listButtons.append(bType);
|
// TODO refactor so we don't need external sorts
|
||||||
// TODO refactor so we don't need external sorts
|
using bt = CaptureToolButton::ButtonType;
|
||||||
using bt = CaptureToolButton::ButtonType;
|
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) {
|
||||||
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) {
|
return CaptureToolButton::getPriorityByButton(a) <
|
||||||
return CaptureToolButton::getPriorityByButton(a) <
|
CaptureToolButton::getPriorityByButton(b);
|
||||||
CaptureToolButton::getPriorityByButton(b);
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
m_listButtons.remove(m_listButtons.indexOf(bType));
|
||||||
m_listButtons.remove(m_listButtons.indexOf(bType));
|
}
|
||||||
}
|
ConfigHandler().setButtons(m_listButtons);
|
||||||
ConfigHandler().setButtons(m_listButtons);
|
}
|
||||||
}
|
|
||||||
|
void ButtonListView::reverseItemCheck(QListWidgetItem* item)
|
||||||
void
|
{
|
||||||
ButtonListView::reverseItemCheck(QListWidgetItem* item)
|
if (item->checkState() == Qt::Checked) {
|
||||||
{
|
item->setCheckState(Qt::Unchecked);
|
||||||
if (item->checkState() == Qt::Checked) {
|
} else {
|
||||||
item->setCheckState(Qt::Unchecked);
|
item->setCheckState(Qt::Checked);
|
||||||
} else {
|
}
|
||||||
item->setCheckState(Qt::Checked);
|
updateActiveButtons(item);
|
||||||
}
|
}
|
||||||
updateActiveButtons(item);
|
|
||||||
}
|
void ButtonListView::selectAll()
|
||||||
|
{
|
||||||
void
|
ConfigHandler().setAllTheButtons();
|
||||||
ButtonListView::selectAll()
|
for (int i = 0; i < this->count(); ++i) {
|
||||||
{
|
QListWidgetItem* item = this->item(i);
|
||||||
ConfigHandler().setAllTheButtons();
|
item->setCheckState(Qt::Checked);
|
||||||
for (int i = 0; i < this->count(); ++i) {
|
}
|
||||||
QListWidgetItem* item = this->item(i);
|
}
|
||||||
item->setCheckState(Qt::Checked);
|
|
||||||
}
|
void ButtonListView::updateComponents()
|
||||||
}
|
{
|
||||||
|
m_listButtons = ConfigHandler().getButtons();
|
||||||
void
|
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||||
ButtonListView::updateComponents()
|
for (int i = 0; i < this->count(); ++i) {
|
||||||
{
|
QListWidgetItem* item = this->item(i);
|
||||||
m_listButtons = ConfigHandler().getButtons();
|
auto elem = static_cast<CaptureToolButton::ButtonType>(listTypes.at(i));
|
||||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
if (m_listButtons.contains(elem)) {
|
||||||
for (int i = 0; i < this->count(); ++i) {
|
item->setCheckState(Qt::Checked);
|
||||||
QListWidgetItem* item = this->item(i);
|
} else {
|
||||||
auto elem = static_cast<CaptureToolButton::ButtonType>(listTypes.at(i));
|
item->setCheckState(Qt::Unchecked);
|
||||||
if (m_listButtons.contains(elem)) {
|
}
|
||||||
item->setCheckState(Qt::Checked);
|
|
||||||
} else {
|
|
||||||
item->setCheckState(Qt::Unchecked);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,21 +23,21 @@
|
|||||||
class ButtonListView : public QListWidget
|
class ButtonListView : public QListWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ButtonListView(QWidget* parent = nullptr);
|
explicit ButtonListView(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void selectAll();
|
void selectAll();
|
||||||
void updateComponents();
|
void updateComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void reverseItemCheck(QListWidgetItem*);
|
void reverseItemCheck(QListWidgetItem*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initButtonList();
|
void initButtonList();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<CaptureToolButton::ButtonType> m_listButtons;
|
QVector<CaptureToolButton::ButtonType> m_listButtons;
|
||||||
QMap<QString, CaptureToolButton::ButtonType> m_buttonTypeByName;
|
QMap<QString, CaptureToolButton::ButtonType> m_buttonTypeByName;
|
||||||
|
|
||||||
void updateActiveButtons(QListWidgetItem*);
|
void updateActiveButtons(QListWidgetItem*);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ ClickableLabel::ClickableLabel(QWidget* parent)
|
|||||||
ClickableLabel::ClickableLabel(QString s, QWidget* parent)
|
ClickableLabel::ClickableLabel(QString s, QWidget* parent)
|
||||||
: QLabel(parent)
|
: QLabel(parent)
|
||||||
{
|
{
|
||||||
setText(s);
|
setText(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ClickableLabel::mousePressEvent(QMouseEvent*)
|
||||||
ClickableLabel::mousePressEvent(QMouseEvent*)
|
|
||||||
{
|
{
|
||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
class ClickableLabel : public QLabel
|
class ClickableLabel : public QLabel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ClickableLabel(QWidget* parent = nullptr);
|
explicit ClickableLabel(QWidget* parent = nullptr);
|
||||||
ClickableLabel(QString s, QWidget* parent = nullptr);
|
ClickableLabel(QString s, QWidget* parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mousePressEvent(QMouseEvent*);
|
void mousePressEvent(QMouseEvent*);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,61 +36,61 @@
|
|||||||
ConfigWindow::ConfigWindow(QWidget* parent)
|
ConfigWindow::ConfigWindow(QWidget* parent)
|
||||||
: QTabWidget(parent)
|
: QTabWidget(parent)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
const int size = GlobalValues::buttonBaseSize() * 12;
|
const int size = GlobalValues::buttonBaseSize() * 12;
|
||||||
setMinimumSize(size, size);
|
setMinimumSize(size, size);
|
||||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||||
setWindowTitle(tr("Configuration"));
|
setWindowTitle(tr("Configuration"));
|
||||||
|
|
||||||
auto changedSlot = [this](QString s) {
|
auto changedSlot = [this](QString s) {
|
||||||
QStringList files = m_configWatcher->files();
|
QStringList files = m_configWatcher->files();
|
||||||
if (!files.contains(s)) {
|
if (!files.contains(s)) {
|
||||||
this->m_configWatcher->addPath(s);
|
this->m_configWatcher->addPath(s);
|
||||||
}
|
}
|
||||||
emit updateChildren();
|
emit updateChildren();
|
||||||
};
|
};
|
||||||
m_configWatcher = new QFileSystemWatcher(this);
|
m_configWatcher = new QFileSystemWatcher(this);
|
||||||
m_configWatcher->addPath(ConfigHandler().configFilePath());
|
m_configWatcher->addPath(ConfigHandler().configFilePath());
|
||||||
connect(m_configWatcher, &QFileSystemWatcher::fileChanged, this, changedSlot);
|
connect(
|
||||||
|
m_configWatcher, &QFileSystemWatcher::fileChanged, this, changedSlot);
|
||||||
|
|
||||||
QColor background = this->palette().window().color();
|
QColor background = this->palette().window().color();
|
||||||
bool isDark = ColorUtils::colorIsDark(background);
|
bool isDark = ColorUtils::colorIsDark(background);
|
||||||
QString modifier =
|
QString modifier =
|
||||||
isDark ? PathInfo::whiteIconPath() : PathInfo::blackIconPath();
|
isDark ? PathInfo::whiteIconPath() : PathInfo::blackIconPath();
|
||||||
|
|
||||||
// visuals
|
// visuals
|
||||||
m_visuals = new VisualsEditor();
|
m_visuals = new VisualsEditor();
|
||||||
addTab(m_visuals, QIcon(modifier + "graphics.svg"), tr("Interface"));
|
addTab(m_visuals, QIcon(modifier + "graphics.svg"), tr("Interface"));
|
||||||
|
|
||||||
// filename
|
// filename
|
||||||
m_filenameEditor = new FileNameEditor();
|
m_filenameEditor = new FileNameEditor();
|
||||||
addTab(m_filenameEditor,
|
addTab(m_filenameEditor,
|
||||||
QIcon(modifier + "name_edition.svg"),
|
QIcon(modifier + "name_edition.svg"),
|
||||||
tr("Filename Editor"));
|
tr("Filename Editor"));
|
||||||
|
|
||||||
// general
|
// general
|
||||||
m_generalConfig = new GeneneralConf();
|
m_generalConfig = new GeneneralConf();
|
||||||
addTab(m_generalConfig, QIcon(modifier + "config.svg"), tr("General"));
|
addTab(m_generalConfig, QIcon(modifier + "config.svg"), tr("General"));
|
||||||
|
|
||||||
// connect update sigslots
|
// connect update sigslots
|
||||||
connect(this,
|
connect(this,
|
||||||
&ConfigWindow::updateChildren,
|
&ConfigWindow::updateChildren,
|
||||||
m_filenameEditor,
|
m_filenameEditor,
|
||||||
&FileNameEditor::updateComponents);
|
&FileNameEditor::updateComponents);
|
||||||
connect(this,
|
connect(this,
|
||||||
&ConfigWindow::updateChildren,
|
&ConfigWindow::updateChildren,
|
||||||
m_visuals,
|
m_visuals,
|
||||||
&VisualsEditor::updateComponents);
|
&VisualsEditor::updateComponents);
|
||||||
connect(this,
|
connect(this,
|
||||||
&ConfigWindow::updateChildren,
|
&ConfigWindow::updateChildren,
|
||||||
m_generalConfig,
|
m_generalConfig,
|
||||||
&GeneneralConf::updateComponents);
|
&GeneneralConf::updateComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ConfigWindow::keyPressEvent(QKeyEvent* e)
|
||||||
ConfigWindow::keyPressEvent(QKeyEvent* e)
|
|
||||||
{
|
{
|
||||||
if (e->key() == Qt::Key_Escape) {
|
if (e->key() == Qt::Key_Escape) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,19 +26,19 @@ class VisualsEditor;
|
|||||||
|
|
||||||
class ConfigWindow : public QTabWidget
|
class ConfigWindow : public QTabWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ConfigWindow(QWidget* parent = nullptr);
|
explicit ConfigWindow(QWidget* parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updateChildren();
|
void updateChildren();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent*);
|
void keyPressEvent(QKeyEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileNameEditor* m_filenameEditor;
|
FileNameEditor* m_filenameEditor;
|
||||||
GeneneralConf* m_generalConfig;
|
GeneneralConf* m_generalConfig;
|
||||||
VisualsEditor* m_visuals;
|
VisualsEditor* m_visuals;
|
||||||
QFileSystemWatcher* m_configWatcher;
|
QFileSystemWatcher* m_configWatcher;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,38 +20,37 @@
|
|||||||
ExtendedSlider::ExtendedSlider(QWidget* parent)
|
ExtendedSlider::ExtendedSlider(QWidget* parent)
|
||||||
: QSlider(parent)
|
: QSlider(parent)
|
||||||
{
|
{
|
||||||
connect(
|
connect(this,
|
||||||
this, &ExtendedSlider::valueChanged, this, &ExtendedSlider::updateTooltip);
|
&ExtendedSlider::valueChanged,
|
||||||
connect(this, &ExtendedSlider::sliderMoved, this, &ExtendedSlider::fireTimer);
|
this,
|
||||||
m_timer.setSingleShot(true);
|
&ExtendedSlider::updateTooltip);
|
||||||
connect(
|
connect(
|
||||||
&m_timer, &QTimer::timeout, this, &ExtendedSlider::modificationsEnded);
|
this, &ExtendedSlider::sliderMoved, this, &ExtendedSlider::fireTimer);
|
||||||
|
m_timer.setSingleShot(true);
|
||||||
|
connect(
|
||||||
|
&m_timer, &QTimer::timeout, this, &ExtendedSlider::modificationsEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ExtendedSlider::mappedValue(int min, int max)
|
||||||
ExtendedSlider::mappedValue(int min, int max)
|
|
||||||
{
|
{
|
||||||
qreal progress =
|
qreal progress =
|
||||||
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
||||||
return min + (max - min) * progress;
|
return min + (max - min) * progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExtendedSlider::setMapedValue(int min, int val, int max)
|
||||||
ExtendedSlider::setMapedValue(int min, int val, int max)
|
|
||||||
{
|
{
|
||||||
qreal progress = ((val - min) + 1) / static_cast<qreal>(max - min);
|
qreal progress = ((val - min) + 1) / static_cast<qreal>(max - min);
|
||||||
int value = minimum() + (maximum() - minimum()) * progress;
|
int value = minimum() + (maximum() - minimum()) * progress;
|
||||||
setValue(value);
|
setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExtendedSlider::updateTooltip()
|
||||||
ExtendedSlider::updateTooltip()
|
|
||||||
{
|
{
|
||||||
setToolTip(QString::number(value()) + "%");
|
setToolTip(QString::number(value()) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExtendedSlider::fireTimer()
|
||||||
ExtendedSlider::fireTimer()
|
|
||||||
{
|
{
|
||||||
m_timer.start(500);
|
m_timer.start(500);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,20 +22,20 @@
|
|||||||
|
|
||||||
class ExtendedSlider : public QSlider
|
class ExtendedSlider : public QSlider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ExtendedSlider(QWidget* parent = nullptr);
|
explicit ExtendedSlider(QWidget* parent = nullptr);
|
||||||
|
|
||||||
int mappedValue(int min, int max);
|
int mappedValue(int min, int max);
|
||||||
void setMapedValue(int min, int val, int max);
|
void setMapedValue(int min, int val, int max);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void modificationsEnded();
|
void modificationsEnded();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateTooltip();
|
void updateTooltip();
|
||||||
void fireTimer();
|
void fireTimer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,110 +28,104 @@
|
|||||||
FileNameEditor::FileNameEditor(QWidget* parent)
|
FileNameEditor::FileNameEditor(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
initWidgets();
|
initWidgets();
|
||||||
initLayout();
|
initLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::initLayout()
|
||||||
FileNameEditor::initLayout()
|
|
||||||
{
|
{
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
auto infoLabel = new QLabel(tr("Edit the name of your captures:"), this);
|
auto infoLabel = new QLabel(tr("Edit the name of your captures:"), this);
|
||||||
infoLabel->setFixedHeight(20);
|
infoLabel->setFixedHeight(20);
|
||||||
m_layout->addWidget(infoLabel);
|
m_layout->addWidget(infoLabel);
|
||||||
m_layout->addWidget(m_helperButtons);
|
m_layout->addWidget(m_helperButtons);
|
||||||
m_layout->addWidget(new QLabel(tr("Edit:")));
|
m_layout->addWidget(new QLabel(tr("Edit:")));
|
||||||
m_layout->addWidget(m_nameEditor);
|
m_layout->addWidget(m_nameEditor);
|
||||||
m_layout->addWidget(new QLabel(tr("Preview:")));
|
m_layout->addWidget(new QLabel(tr("Preview:")));
|
||||||
m_layout->addWidget(m_outputLabel);
|
m_layout->addWidget(m_outputLabel);
|
||||||
|
|
||||||
QHBoxLayout* horizLayout = new QHBoxLayout();
|
QHBoxLayout* horizLayout = new QHBoxLayout();
|
||||||
horizLayout->addWidget(m_saveButton);
|
horizLayout->addWidget(m_saveButton);
|
||||||
horizLayout->addWidget(m_resetButton);
|
horizLayout->addWidget(m_resetButton);
|
||||||
horizLayout->addWidget(m_clearButton);
|
horizLayout->addWidget(m_clearButton);
|
||||||
m_layout->addLayout(horizLayout);
|
m_layout->addLayout(horizLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::initWidgets()
|
||||||
FileNameEditor::initWidgets()
|
|
||||||
{
|
{
|
||||||
m_nameHandler = new FileNameHandler(this);
|
m_nameHandler = new FileNameHandler(this);
|
||||||
|
|
||||||
// editor
|
// editor
|
||||||
m_nameEditor = new QLineEdit(this);
|
m_nameEditor = new QLineEdit(this);
|
||||||
m_nameEditor->setMaxLength(FileNameHandler::MAX_CHARACTERS);
|
m_nameEditor->setMaxLength(FileNameHandler::MAX_CHARACTERS);
|
||||||
|
|
||||||
// preview
|
// preview
|
||||||
m_outputLabel = new QLineEdit(this);
|
m_outputLabel = new QLineEdit(this);
|
||||||
m_outputLabel->setDisabled(true);
|
m_outputLabel->setDisabled(true);
|
||||||
QString foreground = this->palette().windowText().color().name();
|
QString foreground = this->palette().windowText().color().name();
|
||||||
m_outputLabel->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
m_outputLabel->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||||
QPalette pal = m_outputLabel->palette();
|
QPalette pal = m_outputLabel->palette();
|
||||||
QColor color = pal.color(QPalette::Disabled, m_outputLabel->backgroundRole());
|
QColor color =
|
||||||
pal.setColor(QPalette::Active, m_outputLabel->backgroundRole(), color);
|
pal.color(QPalette::Disabled, m_outputLabel->backgroundRole());
|
||||||
m_outputLabel->setPalette(pal);
|
pal.setColor(QPalette::Active, m_outputLabel->backgroundRole(), color);
|
||||||
|
m_outputLabel->setPalette(pal);
|
||||||
|
|
||||||
connect(m_nameEditor,
|
connect(m_nameEditor,
|
||||||
&QLineEdit::textChanged,
|
&QLineEdit::textChanged,
|
||||||
this,
|
this,
|
||||||
&FileNameEditor::showParsedPattern);
|
&FileNameEditor::showParsedPattern);
|
||||||
updateComponents();
|
updateComponents();
|
||||||
|
|
||||||
// helper buttons
|
// helper buttons
|
||||||
m_helperButtons = new StrftimeChooserWidget(this);
|
m_helperButtons = new StrftimeChooserWidget(this);
|
||||||
connect(m_helperButtons,
|
connect(m_helperButtons,
|
||||||
&StrftimeChooserWidget::variableEmitted,
|
&StrftimeChooserWidget::variableEmitted,
|
||||||
this,
|
this,
|
||||||
&FileNameEditor::addToNameEditor);
|
&FileNameEditor::addToNameEditor);
|
||||||
|
|
||||||
// save
|
// save
|
||||||
m_saveButton = new QPushButton(tr("Save"), this);
|
m_saveButton = new QPushButton(tr("Save"), this);
|
||||||
connect(
|
connect(
|
||||||
m_saveButton, &QPushButton::clicked, this, &FileNameEditor::savePattern);
|
m_saveButton, &QPushButton::clicked, this, &FileNameEditor::savePattern);
|
||||||
m_saveButton->setToolTip(tr("Saves the pattern"));
|
m_saveButton->setToolTip(tr("Saves the pattern"));
|
||||||
// reset
|
// reset
|
||||||
m_resetButton = new QPushButton(tr("Reset"), this);
|
m_resetButton = new QPushButton(tr("Reset"), this);
|
||||||
connect(
|
connect(
|
||||||
m_resetButton, &QPushButton::clicked, this, &FileNameEditor::resetName);
|
m_resetButton, &QPushButton::clicked, this, &FileNameEditor::resetName);
|
||||||
m_resetButton->setToolTip(tr("Restores the saved pattern"));
|
m_resetButton->setToolTip(tr("Restores the saved pattern"));
|
||||||
// clear
|
// clear
|
||||||
m_clearButton = new QPushButton(tr("Clear"), this);
|
m_clearButton = new QPushButton(tr("Clear"), this);
|
||||||
connect(m_clearButton, &QPushButton::clicked, this, [this]() {
|
connect(m_clearButton, &QPushButton::clicked, this, [this]() {
|
||||||
m_nameEditor->setText(QString());
|
m_nameEditor->setText(QString());
|
||||||
});
|
});
|
||||||
m_clearButton->setToolTip(tr("Deletes the name"));
|
m_clearButton->setToolTip(tr("Deletes the name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::savePattern()
|
||||||
FileNameEditor::savePattern()
|
|
||||||
{
|
{
|
||||||
QString pattern = m_nameEditor->text();
|
QString pattern = m_nameEditor->text();
|
||||||
m_nameHandler->setPattern(pattern);
|
m_nameHandler->setPattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::showParsedPattern(const QString& p)
|
||||||
FileNameEditor::showParsedPattern(const QString& p)
|
|
||||||
{
|
{
|
||||||
QString output = m_nameHandler->parseFilename(p);
|
QString output = m_nameHandler->parseFilename(p);
|
||||||
m_outputLabel->setText(output);
|
m_outputLabel->setText(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::resetName()
|
||||||
FileNameEditor::resetName()
|
|
||||||
{
|
{
|
||||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::addToNameEditor(QString s)
|
||||||
FileNameEditor::addToNameEditor(QString s)
|
|
||||||
{
|
{
|
||||||
m_nameEditor->setText(m_nameEditor->text() + s);
|
m_nameEditor->setText(m_nameEditor->text() + s);
|
||||||
m_nameEditor->setFocus();
|
m_nameEditor->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FileNameEditor::updateComponents()
|
||||||
FileNameEditor::updateComponents()
|
|
||||||
{
|
{
|
||||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||||
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,29 +28,29 @@ class StrftimeChooserWidget;
|
|||||||
|
|
||||||
class FileNameEditor : public QWidget
|
class FileNameEditor : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FileNameEditor(QWidget* parent = nullptr);
|
explicit FileNameEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
QLineEdit* m_outputLabel;
|
QLineEdit* m_outputLabel;
|
||||||
QLineEdit* m_nameEditor;
|
QLineEdit* m_nameEditor;
|
||||||
FileNameHandler* m_nameHandler;
|
FileNameHandler* m_nameHandler;
|
||||||
StrftimeChooserWidget* m_helperButtons;
|
StrftimeChooserWidget* m_helperButtons;
|
||||||
QPushButton* m_saveButton;
|
QPushButton* m_saveButton;
|
||||||
QPushButton* m_resetButton;
|
QPushButton* m_resetButton;
|
||||||
QPushButton* m_clearButton;
|
QPushButton* m_clearButton;
|
||||||
|
|
||||||
void initLayout();
|
void initLayout();
|
||||||
void initWidgets();
|
void initWidgets();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addToNameEditor(QString s);
|
void addToNameEditor(QString s);
|
||||||
void updateComponents();
|
void updateComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void savePattern();
|
void savePattern();
|
||||||
void showParsedPattern(const QString&);
|
void showParsedPattern(const QString&);
|
||||||
void resetName();
|
void resetName();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,343 +33,326 @@
|
|||||||
GeneneralConf::GeneneralConf(QWidget* parent)
|
GeneneralConf::GeneneralConf(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
m_layout->setAlignment(Qt::AlignTop);
|
m_layout->setAlignment(Qt::AlignTop);
|
||||||
initShowHelp();
|
initShowHelp();
|
||||||
initShowSidePanelButton();
|
initShowSidePanelButton();
|
||||||
initShowDesktopNotification();
|
initShowDesktopNotification();
|
||||||
initShowTrayIcon();
|
initShowTrayIcon();
|
||||||
initAutostart();
|
initAutostart();
|
||||||
initCloseAfterCapture();
|
initCloseAfterCapture();
|
||||||
initCopyAndCloseAfterUpload();
|
initCopyAndCloseAfterUpload();
|
||||||
initSaveAfterCopy();
|
initSaveAfterCopy();
|
||||||
|
|
||||||
// this has to be at the end
|
// this has to be at the end
|
||||||
initConfingButtons();
|
initConfingButtons();
|
||||||
updateComponents();
|
updateComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::updateComponents()
|
||||||
GeneneralConf::updateComponents()
|
|
||||||
{
|
{
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
m_helpMessage->setChecked(config.showHelpValue());
|
m_helpMessage->setChecked(config.showHelpValue());
|
||||||
m_sidePanelButton->setChecked(config.showSidePanelButtonValue());
|
m_sidePanelButton->setChecked(config.showSidePanelButtonValue());
|
||||||
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
||||||
m_autostart->setChecked(config.startupLaunchValue());
|
m_autostart->setChecked(config.startupLaunchValue());
|
||||||
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
||||||
m_copyAndCloseAfterUpload->setChecked(
|
m_copyAndCloseAfterUpload->setChecked(
|
||||||
config.copyAndCloseAfterUploadEnabled());
|
config.copyAndCloseAfterUploadEnabled());
|
||||||
m_saveAfterCopy->setChecked(config.saveAfterCopyValue());
|
m_saveAfterCopy->setChecked(config.saveAfterCopyValue());
|
||||||
|
|
||||||
if (!config.saveAfterCopyPathValue().isEmpty()) {
|
if (!config.saveAfterCopyPathValue().isEmpty()) {
|
||||||
m_savePath->setText(config.saveAfterCopyPathValue());
|
m_savePath->setText(config.saveAfterCopyPathValue());
|
||||||
} else {
|
} else {
|
||||||
ConfigHandler().setSaveAfterCopyPath(
|
ConfigHandler().setSaveAfterCopyPath(
|
||||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
|
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||||
m_showTray->setChecked(!config.disabledTrayIconValue());
|
m_showTray->setChecked(!config.disabledTrayIconValue());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::showHelpChanged(bool checked)
|
||||||
GeneneralConf::showHelpChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setShowHelp(checked);
|
ConfigHandler().setShowHelp(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::showSidePanelButtonChanged(bool checked)
|
||||||
GeneneralConf::showSidePanelButtonChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setShowSidePanelButton(checked);
|
ConfigHandler().setShowSidePanelButton(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::showDesktopNotificationChanged(bool checked)
|
||||||
GeneneralConf::showDesktopNotificationChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setDesktopNotification(checked);
|
ConfigHandler().setDesktopNotification(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::showTrayIconChanged(bool checked)
|
||||||
GeneneralConf::showTrayIconChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
auto controller = Controller::getInstance();
|
auto controller = Controller::getInstance();
|
||||||
if (checked) {
|
if (checked) {
|
||||||
controller->enableTrayIcon();
|
controller->enableTrayIcon();
|
||||||
} else {
|
} else {
|
||||||
controller->disableTrayIcon();
|
controller->disableTrayIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::autostartChanged(bool checked)
|
||||||
GeneneralConf::autostartChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setStartupLaunch(checked);
|
ConfigHandler().setStartupLaunch(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::closeAfterCaptureChanged(bool checked)
|
||||||
GeneneralConf::closeAfterCaptureChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setCloseAfterScreenshot(checked);
|
ConfigHandler().setCloseAfterScreenshot(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::importConfiguration()
|
||||||
GeneneralConf::importConfiguration()
|
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import"));
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Import"));
|
||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
QTextCodec* codec = QTextCodec::codecForLocale();
|
QTextCodec* codec = QTextCodec::codecForLocale();
|
||||||
if (!file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
QMessageBox::about(this, tr("Error"), tr("Unable to read file."));
|
QMessageBox::about(this, tr("Error"), tr("Unable to read file."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString text = codec->toUnicode(file.readAll());
|
QString text = codec->toUnicode(file.readAll());
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
QFile config(ConfigHandler().configFilePath());
|
QFile config(ConfigHandler().configFilePath());
|
||||||
if (!config.open(QFile::WriteOnly)) {
|
if (!config.open(QFile::WriteOnly)) {
|
||||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
config.write(codec->fromUnicode(text));
|
config.write(codec->fromUnicode(text));
|
||||||
config.close();
|
config.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::exportFileConfiguration()
|
||||||
GeneneralConf::exportFileConfiguration()
|
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getSaveFileName(
|
QString fileName = QFileDialog::getSaveFileName(
|
||||||
this, tr("Save File"), QStringLiteral("flameshot.conf"));
|
this, tr("Save File"), QStringLiteral("flameshot.conf"));
|
||||||
|
|
||||||
// Cancel button
|
// Cancel button
|
||||||
if (fileName.isNull()) {
|
if (fileName.isNull()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile targetFile(fileName);
|
QFile targetFile(fileName);
|
||||||
if (targetFile.exists()) {
|
if (targetFile.exists()) {
|
||||||
targetFile.remove();
|
targetFile.remove();
|
||||||
}
|
}
|
||||||
bool ok = QFile::copy(ConfigHandler().configFilePath(), fileName);
|
bool ok = QFile::copy(ConfigHandler().configFilePath(), fileName);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::resetConfiguration()
|
||||||
GeneneralConf::resetConfiguration()
|
|
||||||
{
|
{
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
reply = QMessageBox::question(
|
reply = QMessageBox::question(
|
||||||
this,
|
this,
|
||||||
tr("Confirm Reset"),
|
tr("Confirm Reset"),
|
||||||
tr("Are you sure you want to reset the configuration?"),
|
tr("Are you sure you want to reset the configuration?"),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
if (reply == QMessageBox::Yes) {
|
if (reply == QMessageBox::Yes) {
|
||||||
ConfigHandler().setDefaults();
|
ConfigHandler().setDefaults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initShowHelp()
|
||||||
GeneneralConf::initShowHelp()
|
|
||||||
{
|
{
|
||||||
m_helpMessage = new QCheckBox(tr("Show help message"), this);
|
m_helpMessage = new QCheckBox(tr("Show help message"), this);
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
bool checked = config.showHelpValue();
|
bool checked = config.showHelpValue();
|
||||||
m_helpMessage->setChecked(checked);
|
m_helpMessage->setChecked(checked);
|
||||||
m_helpMessage->setToolTip(tr("Show the help message at the beginning "
|
m_helpMessage->setToolTip(tr("Show the help message at the beginning "
|
||||||
"in the capture mode."));
|
"in the capture mode."));
|
||||||
m_layout->addWidget(m_helpMessage);
|
m_layout->addWidget(m_helpMessage);
|
||||||
|
|
||||||
connect(
|
connect(m_helpMessage,
|
||||||
m_helpMessage, &QCheckBox::clicked, this, &GeneneralConf::showHelpChanged);
|
&QCheckBox::clicked,
|
||||||
|
this,
|
||||||
|
&GeneneralConf::showHelpChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initShowSidePanelButton()
|
||||||
GeneneralConf::initShowSidePanelButton()
|
|
||||||
{
|
{
|
||||||
m_sidePanelButton = new QCheckBox(tr("Show the side panel button"), this);
|
m_sidePanelButton = new QCheckBox(tr("Show the side panel button"), this);
|
||||||
m_sidePanelButton->setChecked(ConfigHandler().showSidePanelButtonValue());
|
m_sidePanelButton->setChecked(ConfigHandler().showSidePanelButtonValue());
|
||||||
m_sidePanelButton->setToolTip(
|
m_sidePanelButton->setToolTip(
|
||||||
tr("Show the side panel toggle button in the capture mode."));
|
tr("Show the side panel toggle button in the capture mode."));
|
||||||
m_layout->addWidget(m_sidePanelButton);
|
m_layout->addWidget(m_sidePanelButton);
|
||||||
|
|
||||||
connect(m_sidePanelButton,
|
connect(m_sidePanelButton,
|
||||||
&QCheckBox::clicked,
|
&QCheckBox::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::showSidePanelButtonChanged);
|
&GeneneralConf::showSidePanelButtonChanged);
|
||||||
}
|
}
|
||||||
void
|
void GeneneralConf::initShowDesktopNotification()
|
||||||
GeneneralConf::initShowDesktopNotification()
|
|
||||||
{
|
{
|
||||||
m_sysNotifications = new QCheckBox(tr("Show desktop notifications"), this);
|
m_sysNotifications = new QCheckBox(tr("Show desktop notifications"), this);
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
bool checked = config.desktopNotificationValue();
|
bool checked = config.desktopNotificationValue();
|
||||||
m_sysNotifications->setChecked(checked);
|
m_sysNotifications->setChecked(checked);
|
||||||
m_sysNotifications->setToolTip(tr("Show desktop notifications"));
|
m_sysNotifications->setToolTip(tr("Show desktop notifications"));
|
||||||
m_layout->addWidget(m_sysNotifications);
|
m_layout->addWidget(m_sysNotifications);
|
||||||
|
|
||||||
connect(m_sysNotifications,
|
connect(m_sysNotifications,
|
||||||
&QCheckBox::clicked,
|
&QCheckBox::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::showDesktopNotificationChanged);
|
&GeneneralConf::showDesktopNotificationChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initShowTrayIcon()
|
||||||
GeneneralConf::initShowTrayIcon()
|
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||||
m_showTray = new QCheckBox(tr("Show tray icon"), this);
|
m_showTray = new QCheckBox(tr("Show tray icon"), this);
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
bool checked = !config.disabledTrayIconValue();
|
bool checked = !config.disabledTrayIconValue();
|
||||||
m_showTray->setChecked(checked);
|
m_showTray->setChecked(checked);
|
||||||
m_showTray->setToolTip(tr("Show the systemtray icon"));
|
m_showTray->setToolTip(tr("Show the systemtray icon"));
|
||||||
m_layout->addWidget(m_showTray);
|
m_layout->addWidget(m_showTray);
|
||||||
|
|
||||||
connect(m_showTray,
|
connect(m_showTray,
|
||||||
&QCheckBox::stateChanged,
|
&QCheckBox::stateChanged,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::showTrayIconChanged);
|
&GeneneralConf::showTrayIconChanged);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initConfingButtons()
|
||||||
GeneneralConf::initConfingButtons()
|
|
||||||
{
|
{
|
||||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||||
m_layout->addStretch();
|
m_layout->addStretch();
|
||||||
QGroupBox* box = new QGroupBox(tr("Configuration File"));
|
QGroupBox* box = new QGroupBox(tr("Configuration File"));
|
||||||
box->setFlat(true);
|
box->setFlat(true);
|
||||||
box->setLayout(buttonLayout);
|
box->setLayout(buttonLayout);
|
||||||
m_layout->addWidget(box);
|
m_layout->addWidget(box);
|
||||||
|
|
||||||
m_exportButton = new QPushButton(tr("Export"));
|
m_exportButton = new QPushButton(tr("Export"));
|
||||||
buttonLayout->addWidget(m_exportButton);
|
buttonLayout->addWidget(m_exportButton);
|
||||||
connect(m_exportButton,
|
connect(m_exportButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::exportFileConfiguration);
|
&GeneneralConf::exportFileConfiguration);
|
||||||
|
|
||||||
m_importButton = new QPushButton(tr("Import"));
|
m_importButton = new QPushButton(tr("Import"));
|
||||||
buttonLayout->addWidget(m_importButton);
|
buttonLayout->addWidget(m_importButton);
|
||||||
connect(m_importButton,
|
connect(m_importButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::importConfiguration);
|
&GeneneralConf::importConfiguration);
|
||||||
|
|
||||||
m_resetButton = new QPushButton(tr("Reset"));
|
m_resetButton = new QPushButton(tr("Reset"));
|
||||||
buttonLayout->addWidget(m_resetButton);
|
buttonLayout->addWidget(m_resetButton);
|
||||||
connect(m_resetButton,
|
connect(m_resetButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::resetConfiguration);
|
&GeneneralConf::resetConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initAutostart()
|
||||||
GeneneralConf::initAutostart()
|
|
||||||
{
|
{
|
||||||
m_autostart = new QCheckBox(tr("Launch at startup"), this);
|
m_autostart = new QCheckBox(tr("Launch at startup"), this);
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
bool checked = config.startupLaunchValue();
|
bool checked = config.startupLaunchValue();
|
||||||
m_autostart->setChecked(checked);
|
m_autostart->setChecked(checked);
|
||||||
m_autostart->setToolTip(tr("Launch Flameshot"));
|
m_autostart->setToolTip(tr("Launch Flameshot"));
|
||||||
m_layout->addWidget(m_autostart);
|
m_layout->addWidget(m_autostart);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
m_autostart, &QCheckBox::clicked, this, &GeneneralConf::autostartChanged);
|
m_autostart, &QCheckBox::clicked, this, &GeneneralConf::autostartChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initCloseAfterCapture()
|
||||||
GeneneralConf::initCloseAfterCapture()
|
|
||||||
{
|
{
|
||||||
m_closeAfterCapture = new QCheckBox(tr("Close after capture"), this);
|
m_closeAfterCapture = new QCheckBox(tr("Close after capture"), this);
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
bool checked = config.closeAfterScreenshotValue();
|
bool checked = config.closeAfterScreenshotValue();
|
||||||
m_closeAfterCapture->setChecked(checked);
|
m_closeAfterCapture->setChecked(checked);
|
||||||
m_closeAfterCapture->setToolTip(tr("Close after taking a screenshot"));
|
m_closeAfterCapture->setToolTip(tr("Close after taking a screenshot"));
|
||||||
m_layout->addWidget(m_closeAfterCapture);
|
m_layout->addWidget(m_closeAfterCapture);
|
||||||
|
|
||||||
connect(m_closeAfterCapture,
|
connect(m_closeAfterCapture,
|
||||||
&QCheckBox::clicked,
|
&QCheckBox::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::closeAfterCaptureChanged);
|
&GeneneralConf::closeAfterCaptureChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initCopyAndCloseAfterUpload()
|
||||||
GeneneralConf::initCopyAndCloseAfterUpload()
|
|
||||||
{
|
{
|
||||||
m_copyAndCloseAfterUpload = new QCheckBox(tr("Copy URL after upload"), this);
|
m_copyAndCloseAfterUpload =
|
||||||
ConfigHandler config;
|
new QCheckBox(tr("Copy URL after upload"), this);
|
||||||
m_copyAndCloseAfterUpload->setChecked(
|
ConfigHandler config;
|
||||||
config.copyAndCloseAfterUploadEnabled());
|
m_copyAndCloseAfterUpload->setChecked(
|
||||||
m_copyAndCloseAfterUpload->setToolTip(
|
config.copyAndCloseAfterUploadEnabled());
|
||||||
tr("Copy URL and close window after upload"));
|
m_copyAndCloseAfterUpload->setToolTip(
|
||||||
m_layout->addWidget(m_copyAndCloseAfterUpload);
|
tr("Copy URL and close window after upload"));
|
||||||
|
m_layout->addWidget(m_copyAndCloseAfterUpload);
|
||||||
|
|
||||||
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
||||||
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::initSaveAfterCopy()
|
||||||
GeneneralConf::initSaveAfterCopy()
|
|
||||||
{
|
{
|
||||||
m_saveAfterCopy = new QCheckBox(tr("Save image after copy"), this);
|
m_saveAfterCopy = new QCheckBox(tr("Save image after copy"), this);
|
||||||
m_saveAfterCopy->setToolTip(tr("Save image file after copying it"));
|
m_saveAfterCopy->setToolTip(tr("Save image file after copying it"));
|
||||||
m_layout->addWidget(m_saveAfterCopy);
|
m_layout->addWidget(m_saveAfterCopy);
|
||||||
connect(m_saveAfterCopy,
|
connect(m_saveAfterCopy,
|
||||||
&QCheckBox::clicked,
|
&QCheckBox::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::saveAfterCopyChanged);
|
&GeneneralConf::saveAfterCopyChanged);
|
||||||
|
|
||||||
QHBoxLayout* pathLayout = new QHBoxLayout();
|
QHBoxLayout* pathLayout = new QHBoxLayout();
|
||||||
m_layout->addStretch();
|
m_layout->addStretch();
|
||||||
QGroupBox* box = new QGroupBox(tr("Save Path"));
|
QGroupBox* box = new QGroupBox(tr("Save Path"));
|
||||||
box->setFlat(true);
|
box->setFlat(true);
|
||||||
box->setLayout(pathLayout);
|
box->setLayout(pathLayout);
|
||||||
m_layout->addWidget(box);
|
m_layout->addWidget(box);
|
||||||
|
|
||||||
m_savePath = new QLineEdit(
|
m_savePath = new QLineEdit(
|
||||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), this);
|
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), this);
|
||||||
m_savePath->setDisabled(true);
|
m_savePath->setDisabled(true);
|
||||||
QString foreground = this->palette().foreground().color().name();
|
QString foreground = this->palette().foreground().color().name();
|
||||||
m_savePath->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
m_savePath->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||||
pathLayout->addWidget(m_savePath);
|
pathLayout->addWidget(m_savePath);
|
||||||
|
|
||||||
m_changeSaveButton = new QPushButton(tr("Change..."), this);
|
m_changeSaveButton = new QPushButton(tr("Change..."), this);
|
||||||
pathLayout->addWidget(m_changeSaveButton);
|
pathLayout->addWidget(m_changeSaveButton);
|
||||||
connect(m_changeSaveButton,
|
connect(m_changeSaveButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&GeneneralConf::changeSavePath);
|
&GeneneralConf::changeSavePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::saveAfterCopyChanged(bool checked)
|
||||||
GeneneralConf::saveAfterCopyChanged(bool checked)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setSaveAfterCopy(checked);
|
ConfigHandler().setSaveAfterCopy(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GeneneralConf::changeSavePath()
|
||||||
GeneneralConf::changeSavePath()
|
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getExistingDirectory(
|
QString path = QFileDialog::getExistingDirectory(
|
||||||
this,
|
this,
|
||||||
tr("Choose a Folder"),
|
tr("Choose a Folder"),
|
||||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
|
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!QFileInfo(path).isWritable()) {
|
if (!QFileInfo(path).isWritable()) {
|
||||||
QMessageBox::about(this, tr("Error"), tr("Unable to write to directory."));
|
QMessageBox::about(
|
||||||
return;
|
this, tr("Error"), tr("Unable to write to directory."));
|
||||||
}
|
return;
|
||||||
m_savePath->setText(path);
|
}
|
||||||
ConfigHandler().setSaveAfterCopyPath(path);
|
m_savePath->setText(path);
|
||||||
|
ConfigHandler().setSaveAfterCopyPath(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,49 +27,49 @@ class QLineEdit;
|
|||||||
|
|
||||||
class GeneneralConf : public QWidget
|
class GeneneralConf : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GeneneralConf(QWidget* parent = nullptr);
|
explicit GeneneralConf(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateComponents();
|
void updateComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showHelpChanged(bool checked);
|
void showHelpChanged(bool checked);
|
||||||
void showSidePanelButtonChanged(bool checked);
|
void showSidePanelButtonChanged(bool checked);
|
||||||
void showDesktopNotificationChanged(bool checked);
|
void showDesktopNotificationChanged(bool checked);
|
||||||
void showTrayIconChanged(bool checked);
|
void showTrayIconChanged(bool checked);
|
||||||
void autostartChanged(bool checked);
|
void autostartChanged(bool checked);
|
||||||
void closeAfterCaptureChanged(bool checked);
|
void closeAfterCaptureChanged(bool checked);
|
||||||
void saveAfterCopyChanged(bool checked);
|
void saveAfterCopyChanged(bool checked);
|
||||||
void changeSavePath();
|
void changeSavePath();
|
||||||
void importConfiguration();
|
void importConfiguration();
|
||||||
void exportFileConfiguration();
|
void exportFileConfiguration();
|
||||||
void resetConfiguration();
|
void resetConfiguration();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
QCheckBox* m_sysNotifications;
|
QCheckBox* m_sysNotifications;
|
||||||
QCheckBox* m_showTray;
|
QCheckBox* m_showTray;
|
||||||
QCheckBox* m_helpMessage;
|
QCheckBox* m_helpMessage;
|
||||||
QCheckBox* m_sidePanelButton;
|
QCheckBox* m_sidePanelButton;
|
||||||
QCheckBox* m_autostart;
|
QCheckBox* m_autostart;
|
||||||
QCheckBox* m_closeAfterCapture;
|
QCheckBox* m_closeAfterCapture;
|
||||||
QCheckBox* m_copyAndCloseAfterUpload;
|
QCheckBox* m_copyAndCloseAfterUpload;
|
||||||
QPushButton* m_importButton;
|
QPushButton* m_importButton;
|
||||||
QPushButton* m_exportButton;
|
QPushButton* m_exportButton;
|
||||||
QPushButton* m_resetButton;
|
QPushButton* m_resetButton;
|
||||||
QCheckBox* m_saveAfterCopy;
|
QCheckBox* m_saveAfterCopy;
|
||||||
QLineEdit* m_savePath;
|
QLineEdit* m_savePath;
|
||||||
QPushButton* m_changeSaveButton;
|
QPushButton* m_changeSaveButton;
|
||||||
|
|
||||||
void initShowHelp();
|
void initShowHelp();
|
||||||
void initShowSidePanelButton();
|
void initShowSidePanelButton();
|
||||||
void initShowDesktopNotification();
|
void initShowDesktopNotification();
|
||||||
void initShowTrayIcon();
|
void initShowTrayIcon();
|
||||||
void initConfingButtons();
|
void initConfingButtons();
|
||||||
void initAutostart();
|
void initAutostart();
|
||||||
void initCloseAfterCapture();
|
void initCloseAfterCapture();
|
||||||
void initCopyAndCloseAfterUpload();
|
void initCopyAndCloseAfterUpload();
|
||||||
void initSaveAfterCopy();
|
void initSaveAfterCopy();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,49 +23,50 @@
|
|||||||
StrftimeChooserWidget::StrftimeChooserWidget(QWidget* parent)
|
StrftimeChooserWidget::StrftimeChooserWidget(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
QGridLayout* layout = new QGridLayout(this);
|
QGridLayout* layout = new QGridLayout(this);
|
||||||
auto k = m_buttonData.keys();
|
auto k = m_buttonData.keys();
|
||||||
int middle = k.length() / 2;
|
int middle = k.length() / 2;
|
||||||
// add the buttons in 2 columns (they need to be even)
|
// add the buttons in 2 columns (they need to be even)
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int j = 0; j < middle; j++) {
|
for (int j = 0; j < middle; j++) {
|
||||||
QString key = k.last();
|
QString key = k.last();
|
||||||
k.pop_back();
|
k.pop_back();
|
||||||
QString variable = m_buttonData.value(key);
|
QString variable = m_buttonData.value(key);
|
||||||
QPushButton* button = new QPushButton(this);
|
QPushButton* button = new QPushButton(this);
|
||||||
button->setText(tr(key.toStdString().data()));
|
button->setText(tr(key.toStdString().data()));
|
||||||
button->setToolTip(variable);
|
button->setToolTip(variable);
|
||||||
button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
button->setSizePolicy(QSizePolicy::Expanding,
|
||||||
button->setMinimumHeight(25);
|
QSizePolicy::Expanding);
|
||||||
layout->addWidget(button, j, i);
|
button->setMinimumHeight(25);
|
||||||
connect(button, &QPushButton::clicked, this, [variable, this]() {
|
layout->addWidget(button, j, i);
|
||||||
emit variableEmitted(variable);
|
connect(button, &QPushButton::clicked, this, [variable, this]() {
|
||||||
});
|
emit variableEmitted(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
setLayout(layout);
|
||||||
setLayout(layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> StrftimeChooserWidget::m_buttonData{
|
QMap<QString, QString> StrftimeChooserWidget::m_buttonData{
|
||||||
{ QT_TR_NOOP("Century (00-99)"), "%C" },
|
{ QT_TR_NOOP("Century (00-99)"), "%C" },
|
||||||
{ QT_TR_NOOP("Year (00-99)"), "%y" },
|
{ QT_TR_NOOP("Year (00-99)"), "%y" },
|
||||||
{ QT_TR_NOOP("Year (2000)"), "%Y" },
|
{ QT_TR_NOOP("Year (2000)"), "%Y" },
|
||||||
{ QT_TR_NOOP("Month Name (jan)"), "%b" },
|
{ QT_TR_NOOP("Month Name (jan)"), "%b" },
|
||||||
{ QT_TR_NOOP("Month Name (january)"), "%B" },
|
{ QT_TR_NOOP("Month Name (january)"), "%B" },
|
||||||
{ QT_TR_NOOP("Month (01-12)"), "%m" },
|
{ QT_TR_NOOP("Month (01-12)"), "%m" },
|
||||||
{ QT_TR_NOOP("Week Day (1-7)"), "%u" },
|
{ QT_TR_NOOP("Week Day (1-7)"), "%u" },
|
||||||
{ QT_TR_NOOP("Week (01-53)"), "%V" },
|
{ QT_TR_NOOP("Week (01-53)"), "%V" },
|
||||||
{ QT_TR_NOOP("Day Name (mon)"), "%a" },
|
{ QT_TR_NOOP("Day Name (mon)"), "%a" },
|
||||||
{ QT_TR_NOOP("Day Name (monday)"), "%A" },
|
{ QT_TR_NOOP("Day Name (monday)"), "%A" },
|
||||||
{ QT_TR_NOOP("Day (01-31)"), "%d" },
|
{ QT_TR_NOOP("Day (01-31)"), "%d" },
|
||||||
{ QT_TR_NOOP("Day of Month (1-31)"), "%e" },
|
{ QT_TR_NOOP("Day of Month (1-31)"), "%e" },
|
||||||
{ QT_TR_NOOP("Day (001-366)"), "%j" },
|
{ QT_TR_NOOP("Day (001-366)"), "%j" },
|
||||||
{ QT_TR_NOOP("Time (%H-%M-%S)"), "%T" },
|
{ QT_TR_NOOP("Time (%H-%M-%S)"), "%T" },
|
||||||
{ QT_TR_NOOP("Time (%H-%M)"), "%R" },
|
{ QT_TR_NOOP("Time (%H-%M)"), "%R" },
|
||||||
{ QT_TR_NOOP("Hour (00-23)"), "%H" },
|
{ QT_TR_NOOP("Hour (00-23)"), "%H" },
|
||||||
{ QT_TR_NOOP("Hour (01-12)"), "%I" },
|
{ QT_TR_NOOP("Hour (01-12)"), "%I" },
|
||||||
{ QT_TR_NOOP("Minute (00-59)"), "%M" },
|
{ QT_TR_NOOP("Minute (00-59)"), "%M" },
|
||||||
{ QT_TR_NOOP("Second (00-59)"), "%S" },
|
{ QT_TR_NOOP("Second (00-59)"), "%S" },
|
||||||
{ QT_TR_NOOP("Full Date (%m/%d/%y)"), "%D" },
|
{ QT_TR_NOOP("Full Date (%m/%d/%y)"), "%D" },
|
||||||
{ QT_TR_NOOP("Full Date (%Y-%m-%d)"), "%F" },
|
{ QT_TR_NOOP("Full Date (%Y-%m-%d)"), "%F" },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
class StrftimeChooserWidget : public QWidget
|
class StrftimeChooserWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit StrftimeChooserWidget(QWidget* parent = nullptr);
|
explicit StrftimeChooserWidget(QWidget* parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void variableEmitted(const QString&);
|
void variableEmitted(const QString&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QMap<QString, QString> m_buttonData;
|
static QMap<QString, QString> m_buttonData;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,162 +29,156 @@
|
|||||||
UIcolorEditor::UIcolorEditor(QWidget* parent)
|
UIcolorEditor::UIcolorEditor(QWidget* parent)
|
||||||
: QGroupBox(parent)
|
: QGroupBox(parent)
|
||||||
{
|
{
|
||||||
setTitle(tr("UI Color Editor"));
|
setTitle(tr("UI Color Editor"));
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
m_hLayout = new QHBoxLayout;
|
m_hLayout = new QHBoxLayout;
|
||||||
m_vLayout = new QVBoxLayout;
|
m_vLayout = new QVBoxLayout;
|
||||||
|
|
||||||
const int space = QApplication::fontMetrics().lineSpacing();
|
const int space = QApplication::fontMetrics().lineSpacing();
|
||||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||||
m_vLayout->setAlignment(Qt::AlignVCenter);
|
m_vLayout->setAlignment(Qt::AlignVCenter);
|
||||||
|
|
||||||
initButtons();
|
initButtons();
|
||||||
initColorWheel();
|
initColorWheel();
|
||||||
|
|
||||||
m_vLayout->addSpacing(space);
|
m_vLayout->addSpacing(space);
|
||||||
m_hLayout->addLayout(m_vLayout);
|
m_hLayout->addLayout(m_vLayout);
|
||||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||||
setLayout(m_hLayout);
|
setLayout(m_hLayout);
|
||||||
updateComponents();
|
updateComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void UIcolorEditor::updateComponents()
|
||||||
UIcolorEditor::updateComponents()
|
|
||||||
{
|
{
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
m_uiColor = config.uiMainColorValue();
|
m_uiColor = config.uiMainColorValue();
|
||||||
m_contrastColor = config.uiContrastColorValue();
|
m_contrastColor = config.uiContrastColorValue();
|
||||||
m_buttonContrast->setColor(m_contrastColor);
|
m_buttonContrast->setColor(m_contrastColor);
|
||||||
m_buttonMainColor->setColor(m_uiColor);
|
m_buttonMainColor->setColor(m_uiColor);
|
||||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||||
m_colorWheel->setColor(m_uiColor);
|
m_colorWheel->setColor(m_uiColor);
|
||||||
} else {
|
} else {
|
||||||
m_colorWheel->setColor(m_contrastColor);
|
m_colorWheel->setColor(m_contrastColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateUIcolor updates the appearance of the buttons
|
// updateUIcolor updates the appearance of the buttons
|
||||||
void
|
void UIcolorEditor::updateUIcolor()
|
||||||
UIcolorEditor::updateUIcolor()
|
|
||||||
{
|
{
|
||||||
ConfigHandler config;
|
ConfigHandler config;
|
||||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||||
config.setUIMainColor(m_uiColor);
|
config.setUIMainColor(m_uiColor);
|
||||||
} else {
|
} else {
|
||||||
config.setUIContrastColor(m_contrastColor);
|
config.setUIContrastColor(m_contrastColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateLocalColor updates the local button
|
// updateLocalColor updates the local button
|
||||||
void
|
void UIcolorEditor::updateLocalColor(const QColor c)
|
||||||
UIcolorEditor::updateLocalColor(const QColor c)
|
|
||||||
{
|
{
|
||||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||||
m_uiColor = c;
|
m_uiColor = c;
|
||||||
} else {
|
} else {
|
||||||
m_contrastColor = c;
|
m_contrastColor = c;
|
||||||
}
|
}
|
||||||
m_lastButtonPressed->setColor(c);
|
m_lastButtonPressed->setColor(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void UIcolorEditor::initColorWheel()
|
||||||
UIcolorEditor::initColorWheel()
|
|
||||||
{
|
{
|
||||||
m_colorWheel = new color_widgets::ColorWheel(this);
|
m_colorWheel = new color_widgets::ColorWheel(this);
|
||||||
connect(m_colorWheel,
|
connect(m_colorWheel,
|
||||||
&color_widgets::ColorWheel::mouseReleaseOnColor,
|
&color_widgets::ColorWheel::mouseReleaseOnColor,
|
||||||
this,
|
this,
|
||||||
&UIcolorEditor::updateUIcolor);
|
&UIcolorEditor::updateUIcolor);
|
||||||
connect(m_colorWheel,
|
connect(m_colorWheel,
|
||||||
&color_widgets::ColorWheel::colorChanged,
|
&color_widgets::ColorWheel::colorChanged,
|
||||||
this,
|
this,
|
||||||
&UIcolorEditor::updateLocalColor);
|
&UIcolorEditor::updateLocalColor);
|
||||||
|
|
||||||
const int size = GlobalValues::buttonBaseSize() * 3;
|
const int size = GlobalValues::buttonBaseSize() * 3;
|
||||||
m_colorWheel->setMinimumSize(size, size);
|
m_colorWheel->setMinimumSize(size, size);
|
||||||
m_colorWheel->setMaximumSize(size * 2, size * 2);
|
m_colorWheel->setMaximumSize(size * 2, size * 2);
|
||||||
m_colorWheel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
m_colorWheel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
m_colorWheel->setToolTip(tr("Change the color moving the selectors and see"
|
m_colorWheel->setToolTip(tr("Change the color moving the selectors and see"
|
||||||
" the changes in the preview buttons."));
|
" the changes in the preview buttons."));
|
||||||
|
|
||||||
m_hLayout->addWidget(m_colorWheel);
|
m_hLayout->addWidget(m_colorWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void UIcolorEditor::initButtons()
|
||||||
UIcolorEditor::initButtons()
|
|
||||||
{
|
{
|
||||||
const int extraSize = GlobalValues::buttonBaseSize() / 3;
|
const int extraSize = GlobalValues::buttonBaseSize() / 3;
|
||||||
int frameSize = GlobalValues::buttonBaseSize() + extraSize;
|
int frameSize = GlobalValues::buttonBaseSize() + extraSize;
|
||||||
|
|
||||||
m_vLayout->addWidget(new QLabel(tr("Select a Button to modify it"), this));
|
m_vLayout->addWidget(new QLabel(tr("Select a Button to modify it"), this));
|
||||||
|
|
||||||
QGroupBox* frame = new QGroupBox();
|
QGroupBox* frame = new QGroupBox();
|
||||||
frame->setFixedSize(frameSize, frameSize);
|
frame->setFixedSize(frameSize, frameSize);
|
||||||
|
|
||||||
m_buttonMainColor = new CaptureToolButton(m_buttonIconType, frame);
|
m_buttonMainColor = new CaptureToolButton(m_buttonIconType, frame);
|
||||||
m_buttonMainColor->move(m_buttonMainColor->x() + extraSize / 2,
|
m_buttonMainColor->move(m_buttonMainColor->x() + extraSize / 2,
|
||||||
m_buttonMainColor->y() + extraSize / 2);
|
m_buttonMainColor->y() + extraSize / 2);
|
||||||
QHBoxLayout* h1 = new QHBoxLayout();
|
QHBoxLayout* h1 = new QHBoxLayout();
|
||||||
h1->addWidget(frame);
|
h1->addWidget(frame);
|
||||||
m_labelMain = new ClickableLabel(tr("Main Color"), this);
|
m_labelMain = new ClickableLabel(tr("Main Color"), this);
|
||||||
h1->addWidget(m_labelMain);
|
h1->addWidget(m_labelMain);
|
||||||
m_vLayout->addLayout(h1);
|
m_vLayout->addLayout(h1);
|
||||||
|
|
||||||
m_buttonMainColor->setToolTip(tr("Click on this button to set the edition"
|
m_buttonMainColor->setToolTip(tr("Click on this button to set the edition"
|
||||||
" mode of the main color."));
|
" mode of the main color."));
|
||||||
|
|
||||||
QGroupBox* frame2 = new QGroupBox();
|
QGroupBox* frame2 = new QGroupBox();
|
||||||
m_buttonContrast = new CaptureToolButton(m_buttonIconType, frame2);
|
m_buttonContrast = new CaptureToolButton(m_buttonIconType, frame2);
|
||||||
m_buttonContrast->move(m_buttonContrast->x() + extraSize / 2,
|
m_buttonContrast->move(m_buttonContrast->x() + extraSize / 2,
|
||||||
m_buttonContrast->y() + extraSize / 2);
|
m_buttonContrast->y() + extraSize / 2);
|
||||||
|
|
||||||
QHBoxLayout* h2 = new QHBoxLayout();
|
QHBoxLayout* h2 = new QHBoxLayout();
|
||||||
h2->addWidget(frame2);
|
h2->addWidget(frame2);
|
||||||
frame2->setFixedSize(frameSize, frameSize);
|
frame2->setFixedSize(frameSize, frameSize);
|
||||||
m_labelContrast = new ClickableLabel(tr("Contrast Color"), this);
|
m_labelContrast = new ClickableLabel(tr("Contrast Color"), this);
|
||||||
m_labelContrast->setStyleSheet(QStringLiteral("color : gray"));
|
m_labelContrast->setStyleSheet(QStringLiteral("color : gray"));
|
||||||
h2->addWidget(m_labelContrast);
|
h2->addWidget(m_labelContrast);
|
||||||
m_vLayout->addLayout(h2);
|
m_vLayout->addLayout(h2);
|
||||||
|
|
||||||
m_buttonContrast->setToolTip(tr("Click on this button to set the edition"
|
m_buttonContrast->setToolTip(tr("Click on this button to set the edition"
|
||||||
" mode of the contrast color."));
|
" mode of the contrast color."));
|
||||||
|
|
||||||
connect(m_buttonMainColor,
|
connect(m_buttonMainColor,
|
||||||
&CaptureToolButton::pressedButton,
|
&CaptureToolButton::pressedButton,
|
||||||
this,
|
this,
|
||||||
&UIcolorEditor::changeLastButton);
|
&UIcolorEditor::changeLastButton);
|
||||||
connect(m_buttonContrast,
|
connect(m_buttonContrast,
|
||||||
&CaptureToolButton::pressedButton,
|
&CaptureToolButton::pressedButton,
|
||||||
this,
|
this,
|
||||||
&UIcolorEditor::changeLastButton);
|
&UIcolorEditor::changeLastButton);
|
||||||
// clicking the labels changes the button too
|
// clicking the labels changes the button too
|
||||||
connect(m_labelMain, &ClickableLabel::clicked, this, [this] {
|
connect(m_labelMain, &ClickableLabel::clicked, this, [this] {
|
||||||
changeLastButton(m_buttonMainColor);
|
changeLastButton(m_buttonMainColor);
|
||||||
});
|
});
|
||||||
connect(m_labelContrast, &ClickableLabel::clicked, this, [this] {
|
connect(m_labelContrast, &ClickableLabel::clicked, this, [this] {
|
||||||
changeLastButton(m_buttonContrast);
|
changeLastButton(m_buttonContrast);
|
||||||
});
|
});
|
||||||
m_lastButtonPressed = m_buttonMainColor;
|
m_lastButtonPressed = m_buttonMainColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// visual update for the selected button
|
// visual update for the selected button
|
||||||
void
|
void UIcolorEditor::changeLastButton(CaptureToolButton* b)
|
||||||
UIcolorEditor::changeLastButton(CaptureToolButton* b)
|
|
||||||
{
|
{
|
||||||
if (m_lastButtonPressed != b) {
|
if (m_lastButtonPressed != b) {
|
||||||
m_lastButtonPressed = b;
|
m_lastButtonPressed = b;
|
||||||
|
|
||||||
QString offStyle(QStringLiteral("QLabel { color : gray; }"));
|
QString offStyle(QStringLiteral("QLabel { color : gray; }"));
|
||||||
|
|
||||||
if (b == m_buttonMainColor) {
|
if (b == m_buttonMainColor) {
|
||||||
m_colorWheel->setColor(m_uiColor);
|
m_colorWheel->setColor(m_uiColor);
|
||||||
m_labelContrast->setStyleSheet(offStyle);
|
m_labelContrast->setStyleSheet(offStyle);
|
||||||
m_labelMain->setStyleSheet(styleSheet());
|
m_labelMain->setStyleSheet(styleSheet());
|
||||||
} else {
|
} else {
|
||||||
m_colorWheel->setColor(m_contrastColor);
|
m_colorWheel->setColor(m_contrastColor);
|
||||||
m_labelContrast->setStyleSheet(styleSheet());
|
m_labelContrast->setStyleSheet(styleSheet());
|
||||||
m_labelMain->setStyleSheet(offStyle);
|
m_labelMain->setStyleSheet(offStyle);
|
||||||
|
}
|
||||||
|
b->setIcon(b->icon());
|
||||||
}
|
}
|
||||||
b->setIcon(b->icon());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,33 +28,33 @@ class ClickableLabel;
|
|||||||
|
|
||||||
class UIcolorEditor : public QGroupBox
|
class UIcolorEditor : public QGroupBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit UIcolorEditor(QWidget* parent = nullptr);
|
explicit UIcolorEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateComponents();
|
void updateComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateUIcolor();
|
void updateUIcolor();
|
||||||
void updateLocalColor(const QColor);
|
void updateLocalColor(const QColor);
|
||||||
void changeLastButton(CaptureToolButton*);
|
void changeLastButton(CaptureToolButton*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QColor m_uiColor, m_contrastColor;
|
QColor m_uiColor, m_contrastColor;
|
||||||
CaptureToolButton* m_buttonMainColor;
|
CaptureToolButton* m_buttonMainColor;
|
||||||
ClickableLabel* m_labelMain;
|
ClickableLabel* m_labelMain;
|
||||||
CaptureToolButton* m_buttonContrast;
|
CaptureToolButton* m_buttonContrast;
|
||||||
ClickableLabel* m_labelContrast;
|
ClickableLabel* m_labelContrast;
|
||||||
CaptureToolButton* m_lastButtonPressed;
|
CaptureToolButton* m_lastButtonPressed;
|
||||||
color_widgets::ColorWheel* m_colorWheel;
|
color_widgets::ColorWheel* m_colorWheel;
|
||||||
|
|
||||||
static const CaptureToolButton::ButtonType m_buttonIconType =
|
static const CaptureToolButton::ButtonType m_buttonIconType =
|
||||||
CaptureToolButton::TYPE_CIRCLE;
|
CaptureToolButton::TYPE_CIRCLE;
|
||||||
|
|
||||||
QHBoxLayout* m_hLayout;
|
QHBoxLayout* m_hLayout;
|
||||||
QVBoxLayout* m_vLayout;
|
QVBoxLayout* m_vLayout;
|
||||||
|
|
||||||
void initColorWheel();
|
void initColorWheel();
|
||||||
void initButtons();
|
void initButtons();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,75 +27,71 @@
|
|||||||
VisualsEditor::VisualsEditor(QWidget* parent)
|
VisualsEditor::VisualsEditor(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
m_layout = new QVBoxLayout();
|
m_layout = new QVBoxLayout();
|
||||||
setLayout(m_layout);
|
setLayout(m_layout);
|
||||||
initWidgets();
|
initWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void VisualsEditor::updateComponents()
|
||||||
VisualsEditor::updateComponents()
|
|
||||||
{
|
{
|
||||||
m_buttonList->updateComponents();
|
m_buttonList->updateComponents();
|
||||||
m_colorEditor->updateComponents();
|
m_colorEditor->updateComponents();
|
||||||
int opacity = ConfigHandler().contrastOpacityValue();
|
int opacity = ConfigHandler().contrastOpacityValue();
|
||||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void VisualsEditor::initOpacitySlider()
|
||||||
VisualsEditor::initOpacitySlider()
|
|
||||||
{
|
{
|
||||||
m_opacitySlider = new ExtendedSlider();
|
m_opacitySlider = new ExtendedSlider();
|
||||||
m_opacitySlider->setFocusPolicy(Qt::NoFocus);
|
m_opacitySlider->setFocusPolicy(Qt::NoFocus);
|
||||||
m_opacitySlider->setOrientation(Qt::Horizontal);
|
m_opacitySlider->setOrientation(Qt::Horizontal);
|
||||||
m_opacitySlider->setRange(0, 100);
|
m_opacitySlider->setRange(0, 100);
|
||||||
connect(m_opacitySlider,
|
connect(m_opacitySlider,
|
||||||
&ExtendedSlider::modificationsEnded,
|
&ExtendedSlider::modificationsEnded,
|
||||||
this,
|
this,
|
||||||
&VisualsEditor::saveOpacity);
|
&VisualsEditor::saveOpacity);
|
||||||
QHBoxLayout* localLayout = new QHBoxLayout();
|
QHBoxLayout* localLayout = new QHBoxLayout();
|
||||||
localLayout->addWidget(new QLabel(QStringLiteral("0%")));
|
localLayout->addWidget(new QLabel(QStringLiteral("0%")));
|
||||||
localLayout->addWidget(m_opacitySlider);
|
localLayout->addWidget(m_opacitySlider);
|
||||||
localLayout->addWidget(new QLabel(QStringLiteral("100%")));
|
localLayout->addWidget(new QLabel(QStringLiteral("100%")));
|
||||||
|
|
||||||
QLabel* label = new QLabel();
|
QLabel* label = new QLabel();
|
||||||
QString labelMsg = tr("Opacity of area outside selection:") + " %1%";
|
QString labelMsg = tr("Opacity of area outside selection:") + " %1%";
|
||||||
connect(m_opacitySlider,
|
connect(m_opacitySlider,
|
||||||
&ExtendedSlider::valueChanged,
|
&ExtendedSlider::valueChanged,
|
||||||
this,
|
this,
|
||||||
[labelMsg, label](int val) { label->setText(labelMsg.arg(val)); });
|
[labelMsg, label](int val) { label->setText(labelMsg.arg(val)); });
|
||||||
m_layout->addWidget(label);
|
m_layout->addWidget(label);
|
||||||
m_layout->addLayout(localLayout);
|
m_layout->addLayout(localLayout);
|
||||||
|
|
||||||
int opacity = ConfigHandler().contrastOpacityValue();
|
int opacity = ConfigHandler().contrastOpacityValue();
|
||||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void VisualsEditor::saveOpacity()
|
||||||
VisualsEditor::saveOpacity()
|
|
||||||
{
|
{
|
||||||
int value = m_opacitySlider->mappedValue(0, 255);
|
int value = m_opacitySlider->mappedValue(0, 255);
|
||||||
ConfigHandler().setContrastOpacity(value);
|
ConfigHandler().setContrastOpacity(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void VisualsEditor::initWidgets()
|
||||||
VisualsEditor::initWidgets()
|
|
||||||
{
|
{
|
||||||
m_colorEditor = new UIcolorEditor();
|
m_colorEditor = new UIcolorEditor();
|
||||||
m_layout->addWidget(m_colorEditor);
|
m_layout->addWidget(m_colorEditor);
|
||||||
|
|
||||||
initOpacitySlider();
|
initOpacitySlider();
|
||||||
|
|
||||||
auto boxButtons = new QGroupBox();
|
auto boxButtons = new QGroupBox();
|
||||||
boxButtons->setTitle(tr("Button Selection"));
|
boxButtons->setTitle(tr("Button Selection"));
|
||||||
auto listLayout = new QVBoxLayout(boxButtons);
|
auto listLayout = new QVBoxLayout(boxButtons);
|
||||||
m_buttonList = new ButtonListView();
|
m_buttonList = new ButtonListView();
|
||||||
m_layout->addWidget(boxButtons);
|
m_layout->addWidget(boxButtons);
|
||||||
listLayout->addWidget(m_buttonList);
|
listLayout->addWidget(m_buttonList);
|
||||||
|
|
||||||
QPushButton* setAllButtons = new QPushButton(tr("Select All"));
|
QPushButton* setAllButtons = new QPushButton(tr("Select All"));
|
||||||
connect(setAllButtons,
|
connect(setAllButtons,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
m_buttonList,
|
m_buttonList,
|
||||||
&ButtonListView::selectAll);
|
&ButtonListView::selectAll);
|
||||||
listLayout->addWidget(setAllButtons);
|
listLayout->addWidget(setAllButtons);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,22 +26,22 @@ class UIcolorEditor;
|
|||||||
|
|
||||||
class VisualsEditor : public QWidget
|
class VisualsEditor : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VisualsEditor(QWidget* parent = nullptr);
|
explicit VisualsEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateComponents();
|
void updateComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void saveOpacity();
|
void saveOpacity();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
ButtonListView* m_buttonList;
|
ButtonListView* m_buttonList;
|
||||||
UIcolorEditor* m_colorEditor;
|
UIcolorEditor* m_colorEditor;
|
||||||
ExtendedSlider* m_opacitySlider;
|
ExtendedSlider* m_opacitySlider;
|
||||||
|
|
||||||
void initWidgets();
|
void initWidgets();
|
||||||
void initOpacitySlider();
|
void initOpacitySlider();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,72 +34,64 @@ CaptureRequest::CaptureRequest(CaptureRequest::CaptureMode mode,
|
|||||||
, m_id(0)
|
, m_id(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
void CaptureRequest::setStaticID(uint id)
|
||||||
CaptureRequest::setStaticID(uint id)
|
|
||||||
{
|
{
|
||||||
m_forcedID = true;
|
m_forcedID = true;
|
||||||
m_id = id;
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint
|
uint CaptureRequest::id() const
|
||||||
CaptureRequest::id() const
|
|
||||||
{
|
{
|
||||||
if (m_forcedID) {
|
if (m_forcedID) {
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
|
||||||
|
|
||||||
uint id = 0;
|
|
||||||
QVector<uint> v;
|
|
||||||
v << qHash(m_mode) << qHash(m_delay * QDateTime::currentMSecsSinceEpoch())
|
|
||||||
<< qHash(m_path) << qHash(m_tasks) << m_data.toInt();
|
|
||||||
for (uint i : v) {
|
|
||||||
id ^= i + 0x9e3779b9 + (id << 6) + (id >> 2);
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
CaptureRequest::CaptureMode
|
|
||||||
CaptureRequest::captureMode() const
|
|
||||||
{
|
|
||||||
return m_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint
|
|
||||||
CaptureRequest::delay() const
|
|
||||||
{
|
|
||||||
return m_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString
|
|
||||||
CaptureRequest::path() const
|
|
||||||
{
|
|
||||||
return m_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant
|
|
||||||
CaptureRequest::data() const
|
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CaptureRequest::addTask(CaptureRequest::ExportTask task)
|
|
||||||
{
|
|
||||||
m_tasks |= task;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CaptureRequest::exportCapture(const QPixmap& p)
|
|
||||||
{
|
|
||||||
if ((m_tasks & ExportTask::FILESYSTEM_SAVE_TASK) != ExportTask::NO_TASK) {
|
|
||||||
if (m_path.isEmpty()) {
|
|
||||||
ScreenshotSaver().saveToFilesystemGUI(p);
|
|
||||||
} else {
|
|
||||||
ScreenshotSaver().saveToFilesystem(p, m_path, "");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_tasks & ExportTask::CLIPBOARD_SAVE_TASK) != ExportTask::NO_TASK) {
|
uint id = 0;
|
||||||
ScreenshotSaver().saveToClipboard(p);
|
QVector<uint> v;
|
||||||
}
|
v << qHash(m_mode) << qHash(m_delay * QDateTime::currentMSecsSinceEpoch())
|
||||||
|
<< qHash(m_path) << qHash(m_tasks) << m_data.toInt();
|
||||||
|
for (uint i : v) {
|
||||||
|
id ^= i + 0x9e3779b9 + (id << 6) + (id >> 2);
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
CaptureRequest::CaptureMode CaptureRequest::captureMode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint CaptureRequest::delay() const
|
||||||
|
{
|
||||||
|
return m_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CaptureRequest::path() const
|
||||||
|
{
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CaptureRequest::data() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureRequest::addTask(CaptureRequest::ExportTask task)
|
||||||
|
{
|
||||||
|
m_tasks |= task;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureRequest::exportCapture(const QPixmap& p)
|
||||||
|
{
|
||||||
|
if ((m_tasks & ExportTask::FILESYSTEM_SAVE_TASK) != ExportTask::NO_TASK) {
|
||||||
|
if (m_path.isEmpty()) {
|
||||||
|
ScreenshotSaver().saveToFilesystemGUI(p);
|
||||||
|
} else {
|
||||||
|
ScreenshotSaver().saveToFilesystem(p, m_path, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_tasks & ExportTask::CLIPBOARD_SAVE_TASK) != ExportTask::NO_TASK) {
|
||||||
|
ScreenshotSaver().saveToClipboard(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,65 +24,62 @@
|
|||||||
class CaptureRequest
|
class CaptureRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum CaptureMode
|
enum CaptureMode
|
||||||
{
|
{
|
||||||
FULLSCREEN_MODE,
|
FULLSCREEN_MODE,
|
||||||
GRAPHICAL_MODE,
|
GRAPHICAL_MODE,
|
||||||
SCREEN_MODE,
|
SCREEN_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ExportTask
|
enum ExportTask
|
||||||
{
|
{
|
||||||
NO_TASK = 0,
|
NO_TASK = 0,
|
||||||
CLIPBOARD_SAVE_TASK = 1,
|
CLIPBOARD_SAVE_TASK = 1,
|
||||||
FILESYSTEM_SAVE_TASK = 2,
|
FILESYSTEM_SAVE_TASK = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
CaptureRequest(CaptureMode mode,
|
CaptureRequest(CaptureMode mode,
|
||||||
const uint delay = 0,
|
const uint delay = 0,
|
||||||
const QString& path = QLatin1String(""),
|
const QString& path = QLatin1String(""),
|
||||||
const QVariant& data = QVariant(),
|
const QVariant& data = QVariant(),
|
||||||
ExportTask tasks = NO_TASK);
|
ExportTask tasks = NO_TASK);
|
||||||
|
|
||||||
void setStaticID(uint id);
|
void setStaticID(uint id);
|
||||||
|
|
||||||
uint id() const;
|
uint id() const;
|
||||||
uint delay() const;
|
uint delay() const;
|
||||||
QString path() const;
|
QString path() const;
|
||||||
QVariant data() const;
|
QVariant data() const;
|
||||||
CaptureMode captureMode() const;
|
CaptureMode captureMode() const;
|
||||||
|
|
||||||
void addTask(ExportTask task);
|
void addTask(ExportTask task);
|
||||||
void exportCapture(const QPixmap& p);
|
void exportCapture(const QPixmap& p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CaptureMode m_mode;
|
CaptureMode m_mode;
|
||||||
uint m_delay;
|
uint m_delay;
|
||||||
QString m_path;
|
QString m_path;
|
||||||
ExportTask m_tasks;
|
ExportTask m_tasks;
|
||||||
QVariant m_data;
|
QVariant m_data;
|
||||||
|
|
||||||
bool m_forcedID;
|
bool m_forcedID;
|
||||||
uint m_id;
|
uint m_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
using eTask = CaptureRequest::ExportTask;
|
using eTask = CaptureRequest::ExportTask;
|
||||||
|
|
||||||
inline eTask
|
inline eTask operator|(const eTask& a, const eTask& b)
|
||||||
operator|(const eTask& a, const eTask& b)
|
|
||||||
{
|
{
|
||||||
return static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
return static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline eTask
|
inline eTask operator&(const eTask& a, const eTask& b)
|
||||||
operator&(const eTask& a, const eTask& b)
|
|
||||||
{
|
{
|
||||||
return static_cast<eTask>(static_cast<int>(a) & static_cast<int>(b));
|
return static_cast<eTask>(static_cast<int>(a) & static_cast<int>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline eTask&
|
inline eTask& operator|=(eTask& a, const eTask& b)
|
||||||
operator|=(eTask& a, const eTask& b)
|
|
||||||
{
|
{
|
||||||
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,279 +41,268 @@
|
|||||||
Controller::Controller()
|
Controller::Controller()
|
||||||
: m_captureWindow(nullptr)
|
: m_captureWindow(nullptr)
|
||||||
{
|
{
|
||||||
qApp->setQuitOnLastWindowClosed(false);
|
qApp->setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
// init tray icon
|
// init tray icon
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||||
if (!ConfigHandler().disabledTrayIconValue()) {
|
if (!ConfigHandler().disabledTrayIconValue()) {
|
||||||
enableTrayIcon();
|
enableTrayIcon();
|
||||||
}
|
}
|
||||||
#elif defined(Q_OS_WIN)
|
#elif defined(Q_OS_WIN)
|
||||||
enableTrayIcon();
|
enableTrayIcon();
|
||||||
|
|
||||||
GlobalShortcutFilter* nativeFilter = new GlobalShortcutFilter(this);
|
GlobalShortcutFilter* nativeFilter = new GlobalShortcutFilter(this);
|
||||||
qApp->installNativeEventFilter(nativeFilter);
|
qApp->installNativeEventFilter(nativeFilter);
|
||||||
connect(nativeFilter, &GlobalShortcutFilter::printPressed, this, [this]() {
|
connect(nativeFilter, &GlobalShortcutFilter::printPressed, this, [this]() {
|
||||||
this->requestCapture(CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
this->requestCapture(CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString StyleSheet = CaptureButton::globalStyleSheet();
|
QString StyleSheet = CaptureButton::globalStyleSheet();
|
||||||
qApp->setStyleSheet(StyleSheet);
|
qApp->setStyleSheet(StyleSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller*
|
Controller* Controller::getInstance()
|
||||||
Controller::getInstance()
|
|
||||||
{
|
{
|
||||||
static Controller c;
|
static Controller c;
|
||||||
return &c;
|
return &c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::enableExports()
|
||||||
Controller::enableExports()
|
|
||||||
{
|
{
|
||||||
connect(
|
connect(
|
||||||
this, &Controller::captureTaken, this, &Controller::handleCaptureTaken);
|
this, &Controller::captureTaken, this, &Controller::handleCaptureTaken);
|
||||||
connect(
|
connect(
|
||||||
this, &Controller::captureFailed, this, &Controller::handleCaptureFailed);
|
this, &Controller::captureFailed, this, &Controller::handleCaptureFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::requestCapture(const CaptureRequest& request)
|
||||||
Controller::requestCapture(const CaptureRequest& request)
|
|
||||||
{
|
{
|
||||||
uint id = request.id();
|
uint id = request.id();
|
||||||
m_requestMap.insert(id, request);
|
m_requestMap.insert(id, request);
|
||||||
|
|
||||||
switch (request.captureMode()) {
|
switch (request.captureMode()) {
|
||||||
case CaptureRequest::FULLSCREEN_MODE:
|
case CaptureRequest::FULLSCREEN_MODE:
|
||||||
doLater(request.delay(), this, [this, id]() {
|
doLater(request.delay(), this, [this, id]() {
|
||||||
this->startFullscreenCapture(id);
|
this->startFullscreenCapture(id);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
// TODO: Figure out the code path that gets here so the deprated warning can
|
// TODO: Figure out the code path that gets here so the deprated warning
|
||||||
// be fixed
|
// can be fixed
|
||||||
case CaptureRequest::SCREEN_MODE: {
|
case CaptureRequest::SCREEN_MODE: {
|
||||||
int&& number = request.data().toInt();
|
int&& number = request.data().toInt();
|
||||||
doLater(request.delay(), this, [this, id, number]() {
|
doLater(request.delay(), this, [this, id, number]() {
|
||||||
this->startScreenGrab(id, number);
|
this->startScreenGrab(id, number);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case CaptureRequest::GRAPHICAL_MODE: {
|
||||||
|
QString&& path = request.path();
|
||||||
|
doLater(request.delay(), this, [this, id, path]() {
|
||||||
|
this->startVisualCapture(id, path);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
emit captureFailed(id);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case CaptureRequest::GRAPHICAL_MODE: {
|
|
||||||
QString&& path = request.path();
|
|
||||||
doLater(request.delay(), this, [this, id, path]() {
|
|
||||||
this->startVisualCapture(id, path);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
emit captureFailed(id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// creation of a new capture in GUI mode
|
// creation of a new capture in GUI mode
|
||||||
void
|
void Controller::startVisualCapture(const uint id,
|
||||||
Controller::startVisualCapture(const uint id, const QString& forcedSavePath)
|
const QString& forcedSavePath)
|
||||||
{
|
{
|
||||||
if (!m_captureWindow) {
|
if (!m_captureWindow) {
|
||||||
QWidget* modalWidget = nullptr;
|
QWidget* modalWidget = nullptr;
|
||||||
do {
|
do {
|
||||||
modalWidget = qApp->activeModalWidget();
|
modalWidget = qApp->activeModalWidget();
|
||||||
if (modalWidget) {
|
if (modalWidget) {
|
||||||
modalWidget->close();
|
modalWidget->close();
|
||||||
modalWidget->deleteLater();
|
modalWidget->deleteLater();
|
||||||
}
|
}
|
||||||
} while (modalWidget);
|
} while (modalWidget);
|
||||||
|
|
||||||
m_captureWindow = new CaptureWidget(id, forcedSavePath);
|
m_captureWindow = new CaptureWidget(id, forcedSavePath);
|
||||||
// m_captureWindow = new CaptureWidget(id, forcedSavePath, false); // debug
|
// m_captureWindow = new CaptureWidget(id, forcedSavePath, false); //
|
||||||
connect(m_captureWindow,
|
// debug
|
||||||
&CaptureWidget::captureFailed,
|
connect(m_captureWindow,
|
||||||
this,
|
&CaptureWidget::captureFailed,
|
||||||
&Controller::captureFailed);
|
this,
|
||||||
connect(m_captureWindow,
|
&Controller::captureFailed);
|
||||||
&CaptureWidget::captureTaken,
|
connect(m_captureWindow,
|
||||||
this,
|
&CaptureWidget::captureTaken,
|
||||||
&Controller::captureTaken);
|
this,
|
||||||
|
&Controller::captureTaken);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
m_captureWindow->show();
|
m_captureWindow->show();
|
||||||
#else
|
#else
|
||||||
m_captureWindow->showFullScreen();
|
m_captureWindow->showFullScreen();
|
||||||
// m_captureWindow->show(); // Debug
|
// m_captureWindow->show(); // Debug
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
emit captureFailed(id);
|
emit captureFailed(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::startScreenGrab(const uint id, const int screenNumber)
|
||||||
Controller::startScreenGrab(const uint id, const int screenNumber)
|
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
int n = screenNumber;
|
int n = screenNumber;
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
QPoint globalCursorPos = QCursor::pos();
|
QPoint globalCursorPos = QCursor::pos();
|
||||||
n = qApp->desktop()->screenNumber(globalCursorPos);
|
n = qApp->desktop()->screenNumber(globalCursorPos);
|
||||||
}
|
}
|
||||||
QPixmap p(ScreenGrabber().grabScreen(n, ok));
|
QPixmap p(ScreenGrabber().grabScreen(n, ok));
|
||||||
if (ok) {
|
if (ok) {
|
||||||
emit captureTaken(id, p);
|
emit captureTaken(id, p);
|
||||||
} else {
|
} else {
|
||||||
emit captureFailed(id);
|
emit captureFailed(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// creation of the configuration window
|
// creation of the configuration window
|
||||||
void
|
void Controller::openConfigWindow()
|
||||||
Controller::openConfigWindow()
|
|
||||||
{
|
{
|
||||||
if (!m_configWindow) {
|
if (!m_configWindow) {
|
||||||
m_configWindow = new ConfigWindow();
|
m_configWindow = new ConfigWindow();
|
||||||
m_configWindow->show();
|
m_configWindow->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// creation of the window of information
|
// creation of the window of information
|
||||||
void
|
void Controller::openInfoWindow()
|
||||||
Controller::openInfoWindow()
|
|
||||||
{
|
{
|
||||||
if (!m_infoWindow) {
|
if (!m_infoWindow) {
|
||||||
m_infoWindow = new InfoWindow();
|
m_infoWindow = new InfoWindow();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Controller::openLauncherWindow()
|
|
||||||
{
|
|
||||||
if (!m_launcherWindow) {
|
|
||||||
m_launcherWindow = new CaptureLauncher();
|
|
||||||
}
|
|
||||||
m_launcherWindow->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Controller::enableTrayIcon()
|
|
||||||
{
|
|
||||||
if (m_trayIcon) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ConfigHandler().setDisabledTrayIcon(false);
|
|
||||||
QAction* captureAction = new QAction(tr("&Take Screenshot"), this);
|
|
||||||
connect(captureAction, &QAction::triggered, this, [this]() {
|
|
||||||
// Wait 400 ms to hide the QMenu
|
|
||||||
doLater(400, this, [this]() { this->startVisualCapture(); });
|
|
||||||
});
|
|
||||||
QAction* launcherAction = new QAction(tr("&Open Launcher"), this);
|
|
||||||
connect(
|
|
||||||
launcherAction, &QAction::triggered, this, &Controller::openLauncherWindow);
|
|
||||||
QAction* configAction = new QAction(tr("&Configuration"), this);
|
|
||||||
connect(
|
|
||||||
configAction, &QAction::triggered, this, &Controller::openConfigWindow);
|
|
||||||
QAction* infoAction = new QAction(tr("&About"), this);
|
|
||||||
connect(infoAction, &QAction::triggered, this, &Controller::openInfoWindow);
|
|
||||||
QAction* quitAction = new QAction(tr("&Quit"), this);
|
|
||||||
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
|
|
||||||
|
|
||||||
QMenu* trayIconMenu = new QMenu();
|
|
||||||
trayIconMenu->addAction(captureAction);
|
|
||||||
trayIconMenu->addAction(launcherAction);
|
|
||||||
trayIconMenu->addSeparator();
|
|
||||||
trayIconMenu->addAction(configAction);
|
|
||||||
trayIconMenu->addAction(infoAction);
|
|
||||||
trayIconMenu->addSeparator();
|
|
||||||
trayIconMenu->addAction(quitAction);
|
|
||||||
|
|
||||||
m_trayIcon = new QSystemTrayIcon();
|
|
||||||
m_trayIcon->setToolTip(QStringLiteral("Flameshot"));
|
|
||||||
m_trayIcon->setContextMenu(trayIconMenu);
|
|
||||||
QIcon trayicon =
|
|
||||||
QIcon::fromTheme("flameshot-tray", QIcon(":img/app/flameshot.png"));
|
|
||||||
m_trayIcon->setIcon(trayicon);
|
|
||||||
|
|
||||||
auto trayIconActivated = [this](QSystemTrayIcon::ActivationReason r) {
|
|
||||||
if (r == QSystemTrayIcon::Trigger) {
|
|
||||||
startVisualCapture();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
connect(m_trayIcon, &QSystemTrayIcon::activated, this, trayIconActivated);
|
|
||||||
m_trayIcon->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::openLauncherWindow()
|
||||||
Controller::disableTrayIcon()
|
{
|
||||||
|
if (!m_launcherWindow) {
|
||||||
|
m_launcherWindow = new CaptureLauncher();
|
||||||
|
}
|
||||||
|
m_launcherWindow->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::enableTrayIcon()
|
||||||
|
{
|
||||||
|
if (m_trayIcon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ConfigHandler().setDisabledTrayIcon(false);
|
||||||
|
QAction* captureAction = new QAction(tr("&Take Screenshot"), this);
|
||||||
|
connect(captureAction, &QAction::triggered, this, [this]() {
|
||||||
|
// Wait 400 ms to hide the QMenu
|
||||||
|
doLater(400, this, [this]() { this->startVisualCapture(); });
|
||||||
|
});
|
||||||
|
QAction* launcherAction = new QAction(tr("&Open Launcher"), this);
|
||||||
|
connect(launcherAction,
|
||||||
|
&QAction::triggered,
|
||||||
|
this,
|
||||||
|
&Controller::openLauncherWindow);
|
||||||
|
QAction* configAction = new QAction(tr("&Configuration"), this);
|
||||||
|
connect(
|
||||||
|
configAction, &QAction::triggered, this, &Controller::openConfigWindow);
|
||||||
|
QAction* infoAction = new QAction(tr("&About"), this);
|
||||||
|
connect(infoAction, &QAction::triggered, this, &Controller::openInfoWindow);
|
||||||
|
QAction* quitAction = new QAction(tr("&Quit"), this);
|
||||||
|
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
|
||||||
|
|
||||||
|
QMenu* trayIconMenu = new QMenu();
|
||||||
|
trayIconMenu->addAction(captureAction);
|
||||||
|
trayIconMenu->addAction(launcherAction);
|
||||||
|
trayIconMenu->addSeparator();
|
||||||
|
trayIconMenu->addAction(configAction);
|
||||||
|
trayIconMenu->addAction(infoAction);
|
||||||
|
trayIconMenu->addSeparator();
|
||||||
|
trayIconMenu->addAction(quitAction);
|
||||||
|
|
||||||
|
m_trayIcon = new QSystemTrayIcon();
|
||||||
|
m_trayIcon->setToolTip(QStringLiteral("Flameshot"));
|
||||||
|
m_trayIcon->setContextMenu(trayIconMenu);
|
||||||
|
QIcon trayicon =
|
||||||
|
QIcon::fromTheme("flameshot-tray", QIcon(":img/app/flameshot.png"));
|
||||||
|
m_trayIcon->setIcon(trayicon);
|
||||||
|
|
||||||
|
auto trayIconActivated = [this](QSystemTrayIcon::ActivationReason r) {
|
||||||
|
if (r == QSystemTrayIcon::Trigger) {
|
||||||
|
startVisualCapture();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connect(m_trayIcon, &QSystemTrayIcon::activated, this, trayIconActivated);
|
||||||
|
m_trayIcon->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::disableTrayIcon()
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||||
if (m_trayIcon) {
|
if (m_trayIcon) {
|
||||||
m_trayIcon->deleteLater();
|
m_trayIcon->deleteLater();
|
||||||
}
|
}
|
||||||
ConfigHandler().setDisabledTrayIcon(true);
|
ConfigHandler().setDisabledTrayIcon(true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::sendTrayNotification(const QString& text,
|
||||||
Controller::sendTrayNotification(const QString& text,
|
const QString& title,
|
||||||
const QString& title,
|
const int timeout)
|
||||||
const int timeout)
|
|
||||||
{
|
{
|
||||||
if (m_trayIcon) {
|
if (m_trayIcon) {
|
||||||
m_trayIcon->showMessage(title, text, QSystemTrayIcon::Information, timeout);
|
m_trayIcon->showMessage(
|
||||||
}
|
title, text, QSystemTrayIcon::Information, timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::updateConfigComponents()
|
||||||
Controller::updateConfigComponents()
|
|
||||||
{
|
{
|
||||||
if (m_configWindow) {
|
if (m_configWindow) {
|
||||||
m_configWindow->updateChildren();
|
m_configWindow->updateChildren();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::startFullscreenCapture(const uint id)
|
||||||
Controller::startFullscreenCapture(const uint id)
|
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
|
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
|
||||||
if (ok) {
|
if (ok) {
|
||||||
emit captureTaken(id, p);
|
emit captureTaken(id, p);
|
||||||
} else {
|
} else {
|
||||||
emit captureFailed(id);
|
emit captureFailed(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::handleCaptureTaken(uint id, QPixmap p)
|
||||||
Controller::handleCaptureTaken(uint id, QPixmap p)
|
|
||||||
{
|
{
|
||||||
auto it = m_requestMap.find(id);
|
auto it = m_requestMap.find(id);
|
||||||
if (it != m_requestMap.end()) {
|
if (it != m_requestMap.end()) {
|
||||||
it.value().exportCapture(p);
|
it.value().exportCapture(p);
|
||||||
m_requestMap.erase(it);
|
m_requestMap.erase(it);
|
||||||
}
|
}
|
||||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||||
QApplication::quit();
|
QApplication::quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::handleCaptureFailed(uint id)
|
||||||
Controller::handleCaptureFailed(uint id)
|
|
||||||
{
|
{
|
||||||
m_requestMap.remove(id);
|
m_requestMap.remove(id);
|
||||||
|
|
||||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||||
QApplication::quit();
|
QApplication::quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Controller::doLater(int msec, QObject* receiver, lambda func)
|
||||||
Controller::doLater(int msec, QObject* receiver, lambda func)
|
|
||||||
{
|
{
|
||||||
QTimer* timer = new QTimer(receiver);
|
QTimer* timer = new QTimer(receiver);
|
||||||
QObject::connect(timer, &QTimer::timeout, receiver, [timer, func]() {
|
QObject::connect(timer, &QTimer::timeout, receiver, [timer, func]() {
|
||||||
func();
|
func();
|
||||||
timer->deleteLater();
|
timer->deleteLater();
|
||||||
});
|
});
|
||||||
timer->setInterval(msec);
|
timer->setInterval(msec);
|
||||||
timer->start();
|
timer->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,55 +34,55 @@ using lambda = std::function<void(void)>;
|
|||||||
|
|
||||||
class Controller : public QObject
|
class Controller : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Controller* getInstance();
|
static Controller* getInstance();
|
||||||
|
|
||||||
Controller(const Controller&) = delete;
|
Controller(const Controller&) = delete;
|
||||||
void operator=(const Controller&) = delete;
|
void operator=(const Controller&) = delete;
|
||||||
|
|
||||||
void enableExports();
|
void enableExports();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void captureTaken(uint id, QPixmap p);
|
void captureTaken(uint id, QPixmap p);
|
||||||
void captureFailed(uint id);
|
void captureFailed(uint id);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void requestCapture(const CaptureRequest& request);
|
void requestCapture(const CaptureRequest& request);
|
||||||
|
|
||||||
void openConfigWindow();
|
void openConfigWindow();
|
||||||
void openInfoWindow();
|
void openInfoWindow();
|
||||||
void openLauncherWindow();
|
void openLauncherWindow();
|
||||||
void enableTrayIcon();
|
void enableTrayIcon();
|
||||||
void disableTrayIcon();
|
void disableTrayIcon();
|
||||||
void sendTrayNotification(
|
void sendTrayNotification(
|
||||||
const QString& text,
|
const QString& text,
|
||||||
const QString& title = QStringLiteral("Flameshot Info"),
|
const QString& title = QStringLiteral("Flameshot Info"),
|
||||||
const int timeout = 5000);
|
const int timeout = 5000);
|
||||||
|
|
||||||
void updateConfigComponents();
|
void updateConfigComponents();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startFullscreenCapture(const uint id = 0);
|
void startFullscreenCapture(const uint id = 0);
|
||||||
void startVisualCapture(const uint id = 0,
|
void startVisualCapture(const uint id = 0,
|
||||||
const QString& forcedSavePath = QString());
|
const QString& forcedSavePath = QString());
|
||||||
void startScreenGrab(const uint id = 0, const int screenNumber = -1);
|
void startScreenGrab(const uint id = 0, const int screenNumber = -1);
|
||||||
|
|
||||||
void handleCaptureTaken(uint id, QPixmap p);
|
void handleCaptureTaken(uint id, QPixmap p);
|
||||||
void handleCaptureFailed(uint id);
|
void handleCaptureFailed(uint id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Controller();
|
Controller();
|
||||||
|
|
||||||
// replace QTimer::singleShot introduced in Qt 5.4
|
// replace QTimer::singleShot introduced in Qt 5.4
|
||||||
// the actual target Qt version is 5.3
|
// the actual target Qt version is 5.3
|
||||||
void doLater(int msec, QObject* receiver, lambda func);
|
void doLater(int msec, QObject* receiver, lambda func);
|
||||||
|
|
||||||
QMap<uint, CaptureRequest> m_requestMap;
|
QMap<uint, CaptureRequest> m_requestMap;
|
||||||
QPointer<CaptureWidget> m_captureWindow;
|
QPointer<CaptureWidget> m_captureWindow;
|
||||||
QPointer<InfoWindow> m_infoWindow;
|
QPointer<InfoWindow> m_infoWindow;
|
||||||
QPointer<CaptureLauncher> m_launcherWindow;
|
QPointer<CaptureLauncher> m_launcherWindow;
|
||||||
QPointer<ConfigWindow> m_configWindow;
|
QPointer<ConfigWindow> m_configWindow;
|
||||||
QPointer<QSystemTrayIcon> m_trayIcon;
|
QPointer<QSystemTrayIcon> m_trayIcon;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,102 +25,94 @@
|
|||||||
FlameshotDBusAdapter::FlameshotDBusAdapter(QObject* parent)
|
FlameshotDBusAdapter::FlameshotDBusAdapter(QObject* parent)
|
||||||
: QDBusAbstractAdaptor(parent)
|
: QDBusAbstractAdaptor(parent)
|
||||||
{
|
{
|
||||||
auto controller = Controller::getInstance();
|
auto controller = Controller::getInstance();
|
||||||
connect(controller,
|
connect(controller,
|
||||||
&Controller::captureFailed,
|
&Controller::captureFailed,
|
||||||
this,
|
this,
|
||||||
&FlameshotDBusAdapter::captureFailed);
|
&FlameshotDBusAdapter::captureFailed);
|
||||||
connect(controller,
|
connect(controller,
|
||||||
&Controller::captureTaken,
|
&Controller::captureTaken,
|
||||||
this,
|
this,
|
||||||
&FlameshotDBusAdapter::handleCaptureTaken);
|
&FlameshotDBusAdapter::handleCaptureTaken);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlameshotDBusAdapter::~FlameshotDBusAdapter() {}
|
FlameshotDBusAdapter::~FlameshotDBusAdapter() {}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::graphicCapture(QString path, int delay, uint id)
|
||||||
FlameshotDBusAdapter::graphicCapture(QString path, int delay, uint id)
|
|
||||||
{
|
{
|
||||||
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, path);
|
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, path);
|
||||||
// if (toClipboard) {
|
// if (toClipboard) {
|
||||||
// req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
// req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||||
// }
|
// }
|
||||||
req.setStaticID(id);
|
req.setStaticID(id);
|
||||||
Controller::getInstance()->requestCapture(req);
|
Controller::getInstance()->requestCapture(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::fullScreen(QString path,
|
||||||
FlameshotDBusAdapter::fullScreen(QString path,
|
bool toClipboard,
|
||||||
bool toClipboard,
|
int delay,
|
||||||
int delay,
|
uint id)
|
||||||
uint id)
|
|
||||||
{
|
{
|
||||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, path);
|
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, path);
|
||||||
if (toClipboard) {
|
if (toClipboard) {
|
||||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||||
}
|
}
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||||
}
|
}
|
||||||
req.setStaticID(id);
|
req.setStaticID(id);
|
||||||
Controller::getInstance()->requestCapture(req);
|
Controller::getInstance()->requestCapture(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::openLauncher()
|
||||||
FlameshotDBusAdapter::openLauncher()
|
|
||||||
{
|
{
|
||||||
Controller::getInstance()->openLauncherWindow();
|
Controller::getInstance()->openLauncherWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::captureScreen(int number,
|
||||||
FlameshotDBusAdapter::captureScreen(int number,
|
QString path,
|
||||||
QString path,
|
bool toClipboard,
|
||||||
bool toClipboard,
|
int delay,
|
||||||
int delay,
|
uint id)
|
||||||
uint id)
|
|
||||||
{
|
{
|
||||||
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, path, number);
|
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, path, number);
|
||||||
if (toClipboard) {
|
if (toClipboard) {
|
||||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||||
}
|
}
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||||
}
|
}
|
||||||
req.setStaticID(id);
|
req.setStaticID(id);
|
||||||
Controller::getInstance()->requestCapture(req);
|
Controller::getInstance()->requestCapture(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::openConfig()
|
||||||
FlameshotDBusAdapter::openConfig()
|
|
||||||
{
|
{
|
||||||
Controller::getInstance()->openConfigWindow();
|
Controller::getInstance()->openConfigWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::trayIconEnabled(bool enabled)
|
||||||
FlameshotDBusAdapter::trayIconEnabled(bool enabled)
|
|
||||||
{
|
{
|
||||||
auto controller = Controller::getInstance();
|
auto controller = Controller::getInstance();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
controller->enableTrayIcon();
|
controller->enableTrayIcon();
|
||||||
} else {
|
} else {
|
||||||
controller->disableTrayIcon();
|
controller->disableTrayIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::autostartEnabled(bool enabled)
|
||||||
FlameshotDBusAdapter::autostartEnabled(bool enabled)
|
|
||||||
{
|
{
|
||||||
ConfigHandler().setStartupLaunch(enabled);
|
ConfigHandler().setStartupLaunch(enabled);
|
||||||
auto controller = Controller::getInstance();
|
auto controller = Controller::getInstance();
|
||||||
// Autostart is not saved in a .ini file, requires manual update
|
// Autostart is not saved in a .ini file, requires manual update
|
||||||
controller->updateConfigComponents();
|
controller->updateConfigComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap& p)
|
||||||
FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap& p)
|
|
||||||
{
|
{
|
||||||
QByteArray byteArray;
|
QByteArray byteArray;
|
||||||
QBuffer buffer(&byteArray);
|
QBuffer buffer(&byteArray);
|
||||||
p.save(&buffer, "PNG");
|
p.save(&buffer, "PNG");
|
||||||
emit captureTaken(id, byteArray);
|
emit captureTaken(id, byteArray);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,30 +22,33 @@
|
|||||||
|
|
||||||
class FlameshotDBusAdapter : public QDBusAbstractAdaptor
|
class FlameshotDBusAdapter : public QDBusAbstractAdaptor
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_CLASSINFO("D-Bus Interface", "org.flameshot.Flameshot")
|
Q_CLASSINFO("D-Bus Interface", "org.flameshot.Flameshot")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FlameshotDBusAdapter(QObject* parent = nullptr);
|
explicit FlameshotDBusAdapter(QObject* parent = nullptr);
|
||||||
virtual ~FlameshotDBusAdapter();
|
virtual ~FlameshotDBusAdapter();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void captureTaken(uint id, QByteArray rawImage);
|
void captureTaken(uint id, QByteArray rawImage);
|
||||||
void captureFailed(uint id);
|
void captureFailed(uint id);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_NOREPLY void graphicCapture(QString path, int delay, uint id);
|
Q_NOREPLY void graphicCapture(QString path, int delay, uint id);
|
||||||
Q_NOREPLY void fullScreen(QString path, bool toClipboard, int delay, uint id);
|
Q_NOREPLY void fullScreen(QString path,
|
||||||
Q_NOREPLY void captureScreen(int number,
|
bool toClipboard,
|
||||||
QString path,
|
int delay,
|
||||||
bool toClipboard,
|
uint id);
|
||||||
int delay,
|
Q_NOREPLY void captureScreen(int number,
|
||||||
uint id);
|
QString path,
|
||||||
Q_NOREPLY void openLauncher();
|
bool toClipboard,
|
||||||
Q_NOREPLY void openConfig();
|
int delay,
|
||||||
Q_NOREPLY void trayIconEnabled(bool enabled);
|
uint id);
|
||||||
Q_NOREPLY void autostartEnabled(bool enabled);
|
Q_NOREPLY void openLauncher();
|
||||||
|
Q_NOREPLY void openConfig();
|
||||||
|
Q_NOREPLY void trayIconEnabled(bool enabled);
|
||||||
|
Q_NOREPLY void autostartEnabled(bool enabled);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleCaptureTaken(uint id, const QPixmap& p);
|
void handleCaptureTaken(uint id, const QPixmap& p);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,30 +22,29 @@
|
|||||||
GlobalShortcutFilter::GlobalShortcutFilter(QObject* parent)
|
GlobalShortcutFilter::GlobalShortcutFilter(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
// Forced Print Screen
|
// Forced Print Screen
|
||||||
if (RegisterHotKey(NULL, 1, 0, VK_SNAPSHOT)) {
|
if (RegisterHotKey(NULL, 1, 0, VK_SNAPSHOT)) {
|
||||||
// ok
|
// ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool GlobalShortcutFilter::nativeEventFilter(const QByteArray& eventType,
|
||||||
GlobalShortcutFilter::nativeEventFilter(const QByteArray& eventType,
|
void* message,
|
||||||
void* message,
|
long* result)
|
||||||
long* result)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(eventType);
|
Q_UNUSED(eventType);
|
||||||
Q_UNUSED(result);
|
Q_UNUSED(result);
|
||||||
|
|
||||||
MSG* msg = static_cast<MSG*>(message);
|
MSG* msg = static_cast<MSG*>(message);
|
||||||
if (msg->message == WM_HOTKEY) {
|
if (msg->message == WM_HOTKEY) {
|
||||||
// const quint32 keycode = HIWORD(msg->lParam);
|
// const quint32 keycode = HIWORD(msg->lParam);
|
||||||
// const quint32 modifiers = LOWORD(msg->lParam);
|
// const quint32 modifiers = LOWORD(msg->lParam);
|
||||||
|
|
||||||
// TODO: this is just a temporal workwrround, proper global
|
// TODO: this is just a temporal workwrround, proper global
|
||||||
// support would need custom shortcuts defined by the user.
|
// support would need custom shortcuts defined by the user.
|
||||||
Controller::getInstance()->requestCapture(
|
Controller::getInstance()->requestCapture(
|
||||||
CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,20 +24,20 @@ class GlobalShortcutFilter
|
|||||||
: public QObject
|
: public QObject
|
||||||
, public QAbstractNativeEventFilter
|
, public QAbstractNativeEventFilter
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GlobalShortcutFilter(QObject* parent = nullptr);
|
explicit GlobalShortcutFilter(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool nativeEventFilter(const QByteArray& eventType,
|
bool nativeEventFilter(const QByteArray& eventType,
|
||||||
void* message,
|
void* message,
|
||||||
long* result);
|
long* result);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void printPressed();
|
void printPressed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
quint32 getNativeModifier(Qt::KeyboardModifiers modifiers);
|
quint32 getNativeModifier(Qt::KeyboardModifiers modifiers);
|
||||||
quint32 nativeKeycode(Qt::Key key);
|
quint32 nativeKeycode(Qt::Key key);
|
||||||
bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
|
bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||||
bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
|
bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||||
};
|
};
|
||||||
|
|||||||
811
src/main.cpp
811
src/main.cpp
@@ -37,431 +37,448 @@
|
|||||||
#include <QDBusMessage>
|
#include <QDBusMessage>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int main(int argc, char* argv[])
|
||||||
main(int argc, char* argv[])
|
|
||||||
{
|
{
|
||||||
// required for the button serialization
|
// required for the button serialization
|
||||||
// TODO: change to QVector in v1.0
|
// TODO: change to QVector in v1.0
|
||||||
qRegisterMetaTypeStreamOperators<QList<int>>("QList<int>");
|
qRegisterMetaTypeStreamOperators<QList<int>>("QList<int>");
|
||||||
qApp->setApplicationVersion(static_cast<QString>(APP_VERSION));
|
qApp->setApplicationVersion(static_cast<QString>(APP_VERSION));
|
||||||
|
|
||||||
// no arguments, just launch Flameshot
|
// no arguments, just launch Flameshot
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
SingleApplication app(argc, argv);
|
SingleApplication app(argc, argv);
|
||||||
|
|
||||||
QTranslator translator, qtTranslator;
|
QTranslator translator, qtTranslator;
|
||||||
QStringList trPaths = PathInfo::translationsPaths();
|
QStringList trPaths = PathInfo::translationsPaths();
|
||||||
|
|
||||||
for (const QString& path : trPaths) {
|
for (const QString& path : trPaths) {
|
||||||
bool match = translator.load(QLocale(),
|
bool match = translator.load(QLocale(),
|
||||||
QStringLiteral("Internationalization"),
|
QStringLiteral("Internationalization"),
|
||||||
QStringLiteral("_"),
|
QStringLiteral("_"),
|
||||||
path);
|
path);
|
||||||
if (match) {
|
if (match) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qtTranslator.load(QLocale::system(),
|
qtTranslator.load(
|
||||||
"qt",
|
QLocale::system(),
|
||||||
"_",
|
"qt",
|
||||||
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
"_",
|
||||||
|
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||||
|
|
||||||
app.installTranslator(&translator);
|
app.installTranslator(&translator);
|
||||||
app.installTranslator(&qtTranslator);
|
app.installTranslator(&qtTranslator);
|
||||||
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
||||||
app.setApplicationName(QStringLiteral("flameshot"));
|
app.setApplicationName(QStringLiteral("flameshot"));
|
||||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||||
|
|
||||||
auto c = Controller::getInstance();
|
auto c = Controller::getInstance();
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||||
new FlameshotDBusAdapter(c);
|
new FlameshotDBusAdapter(c);
|
||||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||||
if (!dbus.isConnected()) {
|
if (!dbus.isConnected()) {
|
||||||
SystemNotification().sendMessage(
|
SystemNotification().sendMessage(
|
||||||
QObject::tr("Unable to connect via DBus"));
|
QObject::tr("Unable to connect via DBus"));
|
||||||
}
|
}
|
||||||
dbus.registerObject(QStringLiteral("/"), c);
|
dbus.registerObject(QStringLiteral("/"), c);
|
||||||
dbus.registerService(QStringLiteral("org.flameshot.Flameshot"));
|
dbus.registerService(QStringLiteral("org.flameshot.Flameshot"));
|
||||||
#endif
|
#endif
|
||||||
// Exporting captures must be connected after the dbus interface
|
// Exporting captures must be connected after the dbus interface
|
||||||
// or the dbus signal gets blocked until we end the exports.
|
// or the dbus signal gets blocked until we end the exports.
|
||||||
c->enableExports();
|
c->enableExports();
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
/*--------------|
|
/*--------------|
|
||||||
* CLI parsing |
|
* CLI parsing |
|
||||||
* ------------*/
|
* ------------*/
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
app.setApplicationName(QStringLiteral("flameshot"));
|
app.setApplicationName(QStringLiteral("flameshot"));
|
||||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||||
app.setApplicationVersion(qApp->applicationVersion());
|
app.setApplicationVersion(qApp->applicationVersion());
|
||||||
CommandLineParser parser;
|
CommandLineParser parser;
|
||||||
// Add description
|
// Add description
|
||||||
parser.setDescription(
|
parser.setDescription(
|
||||||
QObject::tr("Powerful yet simple to use screenshot software."));
|
QObject::tr("Powerful yet simple to use screenshot software."));
|
||||||
parser.setGeneralErrorMessage(QObject::tr("See") + " flameshot --help.");
|
parser.setGeneralErrorMessage(QObject::tr("See") + " flameshot --help.");
|
||||||
// Arguments
|
// Arguments
|
||||||
CommandArgument fullArgument(QStringLiteral("full"),
|
CommandArgument fullArgument(QStringLiteral("full"),
|
||||||
QObject::tr("Capture the entire desktop."));
|
QObject::tr("Capture the entire desktop."));
|
||||||
CommandArgument launcherArgument(QStringLiteral("launcher"),
|
CommandArgument launcherArgument(QStringLiteral("launcher"),
|
||||||
QObject::tr("Open the capture launcher."));
|
QObject::tr("Open the capture launcher."));
|
||||||
CommandArgument guiArgument(
|
CommandArgument guiArgument(
|
||||||
QStringLiteral("gui"), QObject::tr("Start a manual capture in GUI mode."));
|
QStringLiteral("gui"),
|
||||||
CommandArgument configArgument(QStringLiteral("config"),
|
QObject::tr("Start a manual capture in GUI mode."));
|
||||||
QObject::tr("Configure") + " flameshot.");
|
CommandArgument configArgument(QStringLiteral("config"),
|
||||||
CommandArgument screenArgument(QStringLiteral("screen"),
|
QObject::tr("Configure") + " flameshot.");
|
||||||
QObject::tr("Capture a single screen."));
|
CommandArgument screenArgument(QStringLiteral("screen"),
|
||||||
|
QObject::tr("Capture a single screen."));
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
CommandOption pathOption({ "p", "path" },
|
CommandOption pathOption(
|
||||||
QObject::tr("Path where the capture will be saved"),
|
{ "p", "path" },
|
||||||
QStringLiteral("path"));
|
QObject::tr("Path where the capture will be saved"),
|
||||||
CommandOption clipboardOption(
|
QStringLiteral("path"));
|
||||||
{ "c", "clipboard" }, QObject::tr("Save the capture to the clipboard"));
|
CommandOption clipboardOption(
|
||||||
CommandOption delayOption({ "d", "delay" },
|
{ "c", "clipboard" }, QObject::tr("Save the capture to the clipboard"));
|
||||||
QObject::tr("Delay time in milliseconds"),
|
CommandOption delayOption({ "d", "delay" },
|
||||||
QStringLiteral("milliseconds"));
|
QObject::tr("Delay time in milliseconds"),
|
||||||
CommandOption filenameOption({ "f", "filename" },
|
QStringLiteral("milliseconds"));
|
||||||
QObject::tr("Set the filename pattern"),
|
CommandOption filenameOption({ "f", "filename" },
|
||||||
QStringLiteral("pattern"));
|
QObject::tr("Set the filename pattern"),
|
||||||
CommandOption trayOption({ "t", "trayicon" },
|
QStringLiteral("pattern"));
|
||||||
QObject::tr("Enable or disable the trayicon"),
|
CommandOption trayOption({ "t", "trayicon" },
|
||||||
QStringLiteral("bool"));
|
QObject::tr("Enable or disable the trayicon"),
|
||||||
CommandOption autostartOption({ "a", "autostart" },
|
QStringLiteral("bool"));
|
||||||
QObject::tr("Enable or disable run at startup"),
|
CommandOption autostartOption(
|
||||||
QStringLiteral("bool"));
|
{ "a", "autostart" },
|
||||||
CommandOption showHelpOption(
|
QObject::tr("Enable or disable run at startup"),
|
||||||
{ "s", "showhelp" },
|
QStringLiteral("bool"));
|
||||||
QObject::tr("Show the help message in the capture mode"),
|
CommandOption showHelpOption(
|
||||||
QStringLiteral("bool"));
|
{ "s", "showhelp" },
|
||||||
CommandOption mainColorOption({ "m", "maincolor" },
|
QObject::tr("Show the help message in the capture mode"),
|
||||||
QObject::tr("Define the main UI color"),
|
QStringLiteral("bool"));
|
||||||
QStringLiteral("color-code"));
|
CommandOption mainColorOption({ "m", "maincolor" },
|
||||||
CommandOption contrastColorOption({ "k", "contrastcolor" },
|
QObject::tr("Define the main UI color"),
|
||||||
QObject::tr("Define the contrast UI color"),
|
QStringLiteral("color-code"));
|
||||||
QStringLiteral("color-code"));
|
CommandOption contrastColorOption(
|
||||||
CommandOption rawImageOption({ "r", "raw" },
|
{ "k", "contrastcolor" },
|
||||||
QObject::tr("Print raw PNG capture"));
|
QObject::tr("Define the contrast UI color"),
|
||||||
CommandOption screenNumberOption(
|
QStringLiteral("color-code"));
|
||||||
{ "n", "number" },
|
CommandOption rawImageOption({ "r", "raw" },
|
||||||
QObject::tr("Define the screen to capture") + ",\n" +
|
QObject::tr("Print raw PNG capture"));
|
||||||
QObject::tr("default: screen containing the cursor"),
|
CommandOption screenNumberOption(
|
||||||
QObject::tr("Screen number"),
|
{ "n", "number" },
|
||||||
QStringLiteral("-1"));
|
QObject::tr("Define the screen to capture") + ",\n" +
|
||||||
|
QObject::tr("default: screen containing the cursor"),
|
||||||
|
QObject::tr("Screen number"),
|
||||||
|
QStringLiteral("-1"));
|
||||||
|
|
||||||
// Add checkers
|
// Add checkers
|
||||||
auto colorChecker = [](const QString& colorCode) -> bool {
|
auto colorChecker = [](const QString& colorCode) -> bool {
|
||||||
QColor parsedColor(colorCode);
|
QColor parsedColor(colorCode);
|
||||||
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
||||||
};
|
};
|
||||||
QString colorErr =
|
QString colorErr =
|
||||||
QObject::tr("Invalid color, "
|
QObject::tr("Invalid color, "
|
||||||
"this flag supports the following formats:\n"
|
"this flag supports the following formats:\n"
|
||||||
"- #RGB (each of R, G, and B is a single hex digit)\n"
|
"- #RGB (each of R, G, and B is a single hex digit)\n"
|
||||||
"- #RRGGBB\n- #RRRGGGBBB\n"
|
"- #RRGGBB\n- #RRRGGGBBB\n"
|
||||||
"- #RRRRGGGGBBBB\n"
|
"- #RRRRGGGGBBBB\n"
|
||||||
"- Named colors like 'blue' or 'red'\n"
|
"- Named colors like 'blue' or 'red'\n"
|
||||||
"You may need to escape the '#' sign as in '\\#FFF'");
|
"You may need to escape the '#' sign as in '\\#FFF'");
|
||||||
|
|
||||||
const QString delayErr =
|
const QString delayErr =
|
||||||
QObject::tr("Invalid delay, it must be higher than 0");
|
QObject::tr("Invalid delay, it must be higher than 0");
|
||||||
const QString numberErr =
|
const QString numberErr =
|
||||||
QObject::tr("Invalid screen number, it must be non negative");
|
QObject::tr("Invalid screen number, it must be non negative");
|
||||||
auto numericChecker = [](const QString& delayValue) -> bool {
|
auto numericChecker = [](const QString& delayValue) -> bool {
|
||||||
int value = delayValue.toInt();
|
int value = delayValue.toInt();
|
||||||
return value >= 0;
|
return value >= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString pathErr =
|
const QString pathErr =
|
||||||
QObject::tr("Invalid path, it must be a real path in the system");
|
QObject::tr("Invalid path, it must be a real path in the system");
|
||||||
auto pathChecker = [pathErr](const QString& pathValue) -> bool {
|
auto pathChecker = [pathErr](const QString& pathValue) -> bool {
|
||||||
bool res = QDir(pathValue).exists();
|
bool res = QDir(pathValue).exists();
|
||||||
if (!res) {
|
if (!res) {
|
||||||
SystemNotification().sendMessage(QObject::tr(pathErr.toLatin1().data()));
|
SystemNotification().sendMessage(
|
||||||
}
|
QObject::tr(pathErr.toLatin1().data()));
|
||||||
return res;
|
}
|
||||||
};
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
const QString booleanErr =
|
const QString booleanErr =
|
||||||
QObject::tr("Invalid value, it must be defined as 'true' or 'false'");
|
QObject::tr("Invalid value, it must be defined as 'true' or 'false'");
|
||||||
auto booleanChecker = [](const QString& value) -> bool {
|
auto booleanChecker = [](const QString& value) -> bool {
|
||||||
return value == QLatin1String("true") || value == QLatin1String("false");
|
return value == QLatin1String("true") ||
|
||||||
};
|
value == QLatin1String("false");
|
||||||
|
};
|
||||||
|
|
||||||
contrastColorOption.addChecker(colorChecker, colorErr);
|
contrastColorOption.addChecker(colorChecker, colorErr);
|
||||||
mainColorOption.addChecker(colorChecker, colorErr);
|
mainColorOption.addChecker(colorChecker, colorErr);
|
||||||
delayOption.addChecker(numericChecker, delayErr);
|
delayOption.addChecker(numericChecker, delayErr);
|
||||||
pathOption.addChecker(pathChecker, pathErr);
|
pathOption.addChecker(pathChecker, pathErr);
|
||||||
trayOption.addChecker(booleanChecker, booleanErr);
|
trayOption.addChecker(booleanChecker, booleanErr);
|
||||||
autostartOption.addChecker(booleanChecker, booleanErr);
|
autostartOption.addChecker(booleanChecker, booleanErr);
|
||||||
showHelpOption.addChecker(booleanChecker, booleanErr);
|
showHelpOption.addChecker(booleanChecker, booleanErr);
|
||||||
screenNumberOption.addChecker(numericChecker, numberErr);
|
screenNumberOption.addChecker(numericChecker, numberErr);
|
||||||
|
|
||||||
// Relationships
|
// Relationships
|
||||||
parser.AddArgument(guiArgument);
|
parser.AddArgument(guiArgument);
|
||||||
parser.AddArgument(screenArgument);
|
parser.AddArgument(screenArgument);
|
||||||
parser.AddArgument(fullArgument);
|
parser.AddArgument(fullArgument);
|
||||||
parser.AddArgument(launcherArgument);
|
parser.AddArgument(launcherArgument);
|
||||||
parser.AddArgument(configArgument);
|
parser.AddArgument(configArgument);
|
||||||
auto helpOption = parser.addHelpOption();
|
auto helpOption = parser.addHelpOption();
|
||||||
auto versionOption = parser.addVersionOption();
|
auto versionOption = parser.addVersionOption();
|
||||||
parser.AddOptions({ pathOption, delayOption, rawImageOption }, guiArgument);
|
parser.AddOptions({ pathOption, delayOption, rawImageOption }, guiArgument);
|
||||||
parser.AddOptions({ screenNumberOption,
|
parser.AddOptions({ screenNumberOption,
|
||||||
clipboardOption,
|
clipboardOption,
|
||||||
pathOption,
|
pathOption,
|
||||||
delayOption,
|
delayOption,
|
||||||
rawImageOption },
|
rawImageOption },
|
||||||
screenArgument);
|
screenArgument);
|
||||||
parser.AddOptions(
|
parser.AddOptions(
|
||||||
{ pathOption, clipboardOption, delayOption, rawImageOption }, fullArgument);
|
{ pathOption, clipboardOption, delayOption, rawImageOption },
|
||||||
parser.AddOptions({ autostartOption,
|
fullArgument);
|
||||||
filenameOption,
|
parser.AddOptions({ autostartOption,
|
||||||
trayOption,
|
filenameOption,
|
||||||
showHelpOption,
|
trayOption,
|
||||||
mainColorOption,
|
showHelpOption,
|
||||||
contrastColorOption },
|
mainColorOption,
|
||||||
configArgument);
|
contrastColorOption },
|
||||||
// Parse
|
configArgument);
|
||||||
if (!parser.parse(app.arguments())) {
|
// Parse
|
||||||
goto finish;
|
if (!parser.parse(app.arguments())) {
|
||||||
}
|
goto finish;
|
||||||
|
|
||||||
// PROCESS DATA
|
|
||||||
//--------------
|
|
||||||
if (parser.isSet(helpOption) || parser.isSet(versionOption)) {
|
|
||||||
} else if (parser.isSet(launcherArgument)) { // LAUNCHER
|
|
||||||
QDBusMessage m =
|
|
||||||
QDBusMessage::createMethodCall(QStringLiteral("org.flameshot.Flameshot"),
|
|
||||||
QStringLiteral("/"),
|
|
||||||
QLatin1String(""),
|
|
||||||
QStringLiteral("openLauncher"));
|
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
|
||||||
if (!sessionBus.isConnected()) {
|
|
||||||
SystemNotification().sendMessage(
|
|
||||||
QObject::tr("Unable to connect via DBus"));
|
|
||||||
}
|
|
||||||
sessionBus.call(m);
|
|
||||||
} else if (parser.isSet(guiArgument)) { // GUI
|
|
||||||
QString pathValue = parser.value(pathOption);
|
|
||||||
int delay = parser.value(delayOption).toInt();
|
|
||||||
bool isRaw = parser.isSet(rawImageOption);
|
|
||||||
DBusUtils dbusUtils;
|
|
||||||
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, pathValue);
|
|
||||||
uint id = req.id();
|
|
||||||
|
|
||||||
// Send message
|
|
||||||
QDBusMessage m =
|
|
||||||
QDBusMessage::createMethodCall(QStringLiteral("org.flameshot.Flameshot"),
|
|
||||||
QStringLiteral("/"),
|
|
||||||
QLatin1String(""),
|
|
||||||
QStringLiteral("graphicCapture"));
|
|
||||||
m << pathValue << delay << id;
|
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
|
||||||
dbusUtils.checkDBusConnection(sessionBus);
|
|
||||||
sessionBus.call(m);
|
|
||||||
|
|
||||||
if (isRaw) {
|
|
||||||
dbusUtils.connectPrintCapture(sessionBus, id);
|
|
||||||
QTimer t;
|
|
||||||
t.setInterval(delay + 1000 * 60 * 15); // 15 minutes timeout
|
|
||||||
QObject::connect(&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
|
||||||
t.start();
|
|
||||||
// wait
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
||||||
} else if (parser.isSet(fullArgument)) { // FULL
|
|
||||||
QString pathValue = parser.value(pathOption);
|
|
||||||
int delay = parser.value(delayOption).toInt();
|
|
||||||
bool toClipboard = parser.isSet(clipboardOption);
|
|
||||||
bool isRaw = parser.isSet(rawImageOption);
|
|
||||||
// Not a valid command
|
|
||||||
if (!isRaw && !toClipboard && pathValue.isEmpty()) {
|
|
||||||
QTextStream out(stdout);
|
|
||||||
out << "Invalid format, set where to save the content with one of "
|
|
||||||
<< "the following flags:\n "
|
|
||||||
<< pathOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
|
||||||
<< rawImageOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
|
||||||
<< clipboardOption.dashedNames().join(QStringLiteral(", ")) << "\n\n";
|
|
||||||
parser.parse(QStringList() << argv[0] << QStringLiteral("full")
|
|
||||||
<< QStringLiteral("-h"));
|
|
||||||
goto finish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
// PROCESS DATA
|
||||||
if (toClipboard) {
|
//--------------
|
||||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
if (parser.isSet(helpOption) || parser.isSet(versionOption)) {
|
||||||
}
|
} else if (parser.isSet(launcherArgument)) { // LAUNCHER
|
||||||
if (!pathValue.isEmpty()) {
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
}
|
QStringLiteral("/"),
|
||||||
uint id = req.id();
|
QLatin1String(""),
|
||||||
DBusUtils dbusUtils;
|
QStringLiteral("openLauncher"));
|
||||||
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
|
if (!sessionBus.isConnected()) {
|
||||||
|
SystemNotification().sendMessage(
|
||||||
|
QObject::tr("Unable to connect via DBus"));
|
||||||
|
}
|
||||||
|
sessionBus.call(m);
|
||||||
|
} else if (parser.isSet(guiArgument)) { // GUI
|
||||||
|
QString pathValue = parser.value(pathOption);
|
||||||
|
int delay = parser.value(delayOption).toInt();
|
||||||
|
bool isRaw = parser.isSet(rawImageOption);
|
||||||
|
DBusUtils dbusUtils;
|
||||||
|
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, pathValue);
|
||||||
|
uint id = req.id();
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
QDBusMessage m =
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
QDBusMessage::createMethodCall(QStringLiteral("org.flameshot.Flameshot"),
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
QStringLiteral("/"),
|
QStringLiteral("/"),
|
||||||
QLatin1String(""),
|
QLatin1String(""),
|
||||||
QStringLiteral("fullScreen"));
|
QStringLiteral("graphicCapture"));
|
||||||
m << pathValue << toClipboard << delay << id;
|
m << pathValue << delay << id;
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
dbusUtils.checkDBusConnection(sessionBus);
|
dbusUtils.checkDBusConnection(sessionBus);
|
||||||
sessionBus.call(m);
|
sessionBus.call(m);
|
||||||
|
|
||||||
if (isRaw) {
|
if (isRaw) {
|
||||||
dbusUtils.connectPrintCapture(sessionBus, id);
|
dbusUtils.connectPrintCapture(sessionBus, id);
|
||||||
// timeout just in case
|
QTimer t;
|
||||||
QTimer t;
|
t.setInterval(delay + 1000 * 60 * 15); // 15 minutes timeout
|
||||||
t.setInterval(delay + 2000);
|
QObject::connect(
|
||||||
QObject::connect(&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
||||||
t.start();
|
t.start();
|
||||||
// wait
|
// wait
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
} else if (parser.isSet(screenArgument)) { // SCREEN
|
} else if (parser.isSet(fullArgument)) { // FULL
|
||||||
QString numberStr = parser.value(screenNumberOption);
|
QString pathValue = parser.value(pathOption);
|
||||||
int number =
|
int delay = parser.value(delayOption).toInt();
|
||||||
numberStr.startsWith(QLatin1String("-")) ? -1 : numberStr.toInt();
|
bool toClipboard = parser.isSet(clipboardOption);
|
||||||
QString pathValue = parser.value(pathOption);
|
bool isRaw = parser.isSet(rawImageOption);
|
||||||
int delay = parser.value(delayOption).toInt();
|
// Not a valid command
|
||||||
bool toClipboard = parser.isSet(clipboardOption);
|
if (!isRaw && !toClipboard && pathValue.isEmpty()) {
|
||||||
bool isRaw = parser.isSet(rawImageOption);
|
QTextStream out(stdout);
|
||||||
// Not a valid command
|
out << "Invalid format, set where to save the content with one of "
|
||||||
if (!isRaw && !toClipboard && pathValue.isEmpty()) {
|
<< "the following flags:\n "
|
||||||
QTextStream out(stdout);
|
<< pathOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
||||||
out << "Invalid format, set where to save the content with one of "
|
<< rawImageOption.dashedNames().join(QStringLiteral(", "))
|
||||||
<< "the following flags:\n "
|
<< "\n "
|
||||||
<< pathOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
<< clipboardOption.dashedNames().join(QStringLiteral(", "))
|
||||||
<< rawImageOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
<< "\n\n";
|
||||||
<< clipboardOption.dashedNames().join(QStringLiteral(", ")) << "\n\n";
|
parser.parse(QStringList() << argv[0] << QStringLiteral("full")
|
||||||
parser.parse(QStringList() << argv[0] << QStringLiteral("screen")
|
<< QStringLiteral("-h"));
|
||||||
<< QStringLiteral("-h"));
|
goto finish;
|
||||||
goto finish;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, pathValue, number);
|
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
||||||
if (toClipboard) {
|
if (toClipboard) {
|
||||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||||
}
|
}
|
||||||
if (!pathValue.isEmpty()) {
|
if (!pathValue.isEmpty()) {
|
||||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||||
}
|
}
|
||||||
uint id = req.id();
|
uint id = req.id();
|
||||||
DBusUtils dbusUtils;
|
DBusUtils dbusUtils;
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
QDBusMessage m =
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
QDBusMessage::createMethodCall(QStringLiteral("org.flameshot.Flameshot"),
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
QStringLiteral("/"),
|
QStringLiteral("/"),
|
||||||
QLatin1String(""),
|
QLatin1String(""),
|
||||||
QStringLiteral("captureScreen"));
|
QStringLiteral("fullScreen"));
|
||||||
m << number << pathValue << toClipboard << delay << id;
|
m << pathValue << toClipboard << delay << id;
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
dbusUtils.checkDBusConnection(sessionBus);
|
dbusUtils.checkDBusConnection(sessionBus);
|
||||||
sessionBus.call(m);
|
sessionBus.call(m);
|
||||||
|
|
||||||
if (isRaw) {
|
if (isRaw) {
|
||||||
dbusUtils.connectPrintCapture(sessionBus, id);
|
dbusUtils.connectPrintCapture(sessionBus, id);
|
||||||
// timeout just in case
|
// timeout just in case
|
||||||
QTimer t;
|
QTimer t;
|
||||||
t.setInterval(delay + 2000);
|
t.setInterval(delay + 2000);
|
||||||
QObject::connect(&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
QObject::connect(
|
||||||
t.start();
|
&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
||||||
// wait
|
t.start();
|
||||||
return app.exec();
|
// wait
|
||||||
}
|
return app.exec();
|
||||||
} else if (parser.isSet(configArgument)) { // CONFIG
|
}
|
||||||
bool autostart = parser.isSet(autostartOption);
|
} else if (parser.isSet(screenArgument)) { // SCREEN
|
||||||
bool filename = parser.isSet(filenameOption);
|
QString numberStr = parser.value(screenNumberOption);
|
||||||
bool tray = parser.isSet(trayOption);
|
int number =
|
||||||
bool help = parser.isSet(showHelpOption);
|
numberStr.startsWith(QLatin1String("-")) ? -1 : numberStr.toInt();
|
||||||
bool mainColor = parser.isSet(mainColorOption);
|
QString pathValue = parser.value(pathOption);
|
||||||
bool contrastColor = parser.isSet(contrastColorOption);
|
int delay = parser.value(delayOption).toInt();
|
||||||
bool someFlagSet = (filename || tray || help || mainColor || contrastColor);
|
bool toClipboard = parser.isSet(clipboardOption);
|
||||||
ConfigHandler config;
|
bool isRaw = parser.isSet(rawImageOption);
|
||||||
if (autostart) {
|
// Not a valid command
|
||||||
QDBusMessage m = QDBusMessage::createMethodCall(
|
if (!isRaw && !toClipboard && pathValue.isEmpty()) {
|
||||||
QStringLiteral("org.flameshot.Flameshot"),
|
QTextStream out(stdout);
|
||||||
QStringLiteral("/"),
|
out << "Invalid format, set where to save the content with one of "
|
||||||
QLatin1String(""),
|
<< "the following flags:\n "
|
||||||
QStringLiteral("autostartEnabled"));
|
<< pathOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
||||||
if (parser.value(autostartOption) == QLatin1String("false")) {
|
<< rawImageOption.dashedNames().join(QStringLiteral(", "))
|
||||||
m << false;
|
<< "\n "
|
||||||
} else if (parser.value(autostartOption) == QLatin1String("true")) {
|
<< clipboardOption.dashedNames().join(QStringLiteral(", "))
|
||||||
m << true;
|
<< "\n\n";
|
||||||
}
|
parser.parse(QStringList() << argv[0] << QStringLiteral("screen")
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
<< QStringLiteral("-h"));
|
||||||
if (!sessionBus.isConnected()) {
|
goto finish;
|
||||||
SystemNotification().sendMessage(
|
}
|
||||||
QObject::tr("Unable to connect via DBus"));
|
|
||||||
}
|
|
||||||
sessionBus.call(m);
|
|
||||||
}
|
|
||||||
if (filename) {
|
|
||||||
QString newFilename(parser.value(filenameOption));
|
|
||||||
config.setFilenamePattern(newFilename);
|
|
||||||
FileNameHandler fh;
|
|
||||||
QTextStream(stdout) << QStringLiteral("The new pattern is '%1'\n"
|
|
||||||
"Parsed pattern example: %2\n")
|
|
||||||
.arg(newFilename)
|
|
||||||
.arg(fh.parsedPattern());
|
|
||||||
}
|
|
||||||
if (tray) {
|
|
||||||
QDBusMessage m = QDBusMessage::createMethodCall(
|
|
||||||
QStringLiteral("org.flameshot.Flameshot"),
|
|
||||||
QStringLiteral("/"),
|
|
||||||
QLatin1String(""),
|
|
||||||
QStringLiteral("trayIconEnabled"));
|
|
||||||
if (parser.value(trayOption) == QLatin1String("false")) {
|
|
||||||
m << false;
|
|
||||||
} else if (parser.value(trayOption) == QLatin1String("true")) {
|
|
||||||
m << true;
|
|
||||||
}
|
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
|
||||||
if (!sessionBus.isConnected()) {
|
|
||||||
SystemNotification().sendMessage(
|
|
||||||
QObject::tr("Unable to connect via DBus"));
|
|
||||||
}
|
|
||||||
sessionBus.call(m);
|
|
||||||
}
|
|
||||||
if (help) {
|
|
||||||
if (parser.value(showHelpOption) == QLatin1String("false")) {
|
|
||||||
config.setShowHelp(false);
|
|
||||||
} else if (parser.value(showHelpOption) == QLatin1String("true")) {
|
|
||||||
config.setShowHelp(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mainColor) {
|
|
||||||
QString colorCode = parser.value(mainColorOption);
|
|
||||||
QColor parsedColor(colorCode);
|
|
||||||
config.setUIMainColor(parsedColor);
|
|
||||||
}
|
|
||||||
if (contrastColor) {
|
|
||||||
QString colorCode = parser.value(contrastColorOption);
|
|
||||||
QColor parsedColor(colorCode);
|
|
||||||
config.setUIContrastColor(parsedColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open gui when no options
|
CaptureRequest req(
|
||||||
if (!someFlagSet) {
|
CaptureRequest::SCREEN_MODE, delay, pathValue, number);
|
||||||
QDBusMessage m = QDBusMessage::createMethodCall(
|
if (toClipboard) {
|
||||||
QStringLiteral("org.flameshot.Flameshot"),
|
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||||
QStringLiteral("/"),
|
}
|
||||||
QLatin1String(""),
|
if (!pathValue.isEmpty()) {
|
||||||
QStringLiteral("openConfig"));
|
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
}
|
||||||
if (!sessionBus.isConnected()) {
|
uint id = req.id();
|
||||||
SystemNotification().sendMessage(
|
DBusUtils dbusUtils;
|
||||||
QObject::tr("Unable to connect via DBus"));
|
|
||||||
}
|
// Send message
|
||||||
sessionBus.call(m);
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
|
QStringLiteral("/"),
|
||||||
|
QLatin1String(""),
|
||||||
|
QStringLiteral("captureScreen"));
|
||||||
|
m << number << pathValue << toClipboard << delay << id;
|
||||||
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
|
dbusUtils.checkDBusConnection(sessionBus);
|
||||||
|
sessionBus.call(m);
|
||||||
|
|
||||||
|
if (isRaw) {
|
||||||
|
dbusUtils.connectPrintCapture(sessionBus, id);
|
||||||
|
// timeout just in case
|
||||||
|
QTimer t;
|
||||||
|
t.setInterval(delay + 2000);
|
||||||
|
QObject::connect(
|
||||||
|
&t, &QTimer::timeout, qApp, &QCoreApplication::quit);
|
||||||
|
t.start();
|
||||||
|
// wait
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
} else if (parser.isSet(configArgument)) { // CONFIG
|
||||||
|
bool autostart = parser.isSet(autostartOption);
|
||||||
|
bool filename = parser.isSet(filenameOption);
|
||||||
|
bool tray = parser.isSet(trayOption);
|
||||||
|
bool help = parser.isSet(showHelpOption);
|
||||||
|
bool mainColor = parser.isSet(mainColorOption);
|
||||||
|
bool contrastColor = parser.isSet(contrastColorOption);
|
||||||
|
bool someFlagSet =
|
||||||
|
(filename || tray || help || mainColor || contrastColor);
|
||||||
|
ConfigHandler config;
|
||||||
|
if (autostart) {
|
||||||
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
|
QStringLiteral("/"),
|
||||||
|
QLatin1String(""),
|
||||||
|
QStringLiteral("autostartEnabled"));
|
||||||
|
if (parser.value(autostartOption) == QLatin1String("false")) {
|
||||||
|
m << false;
|
||||||
|
} else if (parser.value(autostartOption) == QLatin1String("true")) {
|
||||||
|
m << true;
|
||||||
|
}
|
||||||
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
|
if (!sessionBus.isConnected()) {
|
||||||
|
SystemNotification().sendMessage(
|
||||||
|
QObject::tr("Unable to connect via DBus"));
|
||||||
|
}
|
||||||
|
sessionBus.call(m);
|
||||||
|
}
|
||||||
|
if (filename) {
|
||||||
|
QString newFilename(parser.value(filenameOption));
|
||||||
|
config.setFilenamePattern(newFilename);
|
||||||
|
FileNameHandler fh;
|
||||||
|
QTextStream(stdout)
|
||||||
|
<< QStringLiteral("The new pattern is '%1'\n"
|
||||||
|
"Parsed pattern example: %2\n")
|
||||||
|
.arg(newFilename)
|
||||||
|
.arg(fh.parsedPattern());
|
||||||
|
}
|
||||||
|
if (tray) {
|
||||||
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
|
QStringLiteral("/"),
|
||||||
|
QLatin1String(""),
|
||||||
|
QStringLiteral("trayIconEnabled"));
|
||||||
|
if (parser.value(trayOption) == QLatin1String("false")) {
|
||||||
|
m << false;
|
||||||
|
} else if (parser.value(trayOption) == QLatin1String("true")) {
|
||||||
|
m << true;
|
||||||
|
}
|
||||||
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
|
if (!sessionBus.isConnected()) {
|
||||||
|
SystemNotification().sendMessage(
|
||||||
|
QObject::tr("Unable to connect via DBus"));
|
||||||
|
}
|
||||||
|
sessionBus.call(m);
|
||||||
|
}
|
||||||
|
if (help) {
|
||||||
|
if (parser.value(showHelpOption) == QLatin1String("false")) {
|
||||||
|
config.setShowHelp(false);
|
||||||
|
} else if (parser.value(showHelpOption) == QLatin1String("true")) {
|
||||||
|
config.setShowHelp(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mainColor) {
|
||||||
|
QString colorCode = parser.value(mainColorOption);
|
||||||
|
QColor parsedColor(colorCode);
|
||||||
|
config.setUIMainColor(parsedColor);
|
||||||
|
}
|
||||||
|
if (contrastColor) {
|
||||||
|
QString colorCode = parser.value(contrastColorOption);
|
||||||
|
QColor parsedColor(colorCode);
|
||||||
|
config.setUIContrastColor(parsedColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open gui when no options
|
||||||
|
if (!someFlagSet) {
|
||||||
|
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||||
|
QStringLiteral("org.flameshot.Flameshot"),
|
||||||
|
QStringLiteral("/"),
|
||||||
|
QLatin1String(""),
|
||||||
|
QStringLiteral("openConfig"));
|
||||||
|
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||||
|
if (!sessionBus.isConnected()) {
|
||||||
|
SystemNotification().sendMessage(
|
||||||
|
QObject::tr("Unable to connect via DBus"));
|
||||||
|
}
|
||||||
|
sessionBus.call(m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
finish:
|
finish:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,74 +21,63 @@ AbstractActionTool::AbstractActionTool(QObject* parent)
|
|||||||
: CaptureTool(parent)
|
: CaptureTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool AbstractActionTool::isValid() const
|
||||||
AbstractActionTool::isValid() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractActionTool::isSelectable() const
|
||||||
AbstractActionTool::isSelectable() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractActionTool::showMousePreview() const
|
||||||
AbstractActionTool::showMousePreview() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::undo(QPixmap& pixmap)
|
||||||
AbstractActionTool::undo(QPixmap& pixmap)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(pixmap);
|
Q_UNUSED(pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::process(QPainter& painter,
|
||||||
AbstractActionTool::process(QPainter& painter,
|
const QPixmap& pixmap,
|
||||||
const QPixmap& pixmap,
|
bool recordUndo)
|
||||||
bool recordUndo)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(painter);
|
Q_UNUSED(painter);
|
||||||
Q_UNUSED(pixmap);
|
Q_UNUSED(pixmap);
|
||||||
Q_UNUSED(recordUndo);
|
Q_UNUSED(recordUndo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::paintMousePreview(QPainter& painter,
|
||||||
AbstractActionTool::paintMousePreview(QPainter& painter,
|
const CaptureContext& context)
|
||||||
const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(painter);
|
Q_UNUSED(painter);
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::drawEnd(const QPoint& p)
|
||||||
AbstractActionTool::drawEnd(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::drawMove(const QPoint& p)
|
||||||
AbstractActionTool::drawMove(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::drawStart(const CaptureContext& context)
|
||||||
AbstractActionTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::colorChanged(const QColor& c)
|
||||||
AbstractActionTool::colorChanged(const QColor& c)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(c);
|
Q_UNUSED(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractActionTool::thicknessChanged(const int th)
|
||||||
AbstractActionTool::thicknessChanged(const int th)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(th);
|
Q_UNUSED(th);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,28 +21,28 @@
|
|||||||
|
|
||||||
class AbstractActionTool : public CaptureTool
|
class AbstractActionTool : public CaptureTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AbstractActionTool(QObject* parent = nullptr);
|
explicit AbstractActionTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
bool isSelectable() const override;
|
bool isSelectable() const override;
|
||||||
bool showMousePreview() const override;
|
bool showMousePreview() const override;
|
||||||
|
|
||||||
void undo(QPixmap& pixmap) override;
|
void undo(QPixmap& pixmap) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ToolType nameID() const = 0;
|
virtual ToolType nameID() const = 0;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawEnd(const QPoint& p) override;
|
void drawEnd(const QPoint& p) override;
|
||||||
void drawMove(const QPoint& p) override;
|
void drawMove(const QPoint& p) override;
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void colorChanged(const QColor& c) override;
|
void colorChanged(const QColor& c) override;
|
||||||
void thicknessChanged(const int th) override;
|
void thicknessChanged(const int th) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,83 +23,72 @@ AbstractPathTool::AbstractPathTool(QObject* parent)
|
|||||||
, m_padding(0)
|
, m_padding(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool AbstractPathTool::isValid() const
|
||||||
AbstractPathTool::isValid() const
|
|
||||||
{
|
{
|
||||||
return m_points.length() > 1;
|
return m_points.length() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractPathTool::closeOnButtonPressed() const
|
||||||
AbstractPathTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractPathTool::isSelectable() const
|
||||||
AbstractPathTool::isSelectable() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractPathTool::showMousePreview() const
|
||||||
AbstractPathTool::showMousePreview() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::undo(QPixmap& pixmap)
|
||||||
AbstractPathTool::undo(QPixmap& pixmap)
|
|
||||||
{
|
{
|
||||||
QPainter p(&pixmap);
|
QPainter p(&pixmap);
|
||||||
const int val = m_thickness + m_padding;
|
const int val = m_thickness + m_padding;
|
||||||
QRect area = m_backupArea + QMargins(val, val, val, val);
|
QRect area = m_backupArea + QMargins(val, val, val, val);
|
||||||
p.drawPixmap(area.intersected(pixmap.rect()).topLeft(), m_pixmapBackup);
|
p.drawPixmap(area.intersected(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::drawEnd(const QPoint& p)
|
||||||
AbstractPathTool::drawEnd(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(p);
|
Q_UNUSED(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::drawMove(const QPoint& p)
|
||||||
AbstractPathTool::drawMove(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
addPoint(p);
|
addPoint(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::colorChanged(const QColor& c)
|
||||||
AbstractPathTool::colorChanged(const QColor& c)
|
|
||||||
{
|
{
|
||||||
m_color = c;
|
m_color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::thicknessChanged(const int th)
|
||||||
AbstractPathTool::thicknessChanged(const int th)
|
|
||||||
{
|
{
|
||||||
m_thickness = th;
|
m_thickness = th;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::updateBackup(const QPixmap& pixmap)
|
||||||
AbstractPathTool::updateBackup(const QPixmap& pixmap)
|
|
||||||
{
|
{
|
||||||
const int val = m_thickness + m_padding;
|
const int val = m_thickness + m_padding;
|
||||||
QRect area = m_backupArea.normalized() + QMargins(val, val, val, val);
|
QRect area = m_backupArea.normalized() + QMargins(val, val, val, val);
|
||||||
m_pixmapBackup = pixmap.copy(area);
|
m_pixmapBackup = pixmap.copy(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractPathTool::addPoint(const QPoint& point)
|
||||||
AbstractPathTool::addPoint(const QPoint& point)
|
|
||||||
{
|
{
|
||||||
if (m_backupArea.left() > point.x()) {
|
if (m_backupArea.left() > point.x()) {
|
||||||
m_backupArea.setLeft(point.x());
|
m_backupArea.setLeft(point.x());
|
||||||
} else if (m_backupArea.right() < point.x()) {
|
} else if (m_backupArea.right() < point.x()) {
|
||||||
m_backupArea.setRight(point.x());
|
m_backupArea.setRight(point.x());
|
||||||
}
|
}
|
||||||
if (m_backupArea.top() > point.y()) {
|
if (m_backupArea.top() > point.y()) {
|
||||||
m_backupArea.setTop(point.y());
|
m_backupArea.setTop(point.y());
|
||||||
} else if (m_backupArea.bottom() < point.y()) {
|
} else if (m_backupArea.bottom() < point.y()) {
|
||||||
m_backupArea.setBottom(point.y());
|
m_backupArea.setBottom(point.y());
|
||||||
}
|
}
|
||||||
m_points.append(point);
|
m_points.append(point);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,34 +21,34 @@
|
|||||||
|
|
||||||
class AbstractPathTool : public CaptureTool
|
class AbstractPathTool : public CaptureTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AbstractPathTool(QObject* parent = nullptr);
|
explicit AbstractPathTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
bool closeOnButtonPressed() const override;
|
bool closeOnButtonPressed() const override;
|
||||||
bool isSelectable() const override;
|
bool isSelectable() const override;
|
||||||
bool showMousePreview() const override;
|
bool showMousePreview() const override;
|
||||||
|
|
||||||
void undo(QPixmap& pixmap) override;
|
void undo(QPixmap& pixmap) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawEnd(const QPoint& p) override;
|
void drawEnd(const QPoint& p) override;
|
||||||
void drawMove(const QPoint& p) override;
|
void drawMove(const QPoint& p) override;
|
||||||
void colorChanged(const QColor& c) override;
|
void colorChanged(const QColor& c) override;
|
||||||
void thicknessChanged(const int th) override;
|
void thicknessChanged(const int th) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateBackup(const QPixmap& pixmap);
|
void updateBackup(const QPixmap& pixmap);
|
||||||
void addPoint(const QPoint& point);
|
void addPoint(const QPoint& point);
|
||||||
|
|
||||||
virtual ToolType nameID() const = 0;
|
virtual ToolType nameID() const = 0;
|
||||||
|
|
||||||
QPixmap m_pixmapBackup;
|
QPixmap m_pixmapBackup;
|
||||||
QRect m_backupArea;
|
QRect m_backupArea;
|
||||||
QColor m_color;
|
QColor m_color;
|
||||||
QVector<QPoint> m_points;
|
QVector<QPoint> m_points;
|
||||||
int m_thickness;
|
int m_thickness;
|
||||||
// use m_padding to extend the area of the backup
|
// use m_padding to extend the area of the backup
|
||||||
int m_padding;
|
int m_padding;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ const int DIRS_NUMBER = 4;
|
|||||||
|
|
||||||
enum UNIT
|
enum UNIT
|
||||||
{
|
{
|
||||||
HORIZ_DIR = 0,
|
HORIZ_DIR = 0,
|
||||||
DIAG1_DIR = 1,
|
DIAG1_DIR = 1,
|
||||||
VERT_DIR = 2,
|
VERT_DIR = 2,
|
||||||
DIAG2_DIR = 3
|
DIAG2_DIR = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
const double ADJ_DIAG_UNIT = 2 * ADJ_UNIT;
|
const double ADJ_DIAG_UNIT = 2 * ADJ_UNIT;
|
||||||
@@ -36,8 +36,8 @@ const int DIAG_DIRS_NUMBER = 2;
|
|||||||
|
|
||||||
enum DIAG_UNIT
|
enum DIAG_UNIT
|
||||||
{
|
{
|
||||||
DIR1 = 0,
|
DIR1 = 0,
|
||||||
DIR2 = 1
|
DIR2 = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -48,123 +48,111 @@ AbstractTwoPointTool::AbstractTwoPointTool(QObject* parent)
|
|||||||
, m_padding(0)
|
, m_padding(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool AbstractTwoPointTool::isValid() const
|
||||||
AbstractTwoPointTool::isValid() const
|
|
||||||
{
|
{
|
||||||
return (m_points.first != m_points.second);
|
return (m_points.first != m_points.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractTwoPointTool::closeOnButtonPressed() const
|
||||||
AbstractTwoPointTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractTwoPointTool::isSelectable() const
|
||||||
AbstractTwoPointTool::isSelectable() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool AbstractTwoPointTool::showMousePreview() const
|
||||||
AbstractTwoPointTool::showMousePreview() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AbstractTwoPointTool::undo(QPixmap& pixmap)
|
||||||
AbstractTwoPointTool::undo(QPixmap& pixmap)
|
|
||||||
{
|
{
|
||||||
QPainter p(&pixmap);
|
QPainter p(&pixmap);
|
||||||
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||||
if (this->nameID() == ToolType::CIRCLECOUNT) {
|
if (this->nameID() == ToolType::CIRCLECOUNT) {
|
||||||
emit requestAction(REQ_DECREMENT_CIRCLE_COUNT);
|
emit requestAction(REQ_DECREMENT_CIRCLE_COUNT);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::drawEnd(const QPoint& p)
|
|
||||||
{
|
|
||||||
Q_UNUSED(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::drawMove(const QPoint& p)
|
|
||||||
{
|
|
||||||
m_points.second = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::drawMoveWithAdjustment(const QPoint& p)
|
|
||||||
{
|
|
||||||
m_points.second = m_points.first + adjustedVector(p - m_points.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::colorChanged(const QColor& c)
|
|
||||||
{
|
|
||||||
m_color = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::thicknessChanged(const int th)
|
|
||||||
{
|
|
||||||
m_thickness = th;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AbstractTwoPointTool::updateBackup(const QPixmap& pixmap)
|
|
||||||
{
|
|
||||||
m_pixmapBackup = pixmap.copy(backupRect(pixmap.rect()));
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect
|
|
||||||
AbstractTwoPointTool::backupRect(const QRect& limits) const
|
|
||||||
{
|
|
||||||
QRect r = QRect(m_points.first, m_points.second).normalized();
|
|
||||||
const int val = m_thickness + m_padding;
|
|
||||||
r += QMargins(val, val, val, val);
|
|
||||||
return r.intersected(limits);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint
|
|
||||||
AbstractTwoPointTool::adjustedVector(QPoint v) const
|
|
||||||
{
|
|
||||||
if (m_supportsOrthogonalAdj && m_supportsDiagonalAdj) {
|
|
||||||
int dir =
|
|
||||||
(static_cast<int>(round(atan2(-v.y(), v.x()) / ADJ_UNIT)) + DIRS_NUMBER) %
|
|
||||||
DIRS_NUMBER;
|
|
||||||
if (dir == UNIT::HORIZ_DIR) {
|
|
||||||
v.setY(0);
|
|
||||||
} else if (dir == UNIT::VERT_DIR) {
|
|
||||||
v.setX(0);
|
|
||||||
} else if (dir == UNIT::DIAG1_DIR) {
|
|
||||||
int newX = (v.x() - v.y()) / 2;
|
|
||||||
int newY = -newX;
|
|
||||||
v.setX(newX);
|
|
||||||
v.setY(newY);
|
|
||||||
} else {
|
|
||||||
int newX = (v.x() + v.y()) / 2;
|
|
||||||
int newY = newX;
|
|
||||||
v.setX(newX);
|
|
||||||
v.setY(newY);
|
|
||||||
}
|
}
|
||||||
} else if (m_supportsDiagonalAdj) {
|
}
|
||||||
int dir = (static_cast<int>(round(
|
|
||||||
(atan2(-v.y(), v.x()) - ADJ_DIAG_UNIT / 2) / ADJ_DIAG_UNIT)) +
|
void AbstractTwoPointTool::drawEnd(const QPoint& p)
|
||||||
DIAG_DIRS_NUMBER) %
|
{
|
||||||
DIAG_DIRS_NUMBER;
|
Q_UNUSED(p);
|
||||||
if (dir == DIAG_UNIT::DIR1) {
|
}
|
||||||
int newX = (v.x() - v.y()) / 2;
|
|
||||||
int newY = -newX;
|
void AbstractTwoPointTool::drawMove(const QPoint& p)
|
||||||
v.setX(newX);
|
{
|
||||||
v.setY(newY);
|
m_points.second = p;
|
||||||
} else {
|
}
|
||||||
int newX = (v.x() + v.y()) / 2;
|
|
||||||
int newY = newX;
|
void AbstractTwoPointTool::drawMoveWithAdjustment(const QPoint& p)
|
||||||
v.setX(newX);
|
{
|
||||||
v.setY(newY);
|
m_points.second = m_points.first + adjustedVector(p - m_points.first);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return v;
|
void AbstractTwoPointTool::colorChanged(const QColor& c)
|
||||||
|
{
|
||||||
|
m_color = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTwoPointTool::thicknessChanged(const int th)
|
||||||
|
{
|
||||||
|
m_thickness = th;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTwoPointTool::updateBackup(const QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
m_pixmapBackup = pixmap.copy(backupRect(pixmap.rect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect AbstractTwoPointTool::backupRect(const QRect& limits) const
|
||||||
|
{
|
||||||
|
QRect r = QRect(m_points.first, m_points.second).normalized();
|
||||||
|
const int val = m_thickness + m_padding;
|
||||||
|
r += QMargins(val, val, val, val);
|
||||||
|
return r.intersected(limits);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint AbstractTwoPointTool::adjustedVector(QPoint v) const
|
||||||
|
{
|
||||||
|
if (m_supportsOrthogonalAdj && m_supportsDiagonalAdj) {
|
||||||
|
int dir = (static_cast<int>(round(atan2(-v.y(), v.x()) / ADJ_UNIT)) +
|
||||||
|
DIRS_NUMBER) %
|
||||||
|
DIRS_NUMBER;
|
||||||
|
if (dir == UNIT::HORIZ_DIR) {
|
||||||
|
v.setY(0);
|
||||||
|
} else if (dir == UNIT::VERT_DIR) {
|
||||||
|
v.setX(0);
|
||||||
|
} else if (dir == UNIT::DIAG1_DIR) {
|
||||||
|
int newX = (v.x() - v.y()) / 2;
|
||||||
|
int newY = -newX;
|
||||||
|
v.setX(newX);
|
||||||
|
v.setY(newY);
|
||||||
|
} else {
|
||||||
|
int newX = (v.x() + v.y()) / 2;
|
||||||
|
int newY = newX;
|
||||||
|
v.setX(newX);
|
||||||
|
v.setY(newY);
|
||||||
|
}
|
||||||
|
} else if (m_supportsDiagonalAdj) {
|
||||||
|
int dir =
|
||||||
|
(static_cast<int>(round((atan2(-v.y(), v.x()) - ADJ_DIAG_UNIT / 2) /
|
||||||
|
ADJ_DIAG_UNIT)) +
|
||||||
|
DIAG_DIRS_NUMBER) %
|
||||||
|
DIAG_DIRS_NUMBER;
|
||||||
|
if (dir == DIAG_UNIT::DIR1) {
|
||||||
|
int newX = (v.x() - v.y()) / 2;
|
||||||
|
int newY = -newX;
|
||||||
|
v.setX(newX);
|
||||||
|
v.setY(newY);
|
||||||
|
} else {
|
||||||
|
int newX = (v.x() + v.y()) / 2;
|
||||||
|
int newY = newX;
|
||||||
|
v.setX(newX);
|
||||||
|
v.setY(newY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,40 +21,40 @@
|
|||||||
|
|
||||||
class AbstractTwoPointTool : public CaptureTool
|
class AbstractTwoPointTool : public CaptureTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AbstractTwoPointTool(QObject* parent = nullptr);
|
explicit AbstractTwoPointTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
bool closeOnButtonPressed() const override;
|
bool closeOnButtonPressed() const override;
|
||||||
bool isSelectable() const override;
|
bool isSelectable() const override;
|
||||||
bool showMousePreview() const override;
|
bool showMousePreview() const override;
|
||||||
|
|
||||||
void undo(QPixmap& pixmap) override;
|
void undo(QPixmap& pixmap) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawEnd(const QPoint& p) override;
|
void drawEnd(const QPoint& p) override;
|
||||||
void drawMove(const QPoint& p) override;
|
void drawMove(const QPoint& p) override;
|
||||||
void drawMoveWithAdjustment(const QPoint& p) override;
|
void drawMoveWithAdjustment(const QPoint& p) override;
|
||||||
void colorChanged(const QColor& c) override;
|
void colorChanged(const QColor& c) override;
|
||||||
void thicknessChanged(const int th) override;
|
void thicknessChanged(const int th) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateBackup(const QPixmap& pixmap);
|
void updateBackup(const QPixmap& pixmap);
|
||||||
QRect backupRect(const QRect& limits) const;
|
QRect backupRect(const QRect& limits) const;
|
||||||
|
|
||||||
QPixmap m_pixmapBackup;
|
QPixmap m_pixmapBackup;
|
||||||
QPair<QPoint, QPoint> m_points;
|
QPair<QPoint, QPoint> m_points;
|
||||||
QColor m_color;
|
QColor m_color;
|
||||||
int m_thickness;
|
int m_thickness;
|
||||||
// use m_padding to extend the area of the backup
|
// use m_padding to extend the area of the backup
|
||||||
int m_padding;
|
int m_padding;
|
||||||
|
|
||||||
bool m_supportsOrthogonalAdj = false;
|
bool m_supportsOrthogonalAdj = false;
|
||||||
bool m_supportsDiagonalAdj = false;
|
bool m_supportsDiagonalAdj = false;
|
||||||
|
|
||||||
virtual ToolType nameID() const = 0;
|
virtual ToolType nameID() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPoint adjustedVector(QPoint v) const;
|
QPoint adjustedVector(QPoint v) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,50 +24,48 @@ namespace {
|
|||||||
const int ArrowWidth = 10;
|
const int ArrowWidth = 10;
|
||||||
const int ArrowHeight = 18;
|
const int ArrowHeight = 18;
|
||||||
|
|
||||||
QPainterPath
|
QPainterPath getArrowHead(QPoint p1, QPoint p2, const int thickness)
|
||||||
getArrowHead(QPoint p1, QPoint p2, const int thickness)
|
|
||||||
{
|
{
|
||||||
QLineF base(p1, p2);
|
QLineF base(p1, p2);
|
||||||
// Create the vector for the position of the base of the arrowhead
|
// Create the vector for the position of the base of the arrowhead
|
||||||
QLineF temp(QPoint(0, 0), p2 - p1);
|
QLineF temp(QPoint(0, 0), p2 - p1);
|
||||||
int val = ArrowHeight + thickness * 4;
|
int val = ArrowHeight + thickness * 4;
|
||||||
if (base.length() < val) {
|
if (base.length() < val) {
|
||||||
val = (base.length() + thickness * 2);
|
val = (base.length() + thickness * 2);
|
||||||
}
|
}
|
||||||
temp.setLength(base.length() + thickness * 2 - val);
|
temp.setLength(base.length() + thickness * 2 - val);
|
||||||
// Move across the line up to the head
|
// Move across the line up to the head
|
||||||
QPointF bottonTranslation(temp.p2());
|
QPointF bottonTranslation(temp.p2());
|
||||||
|
|
||||||
// Rotate base of the arrowhead
|
// Rotate base of the arrowhead
|
||||||
base.setLength(ArrowWidth + thickness * 2);
|
base.setLength(ArrowWidth + thickness * 2);
|
||||||
base.setAngle(base.angle() + 90);
|
base.setAngle(base.angle() + 90);
|
||||||
// Move to the correct point
|
// Move to the correct point
|
||||||
QPointF temp2 = p1 - base.p2();
|
QPointF temp2 = p1 - base.p2();
|
||||||
// Center it
|
// Center it
|
||||||
QPointF centerTranslation((temp2.x() / 2), (temp2.y() / 2));
|
QPointF centerTranslation((temp2.x() / 2), (temp2.y() / 2));
|
||||||
|
|
||||||
base.translate(bottonTranslation);
|
base.translate(bottonTranslation);
|
||||||
base.translate(centerTranslation);
|
base.translate(centerTranslation);
|
||||||
|
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
path.moveTo(p2);
|
path.moveTo(p2);
|
||||||
path.lineTo(base.p1());
|
path.lineTo(base.p1());
|
||||||
path.lineTo(base.p2());
|
path.lineTo(base.p2());
|
||||||
path.lineTo(p2);
|
path.lineTo(p2);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets a shorter line to prevent overlap in the point of the arrow
|
// gets a shorter line to prevent overlap in the point of the arrow
|
||||||
QLine
|
QLine getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
||||||
getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
|
||||||
{
|
{
|
||||||
QLineF l(p1, p2);
|
QLineF l(p1, p2);
|
||||||
int val = ArrowHeight + thickness * 4;
|
int val = ArrowHeight + thickness * 4;
|
||||||
if (l.length() < val) {
|
if (l.length() < val) {
|
||||||
val = (l.length() + thickness * 2);
|
val = (l.length() + thickness * 2);
|
||||||
}
|
}
|
||||||
l.setLength(l.length() + thickness * 2 - val);
|
l.setLength(l.length() + thickness * 2 - val);
|
||||||
return l.toLine();
|
return l.toLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -75,72 +73,66 @@ getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
|||||||
ArrowTool::ArrowTool(QObject* parent)
|
ArrowTool::ArrowTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_padding = ArrowWidth / 2;
|
m_padding = ArrowWidth / 2;
|
||||||
m_supportsOrthogonalAdj = true;
|
m_supportsOrthogonalAdj = true;
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon ArrowTool::icon(const QColor& background, bool inEditor) const
|
||||||
ArrowTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString ArrowTool::name() const
|
||||||
ArrowTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Arrow");
|
return tr("Arrow");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType ArrowTool::nameID() const
|
||||||
ArrowTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::ARROW;
|
return ToolType::ARROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString ArrowTool::description() const
|
||||||
ArrowTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Arrow as the paint tool");
|
return tr("Set the Arrow as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* ArrowTool::copy(QObject* parent)
|
||||||
ArrowTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new ArrowTool(parent);
|
return new ArrowTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ArrowTool::process(QPainter& painter,
|
||||||
ArrowTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawLine(
|
painter.drawLine(
|
||||||
getShorterLine(m_points.first, m_points.second, m_thickness));
|
getShorterLine(m_points.first, m_points.second, m_thickness));
|
||||||
painter.fillPath(getArrowHead(m_points.first, m_points.second, m_thickness),
|
painter.fillPath(getArrowHead(m_points.first, m_points.second, m_thickness),
|
||||||
QBrush(m_color));
|
QBrush(m_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ArrowTool::paintMousePreview(QPainter& painter,
|
||||||
ArrowTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ArrowTool::drawStart(const CaptureContext& context)
|
||||||
ArrowTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ArrowTool::pressed(const CaptureContext& context)
|
||||||
ArrowTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,25 +23,25 @@
|
|||||||
|
|
||||||
class ArrowTool : public AbstractTwoPointTool
|
class ArrowTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ArrowTool(QObject* parent = nullptr);
|
explicit ArrowTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,12 +17,11 @@
|
|||||||
|
|
||||||
#include "capturecontext.h"
|
#include "capturecontext.h"
|
||||||
|
|
||||||
QPixmap
|
QPixmap CaptureContext::selectedScreenshotArea() const
|
||||||
CaptureContext::selectedScreenshotArea() const
|
|
||||||
{
|
{
|
||||||
if (selection.isNull()) {
|
if (selection.isNull()) {
|
||||||
return screenshot;
|
return screenshot;
|
||||||
} else {
|
} else {
|
||||||
return screenshot.copy(selection);
|
return screenshot.copy(selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,27 +24,27 @@
|
|||||||
|
|
||||||
struct CaptureContext
|
struct CaptureContext
|
||||||
{
|
{
|
||||||
// screenshot with modifications
|
// screenshot with modifications
|
||||||
QPixmap screenshot;
|
QPixmap screenshot;
|
||||||
// unmodified screenshot
|
// unmodified screenshot
|
||||||
QPixmap origScreenshot;
|
QPixmap origScreenshot;
|
||||||
// Selection area
|
// Selection area
|
||||||
QRect selection;
|
QRect selection;
|
||||||
// Widget dimensions
|
// Widget dimensions
|
||||||
QRect widgetDimensions;
|
QRect widgetDimensions;
|
||||||
// Selected tool color
|
// Selected tool color
|
||||||
QColor color;
|
QColor color;
|
||||||
// Path where the content has to be saved
|
// Path where the content has to be saved
|
||||||
QString savePath;
|
QString savePath;
|
||||||
// Ofset of the capture widget based on the system's screen (top-left)
|
// Ofset of the capture widget based on the system's screen (top-left)
|
||||||
QPoint widgetOffset;
|
QPoint widgetOffset;
|
||||||
// Mouse position inside the widget
|
// Mouse position inside the widget
|
||||||
QPoint mousePos;
|
QPoint mousePos;
|
||||||
// Value of the desired thickness
|
// Value of the desired thickness
|
||||||
int thickness;
|
int thickness;
|
||||||
int circleCount;
|
int circleCount;
|
||||||
// Mode of the capture widget
|
// Mode of the capture widget
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
|
|
||||||
QPixmap selectedScreenshotArea() const;
|
QPixmap selectedScreenshotArea() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,152 +25,152 @@
|
|||||||
|
|
||||||
enum class ToolType
|
enum class ToolType
|
||||||
{
|
{
|
||||||
ARROW,
|
ARROW,
|
||||||
CIRCLE,
|
CIRCLE,
|
||||||
CIRCLECOUNT,
|
CIRCLECOUNT,
|
||||||
COPY,
|
COPY,
|
||||||
EXIT,
|
EXIT,
|
||||||
IMGUR,
|
IMGUR,
|
||||||
LAUNCHER,
|
LAUNCHER,
|
||||||
LINE,
|
LINE,
|
||||||
MARKER,
|
MARKER,
|
||||||
MOVE,
|
MOVE,
|
||||||
PENCIL,
|
PENCIL,
|
||||||
PIN,
|
PIN,
|
||||||
PIXELATE,
|
PIXELATE,
|
||||||
RECTANGLE,
|
RECTANGLE,
|
||||||
REDO,
|
REDO,
|
||||||
SAVE,
|
SAVE,
|
||||||
SELECTION,
|
SELECTION,
|
||||||
SIZEINDICATOR,
|
SIZEINDICATOR,
|
||||||
TEXT,
|
TEXT,
|
||||||
UNDO
|
UNDO
|
||||||
};
|
};
|
||||||
|
|
||||||
class CaptureTool : public QObject
|
class CaptureTool : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Request actions on the main widget
|
// Request actions on the main widget
|
||||||
enum Request
|
enum Request
|
||||||
{
|
{
|
||||||
// Call close() in the editor.
|
// Call close() in the editor.
|
||||||
REQ_CLOSE_GUI,
|
REQ_CLOSE_GUI,
|
||||||
// Call hide() in the editor.
|
// Call hide() in the editor.
|
||||||
REQ_HIDE_GUI,
|
REQ_HIDE_GUI,
|
||||||
// Select the whole screen.
|
// Select the whole screen.
|
||||||
REQ_SELECT_ALL,
|
REQ_SELECT_ALL,
|
||||||
// Disable the selection.
|
// Disable the selection.
|
||||||
REQ_HIDE_SELECTION,
|
REQ_HIDE_SELECTION,
|
||||||
// Undo the last active modification in the stack.
|
// Undo the last active modification in the stack.
|
||||||
REQ_UNDO_MODIFICATION,
|
REQ_UNDO_MODIFICATION,
|
||||||
// Redo the next modification in the stack.
|
// Redo the next modification in the stack.
|
||||||
REQ_REDO_MODIFICATION,
|
REQ_REDO_MODIFICATION,
|
||||||
// Remove all the modifications.
|
// Remove all the modifications.
|
||||||
REQ_CLEAR_MODIFICATIONS,
|
REQ_CLEAR_MODIFICATIONS,
|
||||||
// Disable the active tool.
|
// Disable the active tool.
|
||||||
REQ_MOVE_MODE,
|
REQ_MOVE_MODE,
|
||||||
// Open the color picker under the mouse.
|
// Open the color picker under the mouse.
|
||||||
REQ_SHOW_COLOR_PICKER,
|
REQ_SHOW_COLOR_PICKER,
|
||||||
// Open/Close the side-panel.
|
// Open/Close the side-panel.
|
||||||
REQ_TOGGLE_SIDEBAR,
|
REQ_TOGGLE_SIDEBAR,
|
||||||
// Call update() in the editor.
|
// Call update() in the editor.
|
||||||
REQ_REDRAW,
|
REQ_REDRAW,
|
||||||
// Append this tool to the undo/redo stack
|
// Append this tool to the undo/redo stack
|
||||||
REQ_APPEND_TO_STACK,
|
REQ_APPEND_TO_STACK,
|
||||||
// Notify is the screenshot has been saved.
|
// Notify is the screenshot has been saved.
|
||||||
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
|
// Instance this->widget()'s widget as a window which closes after
|
||||||
// closing the editor.
|
// closing the editor.
|
||||||
REQ_ADD_CHILD_WINDOW,
|
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,
|
||||||
|
|
||||||
REQ_INCREMENT_CIRCLE_COUNT,
|
REQ_INCREMENT_CIRCLE_COUNT,
|
||||||
|
|
||||||
REQ_DECREMENT_CIRCLE_COUNT,
|
REQ_DECREMENT_CIRCLE_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit CaptureTool(QObject* parent = nullptr)
|
explicit CaptureTool(QObject* parent = nullptr)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Returns false when the tool is in an inconsistent state and shouldn't
|
// Returns false when the tool is in an inconsistent state and shouldn't
|
||||||
// be included in the tool undo/redo stack.
|
// be included in the tool undo/redo stack.
|
||||||
virtual bool isValid() const = 0;
|
virtual bool isValid() const = 0;
|
||||||
// Close the capture after the process() call if the tool was activated
|
// Close the capture after the process() call if the tool was activated
|
||||||
// from a button press.
|
// from a button press.
|
||||||
virtual bool closeOnButtonPressed() const = 0;
|
virtual bool closeOnButtonPressed() const = 0;
|
||||||
// If the tool keeps active after the selection.
|
// If the tool keeps active after the selection.
|
||||||
virtual bool isSelectable() const = 0;
|
virtual bool isSelectable() const = 0;
|
||||||
// Enable mouse preview.
|
// Enable mouse preview.
|
||||||
virtual bool showMousePreview() const = 0;
|
virtual bool showMousePreview() const = 0;
|
||||||
|
|
||||||
// The icon of the tool.
|
// The icon of the tool.
|
||||||
// inEditor is true when the icon is requested inside the editor
|
// inEditor is true when the icon is requested inside the editor
|
||||||
// and false otherwise.
|
// and false otherwise.
|
||||||
virtual QIcon icon(const QColor& background, bool inEditor) const = 0;
|
virtual QIcon icon(const QColor& background, bool inEditor) const = 0;
|
||||||
// Name displayed for the tool, this could be translated with tr()
|
// Name displayed for the tool, this could be translated with tr()
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
// Codename for the tool, this hsouldn't change as it is used as ID
|
// Codename for the tool, this hsouldn't change as it is used as ID
|
||||||
// for the tool in the internals of Flameshot
|
// for the tool in the internals of Flameshot
|
||||||
virtual ToolType nameID() const = 0;
|
virtual ToolType nameID() const = 0;
|
||||||
// Short description of the tool.
|
// Short description of the tool.
|
||||||
virtual QString description() const = 0;
|
virtual QString description() const = 0;
|
||||||
|
|
||||||
// if the type is TYPE_WIDGET the widget is loaded in the main widget.
|
// 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
|
// If the type is TYPE_EXTERNAL_WIDGET it is created outside as an
|
||||||
// individual widget.
|
// individual widget.
|
||||||
virtual QWidget* widget() { return nullptr; }
|
virtual QWidget* widget() { return nullptr; }
|
||||||
// When the tool is selected this method is called and the widget is added
|
// When the tool is selected this method is called and the widget is added
|
||||||
// to the configuration panel inside the main widget.
|
// to the configuration panel inside the main widget.
|
||||||
virtual QWidget* configurationWidget() { return nullptr; }
|
virtual QWidget* configurationWidget() { return nullptr; }
|
||||||
// Permanent configuration used in the configuration outside of the
|
// Permanent configuration used in the configuration outside of the
|
||||||
// capture.
|
// capture.
|
||||||
virtual QWidget* permanentConfigurationWidget() { return nullptr; }
|
virtual QWidget* permanentConfigurationWidget() { return nullptr; }
|
||||||
// Return a copy of the tool
|
// Return a copy of the tool
|
||||||
virtual CaptureTool* copy(QObject* parent = nullptr) = 0;
|
virtual CaptureTool* copy(QObject* parent = nullptr) = 0;
|
||||||
|
|
||||||
// revert changes
|
// revert changes
|
||||||
virtual void undo(QPixmap& pixmap) = 0;
|
virtual void undo(QPixmap& pixmap) = 0;
|
||||||
// Called every time the tool has to draw
|
// Called every time the tool has to draw
|
||||||
// recordUndo indicates when the tool should save the information
|
// recordUndo indicates when the tool should save the information
|
||||||
// for the undo(), if the value is false calling undo() after
|
// for the undo(), if the value is false calling undo() after
|
||||||
// that process should not modify revert the changes.
|
// that process should not modify revert the changes.
|
||||||
virtual void process(QPainter& painter,
|
virtual void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) = 0;
|
bool recordUndo = false) = 0;
|
||||||
// When the tool is selected, this is called when the mouse moves
|
// When the tool is selected, this is called when the mouse moves
|
||||||
virtual void paintMousePreview(QPainter& painter,
|
virtual void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) = 0;
|
const CaptureContext& context) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestAction(Request r);
|
void requestAction(Request r);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString iconPath(const QColor& c) const
|
QString iconPath(const QColor& c) const
|
||||||
{
|
{
|
||||||
return ColorUtils::colorIsDark(c) ? PathInfo::whiteIconPath()
|
return ColorUtils::colorIsDark(c) ? PathInfo::whiteIconPath()
|
||||||
: PathInfo::blackIconPath();
|
: PathInfo::blackIconPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// On mouse release.
|
// On mouse release.
|
||||||
virtual void drawEnd(const QPoint& p) = 0;
|
virtual void drawEnd(const QPoint& p) = 0;
|
||||||
// Mouse pressed and moving, called once a pixel.
|
// Mouse pressed and moving, called once a pixel.
|
||||||
virtual void drawMove(const QPoint& p) = 0;
|
virtual void drawMove(const QPoint& p) = 0;
|
||||||
// Called when drawMove is needed with an adjustment;
|
// Called when drawMove is needed with an adjustment;
|
||||||
// should be overridden in case an adjustment is applicable.
|
// should be overridden in case an adjustment is applicable.
|
||||||
virtual void drawMoveWithAdjustment(const QPoint& p) { drawMove(p); }
|
virtual void drawMoveWithAdjustment(const QPoint& p) { drawMove(p); }
|
||||||
// Called when the tool is activated.
|
// Called when the tool is activated.
|
||||||
virtual void drawStart(const CaptureContext& context) = 0;
|
virtual void drawStart(const CaptureContext& context) = 0;
|
||||||
// Called right after pressign the button which activates the tool.
|
// Called right after pressign the button which activates the tool.
|
||||||
virtual void pressed(const CaptureContext& context) = 0;
|
virtual void pressed(const CaptureContext& context) = 0;
|
||||||
// Called when the color is changed in the editor.
|
// Called when the color is changed in the editor.
|
||||||
virtual void colorChanged(const QColor& c) = 0;
|
virtual void colorChanged(const QColor& c) = 0;
|
||||||
// Called when the thickness of the tool is updated in the editor.
|
// Called when the thickness of the tool is updated in the editor.
|
||||||
virtual void thicknessChanged(const int th) = 0;
|
virtual void thicknessChanged(const int th) = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,67 +25,61 @@ namespace {
|
|||||||
CircleTool::CircleTool(QObject* parent)
|
CircleTool::CircleTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon CircleTool::icon(const QColor& background, bool inEditor) const
|
||||||
CircleTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "circle-outline.svg");
|
return QIcon(iconPath(background) + "circle-outline.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString CircleTool::name() const
|
||||||
CircleTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Circle");
|
return tr("Circle");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType CircleTool::nameID() const
|
||||||
CircleTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::CIRCLE;
|
return ToolType::CIRCLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CircleTool::description() const
|
||||||
CircleTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Circle as the paint tool");
|
return tr("Set the Circle as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* CircleTool::copy(QObject* parent)
|
||||||
CircleTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new CircleTool(parent);
|
return new CircleTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleTool::process(QPainter& painter,
|
||||||
CircleTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawEllipse(QRect(m_points.first, m_points.second));
|
painter.drawEllipse(QRect(m_points.first, m_points.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleTool::paintMousePreview(QPainter& painter,
|
||||||
CircleTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleTool::drawStart(const CaptureContext& context)
|
||||||
CircleTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleTool::pressed(const CaptureContext& context)
|
||||||
CircleTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,25 @@
|
|||||||
|
|
||||||
class CircleTool : public AbstractTwoPointTool
|
class CircleTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CircleTool(QObject* parent = nullptr);
|
explicit CircleTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,120 +24,111 @@ namespace {
|
|||||||
CircleCountTool::CircleCountTool(QObject* parent)
|
CircleCountTool::CircleCountTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_count = 0;
|
m_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon CircleCountTool::icon(const QColor& background, bool inEditor) const
|
||||||
CircleCountTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString CircleCountTool::name() const
|
||||||
CircleCountTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Circle Counter");
|
return tr("Circle Counter");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType CircleCountTool::nameID() const
|
||||||
CircleCountTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::CIRCLECOUNT;
|
return ToolType::CIRCLECOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CircleCountTool::description() const
|
||||||
CircleCountTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Add an autoincrementing counter bubble");
|
return tr("Add an autoincrementing counter bubble");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* CircleCountTool::copy(QObject* parent)
|
||||||
CircleCountTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new CircleCountTool(parent);
|
return new CircleCountTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleCountTool::process(QPainter& painter,
|
||||||
CircleCountTool::process(QPainter& painter,
|
const QPixmap& pixmap,
|
||||||
const QPixmap& pixmap,
|
bool recordUndo)
|
||||||
bool recordUndo)
|
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
|
||||||
painter.setBrush(m_color);
|
|
||||||
|
|
||||||
int bubble_size = m_thickness;
|
|
||||||
// Decrease by 1px so the border is properly ereased when doing undo
|
|
||||||
painter.drawEllipse(m_points.first, bubble_size - 1, bubble_size - 1);
|
|
||||||
QRect textRect = QRect(m_points.first.x() - bubble_size / 2,
|
|
||||||
m_points.first.y() - bubble_size / 2,
|
|
||||||
bubble_size,
|
|
||||||
bubble_size);
|
|
||||||
auto orig_font = painter.font();
|
|
||||||
auto new_font = orig_font;
|
|
||||||
auto fontSize = bubble_size;
|
|
||||||
new_font.setPixelSize(fontSize);
|
|
||||||
painter.setFont(new_font);
|
|
||||||
|
|
||||||
QRect bRect =
|
|
||||||
painter.boundingRect(textRect, Qt::AlignCenter, QString::number(m_count));
|
|
||||||
|
|
||||||
while (bRect.width() > textRect.width()) {
|
|
||||||
fontSize--;
|
|
||||||
if (fontSize == 0) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
painter.setBrush(m_color);
|
||||||
|
|
||||||
|
int bubble_size = m_thickness;
|
||||||
|
// Decrease by 1px so the border is properly ereased when doing undo
|
||||||
|
painter.drawEllipse(m_points.first, bubble_size - 1, bubble_size - 1);
|
||||||
|
QRect textRect = QRect(m_points.first.x() - bubble_size / 2,
|
||||||
|
m_points.first.y() - bubble_size / 2,
|
||||||
|
bubble_size,
|
||||||
|
bubble_size);
|
||||||
|
auto orig_font = painter.font();
|
||||||
|
auto new_font = orig_font;
|
||||||
|
auto fontSize = bubble_size;
|
||||||
new_font.setPixelSize(fontSize);
|
new_font.setPixelSize(fontSize);
|
||||||
painter.setFont(new_font);
|
painter.setFont(new_font);
|
||||||
|
|
||||||
bRect =
|
QRect bRect =
|
||||||
painter.boundingRect(textRect, Qt::AlignCenter, QString::number(m_count));
|
painter.boundingRect(textRect, Qt::AlignCenter, QString::number(m_count));
|
||||||
}
|
|
||||||
|
|
||||||
// Lightness value ranges from 0-255, we split at 75 as this looks best
|
while (bRect.width() > textRect.width()) {
|
||||||
if (m_color.lightness() <= 75) {
|
fontSize--;
|
||||||
painter.setPen(Qt::white);
|
if (fontSize == 0) {
|
||||||
} else {
|
break;
|
||||||
painter.setPen(Qt::black);
|
}
|
||||||
}
|
new_font.setPixelSize(fontSize);
|
||||||
|
painter.setFont(new_font);
|
||||||
|
|
||||||
painter.drawText(textRect, Qt::AlignCenter, QString::number(m_count));
|
bRect = painter.boundingRect(
|
||||||
painter.setFont(orig_font);
|
textRect, Qt::AlignCenter, QString::number(m_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lightness value ranges from 0-255, we split at 75 as this looks best
|
||||||
|
if (m_color.lightness() <= 75) {
|
||||||
|
painter.setPen(Qt::white);
|
||||||
|
} else {
|
||||||
|
painter.setPen(Qt::black);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.drawText(textRect, Qt::AlignCenter, QString::number(m_count));
|
||||||
|
painter.setFont(orig_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleCountTool::paintMousePreview(QPainter& painter,
|
||||||
CircleCountTool::paintMousePreview(QPainter& painter,
|
const CaptureContext& context)
|
||||||
const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
if (m_thickness < 15) {
|
if (m_thickness < 15) {
|
||||||
m_thickness = 15;
|
m_thickness = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thickness for pen is *2 to range from radius to diameter to match the
|
// Thickness for pen is *2 to range from radius to diameter to match the
|
||||||
// ellipse draw function
|
// ellipse draw function
|
||||||
painter.setPen(
|
painter.setPen(
|
||||||
QPen(context.color, m_thickness * 2, Qt::SolidLine, Qt::RoundCap));
|
QPen(context.color, m_thickness * 2, Qt::SolidLine, Qt::RoundCap));
|
||||||
painter.drawLine(context.mousePos,
|
painter.drawLine(context.mousePos,
|
||||||
{ context.mousePos.x() + 1, context.mousePos.y() + 1 });
|
{ context.mousePos.x() + 1, context.mousePos.y() + 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleCountTool::drawStart(const CaptureContext& context)
|
||||||
CircleCountTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
if (m_thickness < 15) {
|
if (m_thickness < 15) {
|
||||||
m_thickness = 15;
|
m_thickness = 15;
|
||||||
}
|
}
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_count = context.circleCount;
|
m_count = context.circleCount;
|
||||||
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CircleCountTool::pressed(const CaptureContext& context)
|
||||||
CircleCountTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,27 +21,27 @@
|
|||||||
|
|
||||||
class CircleCountTool : public AbstractTwoPointTool
|
class CircleCountTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CircleCountTool(QObject* parent = nullptr);
|
explicit CircleCountTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_count;
|
unsigned int m_count;
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,45 +23,38 @@ CopyTool::CopyTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool CopyTool::closeOnButtonPressed() const
|
||||||
CopyTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon CopyTool::icon(const QColor& background, bool inEditor) const
|
||||||
CopyTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "content-copy.svg");
|
return QIcon(iconPath(background) + "content-copy.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString CopyTool::name() const
|
||||||
CopyTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Copy");
|
return tr("Copy");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType CopyTool::nameID() const
|
||||||
CopyTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::COPY;
|
return ToolType::COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString CopyTool::description() const
|
||||||
CopyTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Copy the selection into the clipboard");
|
return tr("Copy the selection into the clipboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* CopyTool::copy(QObject* parent)
|
||||||
CopyTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new CopyTool(parent);
|
return new CopyTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CopyTool::pressed(const CaptureContext& context)
|
||||||
CopyTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,21 @@
|
|||||||
|
|
||||||
class CopyTool : public AbstractActionTool
|
class CopyTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CopyTool(QObject* parent = nullptr);
|
explicit CopyTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,45 +22,38 @@ ExitTool::ExitTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool ExitTool::closeOnButtonPressed() const
|
||||||
ExitTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon ExitTool::icon(const QColor& background, bool inEditor) const
|
||||||
ExitTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "close.svg");
|
return QIcon(iconPath(background) + "close.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString ExitTool::name() const
|
||||||
ExitTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Exit");
|
return tr("Exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType ExitTool::nameID() const
|
||||||
ExitTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::EXIT;
|
return ToolType::EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString ExitTool::description() const
|
||||||
ExitTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Leave the capture screen");
|
return tr("Leave the capture screen");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* ExitTool::copy(QObject* parent)
|
||||||
ExitTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new ExitTool(parent);
|
return new ExitTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExitTool::pressed(const CaptureContext& context)
|
||||||
ExitTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
emit requestAction(REQ_CLOSE_GUI);
|
emit requestAction(REQ_CLOSE_GUI);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,21 @@
|
|||||||
|
|
||||||
class ExitTool : public AbstractActionTool
|
class ExitTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ExitTool(QObject* parent = nullptr);
|
explicit ExitTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,165 +45,158 @@ ImgurUploader::ImgurUploader(const QPixmap& capture, QWidget* parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_pixmap(capture)
|
, m_pixmap(capture)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Upload to Imgur"));
|
setWindowTitle(tr("Upload to Imgur"));
|
||||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||||
|
|
||||||
m_spinner = new LoadSpinner(this);
|
m_spinner = new LoadSpinner(this);
|
||||||
m_spinner->setColor(ConfigHandler().uiMainColorValue());
|
m_spinner->setColor(ConfigHandler().uiMainColorValue());
|
||||||
m_spinner->start();
|
m_spinner->start();
|
||||||
|
|
||||||
m_infoLabel = new QLabel(tr("Uploading Image"));
|
m_infoLabel = new QLabel(tr("Uploading Image"));
|
||||||
|
|
||||||
m_vLayout = new QVBoxLayout();
|
m_vLayout = new QVBoxLayout();
|
||||||
setLayout(m_vLayout);
|
setLayout(m_vLayout);
|
||||||
m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
|
m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
|
||||||
m_vLayout->addWidget(m_infoLabel);
|
m_vLayout->addWidget(m_infoLabel);
|
||||||
|
|
||||||
m_NetworkAM = new QNetworkAccessManager(this);
|
m_NetworkAM = new QNetworkAccessManager(this);
|
||||||
connect(m_NetworkAM,
|
connect(m_NetworkAM,
|
||||||
&QNetworkAccessManager::finished,
|
&QNetworkAccessManager::finished,
|
||||||
this,
|
this,
|
||||||
&ImgurUploader::handleReply);
|
&ImgurUploader::handleReply);
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
upload();
|
upload();
|
||||||
// QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing
|
// QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::handleReply(QNetworkReply* reply)
|
||||||
ImgurUploader::handleReply(QNetworkReply* reply)
|
|
||||||
{
|
{
|
||||||
m_spinner->deleteLater();
|
m_spinner->deleteLater();
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
|
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
|
||||||
QJsonObject json = response.object();
|
QJsonObject json = response.object();
|
||||||
QJsonObject data = json[QStringLiteral("data")].toObject();
|
QJsonObject data = json[QStringLiteral("data")].toObject();
|
||||||
m_imageURL.setUrl(data[QStringLiteral("link")].toString());
|
m_imageURL.setUrl(data[QStringLiteral("link")].toString());
|
||||||
m_deleteImageURL.setUrl(
|
m_deleteImageURL.setUrl(
|
||||||
QStringLiteral("https://imgur.com/delete/%1")
|
QStringLiteral("https://imgur.com/delete/%1")
|
||||||
.arg(data[QStringLiteral("deletehash")].toString()));
|
.arg(data[QStringLiteral("deletehash")].toString()));
|
||||||
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
|
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
|
||||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||||
SystemNotification().sendMessage(QObject::tr("URL copied to clipboard."));
|
SystemNotification().sendMessage(
|
||||||
close();
|
QObject::tr("URL copied to clipboard."));
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
onUploadOk();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
onUploadOk();
|
m_infoLabel->setText(reply->errorString());
|
||||||
}
|
}
|
||||||
} else {
|
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||||
m_infoLabel->setText(reply->errorString());
|
|
||||||
}
|
|
||||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::startDrag()
|
||||||
ImgurUploader::startDrag()
|
|
||||||
{
|
{
|
||||||
QMimeData* mimeData = new QMimeData;
|
QMimeData* mimeData = new QMimeData;
|
||||||
mimeData->setUrls(QList<QUrl>{ m_imageURL });
|
mimeData->setUrls(QList<QUrl>{ m_imageURL });
|
||||||
mimeData->setImageData(m_pixmap);
|
mimeData->setImageData(m_pixmap);
|
||||||
|
|
||||||
QDrag* dragHandler = new QDrag(this);
|
QDrag* dragHandler = new QDrag(this);
|
||||||
dragHandler->setMimeData(mimeData);
|
dragHandler->setMimeData(mimeData);
|
||||||
dragHandler->setPixmap(m_pixmap.scaled(
|
dragHandler->setPixmap(m_pixmap.scaled(
|
||||||
256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||||
dragHandler->exec();
|
dragHandler->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::upload()
|
||||||
ImgurUploader::upload()
|
|
||||||
{
|
{
|
||||||
QByteArray byteArray;
|
QByteArray byteArray;
|
||||||
QBuffer buffer(&byteArray);
|
QBuffer buffer(&byteArray);
|
||||||
m_pixmap.save(&buffer, "PNG");
|
m_pixmap.save(&buffer, "PNG");
|
||||||
|
|
||||||
QUrlQuery urlQuery;
|
QUrlQuery urlQuery;
|
||||||
urlQuery.addQueryItem(QStringLiteral("title"),
|
urlQuery.addQueryItem(QStringLiteral("title"),
|
||||||
QStringLiteral("flameshot_screenshot"));
|
QStringLiteral("flameshot_screenshot"));
|
||||||
QString description = FileNameHandler().parsedPattern();
|
QString description = FileNameHandler().parsedPattern();
|
||||||
urlQuery.addQueryItem(QStringLiteral("description"), description);
|
urlQuery.addQueryItem(QStringLiteral("description"), description);
|
||||||
|
|
||||||
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
|
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
|
||||||
url.setQuery(urlQuery);
|
url.setQuery(urlQuery);
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader,
|
request.setHeader(QNetworkRequest::ContentTypeHeader,
|
||||||
"application/application/x-www-form-urlencoded");
|
"application/application/x-www-form-urlencoded");
|
||||||
request.setRawHeader(
|
request.setRawHeader(
|
||||||
"Authorization",
|
"Authorization",
|
||||||
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
|
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
|
||||||
|
|
||||||
m_NetworkAM->post(request, byteArray);
|
m_NetworkAM->post(request, byteArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::onUploadOk()
|
||||||
ImgurUploader::onUploadOk()
|
|
||||||
{
|
{
|
||||||
m_infoLabel->deleteLater();
|
m_infoLabel->deleteLater();
|
||||||
|
|
||||||
m_notification = new NotificationWidget();
|
m_notification = new NotificationWidget();
|
||||||
m_vLayout->addWidget(m_notification);
|
m_vLayout->addWidget(m_notification);
|
||||||
|
|
||||||
ImageLabel* imageLabel = new ImageLabel();
|
ImageLabel* imageLabel = new ImageLabel();
|
||||||
imageLabel->setScreenshot(m_pixmap);
|
imageLabel->setScreenshot(m_pixmap);
|
||||||
imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
connect(
|
connect(
|
||||||
imageLabel, &ImageLabel::dragInitiated, this, &ImgurUploader::startDrag);
|
imageLabel, &ImageLabel::dragInitiated, this, &ImgurUploader::startDrag);
|
||||||
m_vLayout->addWidget(imageLabel);
|
m_vLayout->addWidget(imageLabel);
|
||||||
|
|
||||||
m_hLayout = new QHBoxLayout();
|
m_hLayout = new QHBoxLayout();
|
||||||
m_vLayout->addLayout(m_hLayout);
|
m_vLayout->addLayout(m_hLayout);
|
||||||
|
|
||||||
m_copyUrlButton = new QPushButton(tr("Copy URL"));
|
m_copyUrlButton = new QPushButton(tr("Copy URL"));
|
||||||
m_openUrlButton = new QPushButton(tr("Open URL"));
|
m_openUrlButton = new QPushButton(tr("Open URL"));
|
||||||
m_openDeleteUrlButton = new QPushButton(tr("Delete image"));
|
m_openDeleteUrlButton = new QPushButton(tr("Delete image"));
|
||||||
m_toClipboardButton = new QPushButton(tr("Image to Clipboard."));
|
m_toClipboardButton = new QPushButton(tr("Image to Clipboard."));
|
||||||
m_hLayout->addWidget(m_copyUrlButton);
|
m_hLayout->addWidget(m_copyUrlButton);
|
||||||
m_hLayout->addWidget(m_openUrlButton);
|
m_hLayout->addWidget(m_openUrlButton);
|
||||||
m_hLayout->addWidget(m_openDeleteUrlButton);
|
m_hLayout->addWidget(m_openDeleteUrlButton);
|
||||||
m_hLayout->addWidget(m_toClipboardButton);
|
m_hLayout->addWidget(m_toClipboardButton);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
m_copyUrlButton, &QPushButton::clicked, this, &ImgurUploader::copyURL);
|
m_copyUrlButton, &QPushButton::clicked, this, &ImgurUploader::copyURL);
|
||||||
connect(
|
connect(
|
||||||
m_openUrlButton, &QPushButton::clicked, this, &ImgurUploader::openURL);
|
m_openUrlButton, &QPushButton::clicked, this, &ImgurUploader::openURL);
|
||||||
connect(m_openDeleteUrlButton,
|
connect(m_openDeleteUrlButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&ImgurUploader::openDeleteURL);
|
&ImgurUploader::openDeleteURL);
|
||||||
connect(m_toClipboardButton,
|
connect(m_toClipboardButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&ImgurUploader::copyImage);
|
&ImgurUploader::copyImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::openURL()
|
||||||
ImgurUploader::openURL()
|
|
||||||
{
|
{
|
||||||
bool successful = QDesktopServices::openUrl(m_imageURL);
|
bool successful = QDesktopServices::openUrl(m_imageURL);
|
||||||
if (!successful) {
|
if (!successful) {
|
||||||
m_notification->showMessage(tr("Unable to open the URL."));
|
m_notification->showMessage(tr("Unable to open the URL."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::copyURL()
|
||||||
ImgurUploader::copyURL()
|
|
||||||
{
|
{
|
||||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||||
m_notification->showMessage(tr("URL copied to clipboard."));
|
m_notification->showMessage(tr("URL copied to clipboard."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::openDeleteURL()
|
||||||
ImgurUploader::openDeleteURL()
|
|
||||||
{
|
{
|
||||||
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
||||||
if (!successful) {
|
if (!successful) {
|
||||||
m_notification->showMessage(tr("Unable to open the URL."));
|
m_notification->showMessage(tr("Unable to open the URL."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploader::copyImage()
|
||||||
ImgurUploader::copyImage()
|
|
||||||
{
|
{
|
||||||
QApplication::clipboard()->setPixmap(m_pixmap);
|
QApplication::clipboard()->setPixmap(m_pixmap);
|
||||||
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,37 +32,37 @@ class NotificationWidget;
|
|||||||
|
|
||||||
class ImgurUploader : public QWidget
|
class ImgurUploader : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr);
|
explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleReply(QNetworkReply* reply);
|
void handleReply(QNetworkReply* reply);
|
||||||
void startDrag();
|
void startDrag();
|
||||||
|
|
||||||
void openURL();
|
void openURL();
|
||||||
void copyURL();
|
void copyURL();
|
||||||
void openDeleteURL();
|
void openDeleteURL();
|
||||||
void copyImage();
|
void copyImage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPixmap m_pixmap;
|
QPixmap m_pixmap;
|
||||||
QNetworkAccessManager* m_NetworkAM;
|
QNetworkAccessManager* m_NetworkAM;
|
||||||
|
|
||||||
QVBoxLayout* m_vLayout;
|
QVBoxLayout* m_vLayout;
|
||||||
QHBoxLayout* m_hLayout;
|
QHBoxLayout* m_hLayout;
|
||||||
// loading
|
// loading
|
||||||
QLabel* m_infoLabel;
|
QLabel* m_infoLabel;
|
||||||
LoadSpinner* m_spinner;
|
LoadSpinner* m_spinner;
|
||||||
// uploaded
|
// uploaded
|
||||||
QPushButton* m_openUrlButton;
|
QPushButton* m_openUrlButton;
|
||||||
QPushButton* m_openDeleteUrlButton;
|
QPushButton* m_openDeleteUrlButton;
|
||||||
QPushButton* m_copyUrlButton;
|
QPushButton* m_copyUrlButton;
|
||||||
QPushButton* m_toClipboardButton;
|
QPushButton* m_toClipboardButton;
|
||||||
QUrl m_imageURL;
|
QUrl m_imageURL;
|
||||||
QUrl m_deleteImageURL;
|
QUrl m_deleteImageURL;
|
||||||
NotificationWidget* m_notification;
|
NotificationWidget* m_notification;
|
||||||
|
|
||||||
void upload();
|
void upload();
|
||||||
void onUploadOk();
|
void onUploadOk();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,52 +23,44 @@ ImgurUploaderTool::ImgurUploaderTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool ImgurUploaderTool::closeOnButtonPressed() const
|
||||||
ImgurUploaderTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
|
||||||
ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "cloud-upload.svg");
|
return QIcon(iconPath(background) + "cloud-upload.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString ImgurUploaderTool::name() const
|
||||||
ImgurUploaderTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Image Uploader");
|
return tr("Image Uploader");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType ImgurUploaderTool::nameID() const
|
||||||
ImgurUploaderTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::IMGUR;
|
return ToolType::IMGUR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString ImgurUploaderTool::description() const
|
||||||
ImgurUploaderTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Upload the selection to Imgur");
|
return tr("Upload the selection to Imgur");
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget*
|
QWidget* ImgurUploaderTool::widget()
|
||||||
ImgurUploaderTool::widget()
|
|
||||||
{
|
{
|
||||||
return new ImgurUploader(capture);
|
return new ImgurUploader(capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* ImgurUploaderTool::copy(QObject* parent)
|
||||||
ImgurUploaderTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new ImgurUploaderTool(parent);
|
return new ImgurUploaderTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ImgurUploaderTool::pressed(const CaptureContext& context)
|
||||||
ImgurUploaderTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
capture = context.selectedScreenshotArea();
|
capture = context.selectedScreenshotArea();
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,26 @@
|
|||||||
|
|
||||||
class ImgurUploaderTool : public AbstractActionTool
|
class ImgurUploaderTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ImgurUploaderTool(QObject* parent = nullptr);
|
explicit ImgurUploaderTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPixmap capture;
|
QPixmap capture;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,52 +22,44 @@ AppLauncher::AppLauncher(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool AppLauncher::closeOnButtonPressed() const
|
||||||
AppLauncher::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon AppLauncher::icon(const QColor& background, bool inEditor) const
|
||||||
AppLauncher::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "open_with.svg");
|
return QIcon(iconPath(background) + "open_with.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString AppLauncher::name() const
|
||||||
AppLauncher::name() const
|
|
||||||
{
|
{
|
||||||
return tr("App Launcher");
|
return tr("App Launcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType AppLauncher::nameID() const
|
||||||
AppLauncher::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::LAUNCHER;
|
return ToolType::LAUNCHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString AppLauncher::description() const
|
||||||
AppLauncher::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Choose an app to open the capture");
|
return tr("Choose an app to open the capture");
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget*
|
QWidget* AppLauncher::widget()
|
||||||
AppLauncher::widget()
|
|
||||||
{
|
{
|
||||||
return new AppLauncherWidget(capture);
|
return new AppLauncherWidget(capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* AppLauncher::copy(QObject* parent)
|
||||||
AppLauncher::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new AppLauncher(parent);
|
return new AppLauncher(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AppLauncher::pressed(const CaptureContext& context)
|
||||||
AppLauncher::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
capture = context.selectedScreenshotArea();
|
capture = context.selectedScreenshotArea();
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,26 @@
|
|||||||
|
|
||||||
class AppLauncher : public AbstractActionTool
|
class AppLauncher : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AppLauncher(QObject* parent = nullptr);
|
explicit AppLauncher(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPixmap capture;
|
QPixmap capture;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,218 +51,213 @@ AppLauncherWidget::AppLauncherWidget(const QPixmap& p, QWidget* parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_pixmap(p)
|
, m_pixmap(p)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||||
setWindowTitle(tr("Open With"));
|
setWindowTitle(tr("Open With"));
|
||||||
|
|
||||||
m_keepOpen = ConfigHandler().keepOpenAppLauncherValue();
|
m_keepOpen = ConfigHandler().keepOpenAppLauncherValue();
|
||||||
|
|
||||||
QString dirLocal = QDir::homePath() + "/.local/share/applications/";
|
QString dirLocal = QDir::homePath() + "/.local/share/applications/";
|
||||||
QDir appsDirLocal(dirLocal);
|
QDir appsDirLocal(dirLocal);
|
||||||
m_parser.processDirectory(appsDirLocal);
|
m_parser.processDirectory(appsDirLocal);
|
||||||
|
|
||||||
QString dir = QStringLiteral("/usr/share/applications/");
|
QString dir = QStringLiteral("/usr/share/applications/");
|
||||||
QDir appsDir(dir);
|
QDir appsDir(dir);
|
||||||
m_parser.processDirectory(appsDir);
|
m_parser.processDirectory(appsDir);
|
||||||
|
|
||||||
initAppMap();
|
initAppMap();
|
||||||
initListWidget();
|
initListWidget();
|
||||||
|
|
||||||
m_terminalCheckbox = new QCheckBox(tr("Launch in terminal"), this);
|
m_terminalCheckbox = new QCheckBox(tr("Launch in terminal"), this);
|
||||||
m_keepOpenCheckbox = new QCheckBox(tr("Keep open after selection"), this);
|
m_keepOpenCheckbox = new QCheckBox(tr("Keep open after selection"), this);
|
||||||
m_keepOpenCheckbox->setChecked(ConfigHandler().keepOpenAppLauncherValue());
|
m_keepOpenCheckbox->setChecked(ConfigHandler().keepOpenAppLauncherValue());
|
||||||
connect(m_keepOpenCheckbox,
|
connect(m_keepOpenCheckbox,
|
||||||
&QCheckBox::clicked,
|
&QCheckBox::clicked,
|
||||||
this,
|
this,
|
||||||
&AppLauncherWidget::checkboxClicked);
|
&AppLauncherWidget::checkboxClicked);
|
||||||
|
|
||||||
// search items
|
// search items
|
||||||
m_lineEdit = new QLineEdit;
|
m_lineEdit = new QLineEdit;
|
||||||
connect(m_lineEdit,
|
connect(m_lineEdit,
|
||||||
&QLineEdit::textChanged,
|
&QLineEdit::textChanged,
|
||||||
this,
|
this,
|
||||||
&AppLauncherWidget::searchChanged);
|
&AppLauncherWidget::searchChanged);
|
||||||
m_filterList = new QListWidget;
|
m_filterList = new QListWidget;
|
||||||
m_filterList->hide();
|
|
||||||
configureListView(m_filterList);
|
|
||||||
connect(
|
|
||||||
m_filterList, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
|
||||||
|
|
||||||
m_layout = new QVBoxLayout(this);
|
|
||||||
m_layout->addWidget(m_filterList);
|
|
||||||
m_layout->addWidget(m_tabWidget);
|
|
||||||
m_layout->addWidget(m_lineEdit);
|
|
||||||
m_layout->addWidget(m_keepOpenCheckbox);
|
|
||||||
m_layout->addWidget(m_terminalCheckbox);
|
|
||||||
m_lineEdit->setFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AppLauncherWidget::launch(const QModelIndex& index)
|
|
||||||
{
|
|
||||||
if (!QFileInfo(m_tempFile).isReadable()) {
|
|
||||||
m_tempFile =
|
|
||||||
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
|
||||||
bool ok = m_pixmap.save(m_tempFile);
|
|
||||||
if (!ok) {
|
|
||||||
QMessageBox::about(
|
|
||||||
this, tr("Error"), tr("Unable to write in") + QDir::tempPath());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QString command = index.data(Qt::UserRole)
|
|
||||||
.toString()
|
|
||||||
.replace(QRegExp("(\\%.)"), '"' + m_tempFile + '"');
|
|
||||||
|
|
||||||
QString app_name = index.data(Qt::UserRole).toString().split(" ").at(0);
|
|
||||||
bool inTerminal =
|
|
||||||
index.data(Qt::UserRole + 1).toBool() || m_terminalCheckbox->isChecked();
|
|
||||||
if (inTerminal) {
|
|
||||||
bool ok = TerminalLauncher::launchDetached(command);
|
|
||||||
if (!ok) {
|
|
||||||
QMessageBox::about(
|
|
||||||
this, tr("Error"), tr("Unable to launch in terminal."));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QProcess::startDetached(app_name, { m_tempFile });
|
|
||||||
}
|
|
||||||
if (!m_keepOpen) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AppLauncherWidget::checkboxClicked(const bool enabled)
|
|
||||||
{
|
|
||||||
m_keepOpen = enabled;
|
|
||||||
ConfigHandler().setKeepOpenAppLauncher(enabled);
|
|
||||||
m_keepOpenCheckbox->setChecked(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AppLauncherWidget::searchChanged(const QString& text)
|
|
||||||
{
|
|
||||||
if (text.isEmpty()) {
|
|
||||||
m_filterList->hide();
|
m_filterList->hide();
|
||||||
m_tabWidget->show();
|
configureListView(m_filterList);
|
||||||
} else {
|
connect(
|
||||||
m_tabWidget->hide();
|
m_filterList, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
||||||
m_filterList->show();
|
|
||||||
m_filterList->clear();
|
m_layout = new QVBoxLayout(this);
|
||||||
QRegExp regexp(text, Qt::CaseInsensitive, QRegExp::Wildcard);
|
m_layout->addWidget(m_filterList);
|
||||||
QVector<DesktopAppData> apps;
|
m_layout->addWidget(m_tabWidget);
|
||||||
|
m_layout->addWidget(m_lineEdit);
|
||||||
|
m_layout->addWidget(m_keepOpenCheckbox);
|
||||||
|
m_layout->addWidget(m_terminalCheckbox);
|
||||||
|
m_lineEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppLauncherWidget::launch(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
if (!QFileInfo(m_tempFile).isReadable()) {
|
||||||
|
m_tempFile =
|
||||||
|
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
||||||
|
bool ok = m_pixmap.save(m_tempFile);
|
||||||
|
if (!ok) {
|
||||||
|
QMessageBox::about(
|
||||||
|
this, tr("Error"), tr("Unable to write in") + QDir::tempPath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString command = index.data(Qt::UserRole)
|
||||||
|
.toString()
|
||||||
|
.replace(QRegExp("(\\%.)"), '"' + m_tempFile + '"');
|
||||||
|
|
||||||
|
QString app_name = index.data(Qt::UserRole).toString().split(" ").at(0);
|
||||||
|
bool inTerminal =
|
||||||
|
index.data(Qt::UserRole + 1).toBool() || m_terminalCheckbox->isChecked();
|
||||||
|
if (inTerminal) {
|
||||||
|
bool ok = TerminalLauncher::launchDetached(command);
|
||||||
|
if (!ok) {
|
||||||
|
QMessageBox::about(
|
||||||
|
this, tr("Error"), tr("Unable to launch in terminal."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QProcess::startDetached(app_name, { m_tempFile });
|
||||||
|
}
|
||||||
|
if (!m_keepOpen) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppLauncherWidget::checkboxClicked(const bool enabled)
|
||||||
|
{
|
||||||
|
m_keepOpen = enabled;
|
||||||
|
ConfigHandler().setKeepOpenAppLauncher(enabled);
|
||||||
|
m_keepOpenCheckbox->setChecked(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppLauncherWidget::searchChanged(const QString& text)
|
||||||
|
{
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
m_filterList->hide();
|
||||||
|
m_tabWidget->show();
|
||||||
|
} else {
|
||||||
|
m_tabWidget->hide();
|
||||||
|
m_filterList->show();
|
||||||
|
m_filterList->clear();
|
||||||
|
QRegExp regexp(text, Qt::CaseInsensitive, QRegExp::Wildcard);
|
||||||
|
QVector<DesktopAppData> apps;
|
||||||
|
|
||||||
|
for (auto const& i : catIconNames.toStdMap()) {
|
||||||
|
const QString& cat = i.first;
|
||||||
|
if (!m_appsMap.contains(cat)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const QVector<DesktopAppData>& appList = m_appsMap[cat];
|
||||||
|
for (const DesktopAppData& app : appList) {
|
||||||
|
if (!apps.contains(app) && (app.name.contains(regexp) ||
|
||||||
|
app.description.contains(regexp))) {
|
||||||
|
apps.append(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addAppsToListWidget(m_filterList, apps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppLauncherWidget::initListWidget()
|
||||||
|
{
|
||||||
|
m_tabWidget = new QTabWidget;
|
||||||
|
const int size = GlobalValues::buttonBaseSize();
|
||||||
|
m_tabWidget->setIconSize(QSize(size, size));
|
||||||
|
|
||||||
for (auto const& i : catIconNames.toStdMap()) {
|
for (auto const& i : catIconNames.toStdMap()) {
|
||||||
const QString& cat = i.first;
|
const QString& cat = i.first;
|
||||||
if (!m_appsMap.contains(cat)) {
|
const QString& iconName = i.second;
|
||||||
continue;
|
|
||||||
}
|
if (!m_appsMap.contains(cat)) {
|
||||||
const QVector<DesktopAppData>& appList = m_appsMap[cat];
|
continue;
|
||||||
for (const DesktopAppData& app : appList) {
|
}
|
||||||
if (!apps.contains(app) &&
|
|
||||||
(app.name.contains(regexp) || app.description.contains(regexp))) {
|
QListWidget* itemsWidget = new QListWidget();
|
||||||
apps.append(app);
|
configureListView(itemsWidget);
|
||||||
|
|
||||||
|
const QVector<DesktopAppData>& appList = m_appsMap[cat];
|
||||||
|
addAppsToListWidget(itemsWidget, appList);
|
||||||
|
|
||||||
|
m_tabWidget->addTab(
|
||||||
|
itemsWidget, QIcon::fromTheme(iconName), QLatin1String(""));
|
||||||
|
m_tabWidget->setTabToolTip(m_tabWidget->count(), cat);
|
||||||
|
if (cat == QLatin1String("Graphics")) {
|
||||||
|
m_tabWidget->setCurrentIndex(m_tabWidget->count() - 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
addAppsToListWidget(m_filterList, apps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AppLauncherWidget::initAppMap()
|
||||||
AppLauncherWidget::initListWidget()
|
|
||||||
{
|
{
|
||||||
m_tabWidget = new QTabWidget;
|
QStringList categories({ "AudioVideo",
|
||||||
const int size = GlobalValues::buttonBaseSize();
|
"Audio",
|
||||||
m_tabWidget->setIconSize(QSize(size, size));
|
"Video",
|
||||||
|
"Development",
|
||||||
|
"Graphics",
|
||||||
|
"Network",
|
||||||
|
"Office",
|
||||||
|
"Science",
|
||||||
|
"Settings",
|
||||||
|
"System",
|
||||||
|
"Utility" });
|
||||||
|
|
||||||
for (auto const& i : catIconNames.toStdMap()) {
|
m_appsMap = m_parser.getAppsByCategory(categories);
|
||||||
const QString& cat = i.first;
|
|
||||||
const QString& iconName = i.second;
|
|
||||||
|
|
||||||
if (!m_appsMap.contains(cat)) {
|
// Unify multimedia.
|
||||||
continue;
|
QVector<DesktopAppData> multimediaList;
|
||||||
|
QStringList multimediaNames;
|
||||||
|
multimediaNames << QStringLiteral("AudioVideo") << QStringLiteral("Audio")
|
||||||
|
<< QStringLiteral("Video");
|
||||||
|
for (const QString& name : multimediaNames) {
|
||||||
|
if (!m_appsMap.contains(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (auto i : m_appsMap[name]) {
|
||||||
|
if (!multimediaList.contains(i)) {
|
||||||
|
multimediaList.append(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_appsMap.remove(name);
|
||||||
}
|
}
|
||||||
|
m_appsMap.insert(QStringLiteral("Multimedia"), multimediaList);
|
||||||
QListWidget* itemsWidget = new QListWidget();
|
|
||||||
configureListView(itemsWidget);
|
|
||||||
|
|
||||||
const QVector<DesktopAppData>& appList = m_appsMap[cat];
|
|
||||||
addAppsToListWidget(itemsWidget, appList);
|
|
||||||
|
|
||||||
m_tabWidget->addTab(
|
|
||||||
itemsWidget, QIcon::fromTheme(iconName), QLatin1String(""));
|
|
||||||
m_tabWidget->setTabToolTip(m_tabWidget->count(), cat);
|
|
||||||
if (cat == QLatin1String("Graphics")) {
|
|
||||||
m_tabWidget->setCurrentIndex(m_tabWidget->count() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AppLauncherWidget::configureListView(QListWidget* widget)
|
||||||
AppLauncherWidget::initAppMap()
|
|
||||||
{
|
{
|
||||||
QStringList categories({ "AudioVideo",
|
widget->setItemDelegate(new LauncherItemDelegate());
|
||||||
"Audio",
|
widget->setViewMode(QListWidget::IconMode);
|
||||||
"Video",
|
widget->setResizeMode(QListView::Adjust);
|
||||||
"Development",
|
widget->setSpacing(4);
|
||||||
"Graphics",
|
widget->setFlow(QListView::LeftToRight);
|
||||||
"Network",
|
widget->setDragEnabled(false);
|
||||||
"Office",
|
widget->setMinimumWidth(GlobalValues::buttonBaseSize() * 11);
|
||||||
"Science",
|
connect(widget, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
||||||
"Settings",
|
|
||||||
"System",
|
|
||||||
"Utility" });
|
|
||||||
|
|
||||||
m_appsMap = m_parser.getAppsByCategory(categories);
|
|
||||||
|
|
||||||
// Unify multimedia.
|
|
||||||
QVector<DesktopAppData> multimediaList;
|
|
||||||
QStringList multimediaNames;
|
|
||||||
multimediaNames << QStringLiteral("AudioVideo") << QStringLiteral("Audio")
|
|
||||||
<< QStringLiteral("Video");
|
|
||||||
for (const QString& name : multimediaNames) {
|
|
||||||
if (!m_appsMap.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (auto i : m_appsMap[name]) {
|
|
||||||
if (!multimediaList.contains(i)) {
|
|
||||||
multimediaList.append(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_appsMap.remove(name);
|
|
||||||
}
|
|
||||||
m_appsMap.insert(QStringLiteral("Multimedia"), multimediaList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void AppLauncherWidget::addAppsToListWidget(
|
||||||
AppLauncherWidget::configureListView(QListWidget* widget)
|
QListWidget* widget,
|
||||||
|
const QVector<DesktopAppData>& appList)
|
||||||
{
|
{
|
||||||
widget->setItemDelegate(new LauncherItemDelegate());
|
for (const DesktopAppData& app : appList) {
|
||||||
widget->setViewMode(QListWidget::IconMode);
|
QListWidgetItem* buttonItem = new QListWidgetItem(widget);
|
||||||
widget->setResizeMode(QListView::Adjust);
|
buttonItem->setData(Qt::DecorationRole, app.icon);
|
||||||
widget->setSpacing(4);
|
buttonItem->setData(Qt::DisplayRole, app.name);
|
||||||
widget->setFlow(QListView::LeftToRight);
|
buttonItem->setData(Qt::UserRole, app.exec);
|
||||||
widget->setDragEnabled(false);
|
buttonItem->setData(Qt::UserRole + 1, app.showInTerminal);
|
||||||
widget->setMinimumWidth(GlobalValues::buttonBaseSize() * 11);
|
QColor foregroundColor =
|
||||||
connect(widget, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
this->palette().color(QWidget::foregroundRole());
|
||||||
}
|
buttonItem->setForeground(foregroundColor);
|
||||||
|
|
||||||
void
|
buttonItem->setIcon(app.icon);
|
||||||
AppLauncherWidget::addAppsToListWidget(QListWidget* widget,
|
buttonItem->setText(app.name);
|
||||||
const QVector<DesktopAppData>& appList)
|
buttonItem->setToolTip(app.description);
|
||||||
{
|
}
|
||||||
for (const DesktopAppData& app : appList) {
|
|
||||||
QListWidgetItem* buttonItem = new QListWidgetItem(widget);
|
|
||||||
buttonItem->setData(Qt::DecorationRole, app.icon);
|
|
||||||
buttonItem->setData(Qt::DisplayRole, app.name);
|
|
||||||
buttonItem->setData(Qt::UserRole, app.exec);
|
|
||||||
buttonItem->setData(Qt::UserRole + 1, app.showInTerminal);
|
|
||||||
QColor foregroundColor = this->palette().color(QWidget::foregroundRole());
|
|
||||||
buttonItem->setForeground(foregroundColor);
|
|
||||||
|
|
||||||
buttonItem->setIcon(app.icon);
|
|
||||||
buttonItem->setText(app.name);
|
|
||||||
buttonItem->setToolTip(app.description);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,31 +29,31 @@ class QListWidget;
|
|||||||
|
|
||||||
class AppLauncherWidget : public QWidget
|
class AppLauncherWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AppLauncherWidget(const QPixmap& p, QWidget* parent = nullptr);
|
explicit AppLauncherWidget(const QPixmap& p, QWidget* parent = nullptr);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void launch(const QModelIndex& index);
|
void launch(const QModelIndex& index);
|
||||||
void checkboxClicked(const bool enabled);
|
void checkboxClicked(const bool enabled);
|
||||||
void searchChanged(const QString& text);
|
void searchChanged(const QString& text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initListWidget();
|
void initListWidget();
|
||||||
void initAppMap();
|
void initAppMap();
|
||||||
void configureListView(QListWidget* widget);
|
void configureListView(QListWidget* widget);
|
||||||
void addAppsToListWidget(QListWidget* widget,
|
void addAppsToListWidget(QListWidget* widget,
|
||||||
const QVector<DesktopAppData>& appList);
|
const QVector<DesktopAppData>& appList);
|
||||||
|
|
||||||
DesktopFileParser m_parser;
|
DesktopFileParser m_parser;
|
||||||
QPixmap m_pixmap;
|
QPixmap m_pixmap;
|
||||||
QString m_tempFile;
|
QString m_tempFile;
|
||||||
bool m_keepOpen;
|
bool m_keepOpen;
|
||||||
QMap<QString, QVector<DesktopAppData>> m_appsMap;
|
QMap<QString, QVector<DesktopAppData>> m_appsMap;
|
||||||
QCheckBox* m_keepOpenCheckbox;
|
QCheckBox* m_keepOpenCheckbox;
|
||||||
QCheckBox* m_terminalCheckbox;
|
QCheckBox* m_terminalCheckbox;
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
QLineEdit* m_lineEdit;
|
QLineEdit* m_lineEdit;
|
||||||
QListWidget* m_filterList;
|
QListWidget* m_filterList;
|
||||||
QTabWidget* m_tabWidget;
|
QTabWidget* m_tabWidget;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,45 +23,44 @@ LauncherItemDelegate::LauncherItemDelegate(QObject* parent)
|
|||||||
: QStyledItemDelegate(parent)
|
: QStyledItemDelegate(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
void LauncherItemDelegate::paint(QPainter* painter,
|
||||||
LauncherItemDelegate::paint(QPainter* painter,
|
const QStyleOptionViewItem& option,
|
||||||
const QStyleOptionViewItem& option,
|
const QModelIndex& index) const
|
||||||
const QModelIndex& index) const
|
|
||||||
{
|
{
|
||||||
const QRect& rect = option.rect;
|
const QRect& rect = option.rect;
|
||||||
if (option.state & (QStyle::State_Selected | QStyle::State_MouseOver)) {
|
if (option.state & (QStyle::State_Selected | QStyle::State_MouseOver)) {
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setPen(Qt::transparent);
|
painter->setPen(Qt::transparent);
|
||||||
painter->setBrush(QPalette().highlight());
|
painter->setBrush(QPalette().highlight());
|
||||||
painter->drawRect(rect.x(), rect.y(), rect.width() - 1, rect.height() - 1);
|
painter->drawRect(
|
||||||
painter->restore();
|
rect.x(), rect.y(), rect.width() - 1, rect.height() - 1);
|
||||||
}
|
painter->restore();
|
||||||
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
|
}
|
||||||
|
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
|
||||||
|
|
||||||
const int iconSide = GlobalValues::buttonBaseSize() * 1.3;
|
const int iconSide = GlobalValues::buttonBaseSize() * 1.3;
|
||||||
const int halfIcon = iconSide / 2;
|
const int halfIcon = iconSide / 2;
|
||||||
const int halfWidth = rect.width() / 2;
|
const int halfWidth = rect.width() / 2;
|
||||||
const int halfHeight = rect.height() / 2;
|
const int halfHeight = rect.height() / 2;
|
||||||
QSize size(iconSide, iconSide);
|
QSize size(iconSide, iconSide);
|
||||||
QPixmap pixIcon = icon.pixmap(size).scaled(size, Qt::KeepAspectRatio);
|
QPixmap pixIcon = icon.pixmap(size).scaled(size, Qt::KeepAspectRatio);
|
||||||
painter->drawPixmap(rect.x() + (halfWidth - halfIcon),
|
painter->drawPixmap(rect.x() + (halfWidth - halfIcon),
|
||||||
rect.y() + (halfHeight / 2 - halfIcon),
|
rect.y() + (halfHeight / 2 - halfIcon),
|
||||||
iconSide,
|
iconSide,
|
||||||
iconSide,
|
iconSide,
|
||||||
pixIcon);
|
pixIcon);
|
||||||
const QRect textRect(
|
const QRect textRect(
|
||||||
rect.x(), rect.y() + halfHeight, rect.width(), halfHeight);
|
rect.x(), rect.y() + halfHeight, rect.width(), halfHeight);
|
||||||
painter->drawText(textRect,
|
painter->drawText(textRect,
|
||||||
Qt::TextWordWrap | Qt::AlignHCenter,
|
Qt::TextWordWrap | Qt::AlignHCenter,
|
||||||
index.data(Qt::DisplayRole).toString());
|
index.data(Qt::DisplayRole).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize
|
QSize LauncherItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
||||||
LauncherItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
const QModelIndex& index) const
|
||||||
const QModelIndex& index) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(option);
|
Q_UNUSED(option);
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
const int size = GlobalValues::buttonBaseSize();
|
const int size = GlobalValues::buttonBaseSize();
|
||||||
return QSize(size * 3.2, size * 3.7);
|
return QSize(size * 3.2, size * 3.7);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,14 @@
|
|||||||
|
|
||||||
class LauncherItemDelegate : public QStyledItemDelegate
|
class LauncherItemDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LauncherItemDelegate(QObject* parent = nullptr);
|
explicit LauncherItemDelegate(QObject* parent = nullptr);
|
||||||
|
|
||||||
void paint(QPainter* painter,
|
void paint(QPainter* painter,
|
||||||
const QStyleOptionViewItem& option,
|
const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex& index) const;
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem& option,
|
QSize sizeHint(const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex& index) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,28 +33,28 @@
|
|||||||
#include "src/tools/launcher/applauncherwidget.h"
|
#include "src/tools/launcher/applauncherwidget.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void showOpenWithMenu(const QPixmap& capture)
|
||||||
showOpenWithMenu(const QPixmap& capture)
|
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
QString tempFile =
|
QString tempFile =
|
||||||
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
||||||
bool ok = capture.save(tempFile);
|
bool ok = capture.save(tempFile);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
QMessageBox::about(nullptr,
|
QMessageBox::about(nullptr,
|
||||||
QObject::tr("Error"),
|
QObject::tr("Error"),
|
||||||
QObject::tr("Unable to write in") + QDir::tempPath());
|
QObject::tr("Unable to write in") +
|
||||||
return;
|
QDir::tempPath());
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OPENASINFO info;
|
OPENASINFO info;
|
||||||
auto wStringFile = tempFile.replace("/", "\\").toStdWString();
|
auto wStringFile = tempFile.replace("/", "\\").toStdWString();
|
||||||
info.pcszFile = wStringFile.c_str();
|
info.pcszFile = wStringFile.c_str();
|
||||||
info.pcszClass = nullptr;
|
info.pcszClass = nullptr;
|
||||||
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
|
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
|
||||||
SHOpenWithDialog(nullptr, &info);
|
SHOpenWithDialog(nullptr, &info);
|
||||||
#else
|
#else
|
||||||
auto w = new AppLauncherWidget(capture);
|
auto w = new AppLauncherWidget(capture);
|
||||||
w->show();
|
w->show();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,4 @@
|
|||||||
|
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
void
|
void showOpenWithMenu(const QPixmap& capture);
|
||||||
showOpenWithMenu(const QPixmap& capture);
|
|
||||||
|
|||||||
@@ -23,18 +23,18 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const TerminalApp terminalApps[] = {
|
static const TerminalApp terminalApps[] = {
|
||||||
{ "x-terminal-emulator", "-e" },
|
{ "x-terminal-emulator", "-e" },
|
||||||
{ "xfce4-terminal", "-x" },
|
{ "xfce4-terminal", "-x" },
|
||||||
{ "konsole", "-e" },
|
{ "konsole", "-e" },
|
||||||
{ "gnome-terminal", "--" },
|
{ "gnome-terminal", "--" },
|
||||||
{ "terminator", "-e" },
|
{ "terminator", "-e" },
|
||||||
{ "terminology", "-e" },
|
{ "terminology", "-e" },
|
||||||
{ "tilix", "-e" },
|
{ "tilix", "-e" },
|
||||||
{ "xterm", "-e" },
|
{ "xterm", "-e" },
|
||||||
{ "aterm", "-e" },
|
{ "aterm", "-e" },
|
||||||
{ "Eterm", "-e" },
|
{ "Eterm", "-e" },
|
||||||
{ "rxvt", "-e" },
|
{ "rxvt", "-e" },
|
||||||
{ "urxvt", "-e" },
|
{ "urxvt", "-e" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,24 +42,22 @@ TerminalLauncher::TerminalLauncher(QObject* parent)
|
|||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TerminalApp
|
TerminalApp TerminalLauncher::getPreferedTerminal()
|
||||||
TerminalLauncher::getPreferedTerminal()
|
|
||||||
{
|
{
|
||||||
TerminalApp res;
|
TerminalApp res;
|
||||||
for (const TerminalApp& app : terminalApps) {
|
for (const TerminalApp& app : terminalApps) {
|
||||||
QString path = QStandardPaths::findExecutable(app.name);
|
QString path = QStandardPaths::findExecutable(app.name);
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
res = app;
|
res = app;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return res;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool TerminalLauncher::launchDetached(const QString& command)
|
||||||
TerminalLauncher::launchDetached(const QString& command)
|
|
||||||
{
|
{
|
||||||
TerminalApp app = getPreferedTerminal();
|
TerminalApp app = getPreferedTerminal();
|
||||||
QString s = app.name + " " + app.arg + " " + command;
|
QString s = app.name + " " + app.arg + " " + command;
|
||||||
return QProcess::startDetached(app.name, { app.arg, command });
|
return QProcess::startDetached(app.name, { app.arg, command });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,18 +21,18 @@
|
|||||||
|
|
||||||
struct TerminalApp
|
struct TerminalApp
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString arg;
|
QString arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TerminalLauncher : public QObject
|
class TerminalLauncher : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TerminalLauncher(QObject* parent = nullptr);
|
explicit TerminalLauncher(QObject* parent = nullptr);
|
||||||
|
|
||||||
static bool launchDetached(const QString& command);
|
static bool launchDetached(const QString& command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static TerminalApp getPreferedTerminal();
|
static TerminalApp getPreferedTerminal();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,68 +27,62 @@ namespace {
|
|||||||
LineTool::LineTool(QObject* parent)
|
LineTool::LineTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_supportsOrthogonalAdj = true;
|
m_supportsOrthogonalAdj = true;
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon LineTool::icon(const QColor& background, bool inEditor) const
|
||||||
LineTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "line.svg");
|
return QIcon(iconPath(background) + "line.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString LineTool::name() const
|
||||||
LineTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Line");
|
return tr("Line");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType LineTool::nameID() const
|
||||||
LineTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::LINE;
|
return ToolType::LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString LineTool::description() const
|
||||||
LineTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Line as the paint tool");
|
return tr("Set the Line as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* LineTool::copy(QObject* parent)
|
||||||
LineTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new LineTool(parent);
|
return new LineTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void LineTool::process(QPainter& painter,
|
||||||
LineTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawLine(m_points.first, m_points.second);
|
painter.drawLine(m_points.first, m_points.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void LineTool::paintMousePreview(QPainter& painter,
|
||||||
LineTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void LineTool::drawStart(const CaptureContext& context)
|
||||||
LineTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void LineTool::pressed(const CaptureContext& context)
|
||||||
LineTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,25 @@
|
|||||||
|
|
||||||
class LineTool : public AbstractTwoPointTool
|
class LineTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LineTool(QObject* parent = nullptr);
|
explicit LineTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,78 +27,71 @@ namespace {
|
|||||||
MarkerTool::MarkerTool(QObject* parent)
|
MarkerTool::MarkerTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_supportsOrthogonalAdj = true;
|
m_supportsOrthogonalAdj = true;
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon MarkerTool::icon(const QColor& background, bool inEditor) const
|
||||||
MarkerTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "marker.svg");
|
return QIcon(iconPath(background) + "marker.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString MarkerTool::name() const
|
||||||
MarkerTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Marker");
|
return tr("Marker");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType MarkerTool::nameID() const
|
||||||
MarkerTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::MARKER;
|
return ToolType::MARKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString MarkerTool::description() const
|
||||||
MarkerTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Marker as the paint tool");
|
return tr("Set the Marker as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* MarkerTool::copy(QObject* parent)
|
||||||
MarkerTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new MarkerTool(parent);
|
return new MarkerTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MarkerTool::process(QPainter& painter,
|
||||||
MarkerTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||||
painter.setOpacity(0.35);
|
painter.setOpacity(0.35);
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawLine(m_points.first, m_points.second);
|
painter.drawLine(m_points.first, m_points.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MarkerTool::paintMousePreview(QPainter& painter,
|
||||||
MarkerTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||||
painter.setOpacity(0.35);
|
painter.setOpacity(0.35);
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MarkerTool::drawStart(const CaptureContext& context)
|
||||||
MarkerTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MarkerTool::pressed(const CaptureContext& context)
|
||||||
MarkerTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MarkerTool::thicknessChanged(const int th)
|
||||||
MarkerTool::thicknessChanged(const int th)
|
|
||||||
{
|
{
|
||||||
m_thickness = th + PADDING_VALUE;
|
m_thickness = th + PADDING_VALUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,26 @@
|
|||||||
|
|
||||||
class MarkerTool : public AbstractTwoPointTool
|
class MarkerTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit MarkerTool(QObject* parent = nullptr);
|
explicit MarkerTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
void thicknessChanged(const int th) override;
|
void thicknessChanged(const int th) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,45 +22,38 @@ MoveTool::MoveTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool MoveTool::closeOnButtonPressed() const
|
||||||
MoveTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon MoveTool::icon(const QColor& background, bool inEditor) const
|
||||||
MoveTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "cursor-move.svg");
|
return QIcon(iconPath(background) + "cursor-move.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString MoveTool::name() const
|
||||||
MoveTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Move");
|
return tr("Move");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType MoveTool::nameID() const
|
||||||
MoveTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::MOVE;
|
return ToolType::MOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString MoveTool::description() const
|
||||||
MoveTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Move the selection area");
|
return tr("Move the selection area");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* MoveTool::copy(QObject* parent)
|
||||||
MoveTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new MoveTool(parent);
|
return new MoveTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MoveTool::pressed(const CaptureContext& context)
|
||||||
MoveTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
emit requestAction(REQ_MOVE_MODE);
|
emit requestAction(REQ_MOVE_MODE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,19 +21,19 @@
|
|||||||
|
|
||||||
class MoveTool : public AbstractActionTool
|
class MoveTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit MoveTool(QObject* parent = nullptr);
|
explicit MoveTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,65 +22,59 @@ PencilTool::PencilTool(QObject* parent)
|
|||||||
: AbstractPathTool(parent)
|
: AbstractPathTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QIcon
|
QIcon PencilTool::icon(const QColor& background, bool inEditor) const
|
||||||
PencilTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "pencil.svg");
|
return QIcon(iconPath(background) + "pencil.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString PencilTool::name() const
|
||||||
PencilTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Pencil");
|
return tr("Pencil");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType PencilTool::nameID() const
|
||||||
PencilTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::PENCIL;
|
return ToolType::PENCIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString PencilTool::description() const
|
||||||
PencilTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Pencil as the paint tool");
|
return tr("Set the Pencil as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* PencilTool::copy(QObject* parent)
|
||||||
PencilTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new PencilTool(parent);
|
return new PencilTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PencilTool::process(QPainter& painter,
|
||||||
PencilTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawPolyline(m_points.data(), m_points.size());
|
painter.drawPolyline(m_points.data(), m_points.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PencilTool::paintMousePreview(QPainter& painter,
|
||||||
PencilTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, context.thickness + 2));
|
painter.setPen(QPen(context.color, context.thickness + 2));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PencilTool::drawStart(const CaptureContext& context)
|
||||||
PencilTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + 2;
|
m_thickness = context.thickness + 2;
|
||||||
m_points.append(context.mousePos);
|
m_points.append(context.mousePos);
|
||||||
m_backupArea.setTopLeft(context.mousePos);
|
m_backupArea.setTopLeft(context.mousePos);
|
||||||
m_backupArea.setBottomRight(context.mousePos);
|
m_backupArea.setBottomRight(context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PencilTool::pressed(const CaptureContext& context)
|
||||||
PencilTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,26 @@
|
|||||||
|
|
||||||
class PencilTool : public AbstractPathTool
|
class PencilTool : public AbstractPathTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PencilTool(QObject* parent = nullptr);
|
explicit PencilTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,58 +22,50 @@ PinTool::PinTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool PinTool::closeOnButtonPressed() const
|
||||||
PinTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon PinTool::icon(const QColor& background, bool inEditor) const
|
||||||
PinTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "pin.svg");
|
return QIcon(iconPath(background) + "pin.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString PinTool::name() const
|
||||||
PinTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Pin Tool");
|
return tr("Pin Tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType PinTool::nameID() const
|
||||||
PinTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::PIN;
|
return ToolType::PIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString PinTool::description() const
|
||||||
PinTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Pin image on the desktop");
|
return tr("Pin image on the desktop");
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget*
|
QWidget* PinTool::widget()
|
||||||
PinTool::widget()
|
|
||||||
{
|
{
|
||||||
PinWidget* w = new PinWidget(m_pixmap);
|
PinWidget* w = new PinWidget(m_pixmap);
|
||||||
const int&& m = w->margin();
|
const int&& m = w->margin();
|
||||||
QRect adjusted_pos = m_geometry + QMargins(m, m, m, m);
|
QRect adjusted_pos = m_geometry + QMargins(m, m, m, m);
|
||||||
w->setGeometry(adjusted_pos);
|
w->setGeometry(adjusted_pos);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* PinTool::copy(QObject* parent)
|
||||||
PinTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new PinTool(parent);
|
return new PinTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinTool::pressed(const CaptureContext& context)
|
||||||
PinTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
m_geometry = context.selection;
|
m_geometry = context.selection;
|
||||||
m_geometry.setTopLeft(m_geometry.topLeft() + context.widgetOffset);
|
m_geometry.setTopLeft(m_geometry.topLeft() + context.widgetOffset);
|
||||||
m_pixmap = context.selectedScreenshotArea();
|
m_pixmap = context.selectedScreenshotArea();
|
||||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,27 +21,27 @@
|
|||||||
|
|
||||||
class PinTool : public AbstractActionTool
|
class PinTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PinTool(QObject* parent = nullptr);
|
explicit PinTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QRect m_geometry;
|
QRect m_geometry;
|
||||||
QPixmap m_pixmap;
|
QPixmap m_pixmap;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,93 +27,85 @@ PinWidget::PinWidget(const QPixmap& pixmap, QWidget* parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_pixmap(pixmap)
|
, m_pixmap(pixmap)
|
||||||
{
|
{
|
||||||
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
||||||
// set the bottom widget background transparent
|
// set the bottom widget background transparent
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
|
||||||
ConfigHandler conf;
|
ConfigHandler conf;
|
||||||
m_baseColor = conf.uiMainColorValue();
|
m_baseColor = conf.uiMainColorValue();
|
||||||
m_hoverColor = conf.uiContrastColorValue();
|
m_hoverColor = conf.uiContrastColorValue();
|
||||||
|
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
const int margin = this->margin();
|
const int margin = this->margin();
|
||||||
m_layout->setContentsMargins(margin, margin, margin, margin);
|
m_layout->setContentsMargins(margin, margin, margin, margin);
|
||||||
|
|
||||||
m_shadowEffect = new QGraphicsDropShadowEffect(this);
|
m_shadowEffect = new QGraphicsDropShadowEffect(this);
|
||||||
m_shadowEffect->setColor(m_baseColor);
|
m_shadowEffect->setColor(m_baseColor);
|
||||||
m_shadowEffect->setBlurRadius(2 * margin);
|
m_shadowEffect->setBlurRadius(2 * margin);
|
||||||
m_shadowEffect->setOffset(0, 0);
|
m_shadowEffect->setOffset(0, 0);
|
||||||
setGraphicsEffect(m_shadowEffect);
|
setGraphicsEffect(m_shadowEffect);
|
||||||
|
|
||||||
m_label = new QLabel();
|
m_label = new QLabel();
|
||||||
m_label->setPixmap(m_pixmap);
|
m_label->setPixmap(m_pixmap);
|
||||||
m_layout->addWidget(m_label);
|
m_layout->addWidget(m_label);
|
||||||
|
|
||||||
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
|
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
|
||||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int PinWidget::margin() const
|
||||||
PinWidget::margin() const
|
|
||||||
{
|
{
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::wheelEvent(QWheelEvent* e)
|
||||||
PinWidget::wheelEvent(QWheelEvent* e)
|
|
||||||
{
|
{
|
||||||
int val = e->angleDelta().y() > 0 ? 15 : -15;
|
int val = e->angleDelta().y() > 0 ? 15 : -15;
|
||||||
int newWidth = qBound(50, m_label->width() + val, maximumWidth());
|
int newWidth = qBound(50, m_label->width() + val, maximumWidth());
|
||||||
int newHeight = qBound(50, m_label->height() + val, maximumHeight());
|
int newHeight = qBound(50, m_label->height() + val, maximumHeight());
|
||||||
|
|
||||||
QSize size(newWidth, newHeight);
|
QSize size(newWidth, newHeight);
|
||||||
setScaledPixmap(size);
|
setScaledPixmap(size);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::enterEvent(QEvent*)
|
||||||
PinWidget::enterEvent(QEvent*)
|
|
||||||
{
|
{
|
||||||
m_shadowEffect->setColor(m_hoverColor);
|
m_shadowEffect->setColor(m_hoverColor);
|
||||||
}
|
}
|
||||||
void
|
void PinWidget::leaveEvent(QEvent*)
|
||||||
PinWidget::leaveEvent(QEvent*)
|
|
||||||
{
|
{
|
||||||
m_shadowEffect->setColor(m_baseColor);
|
m_shadowEffect->setColor(m_baseColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::mouseDoubleClickEvent(QMouseEvent*)
|
||||||
PinWidget::mouseDoubleClickEvent(QMouseEvent*)
|
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::mousePressEvent(QMouseEvent* e)
|
||||||
PinWidget::mousePressEvent(QMouseEvent* e)
|
|
||||||
{
|
{
|
||||||
m_dragStart = e->globalPos();
|
m_dragStart = e->globalPos();
|
||||||
m_offsetX = e->localPos().x() / width();
|
m_offsetX = e->localPos().x() / width();
|
||||||
m_offsetY = e->localPos().y() / height();
|
m_offsetY = e->localPos().y() / height();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::mouseMoveEvent(QMouseEvent* e)
|
||||||
PinWidget::mouseMoveEvent(QMouseEvent* e)
|
|
||||||
{
|
{
|
||||||
const QPoint delta = e->globalPos() - m_dragStart;
|
const QPoint delta = e->globalPos() - m_dragStart;
|
||||||
int offsetW = width() * m_offsetX;
|
int offsetW = width() * m_offsetX;
|
||||||
int offsetH = height() * m_offsetY;
|
int offsetH = height() * m_offsetY;
|
||||||
move(m_dragStart.x() + delta.x() - offsetW,
|
move(m_dragStart.x() + delta.x() - offsetW,
|
||||||
m_dragStart.y() + delta.y() - offsetH);
|
m_dragStart.y() + delta.y() - offsetH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PinWidget::setScaledPixmap(const QSize& size)
|
||||||
PinWidget::setScaledPixmap(const QSize& size)
|
|
||||||
{
|
{
|
||||||
const qreal scale = qApp->devicePixelRatio();
|
const qreal scale = qApp->devicePixelRatio();
|
||||||
QPixmap scaledPixmap = m_pixmap.scaled(
|
QPixmap scaledPixmap = m_pixmap.scaled(
|
||||||
size * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
size * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
scaledPixmap.setDevicePixelRatio(scale);
|
scaledPixmap.setDevicePixelRatio(scale);
|
||||||
m_label->setPixmap(scaledPixmap);
|
m_label->setPixmap(scaledPixmap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,28 +25,28 @@ class QLabel;
|
|||||||
|
|
||||||
class PinWidget : public QWidget
|
class PinWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PinWidget(const QPixmap& pixmap, QWidget* parent = nullptr);
|
explicit PinWidget(const QPixmap& pixmap, QWidget* parent = nullptr);
|
||||||
|
|
||||||
int margin() const;
|
int margin() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void wheelEvent(QWheelEvent* e);
|
void wheelEvent(QWheelEvent* e);
|
||||||
void mouseDoubleClickEvent(QMouseEvent*);
|
void mouseDoubleClickEvent(QMouseEvent*);
|
||||||
void mousePressEvent(QMouseEvent*);
|
void mousePressEvent(QMouseEvent*);
|
||||||
void mouseMoveEvent(QMouseEvent*);
|
void mouseMoveEvent(QMouseEvent*);
|
||||||
void enterEvent(QEvent*);
|
void enterEvent(QEvent*);
|
||||||
void leaveEvent(QEvent*);
|
void leaveEvent(QEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setScaledPixmap(const QSize& size);
|
void setScaledPixmap(const QSize& size);
|
||||||
|
|
||||||
QPixmap m_pixmap;
|
QPixmap m_pixmap;
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
QLabel* m_label;
|
QLabel* m_label;
|
||||||
QPoint m_dragStart;
|
QPoint m_dragStart;
|
||||||
qreal m_offsetX, m_offsetY;
|
qreal m_offsetX, m_offsetY;
|
||||||
QGraphicsDropShadowEffect* m_shadowEffect;
|
QGraphicsDropShadowEffect* m_shadowEffect;
|
||||||
QColor m_baseColor, m_hoverColor;
|
QColor m_baseColor, m_hoverColor;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,95 +28,88 @@ PixelateTool::PixelateTool(QObject* parent)
|
|||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QIcon
|
QIcon PixelateTool::icon(const QColor& background, bool inEditor) const
|
||||||
PixelateTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "pixelate.svg");
|
return QIcon(iconPath(background) + "pixelate.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString PixelateTool::name() const
|
||||||
PixelateTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Pixelate");
|
return tr("Pixelate");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType PixelateTool::nameID() const
|
||||||
PixelateTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::PIXELATE;
|
return ToolType::PIXELATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString PixelateTool::description() const
|
||||||
PixelateTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set Pixelate as the paint tool");
|
return tr("Set Pixelate as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* PixelateTool::copy(QObject* parent)
|
||||||
PixelateTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new PixelateTool(parent);
|
return new PixelateTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PixelateTool::process(QPainter& painter,
|
||||||
PixelateTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint& p0 = m_points.first;
|
QPoint& p0 = m_points.first;
|
||||||
QPoint& p1 = m_points.second;
|
QPoint& p1 = m_points.second;
|
||||||
QRect selection = QRect(p0, p1).normalized();
|
QRect selection = QRect(p0, p1).normalized();
|
||||||
|
|
||||||
// If thickness is less than 1, use old blur process
|
// If thickness is less than 1, use old blur process
|
||||||
if (m_thickness <= 1) {
|
if (m_thickness <= 1) {
|
||||||
auto pixelRatio = pixmap.devicePixelRatio();
|
auto pixelRatio = pixmap.devicePixelRatio();
|
||||||
|
|
||||||
QRect selectionScaled =
|
QRect selectionScaled =
|
||||||
QRect(p0 * pixelRatio, p1 * pixelRatio).normalized();
|
QRect(p0 * pixelRatio, p1 * pixelRatio).normalized();
|
||||||
|
|
||||||
QGraphicsBlurEffect* blur = new QGraphicsBlurEffect;
|
QGraphicsBlurEffect* blur = new QGraphicsBlurEffect;
|
||||||
blur->setBlurRadius(10);
|
blur->setBlurRadius(10);
|
||||||
QGraphicsPixmapItem* item =
|
QGraphicsPixmapItem* item =
|
||||||
new QGraphicsPixmapItem(pixmap.copy(selectionScaled));
|
new QGraphicsPixmapItem(pixmap.copy(selectionScaled));
|
||||||
item->setGraphicsEffect(blur);
|
item->setGraphicsEffect(blur);
|
||||||
|
|
||||||
QGraphicsScene scene;
|
QGraphicsScene scene;
|
||||||
scene.addItem(item);
|
scene.addItem(item);
|
||||||
|
|
||||||
scene.render(&painter, selection, QRectF());
|
scene.render(&painter, selection, QRectF());
|
||||||
blur->setBlurRadius(12);
|
blur->setBlurRadius(12);
|
||||||
scene.render(&painter, selection, QRectF());
|
scene.render(&painter, selection, QRectF());
|
||||||
} else {
|
} else {
|
||||||
int width = selection.width() * (0.5 / qMax(1, m_thickness));
|
int width = selection.width() * (0.5 / qMax(1, m_thickness));
|
||||||
|
|
||||||
QPixmap t = pixmap.copy(selection);
|
QPixmap t = pixmap.copy(selection);
|
||||||
t = t.scaledToWidth(qMax(width, 10), Qt::SmoothTransformation);
|
t = t.scaledToWidth(qMax(width, 10), Qt::SmoothTransformation);
|
||||||
t = t.scaledToWidth(selection.width());
|
t = t.scaledToWidth(selection.width());
|
||||||
painter.drawImage(selection, t.toImage());
|
painter.drawImage(selection, t.toImage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PixelateTool::paintMousePreview(QPainter& painter,
|
||||||
PixelateTool::paintMousePreview(QPainter& painter,
|
const CaptureContext& context)
|
||||||
const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
Q_UNUSED(painter);
|
Q_UNUSED(painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PixelateTool::drawStart(const CaptureContext& context)
|
||||||
PixelateTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_thickness = context.thickness;
|
m_thickness = context.thickness;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PixelateTool::pressed(const CaptureContext& context)
|
||||||
PixelateTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,25 @@
|
|||||||
|
|
||||||
class PixelateTool : public AbstractTwoPointTool
|
class PixelateTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PixelateTool(QObject* parent = nullptr);
|
explicit PixelateTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,71 +25,62 @@ namespace {
|
|||||||
RectangleTool::RectangleTool(QObject* parent)
|
RectangleTool::RectangleTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon RectangleTool::icon(const QColor& background, bool inEditor) const
|
||||||
RectangleTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "square.svg");
|
return QIcon(iconPath(background) + "square.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString RectangleTool::name() const
|
||||||
RectangleTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Rectangle");
|
return tr("Rectangle");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType RectangleTool::nameID() const
|
||||||
RectangleTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::RECTANGLE;
|
return ToolType::RECTANGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString RectangleTool::description() const
|
||||||
RectangleTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set the Rectangle as the paint tool");
|
return tr("Set the Rectangle as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* RectangleTool::copy(QObject* parent)
|
||||||
RectangleTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new RectangleTool(parent);
|
return new RectangleTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RectangleTool::process(QPainter& painter,
|
||||||
RectangleTool::process(QPainter& painter,
|
const QPixmap& pixmap,
|
||||||
const QPixmap& pixmap,
|
bool recordUndo)
|
||||||
bool recordUndo)
|
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.setBrush(QBrush(m_color));
|
painter.setBrush(QBrush(m_color));
|
||||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RectangleTool::paintMousePreview(QPainter& painter,
|
||||||
RectangleTool::paintMousePreview(QPainter& painter,
|
const CaptureContext& context)
|
||||||
const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RectangleTool::drawStart(const CaptureContext& context)
|
||||||
RectangleTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RectangleTool::pressed(const CaptureContext& context)
|
||||||
RectangleTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,25 @@
|
|||||||
|
|
||||||
class RectangleTool : public AbstractTwoPointTool
|
class RectangleTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit RectangleTool(QObject* parent = nullptr);
|
explicit RectangleTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,45 +22,38 @@ RedoTool::RedoTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool RedoTool::closeOnButtonPressed() const
|
||||||
RedoTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon RedoTool::icon(const QColor& background, bool inEditor) const
|
||||||
RedoTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "redo-variant.svg");
|
return QIcon(iconPath(background) + "redo-variant.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString RedoTool::name() const
|
||||||
RedoTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Redo");
|
return tr("Redo");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType RedoTool::nameID() const
|
||||||
RedoTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::REDO;
|
return ToolType::REDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString RedoTool::description() const
|
||||||
RedoTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Redo the next modification");
|
return tr("Redo the next modification");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* RedoTool::copy(QObject* parent)
|
||||||
RedoTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new RedoTool(parent);
|
return new RedoTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RedoTool::pressed(const CaptureContext& context)
|
||||||
RedoTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
emit requestAction(REQ_REDO_MODIFICATION);
|
emit requestAction(REQ_REDO_MODIFICATION);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,21 @@
|
|||||||
|
|
||||||
class RedoTool : public AbstractActionTool
|
class RedoTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit RedoTool(QObject* parent = nullptr);
|
explicit RedoTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,57 +23,50 @@ SaveTool::SaveTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool SaveTool::closeOnButtonPressed() const
|
||||||
SaveTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon SaveTool::icon(const QColor& background, bool inEditor) const
|
||||||
SaveTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "content-save.svg");
|
return QIcon(iconPath(background) + "content-save.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString SaveTool::name() const
|
||||||
SaveTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Save");
|
return tr("Save");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType SaveTool::nameID() const
|
||||||
SaveTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::SAVE;
|
return ToolType::SAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString SaveTool::description() const
|
||||||
SaveTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Save the capture");
|
return tr("Save the capture");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* SaveTool::copy(QObject* parent)
|
||||||
SaveTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new SaveTool(parent);
|
return new SaveTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SaveTool::pressed(const CaptureContext& context)
|
||||||
SaveTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
if (context.savePath.isEmpty()) {
|
if (context.savePath.isEmpty()) {
|
||||||
emit requestAction(REQ_HIDE_GUI);
|
emit requestAction(REQ_HIDE_GUI);
|
||||||
bool ok =
|
bool ok = ScreenshotSaver().saveToFilesystemGUI(
|
||||||
ScreenshotSaver().saveToFilesystemGUI(context.selectedScreenshotArea());
|
context.selectedScreenshotArea());
|
||||||
if (ok) {
|
if (ok) {
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool ok = ScreenshotSaver().saveToFilesystem(
|
||||||
|
context.selectedScreenshotArea(), context.savePath, "");
|
||||||
|
if (ok) {
|
||||||
|
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
bool ok = ScreenshotSaver().saveToFilesystem(
|
|
||||||
context.selectedScreenshotArea(), context.savePath, "");
|
|
||||||
if (ok) {
|
|
||||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,21 @@
|
|||||||
|
|
||||||
class SaveTool : public AbstractActionTool
|
class SaveTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SaveTool(QObject* parent = nullptr);
|
explicit SaveTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,76 +25,66 @@ namespace {
|
|||||||
SelectionTool::SelectionTool(QObject* parent)
|
SelectionTool::SelectionTool(QObject* parent)
|
||||||
: AbstractTwoPointTool(parent)
|
: AbstractTwoPointTool(parent)
|
||||||
{
|
{
|
||||||
m_supportsDiagonalAdj = true;
|
m_supportsDiagonalAdj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool SelectionTool::closeOnButtonPressed() const
|
||||||
SelectionTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon SelectionTool::icon(const QColor& background, bool inEditor) const
|
||||||
SelectionTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "square-outline.svg");
|
return QIcon(iconPath(background) + "square-outline.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString SelectionTool::name() const
|
||||||
SelectionTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Rectangular Selection");
|
return tr("Rectangular Selection");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType SelectionTool::nameID() const
|
||||||
SelectionTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::SELECTION;
|
return ToolType::SELECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString SelectionTool::description() const
|
||||||
SelectionTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Set Selection as the paint tool");
|
return tr("Set Selection as the paint tool");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* SelectionTool::copy(QObject* parent)
|
||||||
SelectionTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new SelectionTool(parent);
|
return new SelectionTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SelectionTool::process(QPainter& painter,
|
||||||
SelectionTool::process(QPainter& painter,
|
const QPixmap& pixmap,
|
||||||
const QPixmap& pixmap,
|
bool recordUndo)
|
||||||
bool recordUndo)
|
|
||||||
{
|
{
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
updateBackup(pixmap);
|
updateBackup(pixmap);
|
||||||
}
|
}
|
||||||
painter.setPen(QPen(m_color, m_thickness));
|
painter.setPen(QPen(m_color, m_thickness));
|
||||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SelectionTool::paintMousePreview(QPainter& painter,
|
||||||
SelectionTool::paintMousePreview(QPainter& painter,
|
const CaptureContext& context)
|
||||||
const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||||
painter.drawLine(context.mousePos, context.mousePos);
|
painter.drawLine(context.mousePos, context.mousePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SelectionTool::drawStart(const CaptureContext& context)
|
||||||
SelectionTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_thickness = context.thickness + PADDING_VALUE;
|
m_thickness = context.thickness + PADDING_VALUE;
|
||||||
m_points.first = context.mousePos;
|
m_points.first = context.mousePos;
|
||||||
m_points.second = context.mousePos;
|
m_points.second = context.mousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SelectionTool::pressed(const CaptureContext& context)
|
||||||
SelectionTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,27 +21,27 @@
|
|||||||
|
|
||||||
class SelectionTool : public AbstractTwoPointTool
|
class SelectionTool : public AbstractTwoPointTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SelectionTool(QObject* parent = nullptr);
|
explicit SelectionTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
void process(QPainter& painter,
|
void process(QPainter& painter,
|
||||||
const QPixmap& pixmap,
|
const QPixmap& pixmap,
|
||||||
bool recordUndo = false) override;
|
bool recordUndo = false) override;
|
||||||
void paintMousePreview(QPainter& painter,
|
void paintMousePreview(QPainter& painter,
|
||||||
const CaptureContext& context) override;
|
const CaptureContext& context) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void drawStart(const CaptureContext& context) override;
|
void drawStart(const CaptureContext& context) override;
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,44 +22,37 @@ SizeIndicatorTool::SizeIndicatorTool(QObject* parent)
|
|||||||
: AbstractActionTool(parent)
|
: AbstractActionTool(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool SizeIndicatorTool::closeOnButtonPressed() const
|
||||||
SizeIndicatorTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon SizeIndicatorTool::icon(const QColor& background, bool inEditor) const
|
||||||
SizeIndicatorTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
return inEditor ? QIcon()
|
return inEditor ? QIcon()
|
||||||
: QIcon(iconPath(background) + "size_indicator.svg");
|
: QIcon(iconPath(background) + "size_indicator.svg");
|
||||||
}
|
}
|
||||||
QString
|
QString SizeIndicatorTool::name() const
|
||||||
SizeIndicatorTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Selection Size Indicator");
|
return tr("Selection Size Indicator");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType SizeIndicatorTool::nameID() const
|
||||||
SizeIndicatorTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::SIZEINDICATOR;
|
return ToolType::SIZEINDICATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString SizeIndicatorTool::description() const
|
||||||
SizeIndicatorTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Show the dimensions of the selection (X Y)");
|
return tr("Show the dimensions of the selection (X Y)");
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* SizeIndicatorTool::copy(QObject* parent)
|
||||||
SizeIndicatorTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
return new SizeIndicatorTool(parent);
|
return new SizeIndicatorTool(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void SizeIndicatorTool::pressed(const CaptureContext& context)
|
||||||
SizeIndicatorTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,21 +21,21 @@
|
|||||||
|
|
||||||
class SizeIndicatorTool : public AbstractActionTool
|
class SizeIndicatorTool : public AbstractActionTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SizeIndicatorTool(QObject* parent = nullptr);
|
explicit SizeIndicatorTool(QObject* parent = nullptr);
|
||||||
|
|
||||||
bool closeOnButtonPressed() const;
|
bool closeOnButtonPressed() const;
|
||||||
|
|
||||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
QString description() const override;
|
QString description() const override;
|
||||||
|
|
||||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ToolType nameID() const override;
|
ToolType nameID() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pressed(const CaptureContext& context) override;
|
void pressed(const CaptureContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,98 +27,93 @@
|
|||||||
TextConfig::TextConfig(QWidget* parent)
|
TextConfig::TextConfig(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
QFontDatabase fontDB;
|
QFontDatabase fontDB;
|
||||||
QComboBox* fontsCB = new QComboBox();
|
QComboBox* fontsCB = new QComboBox();
|
||||||
connect(fontsCB,
|
connect(fontsCB,
|
||||||
&QComboBox::currentTextChanged,
|
&QComboBox::currentTextChanged,
|
||||||
this,
|
this,
|
||||||
&TextConfig::fontFamilyChanged);
|
&TextConfig::fontFamilyChanged);
|
||||||
fontsCB->addItems(fontDB.families());
|
fontsCB->addItems(fontDB.families());
|
||||||
// TODO save family in config
|
// TODO save family in config
|
||||||
int index = fontsCB->findText(font().family());
|
int index = fontsCB->findText(font().family());
|
||||||
fontsCB->setCurrentIndex(index);
|
fontsCB->setCurrentIndex(index);
|
||||||
|
|
||||||
QString iconPrefix = ColorUtils::colorIsDark(palette().windowText().color())
|
QString iconPrefix = ColorUtils::colorIsDark(palette().windowText().color())
|
||||||
? PathInfo::blackIconPath()
|
? PathInfo::blackIconPath()
|
||||||
: PathInfo::whiteIconPath();
|
: PathInfo::whiteIconPath();
|
||||||
|
|
||||||
m_strikeOutButton = new QPushButton(
|
m_strikeOutButton = new QPushButton(
|
||||||
QIcon(iconPrefix + "format_strikethrough.svg"), QLatin1String(""));
|
QIcon(iconPrefix + "format_strikethrough.svg"), QLatin1String(""));
|
||||||
m_strikeOutButton->setCheckable(true);
|
m_strikeOutButton->setCheckable(true);
|
||||||
connect(m_strikeOutButton,
|
connect(m_strikeOutButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&TextConfig::fontStrikeOutChanged);
|
&TextConfig::fontStrikeOutChanged);
|
||||||
m_strikeOutButton->setToolTip(tr("StrikeOut"));
|
m_strikeOutButton->setToolTip(tr("StrikeOut"));
|
||||||
|
|
||||||
m_underlineButton = new QPushButton(
|
m_underlineButton = new QPushButton(
|
||||||
QIcon(iconPrefix + "format_underlined.svg"), QLatin1String(""));
|
QIcon(iconPrefix + "format_underlined.svg"), QLatin1String(""));
|
||||||
m_underlineButton->setCheckable(true);
|
m_underlineButton->setCheckable(true);
|
||||||
connect(m_underlineButton,
|
connect(m_underlineButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&TextConfig::fontUnderlineChanged);
|
&TextConfig::fontUnderlineChanged);
|
||||||
m_underlineButton->setToolTip(tr("Underline"));
|
m_underlineButton->setToolTip(tr("Underline"));
|
||||||
|
|
||||||
m_weightButton =
|
m_weightButton =
|
||||||
new QPushButton(QIcon(iconPrefix + "format_bold.svg"), QLatin1String(""));
|
new QPushButton(QIcon(iconPrefix + "format_bold.svg"), QLatin1String(""));
|
||||||
m_weightButton->setCheckable(true);
|
m_weightButton->setCheckable(true);
|
||||||
connect(m_weightButton,
|
connect(m_weightButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&TextConfig::weightButtonPressed);
|
&TextConfig::weightButtonPressed);
|
||||||
m_weightButton->setToolTip(tr("Bold"));
|
m_weightButton->setToolTip(tr("Bold"));
|
||||||
|
|
||||||
m_italicButton =
|
m_italicButton = new QPushButton(QIcon(iconPrefix + "format_italic.svg"),
|
||||||
new QPushButton(QIcon(iconPrefix + "format_italic.svg"), QLatin1String(""));
|
QLatin1String(""));
|
||||||
m_italicButton->setCheckable(true);
|
m_italicButton->setCheckable(true);
|
||||||
connect(m_italicButton,
|
connect(m_italicButton,
|
||||||
&QPushButton::clicked,
|
&QPushButton::clicked,
|
||||||
this,
|
this,
|
||||||
&TextConfig::fontItalicChanged);
|
&TextConfig::fontItalicChanged);
|
||||||
m_italicButton->setToolTip(tr("Italic"));
|
m_italicButton->setToolTip(tr("Italic"));
|
||||||
QHBoxLayout* modifiersLayout = new QHBoxLayout();
|
QHBoxLayout* modifiersLayout = new QHBoxLayout();
|
||||||
|
|
||||||
m_layout->addWidget(fontsCB);
|
m_layout->addWidget(fontsCB);
|
||||||
modifiersLayout->addWidget(m_strikeOutButton);
|
modifiersLayout->addWidget(m_strikeOutButton);
|
||||||
modifiersLayout->addWidget(m_underlineButton);
|
modifiersLayout->addWidget(m_underlineButton);
|
||||||
modifiersLayout->addWidget(m_weightButton);
|
modifiersLayout->addWidget(m_weightButton);
|
||||||
modifiersLayout->addWidget(m_italicButton);
|
modifiersLayout->addWidget(m_italicButton);
|
||||||
m_layout->addLayout(modifiersLayout);
|
m_layout->addLayout(modifiersLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextConfig::setUnderline(const bool u)
|
||||||
TextConfig::setUnderline(const bool u)
|
|
||||||
{
|
{
|
||||||
m_underlineButton->setChecked(u);
|
m_underlineButton->setChecked(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextConfig::setStrikeOut(const bool s)
|
||||||
TextConfig::setStrikeOut(const bool s)
|
|
||||||
{
|
{
|
||||||
m_strikeOutButton->setChecked(s);
|
m_strikeOutButton->setChecked(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextConfig::setWeight(const int w)
|
||||||
TextConfig::setWeight(const int w)
|
|
||||||
{
|
{
|
||||||
m_weightButton->setChecked(static_cast<QFont::Weight>(w) == QFont::Bold);
|
m_weightButton->setChecked(static_cast<QFont::Weight>(w) == QFont::Bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextConfig::setItalic(const bool i)
|
||||||
TextConfig::setItalic(const bool i)
|
|
||||||
{
|
{
|
||||||
m_italicButton->setChecked(i);
|
m_italicButton->setChecked(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextConfig::weightButtonPressed(const bool w)
|
||||||
TextConfig::weightButtonPressed(const bool w)
|
|
||||||
{
|
{
|
||||||
if (w) {
|
if (w) {
|
||||||
emit fontWeightChanged(QFont::Bold);
|
emit fontWeightChanged(QFont::Bold);
|
||||||
} else {
|
} else {
|
||||||
emit fontWeightChanged(QFont::Normal);
|
emit fontWeightChanged(QFont::Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,31 +24,31 @@ class QPushButton;
|
|||||||
|
|
||||||
class TextConfig : public QWidget
|
class TextConfig : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TextConfig(QWidget* parent = nullptr);
|
explicit TextConfig(QWidget* parent = nullptr);
|
||||||
|
|
||||||
void setUnderline(const bool u);
|
void setUnderline(const bool u);
|
||||||
void setStrikeOut(const bool s);
|
void setStrikeOut(const bool s);
|
||||||
void setWeight(const int w);
|
void setWeight(const int w);
|
||||||
void setItalic(const bool i);
|
void setItalic(const bool i);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fontFamilyChanged(const QString& f);
|
void fontFamilyChanged(const QString& f);
|
||||||
void fontUnderlineChanged(const bool underlined);
|
void fontUnderlineChanged(const bool underlined);
|
||||||
void fontStrikeOutChanged(const bool dashed);
|
void fontStrikeOutChanged(const bool dashed);
|
||||||
void fontWeightChanged(const QFont::Weight w);
|
void fontWeightChanged(const QFont::Weight w);
|
||||||
void fontItalicChanged(const bool italic);
|
void fontItalicChanged(const bool italic);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void weightButtonPressed(const bool w);
|
void weightButtonPressed(const bool w);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout* m_layout;
|
QVBoxLayout* m_layout;
|
||||||
QPushButton* m_strikeOutButton;
|
QPushButton* m_strikeOutButton;
|
||||||
QPushButton* m_underlineButton;
|
QPushButton* m_underlineButton;
|
||||||
QPushButton* m_weightButton;
|
QPushButton* m_weightButton;
|
||||||
QPushButton* m_italicButton;
|
QPushButton* m_italicButton;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,246 +26,227 @@ TextTool::TextTool(QObject* parent)
|
|||||||
, m_size(1)
|
, m_size(1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool TextTool::isValid() const
|
||||||
TextTool::isValid() const
|
|
||||||
{
|
{
|
||||||
return !m_text.isEmpty();
|
return !m_text.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool TextTool::closeOnButtonPressed() const
|
||||||
TextTool::closeOnButtonPressed() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool TextTool::isSelectable() const
|
||||||
TextTool::isSelectable() const
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool TextTool::showMousePreview() const
|
||||||
TextTool::showMousePreview() const
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon
|
QIcon TextTool::icon(const QColor& background, bool inEditor) const
|
||||||
TextTool::icon(const QColor& background, bool inEditor) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(inEditor);
|
Q_UNUSED(inEditor);
|
||||||
return QIcon(iconPath(background) + "text.svg");
|
return QIcon(iconPath(background) + "text.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString TextTool::name() const
|
||||||
TextTool::name() const
|
|
||||||
{
|
{
|
||||||
return tr("Text");
|
return tr("Text");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolType
|
ToolType TextTool::nameID() const
|
||||||
TextTool::nameID() const
|
|
||||||
{
|
{
|
||||||
return ToolType::TEXT;
|
return ToolType::TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString TextTool::description() const
|
||||||
TextTool::description() const
|
|
||||||
{
|
{
|
||||||
return tr("Add text to your capture");
|
return tr("Add text to your capture");
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget*
|
QWidget* TextTool::widget()
|
||||||
TextTool::widget()
|
|
||||||
{
|
{
|
||||||
TextWidget* w = new TextWidget();
|
TextWidget* w = new TextWidget();
|
||||||
w->setTextColor(m_color);
|
w->setTextColor(m_color);
|
||||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||||
w->setFont(m_font);
|
w->setFont(m_font);
|
||||||
connect(w, &TextWidget::textUpdated, this, &TextTool::updateText);
|
connect(w, &TextWidget::textUpdated, this, &TextTool::updateText);
|
||||||
m_widget = w;
|
m_widget = w;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget*
|
QWidget* TextTool::configurationWidget()
|
||||||
TextTool::configurationWidget()
|
|
||||||
{
|
{
|
||||||
m_confW = new TextConfig();
|
m_confW = new TextConfig();
|
||||||
connect(
|
connect(
|
||||||
m_confW, &TextConfig::fontFamilyChanged, this, &TextTool::updateFamily);
|
m_confW, &TextConfig::fontFamilyChanged, this, &TextTool::updateFamily);
|
||||||
connect(
|
connect(m_confW,
|
||||||
m_confW, &TextConfig::fontItalicChanged, this, &TextTool::updateFontItalic);
|
&TextConfig::fontItalicChanged,
|
||||||
connect(m_confW,
|
this,
|
||||||
&TextConfig::fontStrikeOutChanged,
|
&TextTool::updateFontItalic);
|
||||||
this,
|
connect(m_confW,
|
||||||
&TextTool::updateFontStrikeOut);
|
&TextConfig::fontStrikeOutChanged,
|
||||||
connect(m_confW,
|
this,
|
||||||
&TextConfig::fontUnderlineChanged,
|
&TextTool::updateFontStrikeOut);
|
||||||
this,
|
connect(m_confW,
|
||||||
&TextTool::updateFontUnderline);
|
&TextConfig::fontUnderlineChanged,
|
||||||
connect(
|
this,
|
||||||
m_confW, &TextConfig::fontWeightChanged, this, &TextTool::updateFontWeight);
|
&TextTool::updateFontUnderline);
|
||||||
m_confW->setItalic(m_font.italic());
|
connect(m_confW,
|
||||||
m_confW->setUnderline(m_font.underline());
|
&TextConfig::fontWeightChanged,
|
||||||
m_confW->setStrikeOut(m_font.strikeOut());
|
this,
|
||||||
m_confW->setWeight(m_font.weight());
|
&TextTool::updateFontWeight);
|
||||||
return m_confW;
|
m_confW->setItalic(m_font.italic());
|
||||||
|
m_confW->setUnderline(m_font.underline());
|
||||||
|
m_confW->setStrikeOut(m_font.strikeOut());
|
||||||
|
m_confW->setWeight(m_font.weight());
|
||||||
|
return m_confW;
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureTool*
|
CaptureTool* TextTool::copy(QObject* parent)
|
||||||
TextTool::copy(QObject* parent)
|
|
||||||
{
|
{
|
||||||
TextTool* tt = new TextTool(parent);
|
TextTool* tt = new TextTool(parent);
|
||||||
connect(m_confW, &TextConfig::fontFamilyChanged, tt, &TextTool::updateFamily);
|
connect(
|
||||||
connect(
|
m_confW, &TextConfig::fontFamilyChanged, tt, &TextTool::updateFamily);
|
||||||
m_confW, &TextConfig::fontItalicChanged, tt, &TextTool::updateFontItalic);
|
connect(
|
||||||
connect(m_confW,
|
m_confW, &TextConfig::fontItalicChanged, tt, &TextTool::updateFontItalic);
|
||||||
&TextConfig::fontStrikeOutChanged,
|
connect(m_confW,
|
||||||
tt,
|
&TextConfig::fontStrikeOutChanged,
|
||||||
&TextTool::updateFontStrikeOut);
|
tt,
|
||||||
connect(m_confW,
|
&TextTool::updateFontStrikeOut);
|
||||||
&TextConfig::fontUnderlineChanged,
|
connect(m_confW,
|
||||||
tt,
|
&TextConfig::fontUnderlineChanged,
|
||||||
&TextTool::updateFontUnderline);
|
tt,
|
||||||
connect(
|
&TextTool::updateFontUnderline);
|
||||||
m_confW, &TextConfig::fontWeightChanged, tt, &TextTool::updateFontWeight);
|
connect(
|
||||||
tt->m_font = m_font;
|
m_confW, &TextConfig::fontWeightChanged, tt, &TextTool::updateFontWeight);
|
||||||
return tt;
|
tt->m_font = m_font;
|
||||||
|
return tt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::undo(QPixmap& pixmap)
|
||||||
TextTool::undo(QPixmap& pixmap)
|
|
||||||
{
|
{
|
||||||
QPainter p(&pixmap);
|
QPainter p(&pixmap);
|
||||||
p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup);
|
p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::process(QPainter& painter,
|
||||||
TextTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
const QPixmap& pixmap,
|
||||||
|
bool recordUndo)
|
||||||
{
|
{
|
||||||
if (m_text.isEmpty()) {
|
if (m_text.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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());
|
||||||
m_backupArea.setSize(size);
|
m_backupArea.setSize(size);
|
||||||
if (recordUndo) {
|
if (recordUndo) {
|
||||||
m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5));
|
m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5));
|
||||||
}
|
}
|
||||||
// draw text
|
// draw text
|
||||||
painter.setFont(m_font);
|
painter.setFont(m_font);
|
||||||
painter.setPen(m_color);
|
painter.setPen(m_color);
|
||||||
painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text);
|
painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::paintMousePreview(QPainter& painter,
|
||||||
TextTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
const CaptureContext& context)
|
||||||
{
|
{
|
||||||
Q_UNUSED(painter);
|
Q_UNUSED(painter);
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::drawEnd(const QPoint& p)
|
||||||
TextTool::drawEnd(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
m_backupArea.moveTo(p);
|
m_backupArea.moveTo(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::drawMove(const QPoint& p)
|
||||||
TextTool::drawMove(const QPoint& p)
|
|
||||||
{
|
{
|
||||||
m_widget->move(p);
|
m_widget->move(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::drawStart(const CaptureContext& context)
|
||||||
TextTool::drawStart(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
m_color = context.color;
|
m_color = context.color;
|
||||||
m_size = context.thickness;
|
m_size = context.thickness;
|
||||||
emit requestAction(REQ_ADD_CHILD_WIDGET);
|
emit requestAction(REQ_ADD_CHILD_WIDGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::pressed(const CaptureContext& context)
|
||||||
TextTool::pressed(const CaptureContext& context)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(context);
|
Q_UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::colorChanged(const QColor& c)
|
||||||
TextTool::colorChanged(const QColor& c)
|
|
||||||
{
|
{
|
||||||
m_color = c;
|
m_color = c;
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setTextColor(c);
|
m_widget->setTextColor(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::thicknessChanged(const int th)
|
||||||
TextTool::thicknessChanged(const int th)
|
|
||||||
{
|
{
|
||||||
m_size = th;
|
m_size = th;
|
||||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateText(const QString& s)
|
||||||
TextTool::updateText(const QString& s)
|
|
||||||
{
|
{
|
||||||
m_text = s;
|
m_text = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::setFont(const QFont& f)
|
||||||
TextTool::setFont(const QFont& f)
|
|
||||||
{
|
{
|
||||||
m_font = f;
|
m_font = f;
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(f);
|
m_widget->setFont(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateFamily(const QString& s)
|
||||||
TextTool::updateFamily(const QString& s)
|
|
||||||
{
|
{
|
||||||
m_font.setFamily(s);
|
m_font.setFamily(s);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateFontUnderline(const bool underlined)
|
||||||
TextTool::updateFontUnderline(const bool underlined)
|
|
||||||
{
|
{
|
||||||
m_font.setUnderline(underlined);
|
m_font.setUnderline(underlined);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateFontStrikeOut(const bool s)
|
||||||
TextTool::updateFontStrikeOut(const bool s)
|
|
||||||
{
|
{
|
||||||
m_font.setStrikeOut(s);
|
m_font.setStrikeOut(s);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateFontWeight(const QFont::Weight w)
|
||||||
TextTool::updateFontWeight(const QFont::Weight w)
|
|
||||||
{
|
{
|
||||||
m_font.setWeight(w);
|
m_font.setWeight(w);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void TextTool::updateFontItalic(const bool italic)
|
||||||
TextTool::updateFontItalic(const bool italic)
|
|
||||||
{
|
{
|
||||||
m_font.setItalic(italic);
|
m_font.setItalic(italic);
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
m_widget->setFont(m_font);
|
m_widget->setFont(m_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user