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
|
||||
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'
|
||||
extensions: 'h,cpp'
|
||||
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 detail {
|
||||
|
||||
QColor
|
||||
color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha)
|
||||
QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha)
|
||||
{
|
||||
qreal h1 = hue * 6;
|
||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||
QColor col;
|
||||
if (h1 >= 0 && h1 < 1)
|
||||
col = QColor::fromRgbF(chroma, x, 0);
|
||||
else if (h1 < 2)
|
||||
col = QColor::fromRgbF(x, chroma, 0);
|
||||
else if (h1 < 3)
|
||||
col = QColor::fromRgbF(0, chroma, x);
|
||||
else if (h1 < 4)
|
||||
col = QColor::fromRgbF(0, x, chroma);
|
||||
else if (h1 < 5)
|
||||
col = QColor::fromRgbF(x, 0, chroma);
|
||||
else if (h1 < 6)
|
||||
col = QColor::fromRgbF(chroma, 0, x);
|
||||
qreal h1 = hue * 6;
|
||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||
QColor col;
|
||||
if (h1 >= 0 && h1 < 1)
|
||||
col = QColor::fromRgbF(chroma, x, 0);
|
||||
else if (h1 < 2)
|
||||
col = QColor::fromRgbF(x, chroma, 0);
|
||||
else if (h1 < 3)
|
||||
col = QColor::fromRgbF(0, chroma, x);
|
||||
else if (h1 < 4)
|
||||
col = QColor::fromRgbF(0, x, chroma);
|
||||
else if (h1 < 5)
|
||||
col = QColor::fromRgbF(x, 0, chroma);
|
||||
else if (h1 < 6)
|
||||
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),
|
||||
qBound(0.0, col.greenF() + m, 1.0),
|
||||
qBound(0.0, col.blueF() + m, 1.0),
|
||||
alpha);
|
||||
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
||||
qBound(0.0, col.greenF() + m, 1.0),
|
||||
qBound(0.0, col.blueF() + m, 1.0),
|
||||
alpha);
|
||||
}
|
||||
|
||||
QColor
|
||||
color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha)
|
||||
QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha)
|
||||
{
|
||||
qreal chroma = (1 - qAbs(2 * lig - 1)) * sat;
|
||||
qreal h1 = hue * 6;
|
||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||
QColor col;
|
||||
if (h1 >= 0 && h1 < 1)
|
||||
col = QColor::fromRgbF(chroma, x, 0);
|
||||
else if (h1 < 2)
|
||||
col = QColor::fromRgbF(x, chroma, 0);
|
||||
else if (h1 < 3)
|
||||
col = QColor::fromRgbF(0, chroma, x);
|
||||
else if (h1 < 4)
|
||||
col = QColor::fromRgbF(0, x, chroma);
|
||||
else if (h1 < 5)
|
||||
col = QColor::fromRgbF(x, 0, chroma);
|
||||
else if (h1 < 6)
|
||||
col = QColor::fromRgbF(chroma, 0, x);
|
||||
qreal chroma = (1 - qAbs(2 * lig - 1)) * sat;
|
||||
qreal h1 = hue * 6;
|
||||
qreal x = chroma * (1 - qAbs(std::fmod(h1, 2) - 1));
|
||||
QColor col;
|
||||
if (h1 >= 0 && h1 < 1)
|
||||
col = QColor::fromRgbF(chroma, x, 0);
|
||||
else if (h1 < 2)
|
||||
col = QColor::fromRgbF(x, chroma, 0);
|
||||
else if (h1 < 3)
|
||||
col = QColor::fromRgbF(0, chroma, x);
|
||||
else if (h1 < 4)
|
||||
col = QColor::fromRgbF(0, x, chroma);
|
||||
else if (h1 < 5)
|
||||
col = QColor::fromRgbF(x, 0, chroma);
|
||||
else if (h1 < 6)
|
||||
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),
|
||||
qBound(0.0, col.greenF() + m, 1.0),
|
||||
qBound(0.0, col.blueF() + m, 1.0),
|
||||
alpha);
|
||||
return QColor::fromRgbF(qBound(0.0, col.redF() + m, 1.0),
|
||||
qBound(0.0, col.greenF() + m, 1.0),
|
||||
qBound(0.0, col.blueF() + m, 1.0),
|
||||
alpha);
|
||||
}
|
||||
|
||||
} // 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
|
||||
{
|
||||
Nothing,
|
||||
DragCircle,
|
||||
DragSquare
|
||||
Nothing,
|
||||
DragCircle,
|
||||
DragSquare
|
||||
};
|
||||
|
||||
static const ColorWheel::DisplayFlags hard_default_flags =
|
||||
@@ -48,517 +48,499 @@ static const double selector_radius = 6;
|
||||
class ColorWheel::Private
|
||||
{
|
||||
private:
|
||||
ColorWheel* const w;
|
||||
ColorWheel* const w;
|
||||
|
||||
public:
|
||||
qreal hue, sat, val;
|
||||
qreal bgBrightness;
|
||||
unsigned int wheel_width;
|
||||
MouseStatus mouse_status;
|
||||
QPixmap hue_ring;
|
||||
QImage inner_selector;
|
||||
DisplayFlags display_flags;
|
||||
QColor (*color_from)(qreal, qreal, qreal, qreal);
|
||||
QColor (*rainbow_from_hue)(qreal);
|
||||
int max_size = 128;
|
||||
qreal hue, sat, val;
|
||||
qreal bgBrightness;
|
||||
unsigned int wheel_width;
|
||||
MouseStatus mouse_status;
|
||||
QPixmap hue_ring;
|
||||
QImage inner_selector;
|
||||
DisplayFlags display_flags;
|
||||
QColor (*color_from)(qreal, qreal, qreal, qreal);
|
||||
QColor (*rainbow_from_hue)(qreal);
|
||||
int max_size = 128;
|
||||
|
||||
explicit Private(ColorWheel* widget)
|
||||
: w(widget)
|
||||
, hue(0)
|
||||
, sat(0)
|
||||
, val(0)
|
||||
, wheel_width(20)
|
||||
, mouse_status(Nothing)
|
||||
, display_flags(FLAGS_DEFAULT)
|
||||
, color_from(&QColor::fromHsvF)
|
||||
, rainbow_from_hue(&detail::rainbow_hsv)
|
||||
{
|
||||
QColor bgColor = widget->palette().window().color();
|
||||
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));
|
||||
explicit Private(ColorWheel* widget)
|
||||
: w(widget)
|
||||
, hue(0)
|
||||
, sat(0)
|
||||
, val(0)
|
||||
, wheel_width(20)
|
||||
, mouse_status(Nothing)
|
||||
, display_flags(FLAGS_DEFAULT)
|
||||
, color_from(&QColor::fromHsvF)
|
||||
, rainbow_from_hue(&detail::rainbow_hsv)
|
||||
{
|
||||
QColor bgColor = widget->palette().window().color();
|
||||
bgBrightness = color_widgets::detail::color_lumaF(bgColor);
|
||||
}
|
||||
|
||||
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);
|
||||
/// 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());
|
||||
|
||||
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)
|
||||
: QWidget(parent)
|
||||
, p(new Private(this))
|
||||
{
|
||||
setDisplayFlags(FLAGS_DEFAULT);
|
||||
setAcceptDrops(true);
|
||||
setDisplayFlags(FLAGS_DEFAULT);
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
ColorWheel::~ColorWheel()
|
||||
{
|
||||
delete p;
|
||||
delete p;
|
||||
}
|
||||
|
||||
QColor
|
||||
ColorWheel::color() const
|
||||
QColor 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
|
||||
ColorWheel::sizeHint() const
|
||||
QSize ColorWheel::sizeHint() const
|
||||
{
|
||||
return QSize(p->wheel_width * 5, p->wheel_width * 5);
|
||||
return QSize(p->wheel_width * 5, p->wheel_width * 5);
|
||||
}
|
||||
|
||||
qreal
|
||||
ColorWheel::hue() const
|
||||
qreal ColorWheel::hue() const
|
||||
{
|
||||
if ((p->display_flags & COLOR_LCH) && p->sat > 0.01)
|
||||
return color().hueF();
|
||||
return p->hue;
|
||||
if ((p->display_flags & COLOR_LCH) && p->sat > 0.01)
|
||||
return color().hueF();
|
||||
return p->hue;
|
||||
}
|
||||
|
||||
qreal
|
||||
ColorWheel::saturation() const
|
||||
qreal ColorWheel::saturation() const
|
||||
{
|
||||
return color().hsvSaturationF();
|
||||
return color().hsvSaturationF();
|
||||
}
|
||||
|
||||
qreal
|
||||
ColorWheel::value() const
|
||||
qreal ColorWheel::value() const
|
||||
{
|
||||
return color().valueF();
|
||||
return color().valueF();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ColorWheel::wheelWidth() const
|
||||
unsigned int ColorWheel::wheelWidth() const
|
||||
{
|
||||
return p->wheel_width;
|
||||
return p->wheel_width;
|
||||
}
|
||||
|
||||
void
|
||||
ColorWheel::setWheelWidth(unsigned int w)
|
||||
void ColorWheel::setWheelWidth(unsigned int 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->wheel_width = w;
|
||||
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();
|
||||
} 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());
|
||||
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();
|
||||
|
||||
painter.rotate(p->selector_image_angle());
|
||||
painter.translate(p->selector_image_offset());
|
||||
|
||||
QPointF selector_position;
|
||||
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);
|
||||
qreal side = p->square_size();
|
||||
selector_position = QPointF(p->sat * side, p->val * side);
|
||||
} 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();
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
emit colorSelected(color());
|
||||
emit colorChanged(color());
|
||||
update();
|
||||
}
|
||||
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::mousePressEvent(QMouseEvent* ev)
|
||||
void ColorWheel::mouseMoveEvent(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;
|
||||
if (p->mouse_status == DragCircle) {
|
||||
p->hue = p->line_to_point(ev->pos()).angle() / 360.0;
|
||||
p->render_inner_selector();
|
||||
|
||||
// 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);
|
||||
}
|
||||
p->mouse_status = Nothing;
|
||||
emit mouseReleaseOnColor(color());
|
||||
}
|
||||
|
||||
void
|
||||
ColorWheel::mouseReleaseEvent(QMouseEvent* ev)
|
||||
void ColorWheel::resizeEvent(QResizeEvent*)
|
||||
{
|
||||
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->display_flags = flags;
|
||||
p->render_inner_selector();
|
||||
update();
|
||||
emit displayFlagsChanged(flags);
|
||||
p->render_inner_selector();
|
||||
}
|
||||
|
||||
ColorWheel::DisplayFlags
|
||||
ColorWheel::displayFlags(DisplayFlags mask) const
|
||||
void ColorWheel::setColor(QColor c)
|
||||
{
|
||||
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
|
||||
ColorWheel::setDefaultDisplayFlags(DisplayFlags flags)
|
||||
void ColorWheel::setHue(qreal h)
|
||||
{
|
||||
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;
|
||||
p->hue = qBound(0.0, h, 1.0);
|
||||
p->render_inner_selector();
|
||||
update();
|
||||
}
|
||||
|
||||
ColorWheel::DisplayFlags
|
||||
ColorWheel::defaultDisplayFlags(DisplayFlags mask)
|
||||
void ColorWheel::setSaturation(qreal s)
|
||||
{
|
||||
return default_flags & mask;
|
||||
p->sat = qBound(0.0, s, 1.0);
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
ColorWheel::setDisplayFlag(DisplayFlags flag, DisplayFlags mask)
|
||||
void ColorWheel::setValue(qreal v)
|
||||
{
|
||||
setDisplayFlags((p->display_flags & ~mask) | flag);
|
||||
p->val = qBound(0.0, v, 1.0);
|
||||
update();
|
||||
}
|
||||
|
||||
void
|
||||
ColorWheel::dragEnterEvent(QDragEnterEvent* event)
|
||||
void ColorWheel::setDisplayFlags(DisplayFlags flags)
|
||||
{
|
||||
if (event->mimeData()->hasColor() ||
|
||||
(event->mimeData()->hasText() &&
|
||||
QColor(event->mimeData()->text()).isValid()))
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
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;
|
||||
|
||||
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();
|
||||
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->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
|
||||
|
||||
635
external/singleapplication/singleapplication.cpp
vendored
635
external/singleapplication/singleapplication.cpp
vendored
@@ -49,324 +49,319 @@
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication* q_ptr)
|
||||
: q_ptr(q_ptr)
|
||||
{
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
}
|
||||
|
||||
SingleApplicationPrivate::~SingleApplicationPrivate()
|
||||
{
|
||||
if (socket != nullptr) {
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
if (socket != nullptr) {
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if (server != nullptr) {
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
}
|
||||
memory->unlock();
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if (server != nullptr) {
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
}
|
||||
memory->unlock();
|
||||
|
||||
delete memory;
|
||||
delete memory;
|
||||
}
|
||||
|
||||
void
|
||||
SingleApplicationPrivate::genBlockServerName(int timeout)
|
||||
void SingleApplicationPrivate::genBlockServerName(int timeout)
|
||||
{
|
||||
QCryptographicHash appData(QCryptographicHash::Sha256);
|
||||
appData.addData("SingleApplication", 17);
|
||||
appData.addData(SingleApplication::app_t::applicationName().toUtf8());
|
||||
appData.addData(SingleApplication::app_t::organizationName().toUtf8());
|
||||
appData.addData(SingleApplication::app_t::organizationDomain().toUtf8());
|
||||
QCryptographicHash appData(QCryptographicHash::Sha256);
|
||||
appData.addData("SingleApplication", 17);
|
||||
appData.addData(SingleApplication::app_t::applicationName().toUtf8());
|
||||
appData.addData(SingleApplication::app_t::organizationName().toUtf8());
|
||||
appData.addData(SingleApplication::app_t::organizationDomain().toUtf8());
|
||||
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppVersion)) {
|
||||
appData.addData(SingleApplication::app_t::applicationVersion().toUtf8());
|
||||
}
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppVersion)) {
|
||||
appData.addData(
|
||||
SingleApplication::app_t::applicationVersion().toUtf8());
|
||||
}
|
||||
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppPath)) {
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppPath)) {
|
||||
#ifdef Q_OS_WIN
|
||||
appData.addData(
|
||||
SingleApplication::app_t::applicationFilePath().toLower().toUtf8());
|
||||
appData.addData(
|
||||
SingleApplication::app_t::applicationFilePath().toLower().toUtf8());
|
||||
#else
|
||||
appData.addData(SingleApplication::app_t::applicationFilePath().toUtf8());
|
||||
appData.addData(
|
||||
SingleApplication::app_t::applicationFilePath().toUtf8());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// User level block requires a user specific data in the hash
|
||||
if (options & SingleApplication::Mode::User) {
|
||||
// User level block requires a user specific data in the hash
|
||||
if (options & SingleApplication::Mode::User) {
|
||||
#ifdef Q_OS_WIN
|
||||
Q_UNUSED(timeout);
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if (GetUserNameW(username, &usernameLength)) {
|
||||
appData.addData(QString::fromWCharArray(username).toUtf8());
|
||||
} else {
|
||||
appData.addData(
|
||||
QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.join("")
|
||||
.toUtf8());
|
||||
Q_UNUSED(timeout);
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if (GetUserNameW(username, &usernameLength)) {
|
||||
appData.addData(QString::fromWCharArray(username).toUtf8());
|
||||
} else {
|
||||
appData.addData(
|
||||
QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.join("")
|
||||
.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) &&
|
||||
process.exitCode() == QProcess::NormalExit) {
|
||||
appData.addData(process.readLine());
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
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 {
|
||||
appData.addData(
|
||||
QDir(QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.first())
|
||||
.absolutePath()
|
||||
.toUtf8());
|
||||
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
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::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()
|
||||
void SingleApplicationPrivate::startSecondary()
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
// Handle any further termination signals to ensure the
|
||||
// QSharedMemory block is deleted even if the process crashes
|
||||
crashHandler();
|
||||
// Handle any further termination signals to ensure the
|
||||
// QSharedMemory block is deleted even if the process crashes
|
||||
crashHandler();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SingleApplicationPrivate::connectToPrimary(int msecs,
|
||||
ConnectionType connectionType)
|
||||
void SingleApplicationPrivate::connectToPrimary(int msecs,
|
||||
ConnectionType connectionType)
|
||||
{
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if (socket == nullptr) {
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if (socket == nullptr) {
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
|
||||
// If already connected - we are done;
|
||||
if (socket->state() == QLocalSocket::ConnectedState)
|
||||
return;
|
||||
// If already connected - we are done;
|
||||
if (socket->state() == QLocalSocket::ConnectedState)
|
||||
return;
|
||||
|
||||
// If not connect
|
||||
if (socket->state() == QLocalSocket::UnconnectedState ||
|
||||
socket->state() == QLocalSocket::ClosingState) {
|
||||
socket->connectToServer(blockServerName);
|
||||
}
|
||||
// If not connect
|
||||
if (socket->state() == QLocalSocket::UnconnectedState ||
|
||||
socket->state() == QLocalSocket::ClosingState) {
|
||||
socket->connectToServer(blockServerName);
|
||||
}
|
||||
|
||||
// Wait for being connected
|
||||
if (socket->state() == QLocalSocket::ConnectingState) {
|
||||
socket->waitForConnected(msecs);
|
||||
}
|
||||
// Wait for being connected
|
||||
if (socket->state() == QLocalSocket::ConnectingState) {
|
||||
socket->waitForConnected(msecs);
|
||||
}
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
if (socket->state() == QLocalSocket::ConnectedState) {
|
||||
// Notify the parent that a new instance had been started;
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
writeStream.setVersion(QDataStream::Qt_5_2);
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
quint16 checksum =
|
||||
qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
||||
writeStream << checksum;
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
if (socket->state() == QLocalSocket::ConnectedState) {
|
||||
// Notify the parent that a new instance had been started;
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
writeStream.setVersion(QDataStream::Qt_5_2);
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
quint16 checksum = qChecksum(initMsg.constData(),
|
||||
static_cast<quint32>(initMsg.length()));
|
||||
writeStream << checksum;
|
||||
|
||||
socket->write(initMsg);
|
||||
socket->flush();
|
||||
socket->waitForBytesWritten(msecs);
|
||||
}
|
||||
socket->write(initMsg);
|
||||
socket->flush();
|
||||
socket->waitForBytesWritten(msecs);
|
||||
}
|
||||
}
|
||||
|
||||
qint64
|
||||
SingleApplicationPrivate::primaryPid()
|
||||
qint64 SingleApplicationPrivate::primaryPid()
|
||||
{
|
||||
qint64 pid;
|
||||
qint64 pid;
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
|
||||
return pid;
|
||||
return pid;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
void
|
||||
SingleApplicationPrivate::crashHandler()
|
||||
void SingleApplicationPrivate::crashHandler()
|
||||
{
|
||||
// Handle any further termination signals to ensure the
|
||||
// QSharedMemory block is deleted even if the process crashes
|
||||
signal(SIGHUP, SingleApplicationPrivate::terminate); // 1
|
||||
signal(SIGINT, SingleApplicationPrivate::terminate); // 2
|
||||
signal(SIGQUIT, SingleApplicationPrivate::terminate); // 3
|
||||
signal(SIGILL, SingleApplicationPrivate::terminate); // 4
|
||||
signal(SIGABRT, SingleApplicationPrivate::terminate); // 6
|
||||
signal(SIGFPE, SingleApplicationPrivate::terminate); // 8
|
||||
signal(SIGBUS, SingleApplicationPrivate::terminate); // 10
|
||||
signal(SIGSEGV, SingleApplicationPrivate::terminate); // 11
|
||||
signal(SIGSYS, SingleApplicationPrivate::terminate); // 12
|
||||
signal(SIGPIPE, SingleApplicationPrivate::terminate); // 13
|
||||
signal(SIGALRM, SingleApplicationPrivate::terminate); // 14
|
||||
signal(SIGTERM, SingleApplicationPrivate::terminate); // 15
|
||||
signal(SIGXCPU, SingleApplicationPrivate::terminate); // 24
|
||||
signal(SIGXFSZ, SingleApplicationPrivate::terminate); // 25
|
||||
// Handle any further termination signals to ensure the
|
||||
// QSharedMemory block is deleted even if the process crashes
|
||||
signal(SIGHUP, SingleApplicationPrivate::terminate); // 1
|
||||
signal(SIGINT, SingleApplicationPrivate::terminate); // 2
|
||||
signal(SIGQUIT, SingleApplicationPrivate::terminate); // 3
|
||||
signal(SIGILL, SingleApplicationPrivate::terminate); // 4
|
||||
signal(SIGABRT, SingleApplicationPrivate::terminate); // 6
|
||||
signal(SIGFPE, SingleApplicationPrivate::terminate); // 8
|
||||
signal(SIGBUS, SingleApplicationPrivate::terminate); // 10
|
||||
signal(SIGSEGV, SingleApplicationPrivate::terminate); // 11
|
||||
signal(SIGSYS, SingleApplicationPrivate::terminate); // 12
|
||||
signal(SIGPIPE, SingleApplicationPrivate::terminate); // 13
|
||||
signal(SIGALRM, SingleApplicationPrivate::terminate); // 14
|
||||
signal(SIGTERM, SingleApplicationPrivate::terminate); // 15
|
||||
signal(SIGXCPU, SingleApplicationPrivate::terminate); // 24
|
||||
signal(SIGXFSZ, SingleApplicationPrivate::terminate); // 25
|
||||
}
|
||||
|
||||
void
|
||||
SingleApplicationPrivate::terminate(int signum)
|
||||
void SingleApplicationPrivate::terminate(int signum)
|
||||
{
|
||||
delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
|
||||
::exit(128 + signum);
|
||||
delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
|
||||
::exit(128 + signum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Executed when a connection has been made to the LocalServer
|
||||
*/
|
||||
void
|
||||
SingleApplicationPrivate::slotConnectionEstablished()
|
||||
void SingleApplicationPrivate::slotConnectionEstablished()
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
QLocalSocket* nextConnSocket = server->nextPendingConnection();
|
||||
QLocalSocket* nextConnSocket = server->nextPendingConnection();
|
||||
|
||||
quint32 instanceId = 0;
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
if (nextConnSocket->waitForReadyRead(100)) {
|
||||
// read all data from message in same order/format as written
|
||||
QByteArray msgBytes = nextConnSocket->read(
|
||||
nextConnSocket->bytesAvailable() - static_cast<qint64>(sizeof(quint16)));
|
||||
QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
|
||||
QDataStream readStream(msgBytes);
|
||||
readStream.setVersion(QDataStream::Qt_5_2);
|
||||
quint32 instanceId = 0;
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
if (nextConnSocket->waitForReadyRead(100)) {
|
||||
// read all data from message in same order/format as written
|
||||
QByteArray msgBytes =
|
||||
nextConnSocket->read(nextConnSocket->bytesAvailable() -
|
||||
static_cast<qint64>(sizeof(quint16)));
|
||||
QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
|
||||
QDataStream readStream(msgBytes);
|
||||
readStream.setVersion(QDataStream::Qt_5_2);
|
||||
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
// connectioon type
|
||||
quint8 connType = InvalidConnection;
|
||||
readStream >> connType;
|
||||
connectionType = static_cast<ConnectionType>(connType);
|
||||
// instance id
|
||||
readStream >> instanceId;
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
QDataStream checksumStream(checksumBytes);
|
||||
checksumStream.setVersion(QDataStream::Qt_5_2);
|
||||
checksumStream >> msgChecksum;
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
// connectioon type
|
||||
quint8 connType = InvalidConnection;
|
||||
readStream >> connType;
|
||||
connectionType = static_cast<ConnectionType>(connType);
|
||||
// instance id
|
||||
readStream >> instanceId;
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
QDataStream checksumStream(checksumBytes);
|
||||
checksumStream.setVersion(QDataStream::Qt_5_2);
|
||||
checksumStream >> msgChecksum;
|
||||
|
||||
const quint16 actualChecksum =
|
||||
qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
|
||||
const quint16 actualChecksum = qChecksum(
|
||||
msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
|
||||
|
||||
if (readStream.status() != QDataStream::Ok ||
|
||||
QLatin1String(latin1Name) != blockServerName ||
|
||||
msgChecksum != actualChecksum) {
|
||||
connectionType = InvalidConnection;
|
||||
if (readStream.status() != QDataStream::Ok ||
|
||||
QLatin1String(latin1Name) != blockServerName ||
|
||||
msgChecksum != actualChecksum) {
|
||||
connectionType = InvalidConnection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connectionType == InvalidConnection) {
|
||||
nextConnSocket->close();
|
||||
delete nextConnSocket;
|
||||
return;
|
||||
}
|
||||
if (connectionType == InvalidConnection) {
|
||||
nextConnSocket->close();
|
||||
delete nextConnSocket;
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(nextConnSocket,
|
||||
&QLocalSocket::aboutToClose,
|
||||
this,
|
||||
[nextConnSocket, instanceId, this]() {
|
||||
emit this->slotClientConnectionClosed(nextConnSocket,
|
||||
instanceId);
|
||||
});
|
||||
QObject::connect(nextConnSocket,
|
||||
&QLocalSocket::aboutToClose,
|
||||
this,
|
||||
[nextConnSocket, instanceId, this]() {
|
||||
emit this->slotClientConnectionClosed(nextConnSocket,
|
||||
instanceId);
|
||||
});
|
||||
|
||||
QObject::connect(nextConnSocket,
|
||||
&QLocalSocket::readyRead,
|
||||
this,
|
||||
[nextConnSocket, instanceId, this]() {
|
||||
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
||||
});
|
||||
QObject::connect(nextConnSocket,
|
||||
&QLocalSocket::readyRead,
|
||||
this,
|
||||
[nextConnSocket, instanceId, this]() {
|
||||
emit this->slotDataAvailable(nextConnSocket,
|
||||
instanceId);
|
||||
});
|
||||
|
||||
if (connectionType == NewInstance ||
|
||||
(connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification)) {
|
||||
emit q->instanceStarted();
|
||||
}
|
||||
if (connectionType == NewInstance ||
|
||||
(connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification)) {
|
||||
emit q->instanceStarted();
|
||||
}
|
||||
|
||||
if (nextConnSocket->bytesAvailable() > 0) {
|
||||
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
||||
}
|
||||
if (nextConnSocket->bytesAvailable() > 0) {
|
||||
emit this->slotDataAvailable(nextConnSocket, instanceId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SingleApplicationPrivate::slotDataAvailable(QLocalSocket* dataSocket,
|
||||
quint32 instanceId)
|
||||
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket* dataSocket,
|
||||
quint32 instanceId)
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
emit q->receivedMessage(instanceId, dataSocket->readAll());
|
||||
Q_Q(SingleApplication);
|
||||
emit q->receivedMessage(instanceId, dataSocket->readAll());
|
||||
}
|
||||
|
||||
void
|
||||
SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket* closedSocket,
|
||||
quint32 instanceId)
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed(
|
||||
QLocalSocket* closedSocket,
|
||||
quint32 instanceId)
|
||||
{
|
||||
if (closedSocket->bytesAvailable() > 0)
|
||||
emit slotDataAvailable(closedSocket, instanceId);
|
||||
closedSocket->deleteLater();
|
||||
if (closedSocket->bytesAvailable() > 0)
|
||||
emit slotDataAvailable(closedSocket, instanceId);
|
||||
closedSocket->deleteLater();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,61 +379,62 @@ SingleApplication::SingleApplication(int& argc,
|
||||
: app_t(argc, argv)
|
||||
, d_ptr(new SingleApplicationPrivate(this))
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
Q_D(SingleApplication);
|
||||
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName(timeout);
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName(timeout);
|
||||
|
||||
// Guarantee thread safe behaviour with a shared memory block. Also by
|
||||
// explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even if the process had crashed on Unix.
|
||||
// Guarantee thread safe behaviour with a shared memory block. Also by
|
||||
// explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even if the process had crashed on Unix.
|
||||
#ifdef Q_OS_UNIX
|
||||
d->memory = new QSharedMemory(d->blockServerName);
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
d->memory = new QSharedMemory(d->blockServerName);
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
#endif
|
||||
d->memory = new QSharedMemory(d->blockServerName);
|
||||
d->memory = new QSharedMemory(d->blockServerName);
|
||||
|
||||
// Create a shared memory block
|
||||
if (d->memory->create(sizeof(InstancesInfo))) {
|
||||
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();
|
||||
// Create a shared memory block
|
||||
if (d->memory->create(sizeof(InstancesInfo))) {
|
||||
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());
|
||||
|
||||
// Check if another instance can be started
|
||||
if (allowSecondary) {
|
||||
inst->secondary += 1;
|
||||
d->instanceNumber = inst->secondary;
|
||||
d->startSecondary();
|
||||
if (d->options & Mode::SecondaryNotification) {
|
||||
d->connectToPrimary(timeout,
|
||||
SingleApplicationPrivate::SecondaryInstance);
|
||||
if (!inst->primary) {
|
||||
d->startPrimary(false);
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if another instance can be started
|
||||
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);
|
||||
delete d;
|
||||
::exit(EXIT_SUCCESS);
|
||||
d->connectToPrimary(timeout, SingleApplicationPrivate::NewInstance);
|
||||
delete d;
|
||||
::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -446,52 +442,47 @@ SingleApplication::SingleApplication(int& argc,
|
||||
*/
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
delete d;
|
||||
Q_D(SingleApplication);
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool
|
||||
SingleApplication::isPrimary()
|
||||
bool SingleApplication::isPrimary()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server != nullptr;
|
||||
Q_D(SingleApplication);
|
||||
return d->server != nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
SingleApplication::isSecondary()
|
||||
bool SingleApplication::isSecondary()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server == nullptr;
|
||||
Q_D(SingleApplication);
|
||||
return d->server == nullptr;
|
||||
}
|
||||
|
||||
quint32
|
||||
SingleApplication::instanceId()
|
||||
quint32 SingleApplication::instanceId()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->instanceNumber;
|
||||
Q_D(SingleApplication);
|
||||
return d->instanceNumber;
|
||||
}
|
||||
|
||||
qint64
|
||||
SingleApplication::primaryPid()
|
||||
qint64 SingleApplication::primaryPid()
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->primaryPid();
|
||||
Q_D(SingleApplication);
|
||||
return d->primaryPid();
|
||||
}
|
||||
|
||||
bool
|
||||
SingleApplication::sendMessage(QByteArray message, int timeout)
|
||||
bool SingleApplication::sendMessage(QByteArray message, int timeout)
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
Q_D(SingleApplication);
|
||||
|
||||
// Nobody to connect to
|
||||
if (isPrimary())
|
||||
return false;
|
||||
// Nobody to connect to
|
||||
if (isPrimary())
|
||||
return false;
|
||||
|
||||
// Make sure the socket is connected
|
||||
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
|
||||
// Make sure the socket is connected
|
||||
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
|
||||
|
||||
d->socket->write(message);
|
||||
bool dataWritten = d->socket->flush();
|
||||
d->socket->waitForBytesWritten(timeout);
|
||||
return dataWritten;
|
||||
d->socket->write(message);
|
||||
bool dataWritten = d->socket->flush();
|
||||
d->socket->waitForBytesWritten(timeout);
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
typedef QAPPLICATION_CLASS app_t;
|
||||
typedef QAPPLICATION_CLASS app_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Mode of operation of SingleApplication.
|
||||
* Whether the block should be user-wide or system-wide and whether the
|
||||
* primary instance should be notified when a secondary instance had been
|
||||
* started.
|
||||
* @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
|
||||
* block will be user wide.
|
||||
* @enum
|
||||
*/
|
||||
enum Mode
|
||||
{
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
/**
|
||||
* @brief Mode of operation of SingleApplication.
|
||||
* Whether the block should be user-wide or system-wide and whether the
|
||||
* primary instance should be notified when a secondary instance had been
|
||||
* started.
|
||||
* @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
|
||||
* block will be user wide.
|
||||
* @enum
|
||||
*/
|
||||
enum Mode
|
||||
{
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
|
||||
/**
|
||||
* @brief Intitializes a SingleApplication instance with argc command line
|
||||
* arguments in argv
|
||||
* @arg {int &} argc - Number of arguments in argv
|
||||
* @arg {const char *[]} argv - Supplied command line arguments
|
||||
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
* if there is already a primary instance.
|
||||
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
* User wide or System wide.
|
||||
* @arg {int} timeout - Timeout to wait in miliseconds.
|
||||
* @note argc and argv may be changed as Qt removes arguments that it
|
||||
* recognizes
|
||||
* @note Mode::SecondaryNotification only works if set on both the primary
|
||||
* instance and the secondary instance.
|
||||
* @note The timeout is just a hint for the maximum time of blocking
|
||||
* operations. It does not guarantee that the SingleApplication
|
||||
* initialisation will be completed in given time, though is a good hint.
|
||||
* Usually 4*timeout would be the worst case (fail) scenario.
|
||||
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication(int& argc,
|
||||
char* argv[],
|
||||
bool allowSecondary = false,
|
||||
Options options = Mode::User,
|
||||
int timeout = 100);
|
||||
~SingleApplication();
|
||||
/**
|
||||
* @brief Intitializes a SingleApplication instance with argc command line
|
||||
* arguments in argv
|
||||
* @arg {int &} argc - Number of arguments in argv
|
||||
* @arg {const char *[]} argv - Supplied command line arguments
|
||||
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
* if there is already a primary instance.
|
||||
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
* User wide or System wide.
|
||||
* @arg {int} timeout - Timeout to wait in miliseconds.
|
||||
* @note argc and argv may be changed as Qt removes arguments that it
|
||||
* recognizes
|
||||
* @note Mode::SecondaryNotification only works if set on both the primary
|
||||
* instance and the secondary instance.
|
||||
* @note The timeout is just a hint for the maximum time of blocking
|
||||
* operations. It does not guarantee that the SingleApplication
|
||||
* initialisation will be completed in given time, though is a good hint.
|
||||
* Usually 4*timeout would be the worst case (fail) scenario.
|
||||
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication(int& argc,
|
||||
char* argv[],
|
||||
bool allowSecondary = false,
|
||||
Options options = Mode::User,
|
||||
int timeout = 100);
|
||||
~SingleApplication();
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is the primary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isPrimary();
|
||||
/**
|
||||
* @brief Returns if the instance is the primary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isPrimary();
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is a secondary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isSecondary();
|
||||
/**
|
||||
* @brief Returns if the instance is a secondary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isSecondary();
|
||||
|
||||
/**
|
||||
* @brief Returns a unique identifier for the current instance
|
||||
* @returns {qint32}
|
||||
*/
|
||||
quint32 instanceId();
|
||||
/**
|
||||
* @brief Returns a unique identifier for the current instance
|
||||
* @returns {qint32}
|
||||
*/
|
||||
quint32 instanceId();
|
||||
|
||||
/**
|
||||
* @brief Returns the process ID (PID) of the primary instance
|
||||
* @returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid();
|
||||
/**
|
||||
* @brief Returns the process ID (PID) of the primary instance
|
||||
* @returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid();
|
||||
|
||||
/**
|
||||
* @brief Sends a message to the primary instance. Returns true on success.
|
||||
* @param {int} timeout - Timeout for connecting
|
||||
* @returns {bool}
|
||||
* @note sendMessage() will return false if invoked from the primary
|
||||
* instance.
|
||||
*/
|
||||
bool sendMessage(QByteArray message, int timeout = 100);
|
||||
/**
|
||||
* @brief Sends a message to the primary instance. Returns true on success.
|
||||
* @param {int} timeout - Timeout for connecting
|
||||
* @returns {bool}
|
||||
* @note sendMessage() will return false if invoked from the primary
|
||||
* instance.
|
||||
*/
|
||||
bool sendMessage(QByteArray message, int timeout = 100);
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted();
|
||||
void receivedMessage(quint32 instanceId, QByteArray message);
|
||||
void instanceStarted();
|
||||
void receivedMessage(quint32 instanceId, QByteArray message);
|
||||
|
||||
private:
|
||||
SingleApplicationPrivate* d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
SingleApplicationPrivate* d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
};
|
||||
|
||||
class SingleApplicationPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType : quint8
|
||||
{
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
enum ConnectionType : quint8
|
||||
{
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate(SingleApplication* q_ptr);
|
||||
~SingleApplicationPrivate();
|
||||
SingleApplicationPrivate(SingleApplication* q_ptr);
|
||||
~SingleApplicationPrivate();
|
||||
|
||||
void genBlockServerName(int msecs);
|
||||
void startPrimary(bool resetMemory);
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType);
|
||||
qint64 primaryPid();
|
||||
void genBlockServerName(int msecs);
|
||||
void startPrimary(bool resetMemory);
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType);
|
||||
qint64 primaryPid();
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
void crashHandler();
|
||||
static void terminate(int signum);
|
||||
void crashHandler();
|
||||
static void terminate(int signum);
|
||||
#endif
|
||||
|
||||
QSharedMemory* memory;
|
||||
SingleApplication* q_ptr;
|
||||
QLocalSocket* socket;
|
||||
QLocalServer* server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
QSharedMemory* memory;
|
||||
SingleApplication* q_ptr;
|
||||
QLocalSocket* socket;
|
||||
QLocalServer* server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable(QLocalSocket*, quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable(QLocalSocket*, quint32);
|
||||
void slotClientConnectionClosed(QLocalSocket*, quint32);
|
||||
};
|
||||
|
||||
#endif // SINGLEAPPLICATION_P_H
|
||||
|
||||
@@ -25,38 +25,32 @@ CommandArgument::CommandArgument(const QString& name,
|
||||
, m_description(description)
|
||||
{}
|
||||
|
||||
void
|
||||
CommandArgument::setName(const QString& name)
|
||||
void CommandArgument::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandArgument::name() const
|
||||
QString CommandArgument::name() const
|
||||
{
|
||||
return m_name;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void
|
||||
CommandArgument::setDescription(const QString& description)
|
||||
void CommandArgument::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandArgument::description() const
|
||||
QString CommandArgument::description() const
|
||||
{
|
||||
return m_description;
|
||||
return m_description;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandArgument::isRoot() const
|
||||
bool CommandArgument::isRoot() const
|
||||
{
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
CommandArgument::operator==(const CommandArgument& arg) const
|
||||
bool 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
|
||||
{
|
||||
public:
|
||||
CommandArgument();
|
||||
explicit CommandArgument(const QString& name, const QString& description);
|
||||
CommandArgument();
|
||||
explicit CommandArgument(const QString& name, const QString& description);
|
||||
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
|
||||
bool isRoot() const;
|
||||
bool isRoot() const;
|
||||
|
||||
bool operator==(const CommandArgument& arg) const;
|
||||
bool operator==(const CommandArgument& arg) const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_description;
|
||||
QString m_name;
|
||||
QString m_description;
|
||||
};
|
||||
|
||||
@@ -34,399 +34,386 @@ auto versionOption =
|
||||
auto helpOption =
|
||||
CommandOption({ "h", "help" }, QStringLiteral("Displays this help"));
|
||||
|
||||
QString
|
||||
optionsToString(const QList<CommandOption>& options,
|
||||
const QList<CommandArgument>& arguments)
|
||||
QString optionsToString(const QList<CommandOption>& options,
|
||||
const QList<CommandArgument>& arguments)
|
||||
{
|
||||
int size = 0; // track the largest size
|
||||
QStringList dashedOptionList;
|
||||
// save the dashed options and its size in order to print the description
|
||||
// of every option at the same horizontal character position.
|
||||
for (auto const& option : options) {
|
||||
QStringList dashedOptions = option.dashedNames();
|
||||
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
||||
if (!option.valueName().isEmpty()) {
|
||||
joinedDashedOptions += QStringLiteral(" <%1>").arg(option.valueName());
|
||||
int size = 0; // track the largest size
|
||||
QStringList dashedOptionList;
|
||||
// save the dashed options and its size in order to print the description
|
||||
// of every option at the same horizontal character position.
|
||||
for (auto const& option : options) {
|
||||
QStringList dashedOptions = option.dashedNames();
|
||||
QString joinedDashedOptions = dashedOptions.join(QStringLiteral(", "));
|
||||
if (!option.valueName().isEmpty()) {
|
||||
joinedDashedOptions +=
|
||||
QStringLiteral(" <%1>").arg(option.valueName());
|
||||
}
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
}
|
||||
dashedOptionList << joinedDashedOptions;
|
||||
}
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
// check the length of the arguments
|
||||
for (auto const& arg : arguments) {
|
||||
if (arg.name().length() > size)
|
||||
size = arg.name().length();
|
||||
}
|
||||
dashedOptionList << joinedDashedOptions;
|
||||
}
|
||||
// check the length of the arguments
|
||||
for (auto const& arg : arguments) {
|
||||
if (arg.name().length() > size)
|
||||
size = arg.name().length();
|
||||
}
|
||||
// generate the text
|
||||
QString result;
|
||||
if (!dashedOptionList.isEmpty()) {
|
||||
result += QObject::tr("Options") + ":\n";
|
||||
QString linePadding = QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
||||
for (int i = 0; i < options.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
||||
.arg(options.at(i).description().replace(QLatin1String("\n"),
|
||||
linePadding));
|
||||
// generate the text
|
||||
QString result;
|
||||
if (!dashedOptionList.isEmpty()) {
|
||||
result += QObject::tr("Options") + ":\n";
|
||||
QString linePadding =
|
||||
QStringLiteral(" ").repeated(size + 4).prepend("\n");
|
||||
for (int i = 0; i < options.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(dashedOptionList.at(i).leftJustified(size, ' '))
|
||||
.arg(options.at(i).description().replace(
|
||||
QLatin1String("\n"), linePadding));
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1String("\n");
|
||||
}
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1String("\n");
|
||||
result += QObject::tr("Arguments") + ":\n";
|
||||
}
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QObject::tr("Arguments") + ":\n";
|
||||
}
|
||||
for (int i = 0; i < arguments.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
||||
.arg(arguments.at(i).description());
|
||||
}
|
||||
return result;
|
||||
for (int i = 0; i < arguments.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
.arg(arguments.at(i).name().leftJustified(size, ' '))
|
||||
.arg(arguments.at(i).description());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
bool
|
||||
CommandLineParser::processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
bool CommandLineParser::processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
{
|
||||
QString argument = *actualIt;
|
||||
bool ok = true;
|
||||
bool isValidArg = false;
|
||||
for (Node& n : actualNode->subNodes) {
|
||||
if (n.argument.name() == argument) {
|
||||
actualNode = &n;
|
||||
isValidArg = true;
|
||||
break;
|
||||
QString argument = *actualIt;
|
||||
bool ok = true;
|
||||
bool isValidArg = false;
|
||||
for (Node& n : actualNode->subNodes) {
|
||||
if (n.argument.name() == argument) {
|
||||
actualNode = &n;
|
||||
isValidArg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isValidArg) {
|
||||
auto nextArg = actualNode->argument;
|
||||
m_foundArgs.append(nextArg);
|
||||
// check next is help
|
||||
++actualIt;
|
||||
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
||||
--actualIt;
|
||||
} else {
|
||||
ok = false;
|
||||
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
||||
}
|
||||
return ok;
|
||||
if (isValidArg) {
|
||||
auto nextArg = actualNode->argument;
|
||||
m_foundArgs.append(nextArg);
|
||||
// check next is help
|
||||
++actualIt;
|
||||
ok = processIfOptionIsHelp(args, actualIt, actualNode);
|
||||
--actualIt;
|
||||
} else {
|
||||
ok = false;
|
||||
out << QStringLiteral("'%1' is not a valid argument.").arg(argument);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode)
|
||||
bool CommandLineParser::processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode)
|
||||
{
|
||||
QString arg = *actualIt;
|
||||
bool ok = true;
|
||||
// track values
|
||||
int equalsPos = arg.indexOf(QLatin1String("="));
|
||||
QString valueStr;
|
||||
if (equalsPos != -1) {
|
||||
valueStr = arg.mid(equalsPos + 1); // right
|
||||
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;
|
||||
QString arg = *actualIt;
|
||||
bool ok = true;
|
||||
// track values
|
||||
int equalsPos = arg.indexOf(QLatin1String("="));
|
||||
QString valueStr;
|
||||
if (equalsPos != -1) {
|
||||
valueStr = arg.mid(equalsPos + 1); // right
|
||||
arg = arg.mid(0, equalsPos); // left
|
||||
}
|
||||
}
|
||||
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);
|
||||
// check format -x --xx...
|
||||
bool isDoubleDashed = arg.startsWith(QLatin1String("--"));
|
||||
ok = isDoubleDashed ? arg.length() > 3 : arg.length() == 2;
|
||||
if (!ok) {
|
||||
QString err = option.errorMsg();
|
||||
if (!err.endsWith(QLatin1String(".")))
|
||||
err += QLatin1String(".");
|
||||
out << err;
|
||||
return ok;
|
||||
out << QStringLiteral("the option %1 has a wrong format.").arg(arg);
|
||||
return ok;
|
||||
}
|
||||
option.setValue(valueStr);
|
||||
}
|
||||
m_foundOptions.append(option);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
CommandLineParser::parse(const QStringList& args)
|
||||
bool CommandLineParser::parse(const QStringList& args)
|
||||
{
|
||||
m_foundArgs.clear();
|
||||
m_foundOptions.clear();
|
||||
bool ok = true;
|
||||
Node* actualNode = &m_parseTree;
|
||||
auto it = ++args.cbegin();
|
||||
// check version option
|
||||
QStringList dashedVersion = versionOption.dashedNames();
|
||||
if (m_withVersion && args.length() > 1 &&
|
||||
dashedVersion.contains(args.at(1))) {
|
||||
if (args.length() == 2) {
|
||||
printVersion();
|
||||
m_foundOptions << versionOption;
|
||||
} else {
|
||||
out << "Invalid arguments after the version option.";
|
||||
ok = false;
|
||||
m_foundArgs.clear();
|
||||
m_foundOptions.clear();
|
||||
bool ok = true;
|
||||
Node* actualNode = &m_parseTree;
|
||||
auto it = ++args.cbegin();
|
||||
// check version option
|
||||
QStringList dashedVersion = versionOption.dashedNames();
|
||||
if (m_withVersion && args.length() > 1 &&
|
||||
dashedVersion.contains(args.at(1))) {
|
||||
if (args.length() == 2) {
|
||||
printVersion();
|
||||
m_foundOptions << versionOption;
|
||||
} else {
|
||||
out << "Invalid arguments after the version option.";
|
||||
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;
|
||||
}
|
||||
// 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 {
|
||||
ok = processArgs(args, it, actualNode);
|
||||
Node child;
|
||||
child.argument = arg;
|
||||
n->subNodes.append(child);
|
||||
}
|
||||
}
|
||||
if (!ok && !m_generalErrorMessage.isEmpty()) {
|
||||
out << QStringLiteral(" %1\n").arg(m_generalErrorMessage);
|
||||
}
|
||||
return ok;
|
||||
return res;
|
||||
}
|
||||
|
||||
CommandOption
|
||||
CommandLineParser::addVersionOption()
|
||||
bool CommandLineParser::AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
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 {
|
||||
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;
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
n->options.append(option);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||
bool CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
m_generalErrorMessage = msg;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::setDescription(const QString& description)
|
||||
{
|
||||
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;
|
||||
bool res = true;
|
||||
for (auto const& option : options) {
|
||||
if (!AddOption(option, parent)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::printVersion()
|
||||
void CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||
{
|
||||
out << "Flameshot " << qApp->applicationVersion() << "\nCompiled with Qt "
|
||||
<< static_cast<QString>(QT_VERSION_STR) << "\n";
|
||||
m_generalErrorMessage = msg;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::printHelp(QStringList args, const Node* node)
|
||||
void CommandLineParser::setDescription(const QString& description)
|
||||
{
|
||||
args.removeLast(); // remove the help, it's always the last
|
||||
QString helpText;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
// 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);
|
||||
bool CommandLineParser::isSet(const CommandArgument& arg) const
|
||||
{
|
||||
return m_foundArgs.contains(arg);
|
||||
}
|
||||
|
||||
// short section about default behavior
|
||||
helpText += QObject::tr("Per default runs Flameshot in the background and \
|
||||
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 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.");
|
||||
helpText += "\n\n";
|
||||
helpText += "\n\n";
|
||||
|
||||
// add command options and subarguments
|
||||
QList<CommandArgument> subArgs;
|
||||
for (const Node& n : node->subNodes)
|
||||
subArgs.append(n.argument);
|
||||
auto modifiedOptions = node->options;
|
||||
if (m_withHelp)
|
||||
modifiedOptions << helpOption;
|
||||
if (m_withVersion && node == &m_parseTree) {
|
||||
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;
|
||||
// add command options and subarguments
|
||||
QList<CommandArgument> subArgs;
|
||||
for (const Node& n : node->subNodes)
|
||||
subArgs.append(n.argument);
|
||||
auto modifiedOptions = node->options;
|
||||
if (m_withHelp)
|
||||
modifiedOptions << helpOption;
|
||||
if (m_withVersion && node == &m_parseTree) {
|
||||
modifiedOptions << versionOption;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
helpText += optionsToString(modifiedOptions, subArgs);
|
||||
// print it
|
||||
out << helpText;
|
||||
}
|
||||
|
||||
CommandLineParser::Node*
|
||||
CommandLineParser::recursiveParentSearch(const CommandArgument& parent,
|
||||
Node& node) const
|
||||
CommandLineParser::Node* CommandLineParser::findParent(
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
Node* res = nullptr;
|
||||
if (node.argument == parent) {
|
||||
res = &node;
|
||||
} else {
|
||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
if (parent == CommandArgument()) {
|
||||
return &m_parseTree;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode)
|
||||
CommandLineParser::Node* CommandLineParser::recursiveParentSearch(
|
||||
const CommandArgument& parent,
|
||||
Node& node) const
|
||||
{
|
||||
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++;
|
||||
Node* res = nullptr;
|
||||
if (node.argument == parent) {
|
||||
res = &node;
|
||||
} else {
|
||||
out << "Invalid arguments after the help option.";
|
||||
ok = false;
|
||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i) {
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
return res;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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 addHelpOption();
|
||||
CommandOption addVersionOption();
|
||||
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());
|
||||
|
||||
bool AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
bool AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
|
||||
bool AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent = CommandArgument());
|
||||
void setGeneralErrorMessage(const QString& msg);
|
||||
void setDescription(const QString& description);
|
||||
|
||||
void setGeneralErrorMessage(const QString& msg);
|
||||
void setDescription(const QString& description);
|
||||
|
||||
bool isSet(const CommandArgument& arg) const;
|
||||
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:
|
||||
bool m_withHelp = false;
|
||||
bool m_withVersion = false;
|
||||
QString m_description;
|
||||
QString m_generalErrorMessage;
|
||||
bool m_withHelp = false;
|
||||
bool m_withVersion = false;
|
||||
QString m_description;
|
||||
QString m_generalErrorMessage;
|
||||
|
||||
struct Node
|
||||
{
|
||||
explicit Node(const CommandArgument& arg)
|
||||
: argument(arg)
|
||||
{}
|
||||
Node() {}
|
||||
bool operator==(const Node& n) const
|
||||
struct Node
|
||||
{
|
||||
return argument == n.argument && options == n.options &&
|
||||
subNodes == n.subNodes;
|
||||
}
|
||||
CommandArgument argument;
|
||||
QList<CommandOption> options;
|
||||
QList<Node> subNodes;
|
||||
};
|
||||
explicit Node(const CommandArgument& arg)
|
||||
: argument(arg)
|
||||
{}
|
||||
Node() {}
|
||||
bool operator==(const Node& n) const
|
||||
{
|
||||
return argument == n.argument && options == n.options &&
|
||||
subNodes == n.subNodes;
|
||||
}
|
||||
CommandArgument argument;
|
||||
QList<CommandOption> options;
|
||||
QList<Node> subNodes;
|
||||
};
|
||||
|
||||
Node m_parseTree;
|
||||
QList<CommandOption> m_foundOptions;
|
||||
QList<CommandArgument> m_foundArgs;
|
||||
Node m_parseTree;
|
||||
QList<CommandOption> m_foundOptions;
|
||||
QList<CommandArgument> m_foundArgs;
|
||||
|
||||
// helper functions
|
||||
void printVersion();
|
||||
void printHelp(QStringList args, const Node* node);
|
||||
Node* findParent(const CommandArgument& parent);
|
||||
Node* recursiveParentSearch(const CommandArgument& parent, Node& node) const;
|
||||
bool processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode);
|
||||
// helper functions
|
||||
void printVersion();
|
||||
void printHelp(QStringList args, const Node* node);
|
||||
Node* findParent(const CommandArgument& parent);
|
||||
Node* recursiveParentSearch(const CommandArgument& parent,
|
||||
Node& node) const;
|
||||
bool processIfOptionIsHelp(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processArgs(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node*& actualNode);
|
||||
bool processOptions(const QStringList& args,
|
||||
QStringList::const_iterator& actualIt,
|
||||
Node* const actualNode);
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ CommandOption::CommandOption(const QString& name,
|
||||
, m_valueName(valueName)
|
||||
, m_value(defaultValue)
|
||||
{
|
||||
m_checker = [](QString const&) { return true; };
|
||||
m_checker = [](QString const&) { return true; };
|
||||
}
|
||||
|
||||
CommandOption::CommandOption(const QStringList& names,
|
||||
@@ -38,103 +38,89 @@ CommandOption::CommandOption(const QStringList& names,
|
||||
, m_valueName(valueName)
|
||||
, m_value(defaultValue)
|
||||
{
|
||||
m_checker = [](QString const&) -> bool { return true; };
|
||||
m_checker = [](QString const&) -> bool { return true; };
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setName(const QString& name)
|
||||
void CommandOption::setName(const QString& name)
|
||||
{
|
||||
m_names = QStringList() << name;
|
||||
m_names = QStringList() << name;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setNames(const QStringList& names)
|
||||
void CommandOption::setNames(const QStringList& names)
|
||||
{
|
||||
m_names = names;
|
||||
m_names = names;
|
||||
}
|
||||
|
||||
QStringList
|
||||
CommandOption::names() const
|
||||
QStringList CommandOption::names() const
|
||||
{
|
||||
return m_names;
|
||||
return m_names;
|
||||
}
|
||||
|
||||
QStringList
|
||||
CommandOption::dashedNames() const
|
||||
QStringList CommandOption::dashedNames() const
|
||||
{
|
||||
QStringList dashedNames;
|
||||
for (const QString& name : m_names) {
|
||||
// prepend "-" to single character options, and "--" to the others
|
||||
QString dashedName = (name.length() == 1)
|
||||
? QStringLiteral("-%1").arg(name)
|
||||
: QStringLiteral("--%1").arg(name);
|
||||
dashedNames << dashedName;
|
||||
}
|
||||
return dashedNames;
|
||||
QStringList dashedNames;
|
||||
for (const QString& name : m_names) {
|
||||
// prepend "-" to single character options, and "--" to the others
|
||||
QString dashedName = (name.length() == 1)
|
||||
? QStringLiteral("-%1").arg(name)
|
||||
: QStringLiteral("--%1").arg(name);
|
||||
dashedNames << dashedName;
|
||||
}
|
||||
return dashedNames;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setValueName(const QString& name)
|
||||
void CommandOption::setValueName(const QString& name)
|
||||
{
|
||||
m_valueName = name;
|
||||
m_valueName = name;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::valueName() const
|
||||
QString CommandOption::valueName() const
|
||||
{
|
||||
return m_valueName;
|
||||
return m_valueName;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setValue(const QString& value)
|
||||
void CommandOption::setValue(const QString& value)
|
||||
{
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::value() const
|
||||
QString CommandOption::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||
const QString& errMsg)
|
||||
void CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||
const QString& errMsg)
|
||||
{
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::checkValue(const QString& value) const
|
||||
bool CommandOption::checkValue(const QString& value) const
|
||||
{
|
||||
return m_checker(value);
|
||||
return m_checker(value);
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::description() const
|
||||
QString CommandOption::description() const
|
||||
{
|
||||
return m_description;
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setDescription(const QString& description)
|
||||
void CommandOption::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::errorMsg() const
|
||||
QString CommandOption::errorMsg() const
|
||||
{
|
||||
return m_errorMsg;
|
||||
return m_errorMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::operator==(const CommandOption& option) const
|
||||
bool CommandOption::operator==(const CommandOption& option) const
|
||||
{
|
||||
return m_description == option.m_description && m_names == option.m_names &&
|
||||
m_valueName == option.m_valueName;
|
||||
return m_description == option.m_description && m_names == option.m_names &&
|
||||
m_valueName == option.m_valueName;
|
||||
}
|
||||
|
||||
@@ -25,44 +25,44 @@ using std::function;
|
||||
class CommandOption
|
||||
{
|
||||
public:
|
||||
CommandOption(const QString& name,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
CommandOption(const QString& name,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
|
||||
CommandOption(const QStringList& names,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
CommandOption(const QStringList& names,
|
||||
const QString& description,
|
||||
const QString& valueName = QString(),
|
||||
const QString& defaultValue = QString());
|
||||
|
||||
void setName(const QString& name);
|
||||
void setNames(const QStringList& names);
|
||||
QStringList names() const;
|
||||
QStringList dashedNames() const;
|
||||
void setName(const QString& name);
|
||||
void setNames(const QStringList& names);
|
||||
QStringList names() const;
|
||||
QStringList dashedNames() const;
|
||||
|
||||
void setValueName(const QString& name);
|
||||
QString valueName() const;
|
||||
void setValueName(const QString& name);
|
||||
QString valueName() const;
|
||||
|
||||
void setValue(const QString& value);
|
||||
QString value() const;
|
||||
void setValue(const QString& value);
|
||||
QString value() const;
|
||||
|
||||
void addChecker(const function<bool(QString const&)> checker,
|
||||
const QString& errMsg);
|
||||
bool checkValue(const QString& value) const;
|
||||
void addChecker(const function<bool(QString const&)> checker,
|
||||
const QString& errMsg);
|
||||
bool checkValue(const QString& value) const;
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
|
||||
QString errorMsg() const;
|
||||
QString errorMsg() const;
|
||||
|
||||
bool operator==(const CommandOption& option) const;
|
||||
bool operator==(const CommandOption& option) const;
|
||||
|
||||
private:
|
||||
QStringList m_names;
|
||||
QString m_description;
|
||||
QString m_valueName;
|
||||
QString m_value;
|
||||
QStringList m_names;
|
||||
QString m_description;
|
||||
QString m_valueName;
|
||||
QString m_value;
|
||||
|
||||
function<bool(QString const&)> m_checker;
|
||||
QString m_errorMsg;
|
||||
function<bool(QString const&)> m_checker;
|
||||
QString m_errorMsg;
|
||||
};
|
||||
|
||||
@@ -24,94 +24,90 @@
|
||||
ButtonListView::ButtonListView(QWidget* parent)
|
||||
: QListWidget(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setFlow(QListWidget::TopToBottom);
|
||||
initButtonList();
|
||||
updateComponents();
|
||||
connect(
|
||||
this, &QListWidget::itemClicked, this, &ButtonListView::reverseItemCheck);
|
||||
setMouseTracking(true);
|
||||
setFlow(QListWidget::TopToBottom);
|
||||
initButtonList();
|
||||
updateComponents();
|
||||
connect(
|
||||
this, &QListWidget::itemClicked, this, &ButtonListView::reverseItemCheck);
|
||||
}
|
||||
|
||||
void
|
||||
ButtonListView::initButtonList()
|
||||
void ButtonListView::initButtonList()
|
||||
{
|
||||
ToolFactory factory;
|
||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||
ToolFactory factory;
|
||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||
|
||||
for (const CaptureToolButton::ButtonType t : listTypes) {
|
||||
CaptureTool* tool = factory.CreateTool(t);
|
||||
for (const CaptureToolButton::ButtonType t : listTypes) {
|
||||
CaptureTool* tool = factory.CreateTool(t);
|
||||
|
||||
// add element to the local map
|
||||
m_buttonTypeByName.insert(tool->name(), t);
|
||||
// add element to the local map
|
||||
m_buttonTypeByName.insert(tool->name(), t);
|
||||
|
||||
// init the menu option
|
||||
QListWidgetItem* m_buttonItem = new QListWidgetItem(this);
|
||||
// init the menu option
|
||||
QListWidgetItem* m_buttonItem = new QListWidgetItem(this);
|
||||
|
||||
// when the background is lighter than gray, it uses the white icons
|
||||
QColor bgColor = this->palette().color(QWidget::backgroundRole());
|
||||
m_buttonItem->setIcon(tool->icon(bgColor, false));
|
||||
// when the background is lighter than gray, it uses the white icons
|
||||
QColor bgColor = this->palette().color(QWidget::backgroundRole());
|
||||
m_buttonItem->setIcon(tool->icon(bgColor, false));
|
||||
|
||||
m_buttonItem->setFlags(Qt::ItemIsUserCheckable);
|
||||
QColor foregroundColor = this->palette().color(QWidget::foregroundRole());
|
||||
m_buttonItem->setForeground(foregroundColor);
|
||||
m_buttonItem->setFlags(Qt::ItemIsUserCheckable);
|
||||
QColor foregroundColor =
|
||||
this->palette().color(QWidget::foregroundRole());
|
||||
m_buttonItem->setForeground(foregroundColor);
|
||||
|
||||
m_buttonItem->setText(tool->name());
|
||||
m_buttonItem->setToolTip(tool->description());
|
||||
tool->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ButtonListView::updateActiveButtons(QListWidgetItem* item)
|
||||
{
|
||||
CaptureToolButton::ButtonType bType = m_buttonTypeByName[item->text()];
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
m_listButtons.append(bType);
|
||||
// TODO refactor so we don't need external sorts
|
||||
using bt = CaptureToolButton::ButtonType;
|
||||
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) {
|
||||
return CaptureToolButton::getPriorityByButton(a) <
|
||||
CaptureToolButton::getPriorityByButton(b);
|
||||
});
|
||||
} else {
|
||||
m_listButtons.remove(m_listButtons.indexOf(bType));
|
||||
}
|
||||
ConfigHandler().setButtons(m_listButtons);
|
||||
}
|
||||
|
||||
void
|
||||
ButtonListView::reverseItemCheck(QListWidgetItem* item)
|
||||
{
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
updateActiveButtons(item);
|
||||
}
|
||||
|
||||
void
|
||||
ButtonListView::selectAll()
|
||||
{
|
||||
ConfigHandler().setAllTheButtons();
|
||||
for (int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ButtonListView::updateComponents()
|
||||
{
|
||||
m_listButtons = ConfigHandler().getButtons();
|
||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||
for (int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
auto elem = static_cast<CaptureToolButton::ButtonType>(listTypes.at(i));
|
||||
if (m_listButtons.contains(elem)) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
m_buttonItem->setText(tool->name());
|
||||
m_buttonItem->setToolTip(tool->description());
|
||||
tool->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonListView::updateActiveButtons(QListWidgetItem* item)
|
||||
{
|
||||
CaptureToolButton::ButtonType bType = m_buttonTypeByName[item->text()];
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
m_listButtons.append(bType);
|
||||
// TODO refactor so we don't need external sorts
|
||||
using bt = CaptureToolButton::ButtonType;
|
||||
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) {
|
||||
return CaptureToolButton::getPriorityByButton(a) <
|
||||
CaptureToolButton::getPriorityByButton(b);
|
||||
});
|
||||
} else {
|
||||
m_listButtons.remove(m_listButtons.indexOf(bType));
|
||||
}
|
||||
ConfigHandler().setButtons(m_listButtons);
|
||||
}
|
||||
|
||||
void ButtonListView::reverseItemCheck(QListWidgetItem* item)
|
||||
{
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
updateActiveButtons(item);
|
||||
}
|
||||
|
||||
void ButtonListView::selectAll()
|
||||
{
|
||||
ConfigHandler().setAllTheButtons();
|
||||
for (int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonListView::updateComponents()
|
||||
{
|
||||
m_listButtons = ConfigHandler().getButtons();
|
||||
auto listTypes = CaptureToolButton::getIterableButtonTypes();
|
||||
for (int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
auto elem = static_cast<CaptureToolButton::ButtonType>(listTypes.at(i));
|
||||
if (m_listButtons.contains(elem)) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
class ButtonListView : public QListWidget
|
||||
{
|
||||
public:
|
||||
explicit ButtonListView(QWidget* parent = nullptr);
|
||||
explicit ButtonListView(QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void selectAll();
|
||||
void updateComponents();
|
||||
void selectAll();
|
||||
void updateComponents();
|
||||
|
||||
private slots:
|
||||
void reverseItemCheck(QListWidgetItem*);
|
||||
void reverseItemCheck(QListWidgetItem*);
|
||||
|
||||
protected:
|
||||
void initButtonList();
|
||||
void initButtonList();
|
||||
|
||||
private:
|
||||
QVector<CaptureToolButton::ButtonType> m_listButtons;
|
||||
QMap<QString, CaptureToolButton::ButtonType> m_buttonTypeByName;
|
||||
QVector<CaptureToolButton::ButtonType> m_listButtons;
|
||||
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)
|
||||
: QLabel(parent)
|
||||
{
|
||||
setText(s);
|
||||
setText(s);
|
||||
}
|
||||
|
||||
void
|
||||
ClickableLabel::mousePressEvent(QMouseEvent*)
|
||||
void ClickableLabel::mousePressEvent(QMouseEvent*)
|
||||
{
|
||||
emit clicked();
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
class ClickableLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ClickableLabel(QWidget* parent = nullptr);
|
||||
ClickableLabel(QString s, QWidget* parent = nullptr);
|
||||
explicit ClickableLabel(QWidget* parent = nullptr);
|
||||
ClickableLabel(QString s, QWidget* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
};
|
||||
|
||||
@@ -36,61 +36,61 @@
|
||||
ConfigWindow::ConfigWindow(QWidget* parent)
|
||||
: QTabWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
const int size = GlobalValues::buttonBaseSize() * 12;
|
||||
setMinimumSize(size, size);
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
setWindowTitle(tr("Configuration"));
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
const int size = GlobalValues::buttonBaseSize() * 12;
|
||||
setMinimumSize(size, size);
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
setWindowTitle(tr("Configuration"));
|
||||
|
||||
auto changedSlot = [this](QString s) {
|
||||
QStringList files = m_configWatcher->files();
|
||||
if (!files.contains(s)) {
|
||||
this->m_configWatcher->addPath(s);
|
||||
}
|
||||
emit updateChildren();
|
||||
};
|
||||
m_configWatcher = new QFileSystemWatcher(this);
|
||||
m_configWatcher->addPath(ConfigHandler().configFilePath());
|
||||
connect(m_configWatcher, &QFileSystemWatcher::fileChanged, this, changedSlot);
|
||||
auto changedSlot = [this](QString s) {
|
||||
QStringList files = m_configWatcher->files();
|
||||
if (!files.contains(s)) {
|
||||
this->m_configWatcher->addPath(s);
|
||||
}
|
||||
emit updateChildren();
|
||||
};
|
||||
m_configWatcher = new QFileSystemWatcher(this);
|
||||
m_configWatcher->addPath(ConfigHandler().configFilePath());
|
||||
connect(
|
||||
m_configWatcher, &QFileSystemWatcher::fileChanged, this, changedSlot);
|
||||
|
||||
QColor background = this->palette().window().color();
|
||||
bool isDark = ColorUtils::colorIsDark(background);
|
||||
QString modifier =
|
||||
isDark ? PathInfo::whiteIconPath() : PathInfo::blackIconPath();
|
||||
QColor background = this->palette().window().color();
|
||||
bool isDark = ColorUtils::colorIsDark(background);
|
||||
QString modifier =
|
||||
isDark ? PathInfo::whiteIconPath() : PathInfo::blackIconPath();
|
||||
|
||||
// visuals
|
||||
m_visuals = new VisualsEditor();
|
||||
addTab(m_visuals, QIcon(modifier + "graphics.svg"), tr("Interface"));
|
||||
// visuals
|
||||
m_visuals = new VisualsEditor();
|
||||
addTab(m_visuals, QIcon(modifier + "graphics.svg"), tr("Interface"));
|
||||
|
||||
// filename
|
||||
m_filenameEditor = new FileNameEditor();
|
||||
addTab(m_filenameEditor,
|
||||
QIcon(modifier + "name_edition.svg"),
|
||||
tr("Filename Editor"));
|
||||
// filename
|
||||
m_filenameEditor = new FileNameEditor();
|
||||
addTab(m_filenameEditor,
|
||||
QIcon(modifier + "name_edition.svg"),
|
||||
tr("Filename Editor"));
|
||||
|
||||
// general
|
||||
m_generalConfig = new GeneneralConf();
|
||||
addTab(m_generalConfig, QIcon(modifier + "config.svg"), tr("General"));
|
||||
// general
|
||||
m_generalConfig = new GeneneralConf();
|
||||
addTab(m_generalConfig, QIcon(modifier + "config.svg"), tr("General"));
|
||||
|
||||
// connect update sigslots
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_filenameEditor,
|
||||
&FileNameEditor::updateComponents);
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_visuals,
|
||||
&VisualsEditor::updateComponents);
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_generalConfig,
|
||||
&GeneneralConf::updateComponents);
|
||||
// connect update sigslots
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_filenameEditor,
|
||||
&FileNameEditor::updateComponents);
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_visuals,
|
||||
&VisualsEditor::updateComponents);
|
||||
connect(this,
|
||||
&ConfigWindow::updateChildren,
|
||||
m_generalConfig,
|
||||
&GeneneralConf::updateComponents);
|
||||
}
|
||||
|
||||
void
|
||||
ConfigWindow::keyPressEvent(QKeyEvent* e)
|
||||
void ConfigWindow::keyPressEvent(QKeyEvent* e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
close();
|
||||
}
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,19 +26,19 @@ class VisualsEditor;
|
||||
|
||||
class ConfigWindow : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConfigWindow(QWidget* parent = nullptr);
|
||||
explicit ConfigWindow(QWidget* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void updateChildren();
|
||||
void updateChildren();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
|
||||
private:
|
||||
FileNameEditor* m_filenameEditor;
|
||||
GeneneralConf* m_generalConfig;
|
||||
VisualsEditor* m_visuals;
|
||||
QFileSystemWatcher* m_configWatcher;
|
||||
FileNameEditor* m_filenameEditor;
|
||||
GeneneralConf* m_generalConfig;
|
||||
VisualsEditor* m_visuals;
|
||||
QFileSystemWatcher* m_configWatcher;
|
||||
};
|
||||
|
||||
@@ -20,38 +20,37 @@
|
||||
ExtendedSlider::ExtendedSlider(QWidget* parent)
|
||||
: QSlider(parent)
|
||||
{
|
||||
connect(
|
||||
this, &ExtendedSlider::valueChanged, this, &ExtendedSlider::updateTooltip);
|
||||
connect(this, &ExtendedSlider::sliderMoved, this, &ExtendedSlider::fireTimer);
|
||||
m_timer.setSingleShot(true);
|
||||
connect(
|
||||
&m_timer, &QTimer::timeout, this, &ExtendedSlider::modificationsEnded);
|
||||
connect(this,
|
||||
&ExtendedSlider::valueChanged,
|
||||
this,
|
||||
&ExtendedSlider::updateTooltip);
|
||||
connect(
|
||||
this, &ExtendedSlider::sliderMoved, this, &ExtendedSlider::fireTimer);
|
||||
m_timer.setSingleShot(true);
|
||||
connect(
|
||||
&m_timer, &QTimer::timeout, this, &ExtendedSlider::modificationsEnded);
|
||||
}
|
||||
|
||||
int
|
||||
ExtendedSlider::mappedValue(int min, int max)
|
||||
int ExtendedSlider::mappedValue(int min, int max)
|
||||
{
|
||||
qreal progress =
|
||||
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
||||
return min + (max - min) * progress;
|
||||
qreal progress =
|
||||
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
||||
return min + (max - min) * progress;
|
||||
}
|
||||
|
||||
void
|
||||
ExtendedSlider::setMapedValue(int min, int val, int max)
|
||||
void ExtendedSlider::setMapedValue(int min, int val, int max)
|
||||
{
|
||||
qreal progress = ((val - min) + 1) / static_cast<qreal>(max - min);
|
||||
int value = minimum() + (maximum() - minimum()) * progress;
|
||||
setValue(value);
|
||||
qreal progress = ((val - min) + 1) / static_cast<qreal>(max - min);
|
||||
int value = minimum() + (maximum() - minimum()) * progress;
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
void
|
||||
ExtendedSlider::updateTooltip()
|
||||
void ExtendedSlider::updateTooltip()
|
||||
{
|
||||
setToolTip(QString::number(value()) + "%");
|
||||
setToolTip(QString::number(value()) + "%");
|
||||
}
|
||||
|
||||
void
|
||||
ExtendedSlider::fireTimer()
|
||||
void ExtendedSlider::fireTimer()
|
||||
{
|
||||
m_timer.start(500);
|
||||
m_timer.start(500);
|
||||
}
|
||||
|
||||
@@ -22,20 +22,20 @@
|
||||
|
||||
class ExtendedSlider : public QSlider
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExtendedSlider(QWidget* parent = nullptr);
|
||||
explicit ExtendedSlider(QWidget* parent = nullptr);
|
||||
|
||||
int mappedValue(int min, int max);
|
||||
void setMapedValue(int min, int val, int max);
|
||||
int mappedValue(int min, int max);
|
||||
void setMapedValue(int min, int val, int max);
|
||||
|
||||
signals:
|
||||
void modificationsEnded();
|
||||
void modificationsEnded();
|
||||
|
||||
private slots:
|
||||
void updateTooltip();
|
||||
void fireTimer();
|
||||
void updateTooltip();
|
||||
void fireTimer();
|
||||
|
||||
private:
|
||||
QTimer m_timer;
|
||||
QTimer m_timer;
|
||||
};
|
||||
|
||||
@@ -28,110 +28,104 @@
|
||||
FileNameEditor::FileNameEditor(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
initWidgets();
|
||||
initLayout();
|
||||
initWidgets();
|
||||
initLayout();
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::initLayout()
|
||||
void FileNameEditor::initLayout()
|
||||
{
|
||||
m_layout = new QVBoxLayout(this);
|
||||
auto infoLabel = new QLabel(tr("Edit the name of your captures:"), this);
|
||||
infoLabel->setFixedHeight(20);
|
||||
m_layout->addWidget(infoLabel);
|
||||
m_layout->addWidget(m_helperButtons);
|
||||
m_layout->addWidget(new QLabel(tr("Edit:")));
|
||||
m_layout->addWidget(m_nameEditor);
|
||||
m_layout->addWidget(new QLabel(tr("Preview:")));
|
||||
m_layout->addWidget(m_outputLabel);
|
||||
m_layout = new QVBoxLayout(this);
|
||||
auto infoLabel = new QLabel(tr("Edit the name of your captures:"), this);
|
||||
infoLabel->setFixedHeight(20);
|
||||
m_layout->addWidget(infoLabel);
|
||||
m_layout->addWidget(m_helperButtons);
|
||||
m_layout->addWidget(new QLabel(tr("Edit:")));
|
||||
m_layout->addWidget(m_nameEditor);
|
||||
m_layout->addWidget(new QLabel(tr("Preview:")));
|
||||
m_layout->addWidget(m_outputLabel);
|
||||
|
||||
QHBoxLayout* horizLayout = new QHBoxLayout();
|
||||
horizLayout->addWidget(m_saveButton);
|
||||
horizLayout->addWidget(m_resetButton);
|
||||
horizLayout->addWidget(m_clearButton);
|
||||
m_layout->addLayout(horizLayout);
|
||||
QHBoxLayout* horizLayout = new QHBoxLayout();
|
||||
horizLayout->addWidget(m_saveButton);
|
||||
horizLayout->addWidget(m_resetButton);
|
||||
horizLayout->addWidget(m_clearButton);
|
||||
m_layout->addLayout(horizLayout);
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::initWidgets()
|
||||
void FileNameEditor::initWidgets()
|
||||
{
|
||||
m_nameHandler = new FileNameHandler(this);
|
||||
m_nameHandler = new FileNameHandler(this);
|
||||
|
||||
// editor
|
||||
m_nameEditor = new QLineEdit(this);
|
||||
m_nameEditor->setMaxLength(FileNameHandler::MAX_CHARACTERS);
|
||||
// editor
|
||||
m_nameEditor = new QLineEdit(this);
|
||||
m_nameEditor->setMaxLength(FileNameHandler::MAX_CHARACTERS);
|
||||
|
||||
// preview
|
||||
m_outputLabel = new QLineEdit(this);
|
||||
m_outputLabel->setDisabled(true);
|
||||
QString foreground = this->palette().windowText().color().name();
|
||||
m_outputLabel->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||
QPalette pal = m_outputLabel->palette();
|
||||
QColor color = pal.color(QPalette::Disabled, m_outputLabel->backgroundRole());
|
||||
pal.setColor(QPalette::Active, m_outputLabel->backgroundRole(), color);
|
||||
m_outputLabel->setPalette(pal);
|
||||
// preview
|
||||
m_outputLabel = new QLineEdit(this);
|
||||
m_outputLabel->setDisabled(true);
|
||||
QString foreground = this->palette().windowText().color().name();
|
||||
m_outputLabel->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||
QPalette pal = m_outputLabel->palette();
|
||||
QColor color =
|
||||
pal.color(QPalette::Disabled, m_outputLabel->backgroundRole());
|
||||
pal.setColor(QPalette::Active, m_outputLabel->backgroundRole(), color);
|
||||
m_outputLabel->setPalette(pal);
|
||||
|
||||
connect(m_nameEditor,
|
||||
&QLineEdit::textChanged,
|
||||
this,
|
||||
&FileNameEditor::showParsedPattern);
|
||||
updateComponents();
|
||||
connect(m_nameEditor,
|
||||
&QLineEdit::textChanged,
|
||||
this,
|
||||
&FileNameEditor::showParsedPattern);
|
||||
updateComponents();
|
||||
|
||||
// helper buttons
|
||||
m_helperButtons = new StrftimeChooserWidget(this);
|
||||
connect(m_helperButtons,
|
||||
&StrftimeChooserWidget::variableEmitted,
|
||||
this,
|
||||
&FileNameEditor::addToNameEditor);
|
||||
// helper buttons
|
||||
m_helperButtons = new StrftimeChooserWidget(this);
|
||||
connect(m_helperButtons,
|
||||
&StrftimeChooserWidget::variableEmitted,
|
||||
this,
|
||||
&FileNameEditor::addToNameEditor);
|
||||
|
||||
// save
|
||||
m_saveButton = new QPushButton(tr("Save"), this);
|
||||
connect(
|
||||
m_saveButton, &QPushButton::clicked, this, &FileNameEditor::savePattern);
|
||||
m_saveButton->setToolTip(tr("Saves the pattern"));
|
||||
// reset
|
||||
m_resetButton = new QPushButton(tr("Reset"), this);
|
||||
connect(
|
||||
m_resetButton, &QPushButton::clicked, this, &FileNameEditor::resetName);
|
||||
m_resetButton->setToolTip(tr("Restores the saved pattern"));
|
||||
// clear
|
||||
m_clearButton = new QPushButton(tr("Clear"), this);
|
||||
connect(m_clearButton, &QPushButton::clicked, this, [this]() {
|
||||
m_nameEditor->setText(QString());
|
||||
});
|
||||
m_clearButton->setToolTip(tr("Deletes the name"));
|
||||
// save
|
||||
m_saveButton = new QPushButton(tr("Save"), this);
|
||||
connect(
|
||||
m_saveButton, &QPushButton::clicked, this, &FileNameEditor::savePattern);
|
||||
m_saveButton->setToolTip(tr("Saves the pattern"));
|
||||
// reset
|
||||
m_resetButton = new QPushButton(tr("Reset"), this);
|
||||
connect(
|
||||
m_resetButton, &QPushButton::clicked, this, &FileNameEditor::resetName);
|
||||
m_resetButton->setToolTip(tr("Restores the saved pattern"));
|
||||
// clear
|
||||
m_clearButton = new QPushButton(tr("Clear"), this);
|
||||
connect(m_clearButton, &QPushButton::clicked, this, [this]() {
|
||||
m_nameEditor->setText(QString());
|
||||
});
|
||||
m_clearButton->setToolTip(tr("Deletes the name"));
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::savePattern()
|
||||
void FileNameEditor::savePattern()
|
||||
{
|
||||
QString pattern = m_nameEditor->text();
|
||||
m_nameHandler->setPattern(pattern);
|
||||
QString pattern = m_nameEditor->text();
|
||||
m_nameHandler->setPattern(pattern);
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::showParsedPattern(const QString& p)
|
||||
void FileNameEditor::showParsedPattern(const QString& p)
|
||||
{
|
||||
QString output = m_nameHandler->parseFilename(p);
|
||||
m_outputLabel->setText(output);
|
||||
QString output = m_nameHandler->parseFilename(p);
|
||||
m_outputLabel->setText(output);
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::resetName()
|
||||
void FileNameEditor::resetName()
|
||||
{
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::addToNameEditor(QString s)
|
||||
void FileNameEditor::addToNameEditor(QString s)
|
||||
{
|
||||
m_nameEditor->setText(m_nameEditor->text() + s);
|
||||
m_nameEditor->setFocus();
|
||||
m_nameEditor->setText(m_nameEditor->text() + s);
|
||||
m_nameEditor->setFocus();
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::updateComponents()
|
||||
void FileNameEditor::updateComponents()
|
||||
{
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
||||
}
|
||||
|
||||
@@ -28,29 +28,29 @@ class StrftimeChooserWidget;
|
||||
|
||||
class FileNameEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FileNameEditor(QWidget* parent = nullptr);
|
||||
explicit FileNameEditor(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QVBoxLayout* m_layout;
|
||||
QLineEdit* m_outputLabel;
|
||||
QLineEdit* m_nameEditor;
|
||||
FileNameHandler* m_nameHandler;
|
||||
StrftimeChooserWidget* m_helperButtons;
|
||||
QPushButton* m_saveButton;
|
||||
QPushButton* m_resetButton;
|
||||
QPushButton* m_clearButton;
|
||||
QVBoxLayout* m_layout;
|
||||
QLineEdit* m_outputLabel;
|
||||
QLineEdit* m_nameEditor;
|
||||
FileNameHandler* m_nameHandler;
|
||||
StrftimeChooserWidget* m_helperButtons;
|
||||
QPushButton* m_saveButton;
|
||||
QPushButton* m_resetButton;
|
||||
QPushButton* m_clearButton;
|
||||
|
||||
void initLayout();
|
||||
void initWidgets();
|
||||
void initLayout();
|
||||
void initWidgets();
|
||||
|
||||
public slots:
|
||||
void addToNameEditor(QString s);
|
||||
void updateComponents();
|
||||
void addToNameEditor(QString s);
|
||||
void updateComponents();
|
||||
|
||||
private slots:
|
||||
void savePattern();
|
||||
void showParsedPattern(const QString&);
|
||||
void resetName();
|
||||
void savePattern();
|
||||
void showParsedPattern(const QString&);
|
||||
void resetName();
|
||||
};
|
||||
|
||||
@@ -33,343 +33,326 @@
|
||||
GeneneralConf::GeneneralConf(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->setAlignment(Qt::AlignTop);
|
||||
initShowHelp();
|
||||
initShowSidePanelButton();
|
||||
initShowDesktopNotification();
|
||||
initShowTrayIcon();
|
||||
initAutostart();
|
||||
initCloseAfterCapture();
|
||||
initCopyAndCloseAfterUpload();
|
||||
initSaveAfterCopy();
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->setAlignment(Qt::AlignTop);
|
||||
initShowHelp();
|
||||
initShowSidePanelButton();
|
||||
initShowDesktopNotification();
|
||||
initShowTrayIcon();
|
||||
initAutostart();
|
||||
initCloseAfterCapture();
|
||||
initCopyAndCloseAfterUpload();
|
||||
initSaveAfterCopy();
|
||||
|
||||
// this has to be at the end
|
||||
initConfingButtons();
|
||||
updateComponents();
|
||||
// this has to be at the end
|
||||
initConfingButtons();
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::updateComponents()
|
||||
void GeneneralConf::updateComponents()
|
||||
{
|
||||
ConfigHandler config;
|
||||
m_helpMessage->setChecked(config.showHelpValue());
|
||||
m_sidePanelButton->setChecked(config.showSidePanelButtonValue());
|
||||
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
||||
m_autostart->setChecked(config.startupLaunchValue());
|
||||
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
||||
m_copyAndCloseAfterUpload->setChecked(
|
||||
config.copyAndCloseAfterUploadEnabled());
|
||||
m_saveAfterCopy->setChecked(config.saveAfterCopyValue());
|
||||
ConfigHandler config;
|
||||
m_helpMessage->setChecked(config.showHelpValue());
|
||||
m_sidePanelButton->setChecked(config.showSidePanelButtonValue());
|
||||
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
||||
m_autostart->setChecked(config.startupLaunchValue());
|
||||
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
||||
m_copyAndCloseAfterUpload->setChecked(
|
||||
config.copyAndCloseAfterUploadEnabled());
|
||||
m_saveAfterCopy->setChecked(config.saveAfterCopyValue());
|
||||
|
||||
if (!config.saveAfterCopyPathValue().isEmpty()) {
|
||||
m_savePath->setText(config.saveAfterCopyPathValue());
|
||||
} else {
|
||||
ConfigHandler().setSaveAfterCopyPath(
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
|
||||
}
|
||||
if (!config.saveAfterCopyPathValue().isEmpty()) {
|
||||
m_savePath->setText(config.saveAfterCopyPathValue());
|
||||
} else {
|
||||
ConfigHandler().setSaveAfterCopyPath(
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
m_showTray->setChecked(!config.disabledTrayIconValue());
|
||||
m_showTray->setChecked(!config.disabledTrayIconValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showHelpChanged(bool checked)
|
||||
void GeneneralConf::showHelpChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setShowHelp(checked);
|
||||
ConfigHandler().setShowHelp(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showSidePanelButtonChanged(bool checked)
|
||||
void GeneneralConf::showSidePanelButtonChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setShowSidePanelButton(checked);
|
||||
ConfigHandler().setShowSidePanelButton(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showDesktopNotificationChanged(bool checked)
|
||||
void GeneneralConf::showDesktopNotificationChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setDesktopNotification(checked);
|
||||
ConfigHandler().setDesktopNotification(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showTrayIconChanged(bool checked)
|
||||
void GeneneralConf::showTrayIconChanged(bool checked)
|
||||
{
|
||||
auto controller = Controller::getInstance();
|
||||
if (checked) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
auto controller = Controller::getInstance();
|
||||
if (checked) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::autostartChanged(bool checked)
|
||||
void GeneneralConf::autostartChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setStartupLaunch(checked);
|
||||
ConfigHandler().setStartupLaunch(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::closeAfterCaptureChanged(bool checked)
|
||||
void GeneneralConf::closeAfterCaptureChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setCloseAfterScreenshot(checked);
|
||||
ConfigHandler().setCloseAfterScreenshot(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::importConfiguration()
|
||||
void GeneneralConf::importConfiguration()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import"));
|
||||
if (fileName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFile file(fileName);
|
||||
QTextCodec* codec = QTextCodec::codecForLocale();
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to read file."));
|
||||
return;
|
||||
}
|
||||
QString text = codec->toUnicode(file.readAll());
|
||||
file.close();
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import"));
|
||||
if (fileName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFile file(fileName);
|
||||
QTextCodec* codec = QTextCodec::codecForLocale();
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to read file."));
|
||||
return;
|
||||
}
|
||||
QString text = codec->toUnicode(file.readAll());
|
||||
file.close();
|
||||
|
||||
QFile config(ConfigHandler().configFilePath());
|
||||
if (!config.open(QFile::WriteOnly)) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||
return;
|
||||
}
|
||||
config.write(codec->fromUnicode(text));
|
||||
config.close();
|
||||
QFile config(ConfigHandler().configFilePath());
|
||||
if (!config.open(QFile::WriteOnly)) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||
return;
|
||||
}
|
||||
config.write(codec->fromUnicode(text));
|
||||
config.close();
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::exportFileConfiguration()
|
||||
void GeneneralConf::exportFileConfiguration()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this, tr("Save File"), QStringLiteral("flameshot.conf"));
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this, tr("Save File"), QStringLiteral("flameshot.conf"));
|
||||
|
||||
// Cancel button
|
||||
if (fileName.isNull()) {
|
||||
return;
|
||||
}
|
||||
// Cancel button
|
||||
if (fileName.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile targetFile(fileName);
|
||||
if (targetFile.exists()) {
|
||||
targetFile.remove();
|
||||
}
|
||||
bool ok = QFile::copy(ConfigHandler().configFilePath(), fileName);
|
||||
if (!ok) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||
}
|
||||
QFile targetFile(fileName);
|
||||
if (targetFile.exists()) {
|
||||
targetFile.remove();
|
||||
}
|
||||
bool ok = QFile::copy(ConfigHandler().configFilePath(), fileName);
|
||||
if (!ok) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write file."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::resetConfiguration()
|
||||
void GeneneralConf::resetConfiguration()
|
||||
{
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(
|
||||
this,
|
||||
tr("Confirm Reset"),
|
||||
tr("Are you sure you want to reset the configuration?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
ConfigHandler().setDefaults();
|
||||
}
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(
|
||||
this,
|
||||
tr("Confirm Reset"),
|
||||
tr("Are you sure you want to reset the configuration?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
ConfigHandler().setDefaults();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initShowHelp()
|
||||
void GeneneralConf::initShowHelp()
|
||||
{
|
||||
m_helpMessage = new QCheckBox(tr("Show help message"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.showHelpValue();
|
||||
m_helpMessage->setChecked(checked);
|
||||
m_helpMessage->setToolTip(tr("Show the help message at the beginning "
|
||||
"in the capture mode."));
|
||||
m_layout->addWidget(m_helpMessage);
|
||||
m_helpMessage = new QCheckBox(tr("Show help message"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.showHelpValue();
|
||||
m_helpMessage->setChecked(checked);
|
||||
m_helpMessage->setToolTip(tr("Show the help message at the beginning "
|
||||
"in the capture mode."));
|
||||
m_layout->addWidget(m_helpMessage);
|
||||
|
||||
connect(
|
||||
m_helpMessage, &QCheckBox::clicked, this, &GeneneralConf::showHelpChanged);
|
||||
connect(m_helpMessage,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showHelpChanged);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initShowSidePanelButton()
|
||||
void GeneneralConf::initShowSidePanelButton()
|
||||
{
|
||||
m_sidePanelButton = new QCheckBox(tr("Show the side panel button"), this);
|
||||
m_sidePanelButton->setChecked(ConfigHandler().showSidePanelButtonValue());
|
||||
m_sidePanelButton->setToolTip(
|
||||
tr("Show the side panel toggle button in the capture mode."));
|
||||
m_layout->addWidget(m_sidePanelButton);
|
||||
m_sidePanelButton = new QCheckBox(tr("Show the side panel button"), this);
|
||||
m_sidePanelButton->setChecked(ConfigHandler().showSidePanelButtonValue());
|
||||
m_sidePanelButton->setToolTip(
|
||||
tr("Show the side panel toggle button in the capture mode."));
|
||||
m_layout->addWidget(m_sidePanelButton);
|
||||
|
||||
connect(m_sidePanelButton,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showSidePanelButtonChanged);
|
||||
connect(m_sidePanelButton,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showSidePanelButtonChanged);
|
||||
}
|
||||
void
|
||||
GeneneralConf::initShowDesktopNotification()
|
||||
void GeneneralConf::initShowDesktopNotification()
|
||||
{
|
||||
m_sysNotifications = new QCheckBox(tr("Show desktop notifications"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.desktopNotificationValue();
|
||||
m_sysNotifications->setChecked(checked);
|
||||
m_sysNotifications->setToolTip(tr("Show desktop notifications"));
|
||||
m_layout->addWidget(m_sysNotifications);
|
||||
m_sysNotifications = new QCheckBox(tr("Show desktop notifications"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.desktopNotificationValue();
|
||||
m_sysNotifications->setChecked(checked);
|
||||
m_sysNotifications->setToolTip(tr("Show desktop notifications"));
|
||||
m_layout->addWidget(m_sysNotifications);
|
||||
|
||||
connect(m_sysNotifications,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showDesktopNotificationChanged);
|
||||
connect(m_sysNotifications,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showDesktopNotificationChanged);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initShowTrayIcon()
|
||||
void GeneneralConf::initShowTrayIcon()
|
||||
{
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
m_showTray = new QCheckBox(tr("Show tray icon"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = !config.disabledTrayIconValue();
|
||||
m_showTray->setChecked(checked);
|
||||
m_showTray->setToolTip(tr("Show the systemtray icon"));
|
||||
m_layout->addWidget(m_showTray);
|
||||
m_showTray = new QCheckBox(tr("Show tray icon"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = !config.disabledTrayIconValue();
|
||||
m_showTray->setChecked(checked);
|
||||
m_showTray->setToolTip(tr("Show the systemtray icon"));
|
||||
m_layout->addWidget(m_showTray);
|
||||
|
||||
connect(m_showTray,
|
||||
&QCheckBox::stateChanged,
|
||||
this,
|
||||
&GeneneralConf::showTrayIconChanged);
|
||||
connect(m_showTray,
|
||||
&QCheckBox::stateChanged,
|
||||
this,
|
||||
&GeneneralConf::showTrayIconChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initConfingButtons()
|
||||
void GeneneralConf::initConfingButtons()
|
||||
{
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
m_layout->addStretch();
|
||||
QGroupBox* box = new QGroupBox(tr("Configuration File"));
|
||||
box->setFlat(true);
|
||||
box->setLayout(buttonLayout);
|
||||
m_layout->addWidget(box);
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
m_layout->addStretch();
|
||||
QGroupBox* box = new QGroupBox(tr("Configuration File"));
|
||||
box->setFlat(true);
|
||||
box->setLayout(buttonLayout);
|
||||
m_layout->addWidget(box);
|
||||
|
||||
m_exportButton = new QPushButton(tr("Export"));
|
||||
buttonLayout->addWidget(m_exportButton);
|
||||
connect(m_exportButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::exportFileConfiguration);
|
||||
m_exportButton = new QPushButton(tr("Export"));
|
||||
buttonLayout->addWidget(m_exportButton);
|
||||
connect(m_exportButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::exportFileConfiguration);
|
||||
|
||||
m_importButton = new QPushButton(tr("Import"));
|
||||
buttonLayout->addWidget(m_importButton);
|
||||
connect(m_importButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::importConfiguration);
|
||||
m_importButton = new QPushButton(tr("Import"));
|
||||
buttonLayout->addWidget(m_importButton);
|
||||
connect(m_importButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::importConfiguration);
|
||||
|
||||
m_resetButton = new QPushButton(tr("Reset"));
|
||||
buttonLayout->addWidget(m_resetButton);
|
||||
connect(m_resetButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::resetConfiguration);
|
||||
m_resetButton = new QPushButton(tr("Reset"));
|
||||
buttonLayout->addWidget(m_resetButton);
|
||||
connect(m_resetButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::resetConfiguration);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initAutostart()
|
||||
void GeneneralConf::initAutostart()
|
||||
{
|
||||
m_autostart = new QCheckBox(tr("Launch at startup"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.startupLaunchValue();
|
||||
m_autostart->setChecked(checked);
|
||||
m_autostart->setToolTip(tr("Launch Flameshot"));
|
||||
m_layout->addWidget(m_autostart);
|
||||
m_autostart = new QCheckBox(tr("Launch at startup"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.startupLaunchValue();
|
||||
m_autostart->setChecked(checked);
|
||||
m_autostart->setToolTip(tr("Launch Flameshot"));
|
||||
m_layout->addWidget(m_autostart);
|
||||
|
||||
connect(
|
||||
m_autostart, &QCheckBox::clicked, this, &GeneneralConf::autostartChanged);
|
||||
connect(
|
||||
m_autostart, &QCheckBox::clicked, this, &GeneneralConf::autostartChanged);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initCloseAfterCapture()
|
||||
void GeneneralConf::initCloseAfterCapture()
|
||||
{
|
||||
m_closeAfterCapture = new QCheckBox(tr("Close after capture"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.closeAfterScreenshotValue();
|
||||
m_closeAfterCapture->setChecked(checked);
|
||||
m_closeAfterCapture->setToolTip(tr("Close after taking a screenshot"));
|
||||
m_layout->addWidget(m_closeAfterCapture);
|
||||
m_closeAfterCapture = new QCheckBox(tr("Close after capture"), this);
|
||||
ConfigHandler config;
|
||||
bool checked = config.closeAfterScreenshotValue();
|
||||
m_closeAfterCapture->setChecked(checked);
|
||||
m_closeAfterCapture->setToolTip(tr("Close after taking a screenshot"));
|
||||
m_layout->addWidget(m_closeAfterCapture);
|
||||
|
||||
connect(m_closeAfterCapture,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::closeAfterCaptureChanged);
|
||||
connect(m_closeAfterCapture,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::closeAfterCaptureChanged);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initCopyAndCloseAfterUpload()
|
||||
void GeneneralConf::initCopyAndCloseAfterUpload()
|
||||
{
|
||||
m_copyAndCloseAfterUpload = new QCheckBox(tr("Copy URL after upload"), this);
|
||||
ConfigHandler config;
|
||||
m_copyAndCloseAfterUpload->setChecked(
|
||||
config.copyAndCloseAfterUploadEnabled());
|
||||
m_copyAndCloseAfterUpload->setToolTip(
|
||||
tr("Copy URL and close window after upload"));
|
||||
m_layout->addWidget(m_copyAndCloseAfterUpload);
|
||||
m_copyAndCloseAfterUpload =
|
||||
new QCheckBox(tr("Copy URL after upload"), this);
|
||||
ConfigHandler config;
|
||||
m_copyAndCloseAfterUpload->setChecked(
|
||||
config.copyAndCloseAfterUploadEnabled());
|
||||
m_copyAndCloseAfterUpload->setToolTip(
|
||||
tr("Copy URL and close window after upload"));
|
||||
m_layout->addWidget(m_copyAndCloseAfterUpload);
|
||||
|
||||
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
||||
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
||||
});
|
||||
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
||||
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::initSaveAfterCopy()
|
||||
void GeneneralConf::initSaveAfterCopy()
|
||||
{
|
||||
m_saveAfterCopy = new QCheckBox(tr("Save image after copy"), this);
|
||||
m_saveAfterCopy->setToolTip(tr("Save image file after copying it"));
|
||||
m_layout->addWidget(m_saveAfterCopy);
|
||||
connect(m_saveAfterCopy,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::saveAfterCopyChanged);
|
||||
m_saveAfterCopy = new QCheckBox(tr("Save image after copy"), this);
|
||||
m_saveAfterCopy->setToolTip(tr("Save image file after copying it"));
|
||||
m_layout->addWidget(m_saveAfterCopy);
|
||||
connect(m_saveAfterCopy,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::saveAfterCopyChanged);
|
||||
|
||||
QHBoxLayout* pathLayout = new QHBoxLayout();
|
||||
m_layout->addStretch();
|
||||
QGroupBox* box = new QGroupBox(tr("Save Path"));
|
||||
box->setFlat(true);
|
||||
box->setLayout(pathLayout);
|
||||
m_layout->addWidget(box);
|
||||
QHBoxLayout* pathLayout = new QHBoxLayout();
|
||||
m_layout->addStretch();
|
||||
QGroupBox* box = new QGroupBox(tr("Save Path"));
|
||||
box->setFlat(true);
|
||||
box->setLayout(pathLayout);
|
||||
m_layout->addWidget(box);
|
||||
|
||||
m_savePath = new QLineEdit(
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), this);
|
||||
m_savePath->setDisabled(true);
|
||||
QString foreground = this->palette().foreground().color().name();
|
||||
m_savePath->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||
pathLayout->addWidget(m_savePath);
|
||||
m_savePath = new QLineEdit(
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation), this);
|
||||
m_savePath->setDisabled(true);
|
||||
QString foreground = this->palette().foreground().color().name();
|
||||
m_savePath->setStyleSheet(QStringLiteral("color: %1").arg(foreground));
|
||||
pathLayout->addWidget(m_savePath);
|
||||
|
||||
m_changeSaveButton = new QPushButton(tr("Change..."), this);
|
||||
pathLayout->addWidget(m_changeSaveButton);
|
||||
connect(m_changeSaveButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::changeSavePath);
|
||||
m_changeSaveButton = new QPushButton(tr("Change..."), this);
|
||||
pathLayout->addWidget(m_changeSaveButton);
|
||||
connect(m_changeSaveButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::changeSavePath);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::saveAfterCopyChanged(bool checked)
|
||||
void GeneneralConf::saveAfterCopyChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setSaveAfterCopy(checked);
|
||||
ConfigHandler().setSaveAfterCopy(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::changeSavePath()
|
||||
void GeneneralConf::changeSavePath()
|
||||
{
|
||||
QString path = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
tr("Choose a Folder"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!QFileInfo(path).isWritable()) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write to directory."));
|
||||
return;
|
||||
}
|
||||
m_savePath->setText(path);
|
||||
ConfigHandler().setSaveAfterCopyPath(path);
|
||||
QString path = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
tr("Choose a Folder"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!QFileInfo(path).isWritable()) {
|
||||
QMessageBox::about(
|
||||
this, tr("Error"), tr("Unable to write to directory."));
|
||||
return;
|
||||
}
|
||||
m_savePath->setText(path);
|
||||
ConfigHandler().setSaveAfterCopyPath(path);
|
||||
}
|
||||
|
||||
@@ -27,49 +27,49 @@ class QLineEdit;
|
||||
|
||||
class GeneneralConf : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GeneneralConf(QWidget* parent = nullptr);
|
||||
explicit GeneneralConf(QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void updateComponents();
|
||||
void updateComponents();
|
||||
|
||||
private slots:
|
||||
void showHelpChanged(bool checked);
|
||||
void showSidePanelButtonChanged(bool checked);
|
||||
void showDesktopNotificationChanged(bool checked);
|
||||
void showTrayIconChanged(bool checked);
|
||||
void autostartChanged(bool checked);
|
||||
void closeAfterCaptureChanged(bool checked);
|
||||
void saveAfterCopyChanged(bool checked);
|
||||
void changeSavePath();
|
||||
void importConfiguration();
|
||||
void exportFileConfiguration();
|
||||
void resetConfiguration();
|
||||
void showHelpChanged(bool checked);
|
||||
void showSidePanelButtonChanged(bool checked);
|
||||
void showDesktopNotificationChanged(bool checked);
|
||||
void showTrayIconChanged(bool checked);
|
||||
void autostartChanged(bool checked);
|
||||
void closeAfterCaptureChanged(bool checked);
|
||||
void saveAfterCopyChanged(bool checked);
|
||||
void changeSavePath();
|
||||
void importConfiguration();
|
||||
void exportFileConfiguration();
|
||||
void resetConfiguration();
|
||||
|
||||
private:
|
||||
QVBoxLayout* m_layout;
|
||||
QCheckBox* m_sysNotifications;
|
||||
QCheckBox* m_showTray;
|
||||
QCheckBox* m_helpMessage;
|
||||
QCheckBox* m_sidePanelButton;
|
||||
QCheckBox* m_autostart;
|
||||
QCheckBox* m_closeAfterCapture;
|
||||
QCheckBox* m_copyAndCloseAfterUpload;
|
||||
QPushButton* m_importButton;
|
||||
QPushButton* m_exportButton;
|
||||
QPushButton* m_resetButton;
|
||||
QCheckBox* m_saveAfterCopy;
|
||||
QLineEdit* m_savePath;
|
||||
QPushButton* m_changeSaveButton;
|
||||
QVBoxLayout* m_layout;
|
||||
QCheckBox* m_sysNotifications;
|
||||
QCheckBox* m_showTray;
|
||||
QCheckBox* m_helpMessage;
|
||||
QCheckBox* m_sidePanelButton;
|
||||
QCheckBox* m_autostart;
|
||||
QCheckBox* m_closeAfterCapture;
|
||||
QCheckBox* m_copyAndCloseAfterUpload;
|
||||
QPushButton* m_importButton;
|
||||
QPushButton* m_exportButton;
|
||||
QPushButton* m_resetButton;
|
||||
QCheckBox* m_saveAfterCopy;
|
||||
QLineEdit* m_savePath;
|
||||
QPushButton* m_changeSaveButton;
|
||||
|
||||
void initShowHelp();
|
||||
void initShowSidePanelButton();
|
||||
void initShowDesktopNotification();
|
||||
void initShowTrayIcon();
|
||||
void initConfingButtons();
|
||||
void initAutostart();
|
||||
void initCloseAfterCapture();
|
||||
void initCopyAndCloseAfterUpload();
|
||||
void initSaveAfterCopy();
|
||||
void initShowHelp();
|
||||
void initShowSidePanelButton();
|
||||
void initShowDesktopNotification();
|
||||
void initShowTrayIcon();
|
||||
void initConfingButtons();
|
||||
void initAutostart();
|
||||
void initCloseAfterCapture();
|
||||
void initCopyAndCloseAfterUpload();
|
||||
void initSaveAfterCopy();
|
||||
};
|
||||
|
||||
@@ -23,49 +23,50 @@
|
||||
StrftimeChooserWidget::StrftimeChooserWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
auto k = m_buttonData.keys();
|
||||
int middle = k.length() / 2;
|
||||
// add the buttons in 2 columns (they need to be even)
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < middle; j++) {
|
||||
QString key = k.last();
|
||||
k.pop_back();
|
||||
QString variable = m_buttonData.value(key);
|
||||
QPushButton* button = new QPushButton(this);
|
||||
button->setText(tr(key.toStdString().data()));
|
||||
button->setToolTip(variable);
|
||||
button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
button->setMinimumHeight(25);
|
||||
layout->addWidget(button, j, i);
|
||||
connect(button, &QPushButton::clicked, this, [variable, this]() {
|
||||
emit variableEmitted(variable);
|
||||
});
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
auto k = m_buttonData.keys();
|
||||
int middle = k.length() / 2;
|
||||
// add the buttons in 2 columns (they need to be even)
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < middle; j++) {
|
||||
QString key = k.last();
|
||||
k.pop_back();
|
||||
QString variable = m_buttonData.value(key);
|
||||
QPushButton* button = new QPushButton(this);
|
||||
button->setText(tr(key.toStdString().data()));
|
||||
button->setToolTip(variable);
|
||||
button->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
button->setMinimumHeight(25);
|
||||
layout->addWidget(button, j, i);
|
||||
connect(button, &QPushButton::clicked, this, [variable, this]() {
|
||||
emit variableEmitted(variable);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
setLayout(layout);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
QMap<QString, QString> StrftimeChooserWidget::m_buttonData{
|
||||
{ QT_TR_NOOP("Century (00-99)"), "%C" },
|
||||
{ QT_TR_NOOP("Year (00-99)"), "%y" },
|
||||
{ QT_TR_NOOP("Year (2000)"), "%Y" },
|
||||
{ QT_TR_NOOP("Month Name (jan)"), "%b" },
|
||||
{ QT_TR_NOOP("Month Name (january)"), "%B" },
|
||||
{ QT_TR_NOOP("Month (01-12)"), "%m" },
|
||||
{ QT_TR_NOOP("Week Day (1-7)"), "%u" },
|
||||
{ QT_TR_NOOP("Week (01-53)"), "%V" },
|
||||
{ QT_TR_NOOP("Day Name (mon)"), "%a" },
|
||||
{ QT_TR_NOOP("Day Name (monday)"), "%A" },
|
||||
{ QT_TR_NOOP("Day (01-31)"), "%d" },
|
||||
{ QT_TR_NOOP("Day of Month (1-31)"), "%e" },
|
||||
{ QT_TR_NOOP("Day (001-366)"), "%j" },
|
||||
{ QT_TR_NOOP("Time (%H-%M-%S)"), "%T" },
|
||||
{ QT_TR_NOOP("Time (%H-%M)"), "%R" },
|
||||
{ QT_TR_NOOP("Hour (00-23)"), "%H" },
|
||||
{ QT_TR_NOOP("Hour (01-12)"), "%I" },
|
||||
{ QT_TR_NOOP("Minute (00-59)"), "%M" },
|
||||
{ QT_TR_NOOP("Second (00-59)"), "%S" },
|
||||
{ QT_TR_NOOP("Full Date (%m/%d/%y)"), "%D" },
|
||||
{ QT_TR_NOOP("Full Date (%Y-%m-%d)"), "%F" },
|
||||
{ QT_TR_NOOP("Century (00-99)"), "%C" },
|
||||
{ QT_TR_NOOP("Year (00-99)"), "%y" },
|
||||
{ QT_TR_NOOP("Year (2000)"), "%Y" },
|
||||
{ QT_TR_NOOP("Month Name (jan)"), "%b" },
|
||||
{ QT_TR_NOOP("Month Name (january)"), "%B" },
|
||||
{ QT_TR_NOOP("Month (01-12)"), "%m" },
|
||||
{ QT_TR_NOOP("Week Day (1-7)"), "%u" },
|
||||
{ QT_TR_NOOP("Week (01-53)"), "%V" },
|
||||
{ QT_TR_NOOP("Day Name (mon)"), "%a" },
|
||||
{ QT_TR_NOOP("Day Name (monday)"), "%A" },
|
||||
{ QT_TR_NOOP("Day (01-31)"), "%d" },
|
||||
{ QT_TR_NOOP("Day of Month (1-31)"), "%e" },
|
||||
{ QT_TR_NOOP("Day (001-366)"), "%j" },
|
||||
{ QT_TR_NOOP("Time (%H-%M-%S)"), "%T" },
|
||||
{ QT_TR_NOOP("Time (%H-%M)"), "%R" },
|
||||
{ QT_TR_NOOP("Hour (00-23)"), "%H" },
|
||||
{ QT_TR_NOOP("Hour (01-12)"), "%I" },
|
||||
{ QT_TR_NOOP("Minute (00-59)"), "%M" },
|
||||
{ QT_TR_NOOP("Second (00-59)"), "%S" },
|
||||
{ QT_TR_NOOP("Full Date (%m/%d/%y)"), "%D" },
|
||||
{ QT_TR_NOOP("Full Date (%Y-%m-%d)"), "%F" },
|
||||
};
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
|
||||
class StrftimeChooserWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StrftimeChooserWidget(QWidget* parent = nullptr);
|
||||
explicit StrftimeChooserWidget(QWidget* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void variableEmitted(const QString&);
|
||||
void variableEmitted(const QString&);
|
||||
|
||||
private:
|
||||
static QMap<QString, QString> m_buttonData;
|
||||
static QMap<QString, QString> m_buttonData;
|
||||
};
|
||||
|
||||
@@ -29,162 +29,156 @@
|
||||
UIcolorEditor::UIcolorEditor(QWidget* parent)
|
||||
: QGroupBox(parent)
|
||||
{
|
||||
setTitle(tr("UI Color Editor"));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_hLayout = new QHBoxLayout;
|
||||
m_vLayout = new QVBoxLayout;
|
||||
setTitle(tr("UI Color Editor"));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_hLayout = new QHBoxLayout;
|
||||
m_vLayout = new QVBoxLayout;
|
||||
|
||||
const int space = QApplication::fontMetrics().lineSpacing();
|
||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||
m_vLayout->setAlignment(Qt::AlignVCenter);
|
||||
const int space = QApplication::fontMetrics().lineSpacing();
|
||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||
m_vLayout->setAlignment(Qt::AlignVCenter);
|
||||
|
||||
initButtons();
|
||||
initColorWheel();
|
||||
initButtons();
|
||||
initColorWheel();
|
||||
|
||||
m_vLayout->addSpacing(space);
|
||||
m_hLayout->addLayout(m_vLayout);
|
||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||
setLayout(m_hLayout);
|
||||
updateComponents();
|
||||
m_vLayout->addSpacing(space);
|
||||
m_hLayout->addLayout(m_vLayout);
|
||||
m_hLayout->addItem(new QSpacerItem(space, space, QSizePolicy::Expanding));
|
||||
setLayout(m_hLayout);
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void
|
||||
UIcolorEditor::updateComponents()
|
||||
void UIcolorEditor::updateComponents()
|
||||
{
|
||||
ConfigHandler config;
|
||||
m_uiColor = config.uiMainColorValue();
|
||||
m_contrastColor = config.uiContrastColorValue();
|
||||
m_buttonContrast->setColor(m_contrastColor);
|
||||
m_buttonMainColor->setColor(m_uiColor);
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_colorWheel->setColor(m_uiColor);
|
||||
} else {
|
||||
m_colorWheel->setColor(m_contrastColor);
|
||||
}
|
||||
ConfigHandler config;
|
||||
m_uiColor = config.uiMainColorValue();
|
||||
m_contrastColor = config.uiContrastColorValue();
|
||||
m_buttonContrast->setColor(m_contrastColor);
|
||||
m_buttonMainColor->setColor(m_uiColor);
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_colorWheel->setColor(m_uiColor);
|
||||
} else {
|
||||
m_colorWheel->setColor(m_contrastColor);
|
||||
}
|
||||
}
|
||||
|
||||
// updateUIcolor updates the appearance of the buttons
|
||||
void
|
||||
UIcolorEditor::updateUIcolor()
|
||||
void UIcolorEditor::updateUIcolor()
|
||||
{
|
||||
ConfigHandler config;
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
config.setUIMainColor(m_uiColor);
|
||||
} else {
|
||||
config.setUIContrastColor(m_contrastColor);
|
||||
}
|
||||
ConfigHandler config;
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
config.setUIMainColor(m_uiColor);
|
||||
} else {
|
||||
config.setUIContrastColor(m_contrastColor);
|
||||
}
|
||||
}
|
||||
|
||||
// updateLocalColor updates the local button
|
||||
void
|
||||
UIcolorEditor::updateLocalColor(const QColor c)
|
||||
void UIcolorEditor::updateLocalColor(const QColor c)
|
||||
{
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_uiColor = c;
|
||||
} else {
|
||||
m_contrastColor = c;
|
||||
}
|
||||
m_lastButtonPressed->setColor(c);
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_uiColor = c;
|
||||
} else {
|
||||
m_contrastColor = c;
|
||||
}
|
||||
m_lastButtonPressed->setColor(c);
|
||||
}
|
||||
|
||||
void
|
||||
UIcolorEditor::initColorWheel()
|
||||
void UIcolorEditor::initColorWheel()
|
||||
{
|
||||
m_colorWheel = new color_widgets::ColorWheel(this);
|
||||
connect(m_colorWheel,
|
||||
&color_widgets::ColorWheel::mouseReleaseOnColor,
|
||||
this,
|
||||
&UIcolorEditor::updateUIcolor);
|
||||
connect(m_colorWheel,
|
||||
&color_widgets::ColorWheel::colorChanged,
|
||||
this,
|
||||
&UIcolorEditor::updateLocalColor);
|
||||
m_colorWheel = new color_widgets::ColorWheel(this);
|
||||
connect(m_colorWheel,
|
||||
&color_widgets::ColorWheel::mouseReleaseOnColor,
|
||||
this,
|
||||
&UIcolorEditor::updateUIcolor);
|
||||
connect(m_colorWheel,
|
||||
&color_widgets::ColorWheel::colorChanged,
|
||||
this,
|
||||
&UIcolorEditor::updateLocalColor);
|
||||
|
||||
const int size = GlobalValues::buttonBaseSize() * 3;
|
||||
m_colorWheel->setMinimumSize(size, size);
|
||||
m_colorWheel->setMaximumSize(size * 2, size * 2);
|
||||
m_colorWheel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_colorWheel->setToolTip(tr("Change the color moving the selectors and see"
|
||||
" the changes in the preview buttons."));
|
||||
const int size = GlobalValues::buttonBaseSize() * 3;
|
||||
m_colorWheel->setMinimumSize(size, size);
|
||||
m_colorWheel->setMaximumSize(size * 2, size * 2);
|
||||
m_colorWheel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_colorWheel->setToolTip(tr("Change the color moving the selectors and see"
|
||||
" the changes in the preview buttons."));
|
||||
|
||||
m_hLayout->addWidget(m_colorWheel);
|
||||
m_hLayout->addWidget(m_colorWheel);
|
||||
}
|
||||
|
||||
void
|
||||
UIcolorEditor::initButtons()
|
||||
void UIcolorEditor::initButtons()
|
||||
{
|
||||
const int extraSize = GlobalValues::buttonBaseSize() / 3;
|
||||
int frameSize = GlobalValues::buttonBaseSize() + extraSize;
|
||||
const int extraSize = GlobalValues::buttonBaseSize() / 3;
|
||||
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();
|
||||
frame->setFixedSize(frameSize, frameSize);
|
||||
QGroupBox* frame = new QGroupBox();
|
||||
frame->setFixedSize(frameSize, frameSize);
|
||||
|
||||
m_buttonMainColor = new CaptureToolButton(m_buttonIconType, frame);
|
||||
m_buttonMainColor->move(m_buttonMainColor->x() + extraSize / 2,
|
||||
m_buttonMainColor->y() + extraSize / 2);
|
||||
QHBoxLayout* h1 = new QHBoxLayout();
|
||||
h1->addWidget(frame);
|
||||
m_labelMain = new ClickableLabel(tr("Main Color"), this);
|
||||
h1->addWidget(m_labelMain);
|
||||
m_vLayout->addLayout(h1);
|
||||
m_buttonMainColor = new CaptureToolButton(m_buttonIconType, frame);
|
||||
m_buttonMainColor->move(m_buttonMainColor->x() + extraSize / 2,
|
||||
m_buttonMainColor->y() + extraSize / 2);
|
||||
QHBoxLayout* h1 = new QHBoxLayout();
|
||||
h1->addWidget(frame);
|
||||
m_labelMain = new ClickableLabel(tr("Main Color"), this);
|
||||
h1->addWidget(m_labelMain);
|
||||
m_vLayout->addLayout(h1);
|
||||
|
||||
m_buttonMainColor->setToolTip(tr("Click on this button to set the edition"
|
||||
" mode of the main color."));
|
||||
m_buttonMainColor->setToolTip(tr("Click on this button to set the edition"
|
||||
" mode of the main color."));
|
||||
|
||||
QGroupBox* frame2 = new QGroupBox();
|
||||
m_buttonContrast = new CaptureToolButton(m_buttonIconType, frame2);
|
||||
m_buttonContrast->move(m_buttonContrast->x() + extraSize / 2,
|
||||
m_buttonContrast->y() + extraSize / 2);
|
||||
QGroupBox* frame2 = new QGroupBox();
|
||||
m_buttonContrast = new CaptureToolButton(m_buttonIconType, frame2);
|
||||
m_buttonContrast->move(m_buttonContrast->x() + extraSize / 2,
|
||||
m_buttonContrast->y() + extraSize / 2);
|
||||
|
||||
QHBoxLayout* h2 = new QHBoxLayout();
|
||||
h2->addWidget(frame2);
|
||||
frame2->setFixedSize(frameSize, frameSize);
|
||||
m_labelContrast = new ClickableLabel(tr("Contrast Color"), this);
|
||||
m_labelContrast->setStyleSheet(QStringLiteral("color : gray"));
|
||||
h2->addWidget(m_labelContrast);
|
||||
m_vLayout->addLayout(h2);
|
||||
QHBoxLayout* h2 = new QHBoxLayout();
|
||||
h2->addWidget(frame2);
|
||||
frame2->setFixedSize(frameSize, frameSize);
|
||||
m_labelContrast = new ClickableLabel(tr("Contrast Color"), this);
|
||||
m_labelContrast->setStyleSheet(QStringLiteral("color : gray"));
|
||||
h2->addWidget(m_labelContrast);
|
||||
m_vLayout->addLayout(h2);
|
||||
|
||||
m_buttonContrast->setToolTip(tr("Click on this button to set the edition"
|
||||
" mode of the contrast color."));
|
||||
m_buttonContrast->setToolTip(tr("Click on this button to set the edition"
|
||||
" mode of the contrast color."));
|
||||
|
||||
connect(m_buttonMainColor,
|
||||
&CaptureToolButton::pressedButton,
|
||||
this,
|
||||
&UIcolorEditor::changeLastButton);
|
||||
connect(m_buttonContrast,
|
||||
&CaptureToolButton::pressedButton,
|
||||
this,
|
||||
&UIcolorEditor::changeLastButton);
|
||||
// clicking the labels changes the button too
|
||||
connect(m_labelMain, &ClickableLabel::clicked, this, [this] {
|
||||
changeLastButton(m_buttonMainColor);
|
||||
});
|
||||
connect(m_labelContrast, &ClickableLabel::clicked, this, [this] {
|
||||
changeLastButton(m_buttonContrast);
|
||||
});
|
||||
m_lastButtonPressed = m_buttonMainColor;
|
||||
connect(m_buttonMainColor,
|
||||
&CaptureToolButton::pressedButton,
|
||||
this,
|
||||
&UIcolorEditor::changeLastButton);
|
||||
connect(m_buttonContrast,
|
||||
&CaptureToolButton::pressedButton,
|
||||
this,
|
||||
&UIcolorEditor::changeLastButton);
|
||||
// clicking the labels changes the button too
|
||||
connect(m_labelMain, &ClickableLabel::clicked, this, [this] {
|
||||
changeLastButton(m_buttonMainColor);
|
||||
});
|
||||
connect(m_labelContrast, &ClickableLabel::clicked, this, [this] {
|
||||
changeLastButton(m_buttonContrast);
|
||||
});
|
||||
m_lastButtonPressed = m_buttonMainColor;
|
||||
}
|
||||
|
||||
// visual update for the selected button
|
||||
void
|
||||
UIcolorEditor::changeLastButton(CaptureToolButton* b)
|
||||
void UIcolorEditor::changeLastButton(CaptureToolButton* b)
|
||||
{
|
||||
if (m_lastButtonPressed != b) {
|
||||
m_lastButtonPressed = b;
|
||||
if (m_lastButtonPressed != b) {
|
||||
m_lastButtonPressed = b;
|
||||
|
||||
QString offStyle(QStringLiteral("QLabel { color : gray; }"));
|
||||
QString offStyle(QStringLiteral("QLabel { color : gray; }"));
|
||||
|
||||
if (b == m_buttonMainColor) {
|
||||
m_colorWheel->setColor(m_uiColor);
|
||||
m_labelContrast->setStyleSheet(offStyle);
|
||||
m_labelMain->setStyleSheet(styleSheet());
|
||||
} else {
|
||||
m_colorWheel->setColor(m_contrastColor);
|
||||
m_labelContrast->setStyleSheet(styleSheet());
|
||||
m_labelMain->setStyleSheet(offStyle);
|
||||
if (b == m_buttonMainColor) {
|
||||
m_colorWheel->setColor(m_uiColor);
|
||||
m_labelContrast->setStyleSheet(offStyle);
|
||||
m_labelMain->setStyleSheet(styleSheet());
|
||||
} else {
|
||||
m_colorWheel->setColor(m_contrastColor);
|
||||
m_labelContrast->setStyleSheet(styleSheet());
|
||||
m_labelMain->setStyleSheet(offStyle);
|
||||
}
|
||||
b->setIcon(b->icon());
|
||||
}
|
||||
b->setIcon(b->icon());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,33 +28,33 @@ class ClickableLabel;
|
||||
|
||||
class UIcolorEditor : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit UIcolorEditor(QWidget* parent = nullptr);
|
||||
explicit UIcolorEditor(QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void updateComponents();
|
||||
void updateComponents();
|
||||
|
||||
private slots:
|
||||
void updateUIcolor();
|
||||
void updateLocalColor(const QColor);
|
||||
void changeLastButton(CaptureToolButton*);
|
||||
void updateUIcolor();
|
||||
void updateLocalColor(const QColor);
|
||||
void changeLastButton(CaptureToolButton*);
|
||||
|
||||
private:
|
||||
QColor m_uiColor, m_contrastColor;
|
||||
CaptureToolButton* m_buttonMainColor;
|
||||
ClickableLabel* m_labelMain;
|
||||
CaptureToolButton* m_buttonContrast;
|
||||
ClickableLabel* m_labelContrast;
|
||||
CaptureToolButton* m_lastButtonPressed;
|
||||
color_widgets::ColorWheel* m_colorWheel;
|
||||
QColor m_uiColor, m_contrastColor;
|
||||
CaptureToolButton* m_buttonMainColor;
|
||||
ClickableLabel* m_labelMain;
|
||||
CaptureToolButton* m_buttonContrast;
|
||||
ClickableLabel* m_labelContrast;
|
||||
CaptureToolButton* m_lastButtonPressed;
|
||||
color_widgets::ColorWheel* m_colorWheel;
|
||||
|
||||
static const CaptureToolButton::ButtonType m_buttonIconType =
|
||||
CaptureToolButton::TYPE_CIRCLE;
|
||||
static const CaptureToolButton::ButtonType m_buttonIconType =
|
||||
CaptureToolButton::TYPE_CIRCLE;
|
||||
|
||||
QHBoxLayout* m_hLayout;
|
||||
QVBoxLayout* m_vLayout;
|
||||
QHBoxLayout* m_hLayout;
|
||||
QVBoxLayout* m_vLayout;
|
||||
|
||||
void initColorWheel();
|
||||
void initButtons();
|
||||
void initColorWheel();
|
||||
void initButtons();
|
||||
};
|
||||
|
||||
@@ -27,75 +27,71 @@
|
||||
VisualsEditor::VisualsEditor(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_layout = new QVBoxLayout();
|
||||
setLayout(m_layout);
|
||||
initWidgets();
|
||||
m_layout = new QVBoxLayout();
|
||||
setLayout(m_layout);
|
||||
initWidgets();
|
||||
}
|
||||
|
||||
void
|
||||
VisualsEditor::updateComponents()
|
||||
void VisualsEditor::updateComponents()
|
||||
{
|
||||
m_buttonList->updateComponents();
|
||||
m_colorEditor->updateComponents();
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
m_buttonList->updateComponents();
|
||||
m_colorEditor->updateComponents();
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
}
|
||||
|
||||
void
|
||||
VisualsEditor::initOpacitySlider()
|
||||
void VisualsEditor::initOpacitySlider()
|
||||
{
|
||||
m_opacitySlider = new ExtendedSlider();
|
||||
m_opacitySlider->setFocusPolicy(Qt::NoFocus);
|
||||
m_opacitySlider->setOrientation(Qt::Horizontal);
|
||||
m_opacitySlider->setRange(0, 100);
|
||||
connect(m_opacitySlider,
|
||||
&ExtendedSlider::modificationsEnded,
|
||||
this,
|
||||
&VisualsEditor::saveOpacity);
|
||||
QHBoxLayout* localLayout = new QHBoxLayout();
|
||||
localLayout->addWidget(new QLabel(QStringLiteral("0%")));
|
||||
localLayout->addWidget(m_opacitySlider);
|
||||
localLayout->addWidget(new QLabel(QStringLiteral("100%")));
|
||||
m_opacitySlider = new ExtendedSlider();
|
||||
m_opacitySlider->setFocusPolicy(Qt::NoFocus);
|
||||
m_opacitySlider->setOrientation(Qt::Horizontal);
|
||||
m_opacitySlider->setRange(0, 100);
|
||||
connect(m_opacitySlider,
|
||||
&ExtendedSlider::modificationsEnded,
|
||||
this,
|
||||
&VisualsEditor::saveOpacity);
|
||||
QHBoxLayout* localLayout = new QHBoxLayout();
|
||||
localLayout->addWidget(new QLabel(QStringLiteral("0%")));
|
||||
localLayout->addWidget(m_opacitySlider);
|
||||
localLayout->addWidget(new QLabel(QStringLiteral("100%")));
|
||||
|
||||
QLabel* label = new QLabel();
|
||||
QString labelMsg = tr("Opacity of area outside selection:") + " %1%";
|
||||
connect(m_opacitySlider,
|
||||
&ExtendedSlider::valueChanged,
|
||||
this,
|
||||
[labelMsg, label](int val) { label->setText(labelMsg.arg(val)); });
|
||||
m_layout->addWidget(label);
|
||||
m_layout->addLayout(localLayout);
|
||||
QLabel* label = new QLabel();
|
||||
QString labelMsg = tr("Opacity of area outside selection:") + " %1%";
|
||||
connect(m_opacitySlider,
|
||||
&ExtendedSlider::valueChanged,
|
||||
this,
|
||||
[labelMsg, label](int val) { label->setText(labelMsg.arg(val)); });
|
||||
m_layout->addWidget(label);
|
||||
m_layout->addLayout(localLayout);
|
||||
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
}
|
||||
|
||||
void
|
||||
VisualsEditor::saveOpacity()
|
||||
void VisualsEditor::saveOpacity()
|
||||
{
|
||||
int value = m_opacitySlider->mappedValue(0, 255);
|
||||
ConfigHandler().setContrastOpacity(value);
|
||||
int value = m_opacitySlider->mappedValue(0, 255);
|
||||
ConfigHandler().setContrastOpacity(value);
|
||||
}
|
||||
|
||||
void
|
||||
VisualsEditor::initWidgets()
|
||||
void VisualsEditor::initWidgets()
|
||||
{
|
||||
m_colorEditor = new UIcolorEditor();
|
||||
m_layout->addWidget(m_colorEditor);
|
||||
m_colorEditor = new UIcolorEditor();
|
||||
m_layout->addWidget(m_colorEditor);
|
||||
|
||||
initOpacitySlider();
|
||||
initOpacitySlider();
|
||||
|
||||
auto boxButtons = new QGroupBox();
|
||||
boxButtons->setTitle(tr("Button Selection"));
|
||||
auto listLayout = new QVBoxLayout(boxButtons);
|
||||
m_buttonList = new ButtonListView();
|
||||
m_layout->addWidget(boxButtons);
|
||||
listLayout->addWidget(m_buttonList);
|
||||
auto boxButtons = new QGroupBox();
|
||||
boxButtons->setTitle(tr("Button Selection"));
|
||||
auto listLayout = new QVBoxLayout(boxButtons);
|
||||
m_buttonList = new ButtonListView();
|
||||
m_layout->addWidget(boxButtons);
|
||||
listLayout->addWidget(m_buttonList);
|
||||
|
||||
QPushButton* setAllButtons = new QPushButton(tr("Select All"));
|
||||
connect(setAllButtons,
|
||||
&QPushButton::clicked,
|
||||
m_buttonList,
|
||||
&ButtonListView::selectAll);
|
||||
listLayout->addWidget(setAllButtons);
|
||||
QPushButton* setAllButtons = new QPushButton(tr("Select All"));
|
||||
connect(setAllButtons,
|
||||
&QPushButton::clicked,
|
||||
m_buttonList,
|
||||
&ButtonListView::selectAll);
|
||||
listLayout->addWidget(setAllButtons);
|
||||
}
|
||||
|
||||
@@ -26,22 +26,22 @@ class UIcolorEditor;
|
||||
|
||||
class VisualsEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VisualsEditor(QWidget* parent = nullptr);
|
||||
explicit VisualsEditor(QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void updateComponents();
|
||||
void updateComponents();
|
||||
|
||||
private slots:
|
||||
void saveOpacity();
|
||||
void saveOpacity();
|
||||
|
||||
private:
|
||||
QVBoxLayout* m_layout;
|
||||
ButtonListView* m_buttonList;
|
||||
UIcolorEditor* m_colorEditor;
|
||||
ExtendedSlider* m_opacitySlider;
|
||||
QVBoxLayout* m_layout;
|
||||
ButtonListView* m_buttonList;
|
||||
UIcolorEditor* m_colorEditor;
|
||||
ExtendedSlider* m_opacitySlider;
|
||||
|
||||
void initWidgets();
|
||||
void initOpacitySlider();
|
||||
void initWidgets();
|
||||
void initOpacitySlider();
|
||||
};
|
||||
|
||||
@@ -34,72 +34,64 @@ CaptureRequest::CaptureRequest(CaptureRequest::CaptureMode mode,
|
||||
, m_id(0)
|
||||
{}
|
||||
|
||||
void
|
||||
CaptureRequest::setStaticID(uint id)
|
||||
void CaptureRequest::setStaticID(uint id)
|
||||
{
|
||||
m_forcedID = true;
|
||||
m_id = id;
|
||||
m_forcedID = true;
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
uint
|
||||
CaptureRequest::id() const
|
||||
uint CaptureRequest::id() const
|
||||
{
|
||||
if (m_forcedID) {
|
||||
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_forcedID) {
|
||||
return m_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_tasks & ExportTask::CLIPBOARD_SAVE_TASK) != ExportTask::NO_TASK) {
|
||||
ScreenshotSaver().saveToClipboard(p);
|
||||
}
|
||||
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) {
|
||||
ScreenshotSaver().saveToClipboard(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,65 +24,62 @@
|
||||
class CaptureRequest
|
||||
{
|
||||
public:
|
||||
enum CaptureMode
|
||||
{
|
||||
FULLSCREEN_MODE,
|
||||
GRAPHICAL_MODE,
|
||||
SCREEN_MODE,
|
||||
};
|
||||
enum CaptureMode
|
||||
{
|
||||
FULLSCREEN_MODE,
|
||||
GRAPHICAL_MODE,
|
||||
SCREEN_MODE,
|
||||
};
|
||||
|
||||
enum ExportTask
|
||||
{
|
||||
NO_TASK = 0,
|
||||
CLIPBOARD_SAVE_TASK = 1,
|
||||
FILESYSTEM_SAVE_TASK = 2,
|
||||
};
|
||||
enum ExportTask
|
||||
{
|
||||
NO_TASK = 0,
|
||||
CLIPBOARD_SAVE_TASK = 1,
|
||||
FILESYSTEM_SAVE_TASK = 2,
|
||||
};
|
||||
|
||||
CaptureRequest(CaptureMode mode,
|
||||
const uint delay = 0,
|
||||
const QString& path = QLatin1String(""),
|
||||
const QVariant& data = QVariant(),
|
||||
ExportTask tasks = NO_TASK);
|
||||
CaptureRequest(CaptureMode mode,
|
||||
const uint delay = 0,
|
||||
const QString& path = QLatin1String(""),
|
||||
const QVariant& data = QVariant(),
|
||||
ExportTask tasks = NO_TASK);
|
||||
|
||||
void setStaticID(uint id);
|
||||
void setStaticID(uint id);
|
||||
|
||||
uint id() const;
|
||||
uint delay() const;
|
||||
QString path() const;
|
||||
QVariant data() const;
|
||||
CaptureMode captureMode() const;
|
||||
uint id() const;
|
||||
uint delay() const;
|
||||
QString path() const;
|
||||
QVariant data() const;
|
||||
CaptureMode captureMode() const;
|
||||
|
||||
void addTask(ExportTask task);
|
||||
void exportCapture(const QPixmap& p);
|
||||
void addTask(ExportTask task);
|
||||
void exportCapture(const QPixmap& p);
|
||||
|
||||
private:
|
||||
CaptureMode m_mode;
|
||||
uint m_delay;
|
||||
QString m_path;
|
||||
ExportTask m_tasks;
|
||||
QVariant m_data;
|
||||
CaptureMode m_mode;
|
||||
uint m_delay;
|
||||
QString m_path;
|
||||
ExportTask m_tasks;
|
||||
QVariant m_data;
|
||||
|
||||
bool m_forcedID;
|
||||
uint m_id;
|
||||
bool m_forcedID;
|
||||
uint m_id;
|
||||
};
|
||||
|
||||
using eTask = CaptureRequest::ExportTask;
|
||||
|
||||
inline eTask
|
||||
operator|(const eTask& a, const eTask& b)
|
||||
inline eTask 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
|
||||
operator&(const eTask& a, const eTask& b)
|
||||
inline eTask 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&
|
||||
operator|=(eTask& a, const eTask& b)
|
||||
inline eTask& operator|=(eTask& a, const eTask& b)
|
||||
{
|
||||
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
return a;
|
||||
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
return a;
|
||||
}
|
||||
|
||||
@@ -41,279 +41,268 @@
|
||||
Controller::Controller()
|
||||
: 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 (!ConfigHandler().disabledTrayIconValue()) {
|
||||
enableTrayIcon();
|
||||
}
|
||||
if (!ConfigHandler().disabledTrayIconValue()) {
|
||||
enableTrayIcon();
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
enableTrayIcon();
|
||||
enableTrayIcon();
|
||||
|
||||
GlobalShortcutFilter* nativeFilter = new GlobalShortcutFilter(this);
|
||||
qApp->installNativeEventFilter(nativeFilter);
|
||||
connect(nativeFilter, &GlobalShortcutFilter::printPressed, this, [this]() {
|
||||
this->requestCapture(CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||
});
|
||||
GlobalShortcutFilter* nativeFilter = new GlobalShortcutFilter(this);
|
||||
qApp->installNativeEventFilter(nativeFilter);
|
||||
connect(nativeFilter, &GlobalShortcutFilter::printPressed, this, [this]() {
|
||||
this->requestCapture(CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||
});
|
||||
#endif
|
||||
|
||||
QString StyleSheet = CaptureButton::globalStyleSheet();
|
||||
qApp->setStyleSheet(StyleSheet);
|
||||
QString StyleSheet = CaptureButton::globalStyleSheet();
|
||||
qApp->setStyleSheet(StyleSheet);
|
||||
}
|
||||
|
||||
Controller*
|
||||
Controller::getInstance()
|
||||
Controller* Controller::getInstance()
|
||||
{
|
||||
static Controller c;
|
||||
return &c;
|
||||
static Controller c;
|
||||
return &c;
|
||||
}
|
||||
|
||||
void
|
||||
Controller::enableExports()
|
||||
void Controller::enableExports()
|
||||
{
|
||||
connect(
|
||||
this, &Controller::captureTaken, this, &Controller::handleCaptureTaken);
|
||||
connect(
|
||||
this, &Controller::captureFailed, this, &Controller::handleCaptureFailed);
|
||||
connect(
|
||||
this, &Controller::captureTaken, this, &Controller::handleCaptureTaken);
|
||||
connect(
|
||||
this, &Controller::captureFailed, this, &Controller::handleCaptureFailed);
|
||||
}
|
||||
|
||||
void
|
||||
Controller::requestCapture(const CaptureRequest& request)
|
||||
void Controller::requestCapture(const CaptureRequest& request)
|
||||
{
|
||||
uint id = request.id();
|
||||
m_requestMap.insert(id, request);
|
||||
uint id = request.id();
|
||||
m_requestMap.insert(id, request);
|
||||
|
||||
switch (request.captureMode()) {
|
||||
case CaptureRequest::FULLSCREEN_MODE:
|
||||
doLater(request.delay(), this, [this, id]() {
|
||||
this->startFullscreenCapture(id);
|
||||
});
|
||||
break;
|
||||
// TODO: Figure out the code path that gets here so the deprated warning can
|
||||
// be fixed
|
||||
case CaptureRequest::SCREEN_MODE: {
|
||||
int&& number = request.data().toInt();
|
||||
doLater(request.delay(), this, [this, id, number]() {
|
||||
this->startScreenGrab(id, number);
|
||||
});
|
||||
break;
|
||||
switch (request.captureMode()) {
|
||||
case CaptureRequest::FULLSCREEN_MODE:
|
||||
doLater(request.delay(), this, [this, id]() {
|
||||
this->startFullscreenCapture(id);
|
||||
});
|
||||
break;
|
||||
// TODO: Figure out the code path that gets here so the deprated warning
|
||||
// can be fixed
|
||||
case CaptureRequest::SCREEN_MODE: {
|
||||
int&& number = request.data().toInt();
|
||||
doLater(request.delay(), this, [this, id, number]() {
|
||||
this->startScreenGrab(id, number);
|
||||
});
|
||||
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
|
||||
void
|
||||
Controller::startVisualCapture(const uint id, const QString& forcedSavePath)
|
||||
void Controller::startVisualCapture(const uint id,
|
||||
const QString& forcedSavePath)
|
||||
{
|
||||
if (!m_captureWindow) {
|
||||
QWidget* modalWidget = nullptr;
|
||||
do {
|
||||
modalWidget = qApp->activeModalWidget();
|
||||
if (modalWidget) {
|
||||
modalWidget->close();
|
||||
modalWidget->deleteLater();
|
||||
}
|
||||
} while (modalWidget);
|
||||
if (!m_captureWindow) {
|
||||
QWidget* modalWidget = nullptr;
|
||||
do {
|
||||
modalWidget = qApp->activeModalWidget();
|
||||
if (modalWidget) {
|
||||
modalWidget->close();
|
||||
modalWidget->deleteLater();
|
||||
}
|
||||
} while (modalWidget);
|
||||
|
||||
m_captureWindow = new CaptureWidget(id, forcedSavePath);
|
||||
// m_captureWindow = new CaptureWidget(id, forcedSavePath, false); // debug
|
||||
connect(m_captureWindow,
|
||||
&CaptureWidget::captureFailed,
|
||||
this,
|
||||
&Controller::captureFailed);
|
||||
connect(m_captureWindow,
|
||||
&CaptureWidget::captureTaken,
|
||||
this,
|
||||
&Controller::captureTaken);
|
||||
m_captureWindow = new CaptureWidget(id, forcedSavePath);
|
||||
// m_captureWindow = new CaptureWidget(id, forcedSavePath, false); //
|
||||
// debug
|
||||
connect(m_captureWindow,
|
||||
&CaptureWidget::captureFailed,
|
||||
this,
|
||||
&Controller::captureFailed);
|
||||
connect(m_captureWindow,
|
||||
&CaptureWidget::captureTaken,
|
||||
this,
|
||||
&Controller::captureTaken);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
m_captureWindow->show();
|
||||
m_captureWindow->show();
|
||||
#else
|
||||
m_captureWindow->showFullScreen();
|
||||
// m_captureWindow->show(); // Debug
|
||||
m_captureWindow->showFullScreen();
|
||||
// m_captureWindow->show(); // Debug
|
||||
#endif
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::startScreenGrab(const uint id, const int screenNumber)
|
||||
void Controller::startScreenGrab(const uint id, const int screenNumber)
|
||||
{
|
||||
bool ok = true;
|
||||
int n = screenNumber;
|
||||
bool ok = true;
|
||||
int n = screenNumber;
|
||||
|
||||
if (n < 0) {
|
||||
QPoint globalCursorPos = QCursor::pos();
|
||||
n = qApp->desktop()->screenNumber(globalCursorPos);
|
||||
}
|
||||
QPixmap p(ScreenGrabber().grabScreen(n, ok));
|
||||
if (ok) {
|
||||
emit captureTaken(id, p);
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
if (n < 0) {
|
||||
QPoint globalCursorPos = QCursor::pos();
|
||||
n = qApp->desktop()->screenNumber(globalCursorPos);
|
||||
}
|
||||
QPixmap p(ScreenGrabber().grabScreen(n, ok));
|
||||
if (ok) {
|
||||
emit captureTaken(id, p);
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
}
|
||||
|
||||
// creation of the configuration window
|
||||
void
|
||||
Controller::openConfigWindow()
|
||||
void Controller::openConfigWindow()
|
||||
{
|
||||
if (!m_configWindow) {
|
||||
m_configWindow = new ConfigWindow();
|
||||
m_configWindow->show();
|
||||
}
|
||||
if (!m_configWindow) {
|
||||
m_configWindow = new ConfigWindow();
|
||||
m_configWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
// creation of the window of information
|
||||
void
|
||||
Controller::openInfoWindow()
|
||||
void Controller::openInfoWindow()
|
||||
{
|
||||
if (!m_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();
|
||||
if (!m_infoWindow) {
|
||||
m_infoWindow = new InfoWindow();
|
||||
}
|
||||
};
|
||||
connect(m_trayIcon, &QSystemTrayIcon::activated, this, trayIconActivated);
|
||||
m_trayIcon->show();
|
||||
}
|
||||
|
||||
void
|
||||
Controller::disableTrayIcon()
|
||||
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 Controller::disableTrayIcon()
|
||||
{
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
if (m_trayIcon) {
|
||||
m_trayIcon->deleteLater();
|
||||
}
|
||||
ConfigHandler().setDisabledTrayIcon(true);
|
||||
if (m_trayIcon) {
|
||||
m_trayIcon->deleteLater();
|
||||
}
|
||||
ConfigHandler().setDisabledTrayIcon(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Controller::sendTrayNotification(const QString& text,
|
||||
const QString& title,
|
||||
const int timeout)
|
||||
void Controller::sendTrayNotification(const QString& text,
|
||||
const QString& title,
|
||||
const int timeout)
|
||||
{
|
||||
if (m_trayIcon) {
|
||||
m_trayIcon->showMessage(title, text, QSystemTrayIcon::Information, timeout);
|
||||
}
|
||||
if (m_trayIcon) {
|
||||
m_trayIcon->showMessage(
|
||||
title, text, QSystemTrayIcon::Information, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::updateConfigComponents()
|
||||
void Controller::updateConfigComponents()
|
||||
{
|
||||
if (m_configWindow) {
|
||||
m_configWindow->updateChildren();
|
||||
}
|
||||
if (m_configWindow) {
|
||||
m_configWindow->updateChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::startFullscreenCapture(const uint id)
|
||||
void Controller::startFullscreenCapture(const uint id)
|
||||
{
|
||||
bool ok = true;
|
||||
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
|
||||
if (ok) {
|
||||
emit captureTaken(id, p);
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
bool ok = true;
|
||||
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
|
||||
if (ok) {
|
||||
emit captureTaken(id, p);
|
||||
} else {
|
||||
emit captureFailed(id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::handleCaptureTaken(uint id, QPixmap p)
|
||||
void Controller::handleCaptureTaken(uint id, QPixmap p)
|
||||
{
|
||||
auto it = m_requestMap.find(id);
|
||||
if (it != m_requestMap.end()) {
|
||||
it.value().exportCapture(p);
|
||||
m_requestMap.erase(it);
|
||||
}
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
auto it = m_requestMap.find(id);
|
||||
if (it != m_requestMap.end()) {
|
||||
it.value().exportCapture(p);
|
||||
m_requestMap.erase(it);
|
||||
}
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::handleCaptureFailed(uint id)
|
||||
void Controller::handleCaptureFailed(uint id)
|
||||
{
|
||||
m_requestMap.remove(id);
|
||||
m_requestMap.remove(id);
|
||||
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::doLater(int msec, QObject* receiver, lambda func)
|
||||
void Controller::doLater(int msec, QObject* receiver, lambda func)
|
||||
{
|
||||
QTimer* timer = new QTimer(receiver);
|
||||
QObject::connect(timer, &QTimer::timeout, receiver, [timer, func]() {
|
||||
func();
|
||||
timer->deleteLater();
|
||||
});
|
||||
timer->setInterval(msec);
|
||||
timer->start();
|
||||
QTimer* timer = new QTimer(receiver);
|
||||
QObject::connect(timer, &QTimer::timeout, receiver, [timer, func]() {
|
||||
func();
|
||||
timer->deleteLater();
|
||||
});
|
||||
timer->setInterval(msec);
|
||||
timer->start();
|
||||
}
|
||||
|
||||
@@ -34,55 +34,55 @@ using lambda = std::function<void(void)>;
|
||||
|
||||
class Controller : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static Controller* getInstance();
|
||||
static Controller* getInstance();
|
||||
|
||||
Controller(const Controller&) = delete;
|
||||
void operator=(const Controller&) = delete;
|
||||
Controller(const Controller&) = delete;
|
||||
void operator=(const Controller&) = delete;
|
||||
|
||||
void enableExports();
|
||||
void enableExports();
|
||||
|
||||
signals:
|
||||
void captureTaken(uint id, QPixmap p);
|
||||
void captureFailed(uint id);
|
||||
void captureTaken(uint id, QPixmap p);
|
||||
void captureFailed(uint id);
|
||||
|
||||
public slots:
|
||||
void requestCapture(const CaptureRequest& request);
|
||||
void requestCapture(const CaptureRequest& request);
|
||||
|
||||
void openConfigWindow();
|
||||
void openInfoWindow();
|
||||
void openLauncherWindow();
|
||||
void enableTrayIcon();
|
||||
void disableTrayIcon();
|
||||
void sendTrayNotification(
|
||||
const QString& text,
|
||||
const QString& title = QStringLiteral("Flameshot Info"),
|
||||
const int timeout = 5000);
|
||||
void openConfigWindow();
|
||||
void openInfoWindow();
|
||||
void openLauncherWindow();
|
||||
void enableTrayIcon();
|
||||
void disableTrayIcon();
|
||||
void sendTrayNotification(
|
||||
const QString& text,
|
||||
const QString& title = QStringLiteral("Flameshot Info"),
|
||||
const int timeout = 5000);
|
||||
|
||||
void updateConfigComponents();
|
||||
void updateConfigComponents();
|
||||
|
||||
private slots:
|
||||
void startFullscreenCapture(const uint id = 0);
|
||||
void startVisualCapture(const uint id = 0,
|
||||
const QString& forcedSavePath = QString());
|
||||
void startScreenGrab(const uint id = 0, const int screenNumber = -1);
|
||||
void startFullscreenCapture(const uint id = 0);
|
||||
void startVisualCapture(const uint id = 0,
|
||||
const QString& forcedSavePath = QString());
|
||||
void startScreenGrab(const uint id = 0, const int screenNumber = -1);
|
||||
|
||||
void handleCaptureTaken(uint id, QPixmap p);
|
||||
void handleCaptureFailed(uint id);
|
||||
void handleCaptureTaken(uint id, QPixmap p);
|
||||
void handleCaptureFailed(uint id);
|
||||
|
||||
private:
|
||||
Controller();
|
||||
Controller();
|
||||
|
||||
// replace QTimer::singleShot introduced in Qt 5.4
|
||||
// the actual target Qt version is 5.3
|
||||
void doLater(int msec, QObject* receiver, lambda func);
|
||||
// replace QTimer::singleShot introduced in Qt 5.4
|
||||
// the actual target Qt version is 5.3
|
||||
void doLater(int msec, QObject* receiver, lambda func);
|
||||
|
||||
QMap<uint, CaptureRequest> m_requestMap;
|
||||
QPointer<CaptureWidget> m_captureWindow;
|
||||
QPointer<InfoWindow> m_infoWindow;
|
||||
QPointer<CaptureLauncher> m_launcherWindow;
|
||||
QPointer<ConfigWindow> m_configWindow;
|
||||
QPointer<QSystemTrayIcon> m_trayIcon;
|
||||
QMap<uint, CaptureRequest> m_requestMap;
|
||||
QPointer<CaptureWidget> m_captureWindow;
|
||||
QPointer<InfoWindow> m_infoWindow;
|
||||
QPointer<CaptureLauncher> m_launcherWindow;
|
||||
QPointer<ConfigWindow> m_configWindow;
|
||||
QPointer<QSystemTrayIcon> m_trayIcon;
|
||||
};
|
||||
|
||||
@@ -25,102 +25,94 @@
|
||||
FlameshotDBusAdapter::FlameshotDBusAdapter(QObject* parent)
|
||||
: QDBusAbstractAdaptor(parent)
|
||||
{
|
||||
auto controller = Controller::getInstance();
|
||||
connect(controller,
|
||||
&Controller::captureFailed,
|
||||
this,
|
||||
&FlameshotDBusAdapter::captureFailed);
|
||||
connect(controller,
|
||||
&Controller::captureTaken,
|
||||
this,
|
||||
&FlameshotDBusAdapter::handleCaptureTaken);
|
||||
auto controller = Controller::getInstance();
|
||||
connect(controller,
|
||||
&Controller::captureFailed,
|
||||
this,
|
||||
&FlameshotDBusAdapter::captureFailed);
|
||||
connect(controller,
|
||||
&Controller::captureTaken,
|
||||
this,
|
||||
&FlameshotDBusAdapter::handleCaptureTaken);
|
||||
}
|
||||
|
||||
FlameshotDBusAdapter::~FlameshotDBusAdapter() {}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::graphicCapture(QString path, int delay, uint id)
|
||||
void FlameshotDBusAdapter::graphicCapture(QString path, int delay, uint id)
|
||||
{
|
||||
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, path);
|
||||
// if (toClipboard) {
|
||||
// req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
// }
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
CaptureRequest req(CaptureRequest::GRAPHICAL_MODE, delay, path);
|
||||
// if (toClipboard) {
|
||||
// req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
// }
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::fullScreen(QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id)
|
||||
void FlameshotDBusAdapter::fullScreen(QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id)
|
||||
{
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, path);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!path.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, path);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!path.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::openLauncher()
|
||||
void FlameshotDBusAdapter::openLauncher()
|
||||
{
|
||||
Controller::getInstance()->openLauncherWindow();
|
||||
Controller::getInstance()->openLauncherWindow();
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::captureScreen(int number,
|
||||
QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id)
|
||||
void FlameshotDBusAdapter::captureScreen(int number,
|
||||
QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id)
|
||||
{
|
||||
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, path, number);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!path.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, path, number);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!path.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::openConfig()
|
||||
void FlameshotDBusAdapter::openConfig()
|
||||
{
|
||||
Controller::getInstance()->openConfigWindow();
|
||||
Controller::getInstance()->openConfigWindow();
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::trayIconEnabled(bool enabled)
|
||||
void FlameshotDBusAdapter::trayIconEnabled(bool enabled)
|
||||
{
|
||||
auto controller = Controller::getInstance();
|
||||
if (enabled) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
auto controller = Controller::getInstance();
|
||||
if (enabled) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::autostartEnabled(bool enabled)
|
||||
void FlameshotDBusAdapter::autostartEnabled(bool enabled)
|
||||
{
|
||||
ConfigHandler().setStartupLaunch(enabled);
|
||||
auto controller = Controller::getInstance();
|
||||
// Autostart is not saved in a .ini file, requires manual update
|
||||
controller->updateConfigComponents();
|
||||
ConfigHandler().setStartupLaunch(enabled);
|
||||
auto controller = Controller::getInstance();
|
||||
// Autostart is not saved in a .ini file, requires manual update
|
||||
controller->updateConfigComponents();
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap& p)
|
||||
void FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap& p)
|
||||
{
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
p.save(&buffer, "PNG");
|
||||
emit captureTaken(id, byteArray);
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
p.save(&buffer, "PNG");
|
||||
emit captureTaken(id, byteArray);
|
||||
}
|
||||
|
||||
@@ -22,30 +22,33 @@
|
||||
|
||||
class FlameshotDBusAdapter : public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.flameshot.Flameshot")
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.flameshot.Flameshot")
|
||||
|
||||
public:
|
||||
explicit FlameshotDBusAdapter(QObject* parent = nullptr);
|
||||
virtual ~FlameshotDBusAdapter();
|
||||
explicit FlameshotDBusAdapter(QObject* parent = nullptr);
|
||||
virtual ~FlameshotDBusAdapter();
|
||||
|
||||
signals:
|
||||
void captureTaken(uint id, QByteArray rawImage);
|
||||
void captureFailed(uint id);
|
||||
void captureTaken(uint id, QByteArray rawImage);
|
||||
void captureFailed(uint id);
|
||||
|
||||
public slots:
|
||||
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 captureScreen(int number,
|
||||
QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id);
|
||||
Q_NOREPLY void openLauncher();
|
||||
Q_NOREPLY void openConfig();
|
||||
Q_NOREPLY void trayIconEnabled(bool enabled);
|
||||
Q_NOREPLY void autostartEnabled(bool enabled);
|
||||
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 captureScreen(int number,
|
||||
QString path,
|
||||
bool toClipboard,
|
||||
int delay,
|
||||
uint id);
|
||||
Q_NOREPLY void openLauncher();
|
||||
Q_NOREPLY void openConfig();
|
||||
Q_NOREPLY void trayIconEnabled(bool enabled);
|
||||
Q_NOREPLY void autostartEnabled(bool enabled);
|
||||
|
||||
private slots:
|
||||
void handleCaptureTaken(uint id, const QPixmap& p);
|
||||
void handleCaptureTaken(uint id, const QPixmap& p);
|
||||
};
|
||||
|
||||
@@ -22,30 +22,29 @@
|
||||
GlobalShortcutFilter::GlobalShortcutFilter(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
// Forced Print Screen
|
||||
if (RegisterHotKey(NULL, 1, 0, VK_SNAPSHOT)) {
|
||||
// ok
|
||||
}
|
||||
// Forced Print Screen
|
||||
if (RegisterHotKey(NULL, 1, 0, VK_SNAPSHOT)) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalShortcutFilter::nativeEventFilter(const QByteArray& eventType,
|
||||
void* message,
|
||||
long* result)
|
||||
bool GlobalShortcutFilter::nativeEventFilter(const QByteArray& eventType,
|
||||
void* message,
|
||||
long* result)
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
Q_UNUSED(result);
|
||||
Q_UNUSED(eventType);
|
||||
Q_UNUSED(result);
|
||||
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (msg->message == WM_HOTKEY) {
|
||||
// const quint32 keycode = HIWORD(msg->lParam);
|
||||
// const quint32 modifiers = LOWORD(msg->lParam);
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (msg->message == WM_HOTKEY) {
|
||||
// const quint32 keycode = HIWORD(msg->lParam);
|
||||
// const quint32 modifiers = LOWORD(msg->lParam);
|
||||
|
||||
// TODO: this is just a temporal workwrround, proper global
|
||||
// support would need custom shortcuts defined by the user.
|
||||
Controller::getInstance()->requestCapture(
|
||||
CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// TODO: this is just a temporal workwrround, proper global
|
||||
// support would need custom shortcuts defined by the user.
|
||||
Controller::getInstance()->requestCapture(
|
||||
CaptureRequest(CaptureRequest::GRAPHICAL_MODE));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,20 +24,20 @@ class GlobalShortcutFilter
|
||||
: public QObject
|
||||
, public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GlobalShortcutFilter(QObject* parent = nullptr);
|
||||
explicit GlobalShortcutFilter(QObject* parent = nullptr);
|
||||
|
||||
bool nativeEventFilter(const QByteArray& eventType,
|
||||
void* message,
|
||||
long* result);
|
||||
bool nativeEventFilter(const QByteArray& eventType,
|
||||
void* message,
|
||||
long* result);
|
||||
|
||||
signals:
|
||||
void printPressed();
|
||||
void printPressed();
|
||||
|
||||
private:
|
||||
quint32 getNativeModifier(Qt::KeyboardModifiers modifiers);
|
||||
quint32 nativeKeycode(Qt::Key key);
|
||||
bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
quint32 getNativeModifier(Qt::KeyboardModifiers modifiers);
|
||||
quint32 nativeKeycode(Qt::Key key);
|
||||
bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
};
|
||||
|
||||
811
src/main.cpp
811
src/main.cpp
@@ -37,431 +37,448 @@
|
||||
#include <QDBusMessage>
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// required for the button serialization
|
||||
// TODO: change to QVector in v1.0
|
||||
qRegisterMetaTypeStreamOperators<QList<int>>("QList<int>");
|
||||
qApp->setApplicationVersion(static_cast<QString>(APP_VERSION));
|
||||
// required for the button serialization
|
||||
// TODO: change to QVector in v1.0
|
||||
qRegisterMetaTypeStreamOperators<QList<int>>("QList<int>");
|
||||
qApp->setApplicationVersion(static_cast<QString>(APP_VERSION));
|
||||
|
||||
// no arguments, just launch Flameshot
|
||||
if (argc == 1) {
|
||||
SingleApplication app(argc, argv);
|
||||
// no arguments, just launch Flameshot
|
||||
if (argc == 1) {
|
||||
SingleApplication app(argc, argv);
|
||||
|
||||
QTranslator translator, qtTranslator;
|
||||
QStringList trPaths = PathInfo::translationsPaths();
|
||||
QTranslator translator, qtTranslator;
|
||||
QStringList trPaths = PathInfo::translationsPaths();
|
||||
|
||||
for (const QString& path : trPaths) {
|
||||
bool match = translator.load(QLocale(),
|
||||
QStringLiteral("Internationalization"),
|
||||
QStringLiteral("_"),
|
||||
path);
|
||||
if (match) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (const QString& path : trPaths) {
|
||||
bool match = translator.load(QLocale(),
|
||||
QStringLiteral("Internationalization"),
|
||||
QStringLiteral("_"),
|
||||
path);
|
||||
if (match) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qtTranslator.load(QLocale::system(),
|
||||
"qt",
|
||||
"_",
|
||||
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
qtTranslator.load(
|
||||
QLocale::system(),
|
||||
"qt",
|
||||
"_",
|
||||
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
|
||||
app.installTranslator(&translator);
|
||||
app.installTranslator(&qtTranslator);
|
||||
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
||||
app.setApplicationName(QStringLiteral("flameshot"));
|
||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||
app.installTranslator(&translator);
|
||||
app.installTranslator(&qtTranslator);
|
||||
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
|
||||
app.setApplicationName(QStringLiteral("flameshot"));
|
||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||
|
||||
auto c = Controller::getInstance();
|
||||
auto c = Controller::getInstance();
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
new FlameshotDBusAdapter(c);
|
||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||
if (!dbus.isConnected()) {
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr("Unable to connect via DBus"));
|
||||
}
|
||||
dbus.registerObject(QStringLiteral("/"), c);
|
||||
dbus.registerService(QStringLiteral("org.flameshot.Flameshot"));
|
||||
new FlameshotDBusAdapter(c);
|
||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||
if (!dbus.isConnected()) {
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr("Unable to connect via DBus"));
|
||||
}
|
||||
dbus.registerObject(QStringLiteral("/"), c);
|
||||
dbus.registerService(QStringLiteral("org.flameshot.Flameshot"));
|
||||
#endif
|
||||
// Exporting captures must be connected after the dbus interface
|
||||
// or the dbus signal gets blocked until we end the exports.
|
||||
c->enableExports();
|
||||
return app.exec();
|
||||
}
|
||||
// Exporting captures must be connected after the dbus interface
|
||||
// or the dbus signal gets blocked until we end the exports.
|
||||
c->enableExports();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
/*--------------|
|
||||
* CLI parsing |
|
||||
* ------------*/
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationName(QStringLiteral("flameshot"));
|
||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||
app.setApplicationVersion(qApp->applicationVersion());
|
||||
CommandLineParser parser;
|
||||
// Add description
|
||||
parser.setDescription(
|
||||
QObject::tr("Powerful yet simple to use screenshot software."));
|
||||
parser.setGeneralErrorMessage(QObject::tr("See") + " flameshot --help.");
|
||||
// Arguments
|
||||
CommandArgument fullArgument(QStringLiteral("full"),
|
||||
QObject::tr("Capture the entire desktop."));
|
||||
CommandArgument launcherArgument(QStringLiteral("launcher"),
|
||||
QObject::tr("Open the capture launcher."));
|
||||
CommandArgument guiArgument(
|
||||
QStringLiteral("gui"), QObject::tr("Start a manual capture in GUI mode."));
|
||||
CommandArgument configArgument(QStringLiteral("config"),
|
||||
QObject::tr("Configure") + " flameshot.");
|
||||
CommandArgument screenArgument(QStringLiteral("screen"),
|
||||
QObject::tr("Capture a single screen."));
|
||||
/*--------------|
|
||||
* CLI parsing |
|
||||
* ------------*/
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationName(QStringLiteral("flameshot"));
|
||||
app.setOrganizationName(QStringLiteral("flameshot"));
|
||||
app.setApplicationVersion(qApp->applicationVersion());
|
||||
CommandLineParser parser;
|
||||
// Add description
|
||||
parser.setDescription(
|
||||
QObject::tr("Powerful yet simple to use screenshot software."));
|
||||
parser.setGeneralErrorMessage(QObject::tr("See") + " flameshot --help.");
|
||||
// Arguments
|
||||
CommandArgument fullArgument(QStringLiteral("full"),
|
||||
QObject::tr("Capture the entire desktop."));
|
||||
CommandArgument launcherArgument(QStringLiteral("launcher"),
|
||||
QObject::tr("Open the capture launcher."));
|
||||
CommandArgument guiArgument(
|
||||
QStringLiteral("gui"),
|
||||
QObject::tr("Start a manual capture in GUI mode."));
|
||||
CommandArgument configArgument(QStringLiteral("config"),
|
||||
QObject::tr("Configure") + " flameshot.");
|
||||
CommandArgument screenArgument(QStringLiteral("screen"),
|
||||
QObject::tr("Capture a single screen."));
|
||||
|
||||
// Options
|
||||
CommandOption pathOption({ "p", "path" },
|
||||
QObject::tr("Path where the capture will be saved"),
|
||||
QStringLiteral("path"));
|
||||
CommandOption clipboardOption(
|
||||
{ "c", "clipboard" }, QObject::tr("Save the capture to the clipboard"));
|
||||
CommandOption delayOption({ "d", "delay" },
|
||||
QObject::tr("Delay time in milliseconds"),
|
||||
QStringLiteral("milliseconds"));
|
||||
CommandOption filenameOption({ "f", "filename" },
|
||||
QObject::tr("Set the filename pattern"),
|
||||
QStringLiteral("pattern"));
|
||||
CommandOption trayOption({ "t", "trayicon" },
|
||||
QObject::tr("Enable or disable the trayicon"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption autostartOption({ "a", "autostart" },
|
||||
QObject::tr("Enable or disable run at startup"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption showHelpOption(
|
||||
{ "s", "showhelp" },
|
||||
QObject::tr("Show the help message in the capture mode"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption mainColorOption({ "m", "maincolor" },
|
||||
QObject::tr("Define the main UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption contrastColorOption({ "k", "contrastcolor" },
|
||||
QObject::tr("Define the contrast UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption rawImageOption({ "r", "raw" },
|
||||
QObject::tr("Print raw PNG capture"));
|
||||
CommandOption screenNumberOption(
|
||||
{ "n", "number" },
|
||||
QObject::tr("Define the screen to capture") + ",\n" +
|
||||
QObject::tr("default: screen containing the cursor"),
|
||||
QObject::tr("Screen number"),
|
||||
QStringLiteral("-1"));
|
||||
// Options
|
||||
CommandOption pathOption(
|
||||
{ "p", "path" },
|
||||
QObject::tr("Path where the capture will be saved"),
|
||||
QStringLiteral("path"));
|
||||
CommandOption clipboardOption(
|
||||
{ "c", "clipboard" }, QObject::tr("Save the capture to the clipboard"));
|
||||
CommandOption delayOption({ "d", "delay" },
|
||||
QObject::tr("Delay time in milliseconds"),
|
||||
QStringLiteral("milliseconds"));
|
||||
CommandOption filenameOption({ "f", "filename" },
|
||||
QObject::tr("Set the filename pattern"),
|
||||
QStringLiteral("pattern"));
|
||||
CommandOption trayOption({ "t", "trayicon" },
|
||||
QObject::tr("Enable or disable the trayicon"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption autostartOption(
|
||||
{ "a", "autostart" },
|
||||
QObject::tr("Enable or disable run at startup"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption showHelpOption(
|
||||
{ "s", "showhelp" },
|
||||
QObject::tr("Show the help message in the capture mode"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption mainColorOption({ "m", "maincolor" },
|
||||
QObject::tr("Define the main UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption contrastColorOption(
|
||||
{ "k", "contrastcolor" },
|
||||
QObject::tr("Define the contrast UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption rawImageOption({ "r", "raw" },
|
||||
QObject::tr("Print raw PNG capture"));
|
||||
CommandOption screenNumberOption(
|
||||
{ "n", "number" },
|
||||
QObject::tr("Define the screen to capture") + ",\n" +
|
||||
QObject::tr("default: screen containing the cursor"),
|
||||
QObject::tr("Screen number"),
|
||||
QStringLiteral("-1"));
|
||||
|
||||
// Add checkers
|
||||
auto colorChecker = [](const QString& colorCode) -> bool {
|
||||
QColor parsedColor(colorCode);
|
||||
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
||||
};
|
||||
QString colorErr =
|
||||
QObject::tr("Invalid color, "
|
||||
"this flag supports the following formats:\n"
|
||||
"- #RGB (each of R, G, and B is a single hex digit)\n"
|
||||
"- #RRGGBB\n- #RRRGGGBBB\n"
|
||||
"- #RRRRGGGGBBBB\n"
|
||||
"- Named colors like 'blue' or 'red'\n"
|
||||
"You may need to escape the '#' sign as in '\\#FFF'");
|
||||
// Add checkers
|
||||
auto colorChecker = [](const QString& colorCode) -> bool {
|
||||
QColor parsedColor(colorCode);
|
||||
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
||||
};
|
||||
QString colorErr =
|
||||
QObject::tr("Invalid color, "
|
||||
"this flag supports the following formats:\n"
|
||||
"- #RGB (each of R, G, and B is a single hex digit)\n"
|
||||
"- #RRGGBB\n- #RRRGGGBBB\n"
|
||||
"- #RRRRGGGGBBBB\n"
|
||||
"- Named colors like 'blue' or 'red'\n"
|
||||
"You may need to escape the '#' sign as in '\\#FFF'");
|
||||
|
||||
const QString delayErr =
|
||||
QObject::tr("Invalid delay, it must be higher than 0");
|
||||
const QString numberErr =
|
||||
QObject::tr("Invalid screen number, it must be non negative");
|
||||
auto numericChecker = [](const QString& delayValue) -> bool {
|
||||
int value = delayValue.toInt();
|
||||
return value >= 0;
|
||||
};
|
||||
const QString delayErr =
|
||||
QObject::tr("Invalid delay, it must be higher than 0");
|
||||
const QString numberErr =
|
||||
QObject::tr("Invalid screen number, it must be non negative");
|
||||
auto numericChecker = [](const QString& delayValue) -> bool {
|
||||
int value = delayValue.toInt();
|
||||
return value >= 0;
|
||||
};
|
||||
|
||||
const QString pathErr =
|
||||
QObject::tr("Invalid path, it must be a real path in the system");
|
||||
auto pathChecker = [pathErr](const QString& pathValue) -> bool {
|
||||
bool res = QDir(pathValue).exists();
|
||||
if (!res) {
|
||||
SystemNotification().sendMessage(QObject::tr(pathErr.toLatin1().data()));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
const QString pathErr =
|
||||
QObject::tr("Invalid path, it must be a real path in the system");
|
||||
auto pathChecker = [pathErr](const QString& pathValue) -> bool {
|
||||
bool res = QDir(pathValue).exists();
|
||||
if (!res) {
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr(pathErr.toLatin1().data()));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const QString booleanErr =
|
||||
QObject::tr("Invalid value, it must be defined as 'true' or 'false'");
|
||||
auto booleanChecker = [](const QString& value) -> bool {
|
||||
return value == QLatin1String("true") || value == QLatin1String("false");
|
||||
};
|
||||
const QString booleanErr =
|
||||
QObject::tr("Invalid value, it must be defined as 'true' or 'false'");
|
||||
auto booleanChecker = [](const QString& value) -> bool {
|
||||
return value == QLatin1String("true") ||
|
||||
value == QLatin1String("false");
|
||||
};
|
||||
|
||||
contrastColorOption.addChecker(colorChecker, colorErr);
|
||||
mainColorOption.addChecker(colorChecker, colorErr);
|
||||
delayOption.addChecker(numericChecker, delayErr);
|
||||
pathOption.addChecker(pathChecker, pathErr);
|
||||
trayOption.addChecker(booleanChecker, booleanErr);
|
||||
autostartOption.addChecker(booleanChecker, booleanErr);
|
||||
showHelpOption.addChecker(booleanChecker, booleanErr);
|
||||
screenNumberOption.addChecker(numericChecker, numberErr);
|
||||
contrastColorOption.addChecker(colorChecker, colorErr);
|
||||
mainColorOption.addChecker(colorChecker, colorErr);
|
||||
delayOption.addChecker(numericChecker, delayErr);
|
||||
pathOption.addChecker(pathChecker, pathErr);
|
||||
trayOption.addChecker(booleanChecker, booleanErr);
|
||||
autostartOption.addChecker(booleanChecker, booleanErr);
|
||||
showHelpOption.addChecker(booleanChecker, booleanErr);
|
||||
screenNumberOption.addChecker(numericChecker, numberErr);
|
||||
|
||||
// Relationships
|
||||
parser.AddArgument(guiArgument);
|
||||
parser.AddArgument(screenArgument);
|
||||
parser.AddArgument(fullArgument);
|
||||
parser.AddArgument(launcherArgument);
|
||||
parser.AddArgument(configArgument);
|
||||
auto helpOption = parser.addHelpOption();
|
||||
auto versionOption = parser.addVersionOption();
|
||||
parser.AddOptions({ pathOption, delayOption, rawImageOption }, guiArgument);
|
||||
parser.AddOptions({ screenNumberOption,
|
||||
clipboardOption,
|
||||
pathOption,
|
||||
delayOption,
|
||||
rawImageOption },
|
||||
screenArgument);
|
||||
parser.AddOptions(
|
||||
{ pathOption, clipboardOption, delayOption, rawImageOption }, fullArgument);
|
||||
parser.AddOptions({ autostartOption,
|
||||
filenameOption,
|
||||
trayOption,
|
||||
showHelpOption,
|
||||
mainColorOption,
|
||||
contrastColorOption },
|
||||
configArgument);
|
||||
// Parse
|
||||
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;
|
||||
// Relationships
|
||||
parser.AddArgument(guiArgument);
|
||||
parser.AddArgument(screenArgument);
|
||||
parser.AddArgument(fullArgument);
|
||||
parser.AddArgument(launcherArgument);
|
||||
parser.AddArgument(configArgument);
|
||||
auto helpOption = parser.addHelpOption();
|
||||
auto versionOption = parser.addVersionOption();
|
||||
parser.AddOptions({ pathOption, delayOption, rawImageOption }, guiArgument);
|
||||
parser.AddOptions({ screenNumberOption,
|
||||
clipboardOption,
|
||||
pathOption,
|
||||
delayOption,
|
||||
rawImageOption },
|
||||
screenArgument);
|
||||
parser.AddOptions(
|
||||
{ pathOption, clipboardOption, delayOption, rawImageOption },
|
||||
fullArgument);
|
||||
parser.AddOptions({ autostartOption,
|
||||
filenameOption,
|
||||
trayOption,
|
||||
showHelpOption,
|
||||
mainColorOption,
|
||||
contrastColorOption },
|
||||
configArgument);
|
||||
// Parse
|
||||
if (!parser.parse(app.arguments())) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
// 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("fullScreen"));
|
||||
m << pathValue << toClipboard << delay << id;
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
dbusUtils.checkDBusConnection(sessionBus);
|
||||
sessionBus.call(m);
|
||||
// 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);
|
||||
// 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(screenArgument)) { // SCREEN
|
||||
QString numberStr = parser.value(screenNumberOption);
|
||||
int number =
|
||||
numberStr.startsWith(QLatin1String("-")) ? -1 : numberStr.toInt();
|
||||
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("screen")
|
||||
<< QStringLiteral("-h"));
|
||||
goto finish;
|
||||
}
|
||||
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::SCREEN_MODE, delay, pathValue, number);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
|
||||
// Send message
|
||||
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);
|
||||
// Send message
|
||||
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||
QStringLiteral("org.flameshot.Flameshot"),
|
||||
QStringLiteral("/"),
|
||||
QLatin1String(""),
|
||||
QStringLiteral("fullScreen"));
|
||||
m << 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);
|
||||
}
|
||||
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(screenArgument)) { // SCREEN
|
||||
QString numberStr = parser.value(screenNumberOption);
|
||||
int number =
|
||||
numberStr.startsWith(QLatin1String("-")) ? -1 : numberStr.toInt();
|
||||
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("screen")
|
||||
<< QStringLiteral("-h"));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// 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);
|
||||
CaptureRequest req(
|
||||
CaptureRequest::SCREEN_MODE, delay, pathValue, number);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
|
||||
// Send message
|
||||
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:
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,74 +21,63 @@ AbstractActionTool::AbstractActionTool(QObject* parent)
|
||||
: CaptureTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
AbstractActionTool::isValid() const
|
||||
bool AbstractActionTool::isValid() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractActionTool::isSelectable() const
|
||||
bool AbstractActionTool::isSelectable() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractActionTool::showMousePreview() const
|
||||
bool AbstractActionTool::showMousePreview() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::undo(QPixmap& pixmap)
|
||||
void AbstractActionTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
Q_UNUSED(pixmap);
|
||||
Q_UNUSED(pixmap);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
void AbstractActionTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(pixmap);
|
||||
Q_UNUSED(recordUndo);
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(pixmap);
|
||||
Q_UNUSED(recordUndo);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
void AbstractActionTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawEnd(const QPoint& p)
|
||||
void AbstractActionTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawMove(const QPoint& p)
|
||||
void AbstractActionTool::drawMove(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawStart(const CaptureContext& context)
|
||||
void AbstractActionTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::colorChanged(const QColor& c)
|
||||
void AbstractActionTool::colorChanged(const QColor& c)
|
||||
{
|
||||
Q_UNUSED(c);
|
||||
Q_UNUSED(c);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::thicknessChanged(const int th)
|
||||
void AbstractActionTool::thicknessChanged(const int th)
|
||||
{
|
||||
Q_UNUSED(th);
|
||||
Q_UNUSED(th);
|
||||
}
|
||||
|
||||
@@ -21,28 +21,28 @@
|
||||
|
||||
class AbstractActionTool : public CaptureTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractActionTool(QObject* parent = nullptr);
|
||||
explicit AbstractActionTool(QObject* parent = nullptr);
|
||||
|
||||
bool isValid() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
bool isValid() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
|
||||
void undo(QPixmap& pixmap) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
void undo(QPixmap& pixmap) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
virtual ToolType nameID() const = 0;
|
||||
virtual ToolType nameID() const = 0;
|
||||
|
||||
public slots:
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
};
|
||||
|
||||
@@ -23,83 +23,72 @@ AbstractPathTool::AbstractPathTool(QObject* parent)
|
||||
, m_padding(0)
|
||||
{}
|
||||
|
||||
bool
|
||||
AbstractPathTool::isValid() const
|
||||
bool AbstractPathTool::isValid() const
|
||||
{
|
||||
return m_points.length() > 1;
|
||||
return m_points.length() > 1;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractPathTool::closeOnButtonPressed() const
|
||||
bool AbstractPathTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractPathTool::isSelectable() const
|
||||
bool AbstractPathTool::isSelectable() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractPathTool::showMousePreview() const
|
||||
bool AbstractPathTool::showMousePreview() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::undo(QPixmap& pixmap)
|
||||
void AbstractPathTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
QPainter p(&pixmap);
|
||||
const int val = m_thickness + m_padding;
|
||||
QRect area = m_backupArea + QMargins(val, val, val, val);
|
||||
p.drawPixmap(area.intersected(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
QPainter p(&pixmap);
|
||||
const int val = m_thickness + m_padding;
|
||||
QRect area = m_backupArea + QMargins(val, val, val, val);
|
||||
p.drawPixmap(area.intersected(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::drawEnd(const QPoint& p)
|
||||
void AbstractPathTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::drawMove(const QPoint& p)
|
||||
void AbstractPathTool::drawMove(const QPoint& p)
|
||||
{
|
||||
addPoint(p);
|
||||
addPoint(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::colorChanged(const QColor& c)
|
||||
void AbstractPathTool::colorChanged(const QColor& c)
|
||||
{
|
||||
m_color = c;
|
||||
m_color = c;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::thicknessChanged(const int th)
|
||||
void AbstractPathTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_thickness = th;
|
||||
m_thickness = th;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::updateBackup(const QPixmap& pixmap)
|
||||
void AbstractPathTool::updateBackup(const QPixmap& pixmap)
|
||||
{
|
||||
const int val = m_thickness + m_padding;
|
||||
QRect area = m_backupArea.normalized() + QMargins(val, val, val, val);
|
||||
m_pixmapBackup = pixmap.copy(area);
|
||||
const int val = m_thickness + m_padding;
|
||||
QRect area = m_backupArea.normalized() + QMargins(val, val, val, val);
|
||||
m_pixmapBackup = pixmap.copy(area);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractPathTool::addPoint(const QPoint& point)
|
||||
void AbstractPathTool::addPoint(const QPoint& point)
|
||||
{
|
||||
if (m_backupArea.left() > point.x()) {
|
||||
m_backupArea.setLeft(point.x());
|
||||
} else if (m_backupArea.right() < point.x()) {
|
||||
m_backupArea.setRight(point.x());
|
||||
}
|
||||
if (m_backupArea.top() > point.y()) {
|
||||
m_backupArea.setTop(point.y());
|
||||
} else if (m_backupArea.bottom() < point.y()) {
|
||||
m_backupArea.setBottom(point.y());
|
||||
}
|
||||
m_points.append(point);
|
||||
if (m_backupArea.left() > point.x()) {
|
||||
m_backupArea.setLeft(point.x());
|
||||
} else if (m_backupArea.right() < point.x()) {
|
||||
m_backupArea.setRight(point.x());
|
||||
}
|
||||
if (m_backupArea.top() > point.y()) {
|
||||
m_backupArea.setTop(point.y());
|
||||
} else if (m_backupArea.bottom() < point.y()) {
|
||||
m_backupArea.setBottom(point.y());
|
||||
}
|
||||
m_points.append(point);
|
||||
}
|
||||
|
||||
@@ -21,34 +21,34 @@
|
||||
|
||||
class AbstractPathTool : public CaptureTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractPathTool(QObject* parent = nullptr);
|
||||
explicit AbstractPathTool(QObject* parent = nullptr);
|
||||
|
||||
bool isValid() const override;
|
||||
bool closeOnButtonPressed() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
bool isValid() const override;
|
||||
bool closeOnButtonPressed() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
|
||||
void undo(QPixmap& pixmap) override;
|
||||
void undo(QPixmap& pixmap) override;
|
||||
|
||||
public slots:
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
|
||||
protected:
|
||||
void updateBackup(const QPixmap& pixmap);
|
||||
void addPoint(const QPoint& point);
|
||||
void updateBackup(const QPixmap& pixmap);
|
||||
void addPoint(const QPoint& point);
|
||||
|
||||
virtual ToolType nameID() const = 0;
|
||||
virtual ToolType nameID() const = 0;
|
||||
|
||||
QPixmap m_pixmapBackup;
|
||||
QRect m_backupArea;
|
||||
QColor m_color;
|
||||
QVector<QPoint> m_points;
|
||||
int m_thickness;
|
||||
// use m_padding to extend the area of the backup
|
||||
int m_padding;
|
||||
QPixmap m_pixmapBackup;
|
||||
QRect m_backupArea;
|
||||
QColor m_color;
|
||||
QVector<QPoint> m_points;
|
||||
int m_thickness;
|
||||
// use m_padding to extend the area of the backup
|
||||
int m_padding;
|
||||
};
|
||||
|
||||
@@ -25,10 +25,10 @@ const int DIRS_NUMBER = 4;
|
||||
|
||||
enum UNIT
|
||||
{
|
||||
HORIZ_DIR = 0,
|
||||
DIAG1_DIR = 1,
|
||||
VERT_DIR = 2,
|
||||
DIAG2_DIR = 3
|
||||
HORIZ_DIR = 0,
|
||||
DIAG1_DIR = 1,
|
||||
VERT_DIR = 2,
|
||||
DIAG2_DIR = 3
|
||||
};
|
||||
|
||||
const double ADJ_DIAG_UNIT = 2 * ADJ_UNIT;
|
||||
@@ -36,8 +36,8 @@ const int DIAG_DIRS_NUMBER = 2;
|
||||
|
||||
enum DIAG_UNIT
|
||||
{
|
||||
DIR1 = 0,
|
||||
DIR2 = 1
|
||||
DIR1 = 0,
|
||||
DIR2 = 1
|
||||
};
|
||||
|
||||
}
|
||||
@@ -48,123 +48,111 @@ AbstractTwoPointTool::AbstractTwoPointTool(QObject* parent)
|
||||
, m_padding(0)
|
||||
{}
|
||||
|
||||
bool
|
||||
AbstractTwoPointTool::isValid() const
|
||||
bool AbstractTwoPointTool::isValid() const
|
||||
{
|
||||
return (m_points.first != m_points.second);
|
||||
return (m_points.first != m_points.second);
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractTwoPointTool::closeOnButtonPressed() const
|
||||
bool AbstractTwoPointTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractTwoPointTool::isSelectable() const
|
||||
bool AbstractTwoPointTool::isSelectable() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AbstractTwoPointTool::showMousePreview() const
|
||||
bool AbstractTwoPointTool::showMousePreview() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractTwoPointTool::undo(QPixmap& pixmap)
|
||||
void AbstractTwoPointTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
if (this->nameID() == ToolType::CIRCLECOUNT) {
|
||||
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);
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
if (this->nameID() == ToolType::CIRCLECOUNT) {
|
||||
emit requestAction(REQ_DECREMENT_CIRCLE_COUNT);
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
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)) +
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractTwoPointTool(QObject* parent = nullptr);
|
||||
explicit AbstractTwoPointTool(QObject* parent = nullptr);
|
||||
|
||||
bool isValid() const override;
|
||||
bool closeOnButtonPressed() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
bool isValid() const override;
|
||||
bool closeOnButtonPressed() const override;
|
||||
bool isSelectable() const override;
|
||||
bool showMousePreview() const override;
|
||||
|
||||
void undo(QPixmap& pixmap) override;
|
||||
void undo(QPixmap& pixmap) override;
|
||||
|
||||
public slots:
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void drawMoveWithAdjustment(const QPoint& p) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
void drawEnd(const QPoint& p) override;
|
||||
void drawMove(const QPoint& p) override;
|
||||
void drawMoveWithAdjustment(const QPoint& p) override;
|
||||
void colorChanged(const QColor& c) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
|
||||
protected:
|
||||
void updateBackup(const QPixmap& pixmap);
|
||||
QRect backupRect(const QRect& limits) const;
|
||||
void updateBackup(const QPixmap& pixmap);
|
||||
QRect backupRect(const QRect& limits) const;
|
||||
|
||||
QPixmap m_pixmapBackup;
|
||||
QPair<QPoint, QPoint> m_points;
|
||||
QColor m_color;
|
||||
int m_thickness;
|
||||
// use m_padding to extend the area of the backup
|
||||
int m_padding;
|
||||
QPixmap m_pixmapBackup;
|
||||
QPair<QPoint, QPoint> m_points;
|
||||
QColor m_color;
|
||||
int m_thickness;
|
||||
// use m_padding to extend the area of the backup
|
||||
int m_padding;
|
||||
|
||||
bool m_supportsOrthogonalAdj = false;
|
||||
bool m_supportsDiagonalAdj = false;
|
||||
bool m_supportsOrthogonalAdj = false;
|
||||
bool m_supportsDiagonalAdj = false;
|
||||
|
||||
virtual ToolType nameID() const = 0;
|
||||
virtual ToolType nameID() const = 0;
|
||||
|
||||
private:
|
||||
QPoint adjustedVector(QPoint v) const;
|
||||
QPoint adjustedVector(QPoint v) const;
|
||||
};
|
||||
|
||||
@@ -24,50 +24,48 @@ namespace {
|
||||
const int ArrowWidth = 10;
|
||||
const int ArrowHeight = 18;
|
||||
|
||||
QPainterPath
|
||||
getArrowHead(QPoint p1, QPoint p2, const int thickness)
|
||||
QPainterPath getArrowHead(QPoint p1, QPoint p2, const int thickness)
|
||||
{
|
||||
QLineF base(p1, p2);
|
||||
// Create the vector for the position of the base of the arrowhead
|
||||
QLineF temp(QPoint(0, 0), p2 - p1);
|
||||
int val = ArrowHeight + thickness * 4;
|
||||
if (base.length() < val) {
|
||||
val = (base.length() + thickness * 2);
|
||||
}
|
||||
temp.setLength(base.length() + thickness * 2 - val);
|
||||
// Move across the line up to the head
|
||||
QPointF bottonTranslation(temp.p2());
|
||||
QLineF base(p1, p2);
|
||||
// Create the vector for the position of the base of the arrowhead
|
||||
QLineF temp(QPoint(0, 0), p2 - p1);
|
||||
int val = ArrowHeight + thickness * 4;
|
||||
if (base.length() < val) {
|
||||
val = (base.length() + thickness * 2);
|
||||
}
|
||||
temp.setLength(base.length() + thickness * 2 - val);
|
||||
// Move across the line up to the head
|
||||
QPointF bottonTranslation(temp.p2());
|
||||
|
||||
// Rotate base of the arrowhead
|
||||
base.setLength(ArrowWidth + thickness * 2);
|
||||
base.setAngle(base.angle() + 90);
|
||||
// Move to the correct point
|
||||
QPointF temp2 = p1 - base.p2();
|
||||
// Center it
|
||||
QPointF centerTranslation((temp2.x() / 2), (temp2.y() / 2));
|
||||
// Rotate base of the arrowhead
|
||||
base.setLength(ArrowWidth + thickness * 2);
|
||||
base.setAngle(base.angle() + 90);
|
||||
// Move to the correct point
|
||||
QPointF temp2 = p1 - base.p2();
|
||||
// Center it
|
||||
QPointF centerTranslation((temp2.x() / 2), (temp2.y() / 2));
|
||||
|
||||
base.translate(bottonTranslation);
|
||||
base.translate(centerTranslation);
|
||||
base.translate(bottonTranslation);
|
||||
base.translate(centerTranslation);
|
||||
|
||||
QPainterPath path;
|
||||
path.moveTo(p2);
|
||||
path.lineTo(base.p1());
|
||||
path.lineTo(base.p2());
|
||||
path.lineTo(p2);
|
||||
return path;
|
||||
QPainterPath path;
|
||||
path.moveTo(p2);
|
||||
path.lineTo(base.p1());
|
||||
path.lineTo(base.p2());
|
||||
path.lineTo(p2);
|
||||
return path;
|
||||
}
|
||||
|
||||
// gets a shorter line to prevent overlap in the point of the arrow
|
||||
QLine
|
||||
getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
||||
QLine getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
||||
{
|
||||
QLineF l(p1, p2);
|
||||
int val = ArrowHeight + thickness * 4;
|
||||
if (l.length() < val) {
|
||||
val = (l.length() + thickness * 2);
|
||||
}
|
||||
l.setLength(l.length() + thickness * 2 - val);
|
||||
return l.toLine();
|
||||
QLineF l(p1, p2);
|
||||
int val = ArrowHeight + thickness * 4;
|
||||
if (l.length() < val) {
|
||||
val = (l.length() + thickness * 2);
|
||||
}
|
||||
l.setLength(l.length() + thickness * 2 - val);
|
||||
return l.toLine();
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -75,72 +73,66 @@ getShorterLine(QPoint p1, QPoint p2, const int thickness)
|
||||
ArrowTool::ArrowTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_padding = ArrowWidth / 2;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_padding = ArrowWidth / 2;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
ArrowTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon ArrowTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
||||
}
|
||||
QString
|
||||
ArrowTool::name() const
|
||||
QString ArrowTool::name() const
|
||||
{
|
||||
return tr("Arrow");
|
||||
return tr("Arrow");
|
||||
}
|
||||
|
||||
ToolType
|
||||
ArrowTool::nameID() const
|
||||
ToolType ArrowTool::nameID() const
|
||||
{
|
||||
return ToolType::ARROW;
|
||||
return ToolType::ARROW;
|
||||
}
|
||||
|
||||
QString
|
||||
ArrowTool::description() const
|
||||
QString ArrowTool::description() const
|
||||
{
|
||||
return tr("Set the Arrow as the paint tool");
|
||||
return tr("Set the Arrow as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
ArrowTool::copy(QObject* parent)
|
||||
CaptureTool* ArrowTool::copy(QObject* parent)
|
||||
{
|
||||
return new ArrowTool(parent);
|
||||
return new ArrowTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
ArrowTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void ArrowTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(
|
||||
getShorterLine(m_points.first, m_points.second, m_thickness));
|
||||
painter.fillPath(getArrowHead(m_points.first, m_points.second, m_thickness),
|
||||
QBrush(m_color));
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(
|
||||
getShorterLine(m_points.first, m_points.second, m_thickness));
|
||||
painter.fillPath(getArrowHead(m_points.first, m_points.second, m_thickness),
|
||||
QBrush(m_color));
|
||||
}
|
||||
|
||||
void
|
||||
ArrowTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void ArrowTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
ArrowTool::drawStart(const CaptureContext& context)
|
||||
void ArrowTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
ArrowTool::pressed(const CaptureContext& context)
|
||||
void ArrowTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -23,25 +23,25 @@
|
||||
|
||||
class ArrowTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ArrowTool(QObject* parent = nullptr);
|
||||
explicit ArrowTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
|
||||
#include "capturecontext.h"
|
||||
|
||||
QPixmap
|
||||
CaptureContext::selectedScreenshotArea() const
|
||||
QPixmap CaptureContext::selectedScreenshotArea() const
|
||||
{
|
||||
if (selection.isNull()) {
|
||||
return screenshot;
|
||||
} else {
|
||||
return screenshot.copy(selection);
|
||||
}
|
||||
if (selection.isNull()) {
|
||||
return screenshot;
|
||||
} else {
|
||||
return screenshot.copy(selection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,27 +24,27 @@
|
||||
|
||||
struct CaptureContext
|
||||
{
|
||||
// screenshot with modifications
|
||||
QPixmap screenshot;
|
||||
// unmodified screenshot
|
||||
QPixmap origScreenshot;
|
||||
// Selection area
|
||||
QRect selection;
|
||||
// Widget dimensions
|
||||
QRect widgetDimensions;
|
||||
// Selected tool color
|
||||
QColor color;
|
||||
// Path where the content has to be saved
|
||||
QString savePath;
|
||||
// Ofset of the capture widget based on the system's screen (top-left)
|
||||
QPoint widgetOffset;
|
||||
// Mouse position inside the widget
|
||||
QPoint mousePos;
|
||||
// Value of the desired thickness
|
||||
int thickness;
|
||||
int circleCount;
|
||||
// Mode of the capture widget
|
||||
bool fullscreen;
|
||||
// screenshot with modifications
|
||||
QPixmap screenshot;
|
||||
// unmodified screenshot
|
||||
QPixmap origScreenshot;
|
||||
// Selection area
|
||||
QRect selection;
|
||||
// Widget dimensions
|
||||
QRect widgetDimensions;
|
||||
// Selected tool color
|
||||
QColor color;
|
||||
// Path where the content has to be saved
|
||||
QString savePath;
|
||||
// Ofset of the capture widget based on the system's screen (top-left)
|
||||
QPoint widgetOffset;
|
||||
// Mouse position inside the widget
|
||||
QPoint mousePos;
|
||||
// Value of the desired thickness
|
||||
int thickness;
|
||||
int circleCount;
|
||||
// Mode of the capture widget
|
||||
bool fullscreen;
|
||||
|
||||
QPixmap selectedScreenshotArea() const;
|
||||
QPixmap selectedScreenshotArea() const;
|
||||
};
|
||||
|
||||
@@ -25,152 +25,152 @@
|
||||
|
||||
enum class ToolType
|
||||
{
|
||||
ARROW,
|
||||
CIRCLE,
|
||||
CIRCLECOUNT,
|
||||
COPY,
|
||||
EXIT,
|
||||
IMGUR,
|
||||
LAUNCHER,
|
||||
LINE,
|
||||
MARKER,
|
||||
MOVE,
|
||||
PENCIL,
|
||||
PIN,
|
||||
PIXELATE,
|
||||
RECTANGLE,
|
||||
REDO,
|
||||
SAVE,
|
||||
SELECTION,
|
||||
SIZEINDICATOR,
|
||||
TEXT,
|
||||
UNDO
|
||||
ARROW,
|
||||
CIRCLE,
|
||||
CIRCLECOUNT,
|
||||
COPY,
|
||||
EXIT,
|
||||
IMGUR,
|
||||
LAUNCHER,
|
||||
LINE,
|
||||
MARKER,
|
||||
MOVE,
|
||||
PENCIL,
|
||||
PIN,
|
||||
PIXELATE,
|
||||
RECTANGLE,
|
||||
REDO,
|
||||
SAVE,
|
||||
SELECTION,
|
||||
SIZEINDICATOR,
|
||||
TEXT,
|
||||
UNDO
|
||||
};
|
||||
|
||||
class CaptureTool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Request actions on the main widget
|
||||
enum Request
|
||||
{
|
||||
// Call close() in the editor.
|
||||
REQ_CLOSE_GUI,
|
||||
// Call hide() in the editor.
|
||||
REQ_HIDE_GUI,
|
||||
// Select the whole screen.
|
||||
REQ_SELECT_ALL,
|
||||
// Disable the selection.
|
||||
REQ_HIDE_SELECTION,
|
||||
// Undo the last active modification in the stack.
|
||||
REQ_UNDO_MODIFICATION,
|
||||
// Redo the next modification in the stack.
|
||||
REQ_REDO_MODIFICATION,
|
||||
// Remove all the modifications.
|
||||
REQ_CLEAR_MODIFICATIONS,
|
||||
// Disable the active tool.
|
||||
REQ_MOVE_MODE,
|
||||
// Open the color picker under the mouse.
|
||||
REQ_SHOW_COLOR_PICKER,
|
||||
// Open/Close the side-panel.
|
||||
REQ_TOGGLE_SIDEBAR,
|
||||
// Call update() in the editor.
|
||||
REQ_REDRAW,
|
||||
// Append this tool to the undo/redo stack
|
||||
REQ_APPEND_TO_STACK,
|
||||
// Notify is the screenshot has been saved.
|
||||
REQ_CAPTURE_DONE_OK,
|
||||
// Instance this->widget()'s widget inside the editor under the mouse.
|
||||
REQ_ADD_CHILD_WIDGET,
|
||||
// Instance this->widget()'s widget as a window which closes after
|
||||
// closing the editor.
|
||||
REQ_ADD_CHILD_WINDOW,
|
||||
// Instance this->widget()'s widget which handles its own lifetime.
|
||||
REQ_ADD_EXTERNAL_WIDGETS,
|
||||
// Request actions on the main widget
|
||||
enum Request
|
||||
{
|
||||
// Call close() in the editor.
|
||||
REQ_CLOSE_GUI,
|
||||
// Call hide() in the editor.
|
||||
REQ_HIDE_GUI,
|
||||
// Select the whole screen.
|
||||
REQ_SELECT_ALL,
|
||||
// Disable the selection.
|
||||
REQ_HIDE_SELECTION,
|
||||
// Undo the last active modification in the stack.
|
||||
REQ_UNDO_MODIFICATION,
|
||||
// Redo the next modification in the stack.
|
||||
REQ_REDO_MODIFICATION,
|
||||
// Remove all the modifications.
|
||||
REQ_CLEAR_MODIFICATIONS,
|
||||
// Disable the active tool.
|
||||
REQ_MOVE_MODE,
|
||||
// Open the color picker under the mouse.
|
||||
REQ_SHOW_COLOR_PICKER,
|
||||
// Open/Close the side-panel.
|
||||
REQ_TOGGLE_SIDEBAR,
|
||||
// Call update() in the editor.
|
||||
REQ_REDRAW,
|
||||
// Append this tool to the undo/redo stack
|
||||
REQ_APPEND_TO_STACK,
|
||||
// Notify is the screenshot has been saved.
|
||||
REQ_CAPTURE_DONE_OK,
|
||||
// Instance this->widget()'s widget inside the editor under the mouse.
|
||||
REQ_ADD_CHILD_WIDGET,
|
||||
// Instance this->widget()'s widget as a window which closes after
|
||||
// closing the editor.
|
||||
REQ_ADD_CHILD_WINDOW,
|
||||
// Instance this->widget()'s widget which handles its own lifetime.
|
||||
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)
|
||||
: QObject(parent)
|
||||
{}
|
||||
explicit CaptureTool(QObject* parent = nullptr)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
// Returns false when the tool is in an inconsistent state and shouldn't
|
||||
// be included in the tool undo/redo stack.
|
||||
virtual bool isValid() const = 0;
|
||||
// Close the capture after the process() call if the tool was activated
|
||||
// from a button press.
|
||||
virtual bool closeOnButtonPressed() const = 0;
|
||||
// If the tool keeps active after the selection.
|
||||
virtual bool isSelectable() const = 0;
|
||||
// Enable mouse preview.
|
||||
virtual bool showMousePreview() const = 0;
|
||||
// Returns false when the tool is in an inconsistent state and shouldn't
|
||||
// be included in the tool undo/redo stack.
|
||||
virtual bool isValid() const = 0;
|
||||
// Close the capture after the process() call if the tool was activated
|
||||
// from a button press.
|
||||
virtual bool closeOnButtonPressed() const = 0;
|
||||
// If the tool keeps active after the selection.
|
||||
virtual bool isSelectable() const = 0;
|
||||
// Enable mouse preview.
|
||||
virtual bool showMousePreview() const = 0;
|
||||
|
||||
// The icon of the tool.
|
||||
// inEditor is true when the icon is requested inside the editor
|
||||
// and false otherwise.
|
||||
virtual QIcon icon(const QColor& background, bool inEditor) const = 0;
|
||||
// Name displayed for the tool, this could be translated with tr()
|
||||
virtual QString name() const = 0;
|
||||
// Codename for the tool, this hsouldn't change as it is used as ID
|
||||
// for the tool in the internals of Flameshot
|
||||
virtual ToolType nameID() const = 0;
|
||||
// Short description of the tool.
|
||||
virtual QString description() const = 0;
|
||||
// The icon of the tool.
|
||||
// inEditor is true when the icon is requested inside the editor
|
||||
// and false otherwise.
|
||||
virtual QIcon icon(const QColor& background, bool inEditor) const = 0;
|
||||
// Name displayed for the tool, this could be translated with tr()
|
||||
virtual QString name() const = 0;
|
||||
// Codename for the tool, this hsouldn't change as it is used as ID
|
||||
// for the tool in the internals of Flameshot
|
||||
virtual ToolType nameID() const = 0;
|
||||
// Short description of the tool.
|
||||
virtual QString description() const = 0;
|
||||
|
||||
// if the type is TYPE_WIDGET the widget is loaded in the main widget.
|
||||
// If the type is TYPE_EXTERNAL_WIDGET it is created outside as an
|
||||
// individual widget.
|
||||
virtual QWidget* widget() { return nullptr; }
|
||||
// When the tool is selected this method is called and the widget is added
|
||||
// to the configuration panel inside the main widget.
|
||||
virtual QWidget* configurationWidget() { return nullptr; }
|
||||
// Permanent configuration used in the configuration outside of the
|
||||
// capture.
|
||||
virtual QWidget* permanentConfigurationWidget() { return nullptr; }
|
||||
// Return a copy of the tool
|
||||
virtual CaptureTool* copy(QObject* parent = nullptr) = 0;
|
||||
// if the type is TYPE_WIDGET the widget is loaded in the main widget.
|
||||
// If the type is TYPE_EXTERNAL_WIDGET it is created outside as an
|
||||
// individual widget.
|
||||
virtual QWidget* widget() { return nullptr; }
|
||||
// When the tool is selected this method is called and the widget is added
|
||||
// to the configuration panel inside the main widget.
|
||||
virtual QWidget* configurationWidget() { return nullptr; }
|
||||
// Permanent configuration used in the configuration outside of the
|
||||
// capture.
|
||||
virtual QWidget* permanentConfigurationWidget() { return nullptr; }
|
||||
// Return a copy of the tool
|
||||
virtual CaptureTool* copy(QObject* parent = nullptr) = 0;
|
||||
|
||||
// revert changes
|
||||
virtual void undo(QPixmap& pixmap) = 0;
|
||||
// Called every time the tool has to draw
|
||||
// recordUndo indicates when the tool should save the information
|
||||
// for the undo(), if the value is false calling undo() after
|
||||
// that process should not modify revert the changes.
|
||||
virtual void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) = 0;
|
||||
// When the tool is selected, this is called when the mouse moves
|
||||
virtual void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) = 0;
|
||||
// revert changes
|
||||
virtual void undo(QPixmap& pixmap) = 0;
|
||||
// Called every time the tool has to draw
|
||||
// recordUndo indicates when the tool should save the information
|
||||
// for the undo(), if the value is false calling undo() after
|
||||
// that process should not modify revert the changes.
|
||||
virtual void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) = 0;
|
||||
// When the tool is selected, this is called when the mouse moves
|
||||
virtual void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) = 0;
|
||||
|
||||
signals:
|
||||
void requestAction(Request r);
|
||||
void requestAction(Request r);
|
||||
|
||||
protected:
|
||||
QString iconPath(const QColor& c) const
|
||||
{
|
||||
return ColorUtils::colorIsDark(c) ? PathInfo::whiteIconPath()
|
||||
: PathInfo::blackIconPath();
|
||||
}
|
||||
QString iconPath(const QColor& c) const
|
||||
{
|
||||
return ColorUtils::colorIsDark(c) ? PathInfo::whiteIconPath()
|
||||
: PathInfo::blackIconPath();
|
||||
}
|
||||
|
||||
public slots:
|
||||
// On mouse release.
|
||||
virtual void drawEnd(const QPoint& p) = 0;
|
||||
// Mouse pressed and moving, called once a pixel.
|
||||
virtual void drawMove(const QPoint& p) = 0;
|
||||
// Called when drawMove is needed with an adjustment;
|
||||
// should be overridden in case an adjustment is applicable.
|
||||
virtual void drawMoveWithAdjustment(const QPoint& p) { drawMove(p); }
|
||||
// Called when the tool is activated.
|
||||
virtual void drawStart(const CaptureContext& context) = 0;
|
||||
// Called right after pressign the button which activates the tool.
|
||||
virtual void pressed(const CaptureContext& context) = 0;
|
||||
// Called when the color is changed in the editor.
|
||||
virtual void colorChanged(const QColor& c) = 0;
|
||||
// Called when the thickness of the tool is updated in the editor.
|
||||
virtual void thicknessChanged(const int th) = 0;
|
||||
// On mouse release.
|
||||
virtual void drawEnd(const QPoint& p) = 0;
|
||||
// Mouse pressed and moving, called once a pixel.
|
||||
virtual void drawMove(const QPoint& p) = 0;
|
||||
// Called when drawMove is needed with an adjustment;
|
||||
// should be overridden in case an adjustment is applicable.
|
||||
virtual void drawMoveWithAdjustment(const QPoint& p) { drawMove(p); }
|
||||
// Called when the tool is activated.
|
||||
virtual void drawStart(const CaptureContext& context) = 0;
|
||||
// Called right after pressign the button which activates the tool.
|
||||
virtual void pressed(const CaptureContext& context) = 0;
|
||||
// Called when the color is changed in the editor.
|
||||
virtual void colorChanged(const QColor& c) = 0;
|
||||
// Called when the thickness of the tool is updated in the editor.
|
||||
virtual void thicknessChanged(const int th) = 0;
|
||||
};
|
||||
|
||||
@@ -25,67 +25,61 @@ namespace {
|
||||
CircleTool::CircleTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
CircleTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon CircleTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circle-outline.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circle-outline.svg");
|
||||
}
|
||||
QString
|
||||
CircleTool::name() const
|
||||
QString CircleTool::name() const
|
||||
{
|
||||
return tr("Circle");
|
||||
return tr("Circle");
|
||||
}
|
||||
|
||||
ToolType
|
||||
CircleTool::nameID() const
|
||||
ToolType CircleTool::nameID() const
|
||||
{
|
||||
return ToolType::CIRCLE;
|
||||
return ToolType::CIRCLE;
|
||||
}
|
||||
|
||||
QString
|
||||
CircleTool::description() const
|
||||
QString CircleTool::description() const
|
||||
{
|
||||
return tr("Set the Circle as the paint tool");
|
||||
return tr("Set the Circle as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
CircleTool::copy(QObject* parent)
|
||||
CaptureTool* CircleTool::copy(QObject* parent)
|
||||
{
|
||||
return new CircleTool(parent);
|
||||
return new CircleTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
CircleTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void CircleTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawEllipse(QRect(m_points.first, m_points.second));
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawEllipse(QRect(m_points.first, m_points.second));
|
||||
}
|
||||
|
||||
void
|
||||
CircleTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void CircleTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
CircleTool::drawStart(const CaptureContext& context)
|
||||
void CircleTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
CircleTool::pressed(const CaptureContext& context)
|
||||
void CircleTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
|
||||
class CircleTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CircleTool(QObject* parent = nullptr);
|
||||
explicit CircleTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -24,120 +24,111 @@ namespace {
|
||||
CircleCountTool::CircleCountTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_count = 0;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
QIcon
|
||||
CircleCountTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon CircleCountTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
||||
}
|
||||
QString
|
||||
CircleCountTool::name() const
|
||||
QString CircleCountTool::name() const
|
||||
{
|
||||
return tr("Circle Counter");
|
||||
return tr("Circle Counter");
|
||||
}
|
||||
|
||||
ToolType
|
||||
CircleCountTool::nameID() const
|
||||
ToolType CircleCountTool::nameID() const
|
||||
{
|
||||
return ToolType::CIRCLECOUNT;
|
||||
return ToolType::CIRCLECOUNT;
|
||||
}
|
||||
|
||||
QString
|
||||
CircleCountTool::description() const
|
||||
QString CircleCountTool::description() const
|
||||
{
|
||||
return tr("Add an autoincrementing counter bubble");
|
||||
return tr("Add an autoincrementing counter bubble");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
CircleCountTool::copy(QObject* parent)
|
||||
CaptureTool* CircleCountTool::copy(QObject* parent)
|
||||
{
|
||||
return new CircleCountTool(parent);
|
||||
return new CircleCountTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
CircleCountTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
void CircleCountTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
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;
|
||||
if (recordUndo) {
|
||||
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);
|
||||
|
||||
bRect =
|
||||
QRect bRect =
|
||||
painter.boundingRect(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);
|
||||
}
|
||||
while (bRect.width() > textRect.width()) {
|
||||
fontSize--;
|
||||
if (fontSize == 0) {
|
||||
break;
|
||||
}
|
||||
new_font.setPixelSize(fontSize);
|
||||
painter.setFont(new_font);
|
||||
|
||||
painter.drawText(textRect, Qt::AlignCenter, QString::number(m_count));
|
||||
painter.setFont(orig_font);
|
||||
bRect = painter.boundingRect(
|
||||
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
|
||||
CircleCountTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
void CircleCountTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
if (m_thickness < 15) {
|
||||
m_thickness = 15;
|
||||
}
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
if (m_thickness < 15) {
|
||||
m_thickness = 15;
|
||||
}
|
||||
|
||||
// Thickness for pen is *2 to range from radius to diameter to match the
|
||||
// ellipse draw function
|
||||
painter.setPen(
|
||||
QPen(context.color, m_thickness * 2, Qt::SolidLine, Qt::RoundCap));
|
||||
painter.drawLine(context.mousePos,
|
||||
{ context.mousePos.x() + 1, context.mousePos.y() + 1 });
|
||||
// Thickness for pen is *2 to range from radius to diameter to match the
|
||||
// ellipse draw function
|
||||
painter.setPen(
|
||||
QPen(context.color, m_thickness * 2, Qt::SolidLine, Qt::RoundCap));
|
||||
painter.drawLine(context.mousePos,
|
||||
{ context.mousePos.x() + 1, context.mousePos.y() + 1 });
|
||||
}
|
||||
|
||||
void
|
||||
CircleCountTool::drawStart(const CaptureContext& context)
|
||||
void CircleCountTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
if (m_thickness < 15) {
|
||||
m_thickness = 15;
|
||||
}
|
||||
m_points.first = context.mousePos;
|
||||
m_count = context.circleCount;
|
||||
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
if (m_thickness < 15) {
|
||||
m_thickness = 15;
|
||||
}
|
||||
m_points.first = context.mousePos;
|
||||
m_count = context.circleCount;
|
||||
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
||||
}
|
||||
|
||||
void
|
||||
CircleCountTool::pressed(const CaptureContext& context)
|
||||
void CircleCountTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,27 +21,27 @@
|
||||
|
||||
class CircleCountTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CircleCountTool(QObject* parent = nullptr);
|
||||
explicit CircleCountTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
private:
|
||||
unsigned int m_count;
|
||||
unsigned int m_count;
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -23,45 +23,38 @@ CopyTool::CopyTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
CopyTool::closeOnButtonPressed() const
|
||||
bool CopyTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
CopyTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon CopyTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-copy.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-copy.svg");
|
||||
}
|
||||
QString
|
||||
CopyTool::name() const
|
||||
QString CopyTool::name() const
|
||||
{
|
||||
return tr("Copy");
|
||||
return tr("Copy");
|
||||
}
|
||||
|
||||
ToolType
|
||||
CopyTool::nameID() const
|
||||
ToolType CopyTool::nameID() const
|
||||
{
|
||||
return ToolType::COPY;
|
||||
return ToolType::COPY;
|
||||
}
|
||||
|
||||
QString
|
||||
CopyTool::description() const
|
||||
QString CopyTool::description() const
|
||||
{
|
||||
return tr("Copy the selection into the clipboard");
|
||||
return tr("Copy the selection into the clipboard");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
CopyTool::copy(QObject* parent)
|
||||
CaptureTool* CopyTool::copy(QObject* parent)
|
||||
{
|
||||
return new CopyTool(parent);
|
||||
return new CopyTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
CopyTool::pressed(const CaptureContext& context)
|
||||
void CopyTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
|
||||
class CopyTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -22,45 +22,38 @@ ExitTool::ExitTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
ExitTool::closeOnButtonPressed() const
|
||||
bool ExitTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
ExitTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon ExitTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "close.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "close.svg");
|
||||
}
|
||||
QString
|
||||
ExitTool::name() const
|
||||
QString ExitTool::name() const
|
||||
{
|
||||
return tr("Exit");
|
||||
return tr("Exit");
|
||||
}
|
||||
|
||||
ToolType
|
||||
ExitTool::nameID() const
|
||||
ToolType ExitTool::nameID() const
|
||||
{
|
||||
return ToolType::EXIT;
|
||||
return ToolType::EXIT;
|
||||
}
|
||||
|
||||
QString
|
||||
ExitTool::description() const
|
||||
QString ExitTool::description() const
|
||||
{
|
||||
return tr("Leave the capture screen");
|
||||
return tr("Leave the capture screen");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
ExitTool::copy(QObject* parent)
|
||||
CaptureTool* ExitTool::copy(QObject* parent)
|
||||
{
|
||||
return new ExitTool(parent);
|
||||
return new ExitTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
ExitTool::pressed(const CaptureContext& context)
|
||||
void ExitTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_CLOSE_GUI);
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_CLOSE_GUI);
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
|
||||
class ExitTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
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)
|
||||
, m_pixmap(capture)
|
||||
{
|
||||
setWindowTitle(tr("Upload to Imgur"));
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
setWindowTitle(tr("Upload to Imgur"));
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
|
||||
m_spinner = new LoadSpinner(this);
|
||||
m_spinner->setColor(ConfigHandler().uiMainColorValue());
|
||||
m_spinner->start();
|
||||
m_spinner = new LoadSpinner(this);
|
||||
m_spinner->setColor(ConfigHandler().uiMainColorValue());
|
||||
m_spinner->start();
|
||||
|
||||
m_infoLabel = new QLabel(tr("Uploading Image"));
|
||||
m_infoLabel = new QLabel(tr("Uploading Image"));
|
||||
|
||||
m_vLayout = new QVBoxLayout();
|
||||
setLayout(m_vLayout);
|
||||
m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
|
||||
m_vLayout->addWidget(m_infoLabel);
|
||||
m_vLayout = new QVBoxLayout();
|
||||
setLayout(m_vLayout);
|
||||
m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
|
||||
m_vLayout->addWidget(m_infoLabel);
|
||||
|
||||
m_NetworkAM = new QNetworkAccessManager(this);
|
||||
connect(m_NetworkAM,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&ImgurUploader::handleReply);
|
||||
m_NetworkAM = new QNetworkAccessManager(this);
|
||||
connect(m_NetworkAM,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&ImgurUploader::handleReply);
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
upload();
|
||||
// QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing
|
||||
upload();
|
||||
// QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::handleReply(QNetworkReply* reply)
|
||||
void ImgurUploader::handleReply(QNetworkReply* reply)
|
||||
{
|
||||
m_spinner->deleteLater();
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
|
||||
QJsonObject json = response.object();
|
||||
QJsonObject data = json[QStringLiteral("data")].toObject();
|
||||
m_imageURL.setUrl(data[QStringLiteral("link")].toString());
|
||||
m_deleteImageURL.setUrl(
|
||||
QStringLiteral("https://imgur.com/delete/%1")
|
||||
.arg(data[QStringLiteral("deletehash")].toString()));
|
||||
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
SystemNotification().sendMessage(QObject::tr("URL copied to clipboard."));
|
||||
close();
|
||||
m_spinner->deleteLater();
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
|
||||
QJsonObject json = response.object();
|
||||
QJsonObject data = json[QStringLiteral("data")].toObject();
|
||||
m_imageURL.setUrl(data[QStringLiteral("link")].toString());
|
||||
m_deleteImageURL.setUrl(
|
||||
QStringLiteral("https://imgur.com/delete/%1")
|
||||
.arg(data[QStringLiteral("deletehash")].toString()));
|
||||
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr("URL copied to clipboard."));
|
||||
close();
|
||||
} else {
|
||||
onUploadOk();
|
||||
}
|
||||
} else {
|
||||
onUploadOk();
|
||||
m_infoLabel->setText(reply->errorString());
|
||||
}
|
||||
} else {
|
||||
m_infoLabel->setText(reply->errorString());
|
||||
}
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::startDrag()
|
||||
void ImgurUploader::startDrag()
|
||||
{
|
||||
QMimeData* mimeData = new QMimeData;
|
||||
mimeData->setUrls(QList<QUrl>{ m_imageURL });
|
||||
mimeData->setImageData(m_pixmap);
|
||||
QMimeData* mimeData = new QMimeData;
|
||||
mimeData->setUrls(QList<QUrl>{ m_imageURL });
|
||||
mimeData->setImageData(m_pixmap);
|
||||
|
||||
QDrag* dragHandler = new QDrag(this);
|
||||
dragHandler->setMimeData(mimeData);
|
||||
dragHandler->setPixmap(m_pixmap.scaled(
|
||||
256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
dragHandler->exec();
|
||||
QDrag* dragHandler = new QDrag(this);
|
||||
dragHandler->setMimeData(mimeData);
|
||||
dragHandler->setPixmap(m_pixmap.scaled(
|
||||
256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
dragHandler->exec();
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::upload()
|
||||
void ImgurUploader::upload()
|
||||
{
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
m_pixmap.save(&buffer, "PNG");
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
m_pixmap.save(&buffer, "PNG");
|
||||
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem(QStringLiteral("title"),
|
||||
QStringLiteral("flameshot_screenshot"));
|
||||
QString description = FileNameHandler().parsedPattern();
|
||||
urlQuery.addQueryItem(QStringLiteral("description"), description);
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem(QStringLiteral("title"),
|
||||
QStringLiteral("flameshot_screenshot"));
|
||||
QString description = FileNameHandler().parsedPattern();
|
||||
urlQuery.addQueryItem(QStringLiteral("description"), description);
|
||||
|
||||
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
|
||||
url.setQuery(urlQuery);
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader,
|
||||
"application/application/x-www-form-urlencoded");
|
||||
request.setRawHeader(
|
||||
"Authorization",
|
||||
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
|
||||
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
|
||||
url.setQuery(urlQuery);
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader,
|
||||
"application/application/x-www-form-urlencoded");
|
||||
request.setRawHeader(
|
||||
"Authorization",
|
||||
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
|
||||
|
||||
m_NetworkAM->post(request, byteArray);
|
||||
m_NetworkAM->post(request, byteArray);
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::onUploadOk()
|
||||
void ImgurUploader::onUploadOk()
|
||||
{
|
||||
m_infoLabel->deleteLater();
|
||||
m_infoLabel->deleteLater();
|
||||
|
||||
m_notification = new NotificationWidget();
|
||||
m_vLayout->addWidget(m_notification);
|
||||
m_notification = new NotificationWidget();
|
||||
m_vLayout->addWidget(m_notification);
|
||||
|
||||
ImageLabel* imageLabel = new ImageLabel();
|
||||
imageLabel->setScreenshot(m_pixmap);
|
||||
imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(
|
||||
imageLabel, &ImageLabel::dragInitiated, this, &ImgurUploader::startDrag);
|
||||
m_vLayout->addWidget(imageLabel);
|
||||
ImageLabel* imageLabel = new ImageLabel();
|
||||
imageLabel->setScreenshot(m_pixmap);
|
||||
imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
connect(
|
||||
imageLabel, &ImageLabel::dragInitiated, this, &ImgurUploader::startDrag);
|
||||
m_vLayout->addWidget(imageLabel);
|
||||
|
||||
m_hLayout = new QHBoxLayout();
|
||||
m_vLayout->addLayout(m_hLayout);
|
||||
m_hLayout = new QHBoxLayout();
|
||||
m_vLayout->addLayout(m_hLayout);
|
||||
|
||||
m_copyUrlButton = new QPushButton(tr("Copy URL"));
|
||||
m_openUrlButton = new QPushButton(tr("Open URL"));
|
||||
m_openDeleteUrlButton = new QPushButton(tr("Delete image"));
|
||||
m_toClipboardButton = new QPushButton(tr("Image to Clipboard."));
|
||||
m_hLayout->addWidget(m_copyUrlButton);
|
||||
m_hLayout->addWidget(m_openUrlButton);
|
||||
m_hLayout->addWidget(m_openDeleteUrlButton);
|
||||
m_hLayout->addWidget(m_toClipboardButton);
|
||||
m_copyUrlButton = new QPushButton(tr("Copy URL"));
|
||||
m_openUrlButton = new QPushButton(tr("Open URL"));
|
||||
m_openDeleteUrlButton = new QPushButton(tr("Delete image"));
|
||||
m_toClipboardButton = new QPushButton(tr("Image to Clipboard."));
|
||||
m_hLayout->addWidget(m_copyUrlButton);
|
||||
m_hLayout->addWidget(m_openUrlButton);
|
||||
m_hLayout->addWidget(m_openDeleteUrlButton);
|
||||
m_hLayout->addWidget(m_toClipboardButton);
|
||||
|
||||
connect(
|
||||
m_copyUrlButton, &QPushButton::clicked, this, &ImgurUploader::copyURL);
|
||||
connect(
|
||||
m_openUrlButton, &QPushButton::clicked, this, &ImgurUploader::openURL);
|
||||
connect(m_openDeleteUrlButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&ImgurUploader::openDeleteURL);
|
||||
connect(m_toClipboardButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&ImgurUploader::copyImage);
|
||||
connect(
|
||||
m_copyUrlButton, &QPushButton::clicked, this, &ImgurUploader::copyURL);
|
||||
connect(
|
||||
m_openUrlButton, &QPushButton::clicked, this, &ImgurUploader::openURL);
|
||||
connect(m_openDeleteUrlButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&ImgurUploader::openDeleteURL);
|
||||
connect(m_toClipboardButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&ImgurUploader::copyImage);
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::openURL()
|
||||
void ImgurUploader::openURL()
|
||||
{
|
||||
bool successful = QDesktopServices::openUrl(m_imageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
bool successful = QDesktopServices::openUrl(m_imageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::copyURL()
|
||||
void ImgurUploader::copyURL()
|
||||
{
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
m_notification->showMessage(tr("URL copied to clipboard."));
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
m_notification->showMessage(tr("URL copied to clipboard."));
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::openDeleteURL()
|
||||
void ImgurUploader::openDeleteURL()
|
||||
{
|
||||
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::copyImage()
|
||||
void ImgurUploader::copyImage()
|
||||
{
|
||||
QApplication::clipboard()->setPixmap(m_pixmap);
|
||||
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
||||
QApplication::clipboard()->setPixmap(m_pixmap);
|
||||
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
||||
}
|
||||
|
||||
@@ -32,37 +32,37 @@ class NotificationWidget;
|
||||
|
||||
class ImgurUploader : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr);
|
||||
explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void handleReply(QNetworkReply* reply);
|
||||
void startDrag();
|
||||
void handleReply(QNetworkReply* reply);
|
||||
void startDrag();
|
||||
|
||||
void openURL();
|
||||
void copyURL();
|
||||
void openDeleteURL();
|
||||
void copyImage();
|
||||
void openURL();
|
||||
void copyURL();
|
||||
void openDeleteURL();
|
||||
void copyImage();
|
||||
|
||||
private:
|
||||
QPixmap m_pixmap;
|
||||
QNetworkAccessManager* m_NetworkAM;
|
||||
QPixmap m_pixmap;
|
||||
QNetworkAccessManager* m_NetworkAM;
|
||||
|
||||
QVBoxLayout* m_vLayout;
|
||||
QHBoxLayout* m_hLayout;
|
||||
// loading
|
||||
QLabel* m_infoLabel;
|
||||
LoadSpinner* m_spinner;
|
||||
// uploaded
|
||||
QPushButton* m_openUrlButton;
|
||||
QPushButton* m_openDeleteUrlButton;
|
||||
QPushButton* m_copyUrlButton;
|
||||
QPushButton* m_toClipboardButton;
|
||||
QUrl m_imageURL;
|
||||
QUrl m_deleteImageURL;
|
||||
NotificationWidget* m_notification;
|
||||
QVBoxLayout* m_vLayout;
|
||||
QHBoxLayout* m_hLayout;
|
||||
// loading
|
||||
QLabel* m_infoLabel;
|
||||
LoadSpinner* m_spinner;
|
||||
// uploaded
|
||||
QPushButton* m_openUrlButton;
|
||||
QPushButton* m_openDeleteUrlButton;
|
||||
QPushButton* m_copyUrlButton;
|
||||
QPushButton* m_toClipboardButton;
|
||||
QUrl m_imageURL;
|
||||
QUrl m_deleteImageURL;
|
||||
NotificationWidget* m_notification;
|
||||
|
||||
void upload();
|
||||
void onUploadOk();
|
||||
void upload();
|
||||
void onUploadOk();
|
||||
};
|
||||
|
||||
@@ -23,52 +23,44 @@ ImgurUploaderTool::ImgurUploaderTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
ImgurUploaderTool::closeOnButtonPressed() const
|
||||
bool ImgurUploaderTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cloud-upload.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cloud-upload.svg");
|
||||
}
|
||||
QString
|
||||
ImgurUploaderTool::name() const
|
||||
QString ImgurUploaderTool::name() const
|
||||
{
|
||||
return tr("Image Uploader");
|
||||
return tr("Image Uploader");
|
||||
}
|
||||
|
||||
ToolType
|
||||
ImgurUploaderTool::nameID() const
|
||||
ToolType ImgurUploaderTool::nameID() const
|
||||
{
|
||||
return ToolType::IMGUR;
|
||||
return ToolType::IMGUR;
|
||||
}
|
||||
|
||||
QString
|
||||
ImgurUploaderTool::description() const
|
||||
QString ImgurUploaderTool::description() const
|
||||
{
|
||||
return tr("Upload the selection to Imgur");
|
||||
return tr("Upload the selection to Imgur");
|
||||
}
|
||||
|
||||
QWidget*
|
||||
ImgurUploaderTool::widget()
|
||||
QWidget* ImgurUploaderTool::widget()
|
||||
{
|
||||
return new ImgurUploader(capture);
|
||||
return new ImgurUploader(capture);
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
ImgurUploaderTool::copy(QObject* parent)
|
||||
CaptureTool* ImgurUploaderTool::copy(QObject* parent)
|
||||
{
|
||||
return new ImgurUploaderTool(parent);
|
||||
return new ImgurUploaderTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploaderTool::pressed(const CaptureContext& context)
|
||||
void ImgurUploaderTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
}
|
||||
|
||||
@@ -21,26 +21,26 @@
|
||||
|
||||
class ImgurUploaderTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() 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:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
|
||||
private:
|
||||
QPixmap capture;
|
||||
QPixmap capture;
|
||||
};
|
||||
|
||||
@@ -22,52 +22,44 @@ AppLauncher::AppLauncher(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
AppLauncher::closeOnButtonPressed() const
|
||||
bool AppLauncher::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
AppLauncher::icon(const QColor& background, bool inEditor) const
|
||||
QIcon AppLauncher::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "open_with.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "open_with.svg");
|
||||
}
|
||||
QString
|
||||
AppLauncher::name() const
|
||||
QString AppLauncher::name() const
|
||||
{
|
||||
return tr("App Launcher");
|
||||
return tr("App Launcher");
|
||||
}
|
||||
|
||||
ToolType
|
||||
AppLauncher::nameID() const
|
||||
ToolType AppLauncher::nameID() const
|
||||
{
|
||||
return ToolType::LAUNCHER;
|
||||
return ToolType::LAUNCHER;
|
||||
}
|
||||
|
||||
QString
|
||||
AppLauncher::description() const
|
||||
QString AppLauncher::description() const
|
||||
{
|
||||
return tr("Choose an app to open the capture");
|
||||
return tr("Choose an app to open the capture");
|
||||
}
|
||||
|
||||
QWidget*
|
||||
AppLauncher::widget()
|
||||
QWidget* AppLauncher::widget()
|
||||
{
|
||||
return new AppLauncherWidget(capture);
|
||||
return new AppLauncherWidget(capture);
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
AppLauncher::copy(QObject* parent)
|
||||
CaptureTool* AppLauncher::copy(QObject* parent)
|
||||
{
|
||||
return new AppLauncher(parent);
|
||||
return new AppLauncher(parent);
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncher::pressed(const CaptureContext& context)
|
||||
void AppLauncher::pressed(const CaptureContext& context)
|
||||
{
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
}
|
||||
|
||||
@@ -21,26 +21,26 @@
|
||||
|
||||
class AppLauncher : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() 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:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
|
||||
private:
|
||||
QPixmap capture;
|
||||
QPixmap capture;
|
||||
};
|
||||
|
||||
@@ -51,218 +51,213 @@ AppLauncherWidget::AppLauncherWidget(const QPixmap& p, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_pixmap(p)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
setWindowTitle(tr("Open With"));
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowIcon(QIcon(":img/app/flameshot.svg"));
|
||||
setWindowTitle(tr("Open With"));
|
||||
|
||||
m_keepOpen = ConfigHandler().keepOpenAppLauncherValue();
|
||||
m_keepOpen = ConfigHandler().keepOpenAppLauncherValue();
|
||||
|
||||
QString dirLocal = QDir::homePath() + "/.local/share/applications/";
|
||||
QDir appsDirLocal(dirLocal);
|
||||
m_parser.processDirectory(appsDirLocal);
|
||||
QString dirLocal = QDir::homePath() + "/.local/share/applications/";
|
||||
QDir appsDirLocal(dirLocal);
|
||||
m_parser.processDirectory(appsDirLocal);
|
||||
|
||||
QString dir = QStringLiteral("/usr/share/applications/");
|
||||
QDir appsDir(dir);
|
||||
m_parser.processDirectory(appsDir);
|
||||
QString dir = QStringLiteral("/usr/share/applications/");
|
||||
QDir appsDir(dir);
|
||||
m_parser.processDirectory(appsDir);
|
||||
|
||||
initAppMap();
|
||||
initListWidget();
|
||||
initAppMap();
|
||||
initListWidget();
|
||||
|
||||
m_terminalCheckbox = new QCheckBox(tr("Launch in terminal"), this);
|
||||
m_keepOpenCheckbox = new QCheckBox(tr("Keep open after selection"), this);
|
||||
m_keepOpenCheckbox->setChecked(ConfigHandler().keepOpenAppLauncherValue());
|
||||
connect(m_keepOpenCheckbox,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&AppLauncherWidget::checkboxClicked);
|
||||
m_terminalCheckbox = new QCheckBox(tr("Launch in terminal"), this);
|
||||
m_keepOpenCheckbox = new QCheckBox(tr("Keep open after selection"), this);
|
||||
m_keepOpenCheckbox->setChecked(ConfigHandler().keepOpenAppLauncherValue());
|
||||
connect(m_keepOpenCheckbox,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&AppLauncherWidget::checkboxClicked);
|
||||
|
||||
// search items
|
||||
m_lineEdit = new QLineEdit;
|
||||
connect(m_lineEdit,
|
||||
&QLineEdit::textChanged,
|
||||
this,
|
||||
&AppLauncherWidget::searchChanged);
|
||||
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()) {
|
||||
// search items
|
||||
m_lineEdit = new QLineEdit;
|
||||
connect(m_lineEdit,
|
||||
&QLineEdit::textChanged,
|
||||
this,
|
||||
&AppLauncherWidget::searchChanged);
|
||||
m_filterList = new QListWidget;
|
||||
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;
|
||||
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_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()) {
|
||||
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);
|
||||
const QString& cat = i.first;
|
||||
const QString& iconName = i.second;
|
||||
|
||||
if (!m_appsMap.contains(cat)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
addAppsToListWidget(m_filterList, apps);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncherWidget::initListWidget()
|
||||
void AppLauncherWidget::initAppMap()
|
||||
{
|
||||
m_tabWidget = new QTabWidget;
|
||||
const int size = GlobalValues::buttonBaseSize();
|
||||
m_tabWidget->setIconSize(QSize(size, size));
|
||||
QStringList categories({ "AudioVideo",
|
||||
"Audio",
|
||||
"Video",
|
||||
"Development",
|
||||
"Graphics",
|
||||
"Network",
|
||||
"Office",
|
||||
"Science",
|
||||
"Settings",
|
||||
"System",
|
||||
"Utility" });
|
||||
|
||||
for (auto const& i : catIconNames.toStdMap()) {
|
||||
const QString& cat = i.first;
|
||||
const QString& iconName = i.second;
|
||||
m_appsMap = m_parser.getAppsByCategory(categories);
|
||||
|
||||
if (!m_appsMap.contains(cat)) {
|
||||
continue;
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
m_appsMap.insert(QStringLiteral("Multimedia"), multimediaList);
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncherWidget::initAppMap()
|
||||
void AppLauncherWidget::configureListView(QListWidget* widget)
|
||||
{
|
||||
QStringList categories({ "AudioVideo",
|
||||
"Audio",
|
||||
"Video",
|
||||
"Development",
|
||||
"Graphics",
|
||||
"Network",
|
||||
"Office",
|
||||
"Science",
|
||||
"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);
|
||||
widget->setItemDelegate(new LauncherItemDelegate());
|
||||
widget->setViewMode(QListWidget::IconMode);
|
||||
widget->setResizeMode(QListView::Adjust);
|
||||
widget->setSpacing(4);
|
||||
widget->setFlow(QListView::LeftToRight);
|
||||
widget->setDragEnabled(false);
|
||||
widget->setMinimumWidth(GlobalValues::buttonBaseSize() * 11);
|
||||
connect(widget, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncherWidget::configureListView(QListWidget* widget)
|
||||
void AppLauncherWidget::addAppsToListWidget(
|
||||
QListWidget* widget,
|
||||
const QVector<DesktopAppData>& appList)
|
||||
{
|
||||
widget->setItemDelegate(new LauncherItemDelegate());
|
||||
widget->setViewMode(QListWidget::IconMode);
|
||||
widget->setResizeMode(QListView::Adjust);
|
||||
widget->setSpacing(4);
|
||||
widget->setFlow(QListView::LeftToRight);
|
||||
widget->setDragEnabled(false);
|
||||
widget->setMinimumWidth(GlobalValues::buttonBaseSize() * 11);
|
||||
connect(widget, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
||||
}
|
||||
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);
|
||||
|
||||
void
|
||||
AppLauncherWidget::addAppsToListWidget(QListWidget* widget,
|
||||
const QVector<DesktopAppData>& appList)
|
||||
{
|
||||
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);
|
||||
}
|
||||
buttonItem->setIcon(app.icon);
|
||||
buttonItem->setText(app.name);
|
||||
buttonItem->setToolTip(app.description);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,31 +29,31 @@ class QListWidget;
|
||||
|
||||
class AppLauncherWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppLauncherWidget(const QPixmap& p, QWidget* parent = nullptr);
|
||||
explicit AppLauncherWidget(const QPixmap& p, QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void launch(const QModelIndex& index);
|
||||
void checkboxClicked(const bool enabled);
|
||||
void searchChanged(const QString& text);
|
||||
void launch(const QModelIndex& index);
|
||||
void checkboxClicked(const bool enabled);
|
||||
void searchChanged(const QString& text);
|
||||
|
||||
private:
|
||||
void initListWidget();
|
||||
void initAppMap();
|
||||
void configureListView(QListWidget* widget);
|
||||
void addAppsToListWidget(QListWidget* widget,
|
||||
const QVector<DesktopAppData>& appList);
|
||||
void initListWidget();
|
||||
void initAppMap();
|
||||
void configureListView(QListWidget* widget);
|
||||
void addAppsToListWidget(QListWidget* widget,
|
||||
const QVector<DesktopAppData>& appList);
|
||||
|
||||
DesktopFileParser m_parser;
|
||||
QPixmap m_pixmap;
|
||||
QString m_tempFile;
|
||||
bool m_keepOpen;
|
||||
QMap<QString, QVector<DesktopAppData>> m_appsMap;
|
||||
QCheckBox* m_keepOpenCheckbox;
|
||||
QCheckBox* m_terminalCheckbox;
|
||||
QVBoxLayout* m_layout;
|
||||
QLineEdit* m_lineEdit;
|
||||
QListWidget* m_filterList;
|
||||
QTabWidget* m_tabWidget;
|
||||
DesktopFileParser m_parser;
|
||||
QPixmap m_pixmap;
|
||||
QString m_tempFile;
|
||||
bool m_keepOpen;
|
||||
QMap<QString, QVector<DesktopAppData>> m_appsMap;
|
||||
QCheckBox* m_keepOpenCheckbox;
|
||||
QCheckBox* m_terminalCheckbox;
|
||||
QVBoxLayout* m_layout;
|
||||
QLineEdit* m_lineEdit;
|
||||
QListWidget* m_filterList;
|
||||
QTabWidget* m_tabWidget;
|
||||
};
|
||||
|
||||
@@ -23,45 +23,44 @@ LauncherItemDelegate::LauncherItemDelegate(QObject* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
void
|
||||
LauncherItemDelegate::paint(QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
void LauncherItemDelegate::paint(QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
{
|
||||
const QRect& rect = option.rect;
|
||||
if (option.state & (QStyle::State_Selected | QStyle::State_MouseOver)) {
|
||||
painter->save();
|
||||
painter->setPen(Qt::transparent);
|
||||
painter->setBrush(QPalette().highlight());
|
||||
painter->drawRect(rect.x(), rect.y(), rect.width() - 1, rect.height() - 1);
|
||||
painter->restore();
|
||||
}
|
||||
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
|
||||
const QRect& rect = option.rect;
|
||||
if (option.state & (QStyle::State_Selected | QStyle::State_MouseOver)) {
|
||||
painter->save();
|
||||
painter->setPen(Qt::transparent);
|
||||
painter->setBrush(QPalette().highlight());
|
||||
painter->drawRect(
|
||||
rect.x(), rect.y(), rect.width() - 1, rect.height() - 1);
|
||||
painter->restore();
|
||||
}
|
||||
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
|
||||
|
||||
const int iconSide = GlobalValues::buttonBaseSize() * 1.3;
|
||||
const int halfIcon = iconSide / 2;
|
||||
const int halfWidth = rect.width() / 2;
|
||||
const int halfHeight = rect.height() / 2;
|
||||
QSize size(iconSide, iconSide);
|
||||
QPixmap pixIcon = icon.pixmap(size).scaled(size, Qt::KeepAspectRatio);
|
||||
painter->drawPixmap(rect.x() + (halfWidth - halfIcon),
|
||||
rect.y() + (halfHeight / 2 - halfIcon),
|
||||
iconSide,
|
||||
iconSide,
|
||||
pixIcon);
|
||||
const QRect textRect(
|
||||
rect.x(), rect.y() + halfHeight, rect.width(), halfHeight);
|
||||
painter->drawText(textRect,
|
||||
Qt::TextWordWrap | Qt::AlignHCenter,
|
||||
index.data(Qt::DisplayRole).toString());
|
||||
const int iconSide = GlobalValues::buttonBaseSize() * 1.3;
|
||||
const int halfIcon = iconSide / 2;
|
||||
const int halfWidth = rect.width() / 2;
|
||||
const int halfHeight = rect.height() / 2;
|
||||
QSize size(iconSide, iconSide);
|
||||
QPixmap pixIcon = icon.pixmap(size).scaled(size, Qt::KeepAspectRatio);
|
||||
painter->drawPixmap(rect.x() + (halfWidth - halfIcon),
|
||||
rect.y() + (halfHeight / 2 - halfIcon),
|
||||
iconSide,
|
||||
iconSide,
|
||||
pixIcon);
|
||||
const QRect textRect(
|
||||
rect.x(), rect.y() + halfHeight, rect.width(), halfHeight);
|
||||
painter->drawText(textRect,
|
||||
Qt::TextWordWrap | Qt::AlignHCenter,
|
||||
index.data(Qt::DisplayRole).toString());
|
||||
}
|
||||
|
||||
QSize
|
||||
LauncherItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
QSize LauncherItemDelegate::sizeHint(const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
const int size = GlobalValues::buttonBaseSize();
|
||||
return QSize(size * 3.2, size * 3.7);
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
const int size = GlobalValues::buttonBaseSize();
|
||||
return QSize(size * 3.2, size * 3.7);
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
|
||||
class LauncherItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LauncherItemDelegate(QObject* parent = nullptr);
|
||||
explicit LauncherItemDelegate(QObject* parent = nullptr);
|
||||
|
||||
void paint(QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
void paint(QPainter* painter,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
};
|
||||
|
||||
@@ -33,28 +33,28 @@
|
||||
#include "src/tools/launcher/applauncherwidget.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
showOpenWithMenu(const QPixmap& capture)
|
||||
void showOpenWithMenu(const QPixmap& capture)
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
QString tempFile =
|
||||
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
||||
bool ok = capture.save(tempFile);
|
||||
if (!ok) {
|
||||
QMessageBox::about(nullptr,
|
||||
QObject::tr("Error"),
|
||||
QObject::tr("Unable to write in") + QDir::tempPath());
|
||||
return;
|
||||
}
|
||||
QString tempFile =
|
||||
FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
||||
bool ok = capture.save(tempFile);
|
||||
if (!ok) {
|
||||
QMessageBox::about(nullptr,
|
||||
QObject::tr("Error"),
|
||||
QObject::tr("Unable to write in") +
|
||||
QDir::tempPath());
|
||||
return;
|
||||
}
|
||||
|
||||
OPENASINFO info;
|
||||
auto wStringFile = tempFile.replace("/", "\\").toStdWString();
|
||||
info.pcszFile = wStringFile.c_str();
|
||||
info.pcszClass = nullptr;
|
||||
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
|
||||
SHOpenWithDialog(nullptr, &info);
|
||||
OPENASINFO info;
|
||||
auto wStringFile = tempFile.replace("/", "\\").toStdWString();
|
||||
info.pcszFile = wStringFile.c_str();
|
||||
info.pcszClass = nullptr;
|
||||
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
|
||||
SHOpenWithDialog(nullptr, &info);
|
||||
#else
|
||||
auto w = new AppLauncherWidget(capture);
|
||||
w->show();
|
||||
auto w = new AppLauncherWidget(capture);
|
||||
w->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -19,5 +19,4 @@
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
void
|
||||
showOpenWithMenu(const QPixmap& capture);
|
||||
void showOpenWithMenu(const QPixmap& capture);
|
||||
|
||||
@@ -23,18 +23,18 @@
|
||||
|
||||
namespace {
|
||||
static const TerminalApp terminalApps[] = {
|
||||
{ "x-terminal-emulator", "-e" },
|
||||
{ "xfce4-terminal", "-x" },
|
||||
{ "konsole", "-e" },
|
||||
{ "gnome-terminal", "--" },
|
||||
{ "terminator", "-e" },
|
||||
{ "terminology", "-e" },
|
||||
{ "tilix", "-e" },
|
||||
{ "xterm", "-e" },
|
||||
{ "aterm", "-e" },
|
||||
{ "Eterm", "-e" },
|
||||
{ "rxvt", "-e" },
|
||||
{ "urxvt", "-e" },
|
||||
{ "x-terminal-emulator", "-e" },
|
||||
{ "xfce4-terminal", "-x" },
|
||||
{ "konsole", "-e" },
|
||||
{ "gnome-terminal", "--" },
|
||||
{ "terminator", "-e" },
|
||||
{ "terminology", "-e" },
|
||||
{ "tilix", "-e" },
|
||||
{ "xterm", "-e" },
|
||||
{ "aterm", "-e" },
|
||||
{ "Eterm", "-e" },
|
||||
{ "rxvt", "-e" },
|
||||
{ "urxvt", "-e" },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,24 +42,22 @@ TerminalLauncher::TerminalLauncher(QObject* parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
TerminalApp
|
||||
TerminalLauncher::getPreferedTerminal()
|
||||
TerminalApp TerminalLauncher::getPreferedTerminal()
|
||||
{
|
||||
TerminalApp res;
|
||||
for (const TerminalApp& app : terminalApps) {
|
||||
QString path = QStandardPaths::findExecutable(app.name);
|
||||
if (!path.isEmpty()) {
|
||||
res = app;
|
||||
break;
|
||||
TerminalApp res;
|
||||
for (const TerminalApp& app : terminalApps) {
|
||||
QString path = QStandardPaths::findExecutable(app.name);
|
||||
if (!path.isEmpty()) {
|
||||
res = app;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
TerminalLauncher::launchDetached(const QString& command)
|
||||
bool TerminalLauncher::launchDetached(const QString& command)
|
||||
{
|
||||
TerminalApp app = getPreferedTerminal();
|
||||
QString s = app.name + " " + app.arg + " " + command;
|
||||
return QProcess::startDetached(app.name, { app.arg, command });
|
||||
TerminalApp app = getPreferedTerminal();
|
||||
QString s = app.name + " " + app.arg + " " + command;
|
||||
return QProcess::startDetached(app.name, { app.arg, command });
|
||||
}
|
||||
|
||||
@@ -21,18 +21,18 @@
|
||||
|
||||
struct TerminalApp
|
||||
{
|
||||
QString name;
|
||||
QString arg;
|
||||
QString name;
|
||||
QString arg;
|
||||
};
|
||||
|
||||
class TerminalLauncher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TerminalLauncher(QObject* parent = nullptr);
|
||||
explicit TerminalLauncher(QObject* parent = nullptr);
|
||||
|
||||
static bool launchDetached(const QString& command);
|
||||
static bool launchDetached(const QString& command);
|
||||
|
||||
private:
|
||||
static TerminalApp getPreferedTerminal();
|
||||
static TerminalApp getPreferedTerminal();
|
||||
};
|
||||
|
||||
@@ -27,68 +27,62 @@ namespace {
|
||||
LineTool::LineTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
LineTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon LineTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "line.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "line.svg");
|
||||
}
|
||||
QString
|
||||
LineTool::name() const
|
||||
QString LineTool::name() const
|
||||
{
|
||||
return tr("Line");
|
||||
return tr("Line");
|
||||
}
|
||||
|
||||
ToolType
|
||||
LineTool::nameID() const
|
||||
ToolType LineTool::nameID() const
|
||||
{
|
||||
return ToolType::LINE;
|
||||
return ToolType::LINE;
|
||||
}
|
||||
|
||||
QString
|
||||
LineTool::description() const
|
||||
QString LineTool::description() const
|
||||
{
|
||||
return tr("Set the Line as the paint tool");
|
||||
return tr("Set the Line as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
LineTool::copy(QObject* parent)
|
||||
CaptureTool* LineTool::copy(QObject* parent)
|
||||
{
|
||||
return new LineTool(parent);
|
||||
return new LineTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
LineTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void LineTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(m_points.first, m_points.second);
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(m_points.first, m_points.second);
|
||||
}
|
||||
|
||||
void
|
||||
LineTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void LineTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
LineTool::drawStart(const CaptureContext& context)
|
||||
void LineTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
LineTool::pressed(const CaptureContext& context)
|
||||
void LineTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
|
||||
class LineTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LineTool(QObject* parent = nullptr);
|
||||
explicit LineTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -27,78 +27,71 @@ namespace {
|
||||
MarkerTool::MarkerTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
MarkerTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon MarkerTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "marker.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "marker.svg");
|
||||
}
|
||||
QString
|
||||
MarkerTool::name() const
|
||||
QString MarkerTool::name() const
|
||||
{
|
||||
return tr("Marker");
|
||||
return tr("Marker");
|
||||
}
|
||||
|
||||
ToolType
|
||||
MarkerTool::nameID() const
|
||||
ToolType MarkerTool::nameID() const
|
||||
{
|
||||
return ToolType::MARKER;
|
||||
return ToolType::MARKER;
|
||||
}
|
||||
|
||||
QString
|
||||
MarkerTool::description() const
|
||||
QString MarkerTool::description() const
|
||||
{
|
||||
return tr("Set the Marker as the paint tool");
|
||||
return tr("Set the Marker as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
MarkerTool::copy(QObject* parent)
|
||||
CaptureTool* MarkerTool::copy(QObject* parent)
|
||||
{
|
||||
return new MarkerTool(parent);
|
||||
return new MarkerTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void MarkerTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(m_points.first, m_points.second);
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawLine(m_points.first, m_points.second);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void MarkerTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerTool::drawStart(const CaptureContext& context)
|
||||
void MarkerTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
MarkerTool::pressed(const CaptureContext& context)
|
||||
void MarkerTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
MarkerTool::thicknessChanged(const int th)
|
||||
void MarkerTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_thickness = th + PADDING_VALUE;
|
||||
m_thickness = th + PADDING_VALUE;
|
||||
}
|
||||
|
||||
@@ -21,26 +21,26 @@
|
||||
|
||||
class MarkerTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MarkerTool(QObject* parent = nullptr);
|
||||
explicit MarkerTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void thicknessChanged(const int th) override;
|
||||
};
|
||||
|
||||
@@ -22,45 +22,38 @@ MoveTool::MoveTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
MoveTool::closeOnButtonPressed() const
|
||||
bool MoveTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon
|
||||
MoveTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon MoveTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cursor-move.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cursor-move.svg");
|
||||
}
|
||||
QString
|
||||
MoveTool::name() const
|
||||
QString MoveTool::name() const
|
||||
{
|
||||
return tr("Move");
|
||||
return tr("Move");
|
||||
}
|
||||
|
||||
ToolType
|
||||
MoveTool::nameID() const
|
||||
ToolType MoveTool::nameID() const
|
||||
{
|
||||
return ToolType::MOVE;
|
||||
return ToolType::MOVE;
|
||||
}
|
||||
|
||||
QString
|
||||
MoveTool::description() const
|
||||
QString MoveTool::description() const
|
||||
{
|
||||
return tr("Move the selection area");
|
||||
return tr("Move the selection area");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
MoveTool::copy(QObject* parent)
|
||||
CaptureTool* MoveTool::copy(QObject* parent)
|
||||
{
|
||||
return new MoveTool(parent);
|
||||
return new MoveTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
MoveTool::pressed(const CaptureContext& context)
|
||||
void MoveTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_MOVE_MODE);
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_MOVE_MODE);
|
||||
}
|
||||
|
||||
@@ -21,19 +21,19 @@
|
||||
|
||||
class MoveTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
ToolType nameID() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
ToolType nameID() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -22,65 +22,59 @@ PencilTool::PencilTool(QObject* parent)
|
||||
: AbstractPathTool(parent)
|
||||
{}
|
||||
|
||||
QIcon
|
||||
PencilTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon PencilTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pencil.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pencil.svg");
|
||||
}
|
||||
QString
|
||||
PencilTool::name() const
|
||||
QString PencilTool::name() const
|
||||
{
|
||||
return tr("Pencil");
|
||||
return tr("Pencil");
|
||||
}
|
||||
|
||||
ToolType
|
||||
PencilTool::nameID() const
|
||||
ToolType PencilTool::nameID() const
|
||||
{
|
||||
return ToolType::PENCIL;
|
||||
return ToolType::PENCIL;
|
||||
}
|
||||
|
||||
QString
|
||||
PencilTool::description() const
|
||||
QString PencilTool::description() const
|
||||
{
|
||||
return tr("Set the Pencil as the paint tool");
|
||||
return tr("Set the Pencil as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
PencilTool::copy(QObject* parent)
|
||||
CaptureTool* PencilTool::copy(QObject* parent)
|
||||
{
|
||||
return new PencilTool(parent);
|
||||
return new PencilTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
PencilTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void PencilTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawPolyline(m_points.data(), m_points.size());
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawPolyline(m_points.data(), m_points.size());
|
||||
}
|
||||
|
||||
void
|
||||
PencilTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void PencilTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, context.thickness + 2));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, context.thickness + 2));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
PencilTool::drawStart(const CaptureContext& context)
|
||||
void PencilTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + 2;
|
||||
m_points.append(context.mousePos);
|
||||
m_backupArea.setTopLeft(context.mousePos);
|
||||
m_backupArea.setBottomRight(context.mousePos);
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + 2;
|
||||
m_points.append(context.mousePos);
|
||||
m_backupArea.setTopLeft(context.mousePos);
|
||||
m_backupArea.setBottomRight(context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
PencilTool::pressed(const CaptureContext& context)
|
||||
void PencilTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,26 +21,26 @@
|
||||
|
||||
class PencilTool : public AbstractPathTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PencilTool(QObject* parent = nullptr);
|
||||
explicit PencilTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -22,58 +22,50 @@ PinTool::PinTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
PinTool::closeOnButtonPressed() const
|
||||
bool PinTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
PinTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon PinTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pin.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pin.svg");
|
||||
}
|
||||
QString
|
||||
PinTool::name() const
|
||||
QString PinTool::name() const
|
||||
{
|
||||
return tr("Pin Tool");
|
||||
return tr("Pin Tool");
|
||||
}
|
||||
|
||||
ToolType
|
||||
PinTool::nameID() const
|
||||
ToolType PinTool::nameID() const
|
||||
{
|
||||
return ToolType::PIN;
|
||||
return ToolType::PIN;
|
||||
}
|
||||
|
||||
QString
|
||||
PinTool::description() const
|
||||
QString PinTool::description() const
|
||||
{
|
||||
return tr("Pin image on the desktop");
|
||||
return tr("Pin image on the desktop");
|
||||
}
|
||||
|
||||
QWidget*
|
||||
PinTool::widget()
|
||||
QWidget* PinTool::widget()
|
||||
{
|
||||
PinWidget* w = new PinWidget(m_pixmap);
|
||||
const int&& m = w->margin();
|
||||
QRect adjusted_pos = m_geometry + QMargins(m, m, m, m);
|
||||
w->setGeometry(adjusted_pos);
|
||||
return w;
|
||||
PinWidget* w = new PinWidget(m_pixmap);
|
||||
const int&& m = w->margin();
|
||||
QRect adjusted_pos = m_geometry + QMargins(m, m, m, m);
|
||||
w->setGeometry(adjusted_pos);
|
||||
return w;
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
PinTool::copy(QObject* parent)
|
||||
CaptureTool* PinTool::copy(QObject* parent)
|
||||
{
|
||||
return new PinTool(parent);
|
||||
return new PinTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
PinTool::pressed(const CaptureContext& context)
|
||||
void PinTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
m_geometry = context.selection;
|
||||
m_geometry.setTopLeft(m_geometry.topLeft() + context.widgetOffset);
|
||||
m_pixmap = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
m_geometry = context.selection;
|
||||
m_geometry.setTopLeft(m_geometry.topLeft() + context.widgetOffset);
|
||||
m_pixmap = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
}
|
||||
|
||||
@@ -21,27 +21,27 @@
|
||||
|
||||
class PinTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() 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:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
|
||||
private:
|
||||
QRect m_geometry;
|
||||
QPixmap m_pixmap;
|
||||
QRect m_geometry;
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
@@ -27,93 +27,85 @@ PinWidget::PinWidget(const QPixmap& pixmap, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_pixmap(pixmap)
|
||||
{
|
||||
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
||||
// set the bottom widget background transparent
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
||||
// set the bottom widget background transparent
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
ConfigHandler conf;
|
||||
m_baseColor = conf.uiMainColorValue();
|
||||
m_hoverColor = conf.uiContrastColorValue();
|
||||
ConfigHandler conf;
|
||||
m_baseColor = conf.uiMainColorValue();
|
||||
m_hoverColor = conf.uiContrastColorValue();
|
||||
|
||||
m_layout = new QVBoxLayout(this);
|
||||
const int margin = this->margin();
|
||||
m_layout->setContentsMargins(margin, margin, margin, margin);
|
||||
m_layout = new QVBoxLayout(this);
|
||||
const int margin = this->margin();
|
||||
m_layout->setContentsMargins(margin, margin, margin, margin);
|
||||
|
||||
m_shadowEffect = new QGraphicsDropShadowEffect(this);
|
||||
m_shadowEffect->setColor(m_baseColor);
|
||||
m_shadowEffect->setBlurRadius(2 * margin);
|
||||
m_shadowEffect->setOffset(0, 0);
|
||||
setGraphicsEffect(m_shadowEffect);
|
||||
m_shadowEffect = new QGraphicsDropShadowEffect(this);
|
||||
m_shadowEffect->setColor(m_baseColor);
|
||||
m_shadowEffect->setBlurRadius(2 * margin);
|
||||
m_shadowEffect->setOffset(0, 0);
|
||||
setGraphicsEffect(m_shadowEffect);
|
||||
|
||||
m_label = new QLabel();
|
||||
m_label->setPixmap(m_pixmap);
|
||||
m_layout->addWidget(m_label);
|
||||
m_label = new QLabel();
|
||||
m_label->setPixmap(m_pixmap);
|
||||
m_layout->addWidget(m_label);
|
||||
|
||||
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this, SLOT(close()));
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
}
|
||||
|
||||
int
|
||||
PinWidget::margin() const
|
||||
int PinWidget::margin() const
|
||||
{
|
||||
return 7;
|
||||
return 7;
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::wheelEvent(QWheelEvent* e)
|
||||
void PinWidget::wheelEvent(QWheelEvent* e)
|
||||
{
|
||||
int val = e->angleDelta().y() > 0 ? 15 : -15;
|
||||
int newWidth = qBound(50, m_label->width() + val, maximumWidth());
|
||||
int newHeight = qBound(50, m_label->height() + val, maximumHeight());
|
||||
int val = e->angleDelta().y() > 0 ? 15 : -15;
|
||||
int newWidth = qBound(50, m_label->width() + val, maximumWidth());
|
||||
int newHeight = qBound(50, m_label->height() + val, maximumHeight());
|
||||
|
||||
QSize size(newWidth, newHeight);
|
||||
setScaledPixmap(size);
|
||||
adjustSize();
|
||||
QSize size(newWidth, newHeight);
|
||||
setScaledPixmap(size);
|
||||
adjustSize();
|
||||
|
||||
e->accept();
|
||||
e->accept();
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::enterEvent(QEvent*)
|
||||
void PinWidget::enterEvent(QEvent*)
|
||||
{
|
||||
m_shadowEffect->setColor(m_hoverColor);
|
||||
m_shadowEffect->setColor(m_hoverColor);
|
||||
}
|
||||
void
|
||||
PinWidget::leaveEvent(QEvent*)
|
||||
void PinWidget::leaveEvent(QEvent*)
|
||||
{
|
||||
m_shadowEffect->setColor(m_baseColor);
|
||||
m_shadowEffect->setColor(m_baseColor);
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::mouseDoubleClickEvent(QMouseEvent*)
|
||||
void PinWidget::mouseDoubleClickEvent(QMouseEvent*)
|
||||
{
|
||||
close();
|
||||
close();
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::mousePressEvent(QMouseEvent* e)
|
||||
void PinWidget::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
m_dragStart = e->globalPos();
|
||||
m_offsetX = e->localPos().x() / width();
|
||||
m_offsetY = e->localPos().y() / height();
|
||||
m_dragStart = e->globalPos();
|
||||
m_offsetX = e->localPos().x() / width();
|
||||
m_offsetY = e->localPos().y() / height();
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::mouseMoveEvent(QMouseEvent* e)
|
||||
void PinWidget::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
const QPoint delta = e->globalPos() - m_dragStart;
|
||||
int offsetW = width() * m_offsetX;
|
||||
int offsetH = height() * m_offsetY;
|
||||
move(m_dragStart.x() + delta.x() - offsetW,
|
||||
m_dragStart.y() + delta.y() - offsetH);
|
||||
const QPoint delta = e->globalPos() - m_dragStart;
|
||||
int offsetW = width() * m_offsetX;
|
||||
int offsetH = height() * m_offsetY;
|
||||
move(m_dragStart.x() + delta.x() - offsetW,
|
||||
m_dragStart.y() + delta.y() - offsetH);
|
||||
}
|
||||
|
||||
void
|
||||
PinWidget::setScaledPixmap(const QSize& size)
|
||||
void PinWidget::setScaledPixmap(const QSize& size)
|
||||
{
|
||||
const qreal scale = qApp->devicePixelRatio();
|
||||
QPixmap scaledPixmap = m_pixmap.scaled(
|
||||
size * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
scaledPixmap.setDevicePixelRatio(scale);
|
||||
m_label->setPixmap(scaledPixmap);
|
||||
const qreal scale = qApp->devicePixelRatio();
|
||||
QPixmap scaledPixmap = m_pixmap.scaled(
|
||||
size * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
scaledPixmap.setDevicePixelRatio(scale);
|
||||
m_label->setPixmap(scaledPixmap);
|
||||
}
|
||||
|
||||
@@ -25,28 +25,28 @@ class QLabel;
|
||||
|
||||
class PinWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PinWidget(const QPixmap& pixmap, QWidget* parent = nullptr);
|
||||
explicit PinWidget(const QPixmap& pixmap, QWidget* parent = nullptr);
|
||||
|
||||
int margin() const;
|
||||
int margin() const;
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent* e);
|
||||
void mouseDoubleClickEvent(QMouseEvent*);
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseMoveEvent(QMouseEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
void wheelEvent(QWheelEvent* e);
|
||||
void mouseDoubleClickEvent(QMouseEvent*);
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseMoveEvent(QMouseEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
|
||||
private:
|
||||
void setScaledPixmap(const QSize& size);
|
||||
void setScaledPixmap(const QSize& size);
|
||||
|
||||
QPixmap m_pixmap;
|
||||
QVBoxLayout* m_layout;
|
||||
QLabel* m_label;
|
||||
QPoint m_dragStart;
|
||||
qreal m_offsetX, m_offsetY;
|
||||
QGraphicsDropShadowEffect* m_shadowEffect;
|
||||
QColor m_baseColor, m_hoverColor;
|
||||
QPixmap m_pixmap;
|
||||
QVBoxLayout* m_layout;
|
||||
QLabel* m_label;
|
||||
QPoint m_dragStart;
|
||||
qreal m_offsetX, m_offsetY;
|
||||
QGraphicsDropShadowEffect* m_shadowEffect;
|
||||
QColor m_baseColor, m_hoverColor;
|
||||
};
|
||||
|
||||
@@ -28,95 +28,88 @@ PixelateTool::PixelateTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{}
|
||||
|
||||
QIcon
|
||||
PixelateTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon PixelateTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pixelate.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pixelate.svg");
|
||||
}
|
||||
QString
|
||||
PixelateTool::name() const
|
||||
QString PixelateTool::name() const
|
||||
{
|
||||
return tr("Pixelate");
|
||||
return tr("Pixelate");
|
||||
}
|
||||
|
||||
ToolType
|
||||
PixelateTool::nameID() const
|
||||
ToolType PixelateTool::nameID() const
|
||||
{
|
||||
return ToolType::PIXELATE;
|
||||
return ToolType::PIXELATE;
|
||||
}
|
||||
|
||||
QString
|
||||
PixelateTool::description() const
|
||||
QString PixelateTool::description() const
|
||||
{
|
||||
return tr("Set Pixelate as the paint tool");
|
||||
return tr("Set Pixelate as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
PixelateTool::copy(QObject* parent)
|
||||
CaptureTool* PixelateTool::copy(QObject* parent)
|
||||
{
|
||||
return new PixelateTool(parent);
|
||||
return new PixelateTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
PixelateTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void PixelateTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
|
||||
QPoint& p0 = m_points.first;
|
||||
QPoint& p1 = m_points.second;
|
||||
QRect selection = QRect(p0, p1).normalized();
|
||||
QPoint& p0 = m_points.first;
|
||||
QPoint& p1 = m_points.second;
|
||||
QRect selection = QRect(p0, p1).normalized();
|
||||
|
||||
// If thickness is less than 1, use old blur process
|
||||
if (m_thickness <= 1) {
|
||||
auto pixelRatio = pixmap.devicePixelRatio();
|
||||
// If thickness is less than 1, use old blur process
|
||||
if (m_thickness <= 1) {
|
||||
auto pixelRatio = pixmap.devicePixelRatio();
|
||||
|
||||
QRect selectionScaled =
|
||||
QRect(p0 * pixelRatio, p1 * pixelRatio).normalized();
|
||||
QRect selectionScaled =
|
||||
QRect(p0 * pixelRatio, p1 * pixelRatio).normalized();
|
||||
|
||||
QGraphicsBlurEffect* blur = new QGraphicsBlurEffect;
|
||||
blur->setBlurRadius(10);
|
||||
QGraphicsPixmapItem* item =
|
||||
new QGraphicsPixmapItem(pixmap.copy(selectionScaled));
|
||||
item->setGraphicsEffect(blur);
|
||||
QGraphicsBlurEffect* blur = new QGraphicsBlurEffect;
|
||||
blur->setBlurRadius(10);
|
||||
QGraphicsPixmapItem* item =
|
||||
new QGraphicsPixmapItem(pixmap.copy(selectionScaled));
|
||||
item->setGraphicsEffect(blur);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.addItem(item);
|
||||
QGraphicsScene scene;
|
||||
scene.addItem(item);
|
||||
|
||||
scene.render(&painter, selection, QRectF());
|
||||
blur->setBlurRadius(12);
|
||||
scene.render(&painter, selection, QRectF());
|
||||
} else {
|
||||
int width = selection.width() * (0.5 / qMax(1, m_thickness));
|
||||
scene.render(&painter, selection, QRectF());
|
||||
blur->setBlurRadius(12);
|
||||
scene.render(&painter, selection, QRectF());
|
||||
} else {
|
||||
int width = selection.width() * (0.5 / qMax(1, m_thickness));
|
||||
|
||||
QPixmap t = pixmap.copy(selection);
|
||||
t = t.scaledToWidth(qMax(width, 10), Qt::SmoothTransformation);
|
||||
t = t.scaledToWidth(selection.width());
|
||||
painter.drawImage(selection, t.toImage());
|
||||
}
|
||||
QPixmap t = pixmap.copy(selection);
|
||||
t = t.scaledToWidth(qMax(width, 10), Qt::SmoothTransformation);
|
||||
t = t.scaledToWidth(selection.width());
|
||||
painter.drawImage(selection, t.toImage());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PixelateTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
void PixelateTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(painter);
|
||||
}
|
||||
|
||||
void
|
||||
PixelateTool::drawStart(const CaptureContext& context)
|
||||
void PixelateTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_thickness = context.thickness;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_thickness = context.thickness;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
PixelateTool::pressed(const CaptureContext& context)
|
||||
void PixelateTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
|
||||
class PixelateTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PixelateTool(QObject* parent = nullptr);
|
||||
explicit PixelateTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -25,71 +25,62 @@ namespace {
|
||||
RectangleTool::RectangleTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
RectangleTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon RectangleTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "square.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "square.svg");
|
||||
}
|
||||
QString
|
||||
RectangleTool::name() const
|
||||
QString RectangleTool::name() const
|
||||
{
|
||||
return tr("Rectangle");
|
||||
return tr("Rectangle");
|
||||
}
|
||||
|
||||
ToolType
|
||||
RectangleTool::nameID() const
|
||||
ToolType RectangleTool::nameID() const
|
||||
{
|
||||
return ToolType::RECTANGLE;
|
||||
return ToolType::RECTANGLE;
|
||||
}
|
||||
|
||||
QString
|
||||
RectangleTool::description() const
|
||||
QString RectangleTool::description() const
|
||||
{
|
||||
return tr("Set the Rectangle as the paint tool");
|
||||
return tr("Set the Rectangle as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
RectangleTool::copy(QObject* parent)
|
||||
CaptureTool* RectangleTool::copy(QObject* parent)
|
||||
{
|
||||
return new RectangleTool(parent);
|
||||
return new RectangleTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
RectangleTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
void RectangleTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.setBrush(QBrush(m_color));
|
||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.setBrush(QBrush(m_color));
|
||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||
}
|
||||
|
||||
void
|
||||
RectangleTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
void RectangleTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
RectangleTool::drawStart(const CaptureContext& context)
|
||||
void RectangleTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
RectangleTool::pressed(const CaptureContext& context)
|
||||
void RectangleTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,25 +21,25 @@
|
||||
|
||||
class RectangleTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RectangleTool(QObject* parent = nullptr);
|
||||
explicit RectangleTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -22,45 +22,38 @@ RedoTool::RedoTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
RedoTool::closeOnButtonPressed() const
|
||||
bool RedoTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon
|
||||
RedoTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon RedoTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "redo-variant.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "redo-variant.svg");
|
||||
}
|
||||
QString
|
||||
RedoTool::name() const
|
||||
QString RedoTool::name() const
|
||||
{
|
||||
return tr("Redo");
|
||||
return tr("Redo");
|
||||
}
|
||||
|
||||
ToolType
|
||||
RedoTool::nameID() const
|
||||
ToolType RedoTool::nameID() const
|
||||
{
|
||||
return ToolType::REDO;
|
||||
return ToolType::REDO;
|
||||
}
|
||||
|
||||
QString
|
||||
RedoTool::description() const
|
||||
QString RedoTool::description() const
|
||||
{
|
||||
return tr("Redo the next modification");
|
||||
return tr("Redo the next modification");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
RedoTool::copy(QObject* parent)
|
||||
CaptureTool* RedoTool::copy(QObject* parent)
|
||||
{
|
||||
return new RedoTool(parent);
|
||||
return new RedoTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
RedoTool::pressed(const CaptureContext& context)
|
||||
void RedoTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_REDO_MODIFICATION);
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_REDO_MODIFICATION);
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
|
||||
class RedoTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -23,57 +23,50 @@ SaveTool::SaveTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
SaveTool::closeOnButtonPressed() const
|
||||
bool SaveTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon
|
||||
SaveTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon SaveTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-save.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-save.svg");
|
||||
}
|
||||
QString
|
||||
SaveTool::name() const
|
||||
QString SaveTool::name() const
|
||||
{
|
||||
return tr("Save");
|
||||
return tr("Save");
|
||||
}
|
||||
|
||||
ToolType
|
||||
SaveTool::nameID() const
|
||||
ToolType SaveTool::nameID() const
|
||||
{
|
||||
return ToolType::SAVE;
|
||||
return ToolType::SAVE;
|
||||
}
|
||||
|
||||
QString
|
||||
SaveTool::description() const
|
||||
QString SaveTool::description() const
|
||||
{
|
||||
return tr("Save the capture");
|
||||
return tr("Save the capture");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
SaveTool::copy(QObject* parent)
|
||||
CaptureTool* SaveTool::copy(QObject* parent)
|
||||
{
|
||||
return new SaveTool(parent);
|
||||
return new SaveTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
SaveTool::pressed(const CaptureContext& context)
|
||||
void SaveTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
if (context.savePath.isEmpty()) {
|
||||
emit requestAction(REQ_HIDE_GUI);
|
||||
bool ok =
|
||||
ScreenshotSaver().saveToFilesystemGUI(context.selectedScreenshotArea());
|
||||
if (ok) {
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
if (context.savePath.isEmpty()) {
|
||||
emit requestAction(REQ_HIDE_GUI);
|
||||
bool ok = ScreenshotSaver().saveToFilesystemGUI(
|
||||
context.selectedScreenshotArea());
|
||||
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);
|
||||
}
|
||||
}
|
||||
} 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
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -25,76 +25,66 @@ namespace {
|
||||
SelectionTool::SelectionTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsDiagonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
bool
|
||||
SelectionTool::closeOnButtonPressed() const
|
||||
bool SelectionTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon
|
||||
SelectionTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon SelectionTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "square-outline.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "square-outline.svg");
|
||||
}
|
||||
QString
|
||||
SelectionTool::name() const
|
||||
QString SelectionTool::name() const
|
||||
{
|
||||
return tr("Rectangular Selection");
|
||||
return tr("Rectangular Selection");
|
||||
}
|
||||
|
||||
ToolType
|
||||
SelectionTool::nameID() const
|
||||
ToolType SelectionTool::nameID() const
|
||||
{
|
||||
return ToolType::SELECTION;
|
||||
return ToolType::SELECTION;
|
||||
}
|
||||
|
||||
QString
|
||||
SelectionTool::description() const
|
||||
QString SelectionTool::description() const
|
||||
{
|
||||
return tr("Set Selection as the paint tool");
|
||||
return tr("Set Selection as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
SelectionTool::copy(QObject* parent)
|
||||
CaptureTool* SelectionTool::copy(QObject* parent)
|
||||
{
|
||||
return new SelectionTool(parent);
|
||||
return new SelectionTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
SelectionTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
void SelectionTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setPen(QPen(m_color, m_thickness));
|
||||
painter.drawRect(QRect(m_points.first, m_points.second));
|
||||
}
|
||||
|
||||
void
|
||||
SelectionTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
void SelectionTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void
|
||||
SelectionTool::drawStart(const CaptureContext& context)
|
||||
void SelectionTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void
|
||||
SelectionTool::pressed(const CaptureContext& context)
|
||||
void SelectionTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,27 +21,27 @@
|
||||
|
||||
class SelectionTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
void process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo = false) override;
|
||||
void paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void drawStart(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -22,44 +22,37 @@ SizeIndicatorTool::SizeIndicatorTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
SizeIndicatorTool::closeOnButtonPressed() const
|
||||
bool SizeIndicatorTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon
|
||||
SizeIndicatorTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon SizeIndicatorTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
return inEditor ? QIcon()
|
||||
: QIcon(iconPath(background) + "size_indicator.svg");
|
||||
return inEditor ? QIcon()
|
||||
: QIcon(iconPath(background) + "size_indicator.svg");
|
||||
}
|
||||
QString
|
||||
SizeIndicatorTool::name() const
|
||||
QString SizeIndicatorTool::name() const
|
||||
{
|
||||
return tr("Selection Size Indicator");
|
||||
return tr("Selection Size Indicator");
|
||||
}
|
||||
|
||||
ToolType
|
||||
SizeIndicatorTool::nameID() const
|
||||
ToolType SizeIndicatorTool::nameID() const
|
||||
{
|
||||
return ToolType::SIZEINDICATOR;
|
||||
return ToolType::SIZEINDICATOR;
|
||||
}
|
||||
|
||||
QString
|
||||
SizeIndicatorTool::description() const
|
||||
QString SizeIndicatorTool::description() const
|
||||
{
|
||||
return tr("Show the dimensions of the selection (X Y)");
|
||||
return tr("Show the dimensions of the selection (X Y)");
|
||||
}
|
||||
|
||||
CaptureTool*
|
||||
SizeIndicatorTool::copy(QObject* parent)
|
||||
CaptureTool* SizeIndicatorTool::copy(QObject* parent)
|
||||
{
|
||||
return new SizeIndicatorTool(parent);
|
||||
return new SizeIndicatorTool(parent);
|
||||
}
|
||||
|
||||
void
|
||||
SizeIndicatorTool::pressed(const CaptureContext& context)
|
||||
void SizeIndicatorTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
|
||||
class SizeIndicatorTool : public AbstractActionTool
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
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;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
QString description() const override;
|
||||
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
CaptureTool* copy(QObject* parent = nullptr) override;
|
||||
|
||||
protected:
|
||||
ToolType nameID() const override;
|
||||
ToolType nameID() const override;
|
||||
|
||||
public slots:
|
||||
void pressed(const CaptureContext& context) override;
|
||||
void pressed(const CaptureContext& context) override;
|
||||
};
|
||||
|
||||
@@ -27,98 +27,93 @@
|
||||
TextConfig::TextConfig(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout = new QVBoxLayout(this);
|
||||
|
||||
QFontDatabase fontDB;
|
||||
QComboBox* fontsCB = new QComboBox();
|
||||
connect(fontsCB,
|
||||
&QComboBox::currentTextChanged,
|
||||
this,
|
||||
&TextConfig::fontFamilyChanged);
|
||||
fontsCB->addItems(fontDB.families());
|
||||
// TODO save family in config
|
||||
int index = fontsCB->findText(font().family());
|
||||
fontsCB->setCurrentIndex(index);
|
||||
QFontDatabase fontDB;
|
||||
QComboBox* fontsCB = new QComboBox();
|
||||
connect(fontsCB,
|
||||
&QComboBox::currentTextChanged,
|
||||
this,
|
||||
&TextConfig::fontFamilyChanged);
|
||||
fontsCB->addItems(fontDB.families());
|
||||
// TODO save family in config
|
||||
int index = fontsCB->findText(font().family());
|
||||
fontsCB->setCurrentIndex(index);
|
||||
|
||||
QString iconPrefix = ColorUtils::colorIsDark(palette().windowText().color())
|
||||
? PathInfo::blackIconPath()
|
||||
: PathInfo::whiteIconPath();
|
||||
QString iconPrefix = ColorUtils::colorIsDark(palette().windowText().color())
|
||||
? PathInfo::blackIconPath()
|
||||
: PathInfo::whiteIconPath();
|
||||
|
||||
m_strikeOutButton = new QPushButton(
|
||||
QIcon(iconPrefix + "format_strikethrough.svg"), QLatin1String(""));
|
||||
m_strikeOutButton->setCheckable(true);
|
||||
connect(m_strikeOutButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontStrikeOutChanged);
|
||||
m_strikeOutButton->setToolTip(tr("StrikeOut"));
|
||||
m_strikeOutButton = new QPushButton(
|
||||
QIcon(iconPrefix + "format_strikethrough.svg"), QLatin1String(""));
|
||||
m_strikeOutButton->setCheckable(true);
|
||||
connect(m_strikeOutButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontStrikeOutChanged);
|
||||
m_strikeOutButton->setToolTip(tr("StrikeOut"));
|
||||
|
||||
m_underlineButton = new QPushButton(
|
||||
QIcon(iconPrefix + "format_underlined.svg"), QLatin1String(""));
|
||||
m_underlineButton->setCheckable(true);
|
||||
connect(m_underlineButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontUnderlineChanged);
|
||||
m_underlineButton->setToolTip(tr("Underline"));
|
||||
m_underlineButton = new QPushButton(
|
||||
QIcon(iconPrefix + "format_underlined.svg"), QLatin1String(""));
|
||||
m_underlineButton->setCheckable(true);
|
||||
connect(m_underlineButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontUnderlineChanged);
|
||||
m_underlineButton->setToolTip(tr("Underline"));
|
||||
|
||||
m_weightButton =
|
||||
new QPushButton(QIcon(iconPrefix + "format_bold.svg"), QLatin1String(""));
|
||||
m_weightButton->setCheckable(true);
|
||||
connect(m_weightButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::weightButtonPressed);
|
||||
m_weightButton->setToolTip(tr("Bold"));
|
||||
m_weightButton =
|
||||
new QPushButton(QIcon(iconPrefix + "format_bold.svg"), QLatin1String(""));
|
||||
m_weightButton->setCheckable(true);
|
||||
connect(m_weightButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::weightButtonPressed);
|
||||
m_weightButton->setToolTip(tr("Bold"));
|
||||
|
||||
m_italicButton =
|
||||
new QPushButton(QIcon(iconPrefix + "format_italic.svg"), QLatin1String(""));
|
||||
m_italicButton->setCheckable(true);
|
||||
connect(m_italicButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontItalicChanged);
|
||||
m_italicButton->setToolTip(tr("Italic"));
|
||||
QHBoxLayout* modifiersLayout = new QHBoxLayout();
|
||||
m_italicButton = new QPushButton(QIcon(iconPrefix + "format_italic.svg"),
|
||||
QLatin1String(""));
|
||||
m_italicButton->setCheckable(true);
|
||||
connect(m_italicButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&TextConfig::fontItalicChanged);
|
||||
m_italicButton->setToolTip(tr("Italic"));
|
||||
QHBoxLayout* modifiersLayout = new QHBoxLayout();
|
||||
|
||||
m_layout->addWidget(fontsCB);
|
||||
modifiersLayout->addWidget(m_strikeOutButton);
|
||||
modifiersLayout->addWidget(m_underlineButton);
|
||||
modifiersLayout->addWidget(m_weightButton);
|
||||
modifiersLayout->addWidget(m_italicButton);
|
||||
m_layout->addLayout(modifiersLayout);
|
||||
m_layout->addWidget(fontsCB);
|
||||
modifiersLayout->addWidget(m_strikeOutButton);
|
||||
modifiersLayout->addWidget(m_underlineButton);
|
||||
modifiersLayout->addWidget(m_weightButton);
|
||||
modifiersLayout->addWidget(m_italicButton);
|
||||
m_layout->addLayout(modifiersLayout);
|
||||
}
|
||||
|
||||
void
|
||||
TextConfig::setUnderline(const bool u)
|
||||
void TextConfig::setUnderline(const bool u)
|
||||
{
|
||||
m_underlineButton->setChecked(u);
|
||||
m_underlineButton->setChecked(u);
|
||||
}
|
||||
|
||||
void
|
||||
TextConfig::setStrikeOut(const bool s)
|
||||
void TextConfig::setStrikeOut(const bool s)
|
||||
{
|
||||
m_strikeOutButton->setChecked(s);
|
||||
m_strikeOutButton->setChecked(s);
|
||||
}
|
||||
|
||||
void
|
||||
TextConfig::setWeight(const int w)
|
||||
void 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
|
||||
TextConfig::setItalic(const bool i)
|
||||
void TextConfig::setItalic(const bool i)
|
||||
{
|
||||
m_italicButton->setChecked(i);
|
||||
m_italicButton->setChecked(i);
|
||||
}
|
||||
|
||||
void
|
||||
TextConfig::weightButtonPressed(const bool w)
|
||||
void TextConfig::weightButtonPressed(const bool w)
|
||||
{
|
||||
if (w) {
|
||||
emit fontWeightChanged(QFont::Bold);
|
||||
} else {
|
||||
emit fontWeightChanged(QFont::Normal);
|
||||
}
|
||||
if (w) {
|
||||
emit fontWeightChanged(QFont::Bold);
|
||||
} else {
|
||||
emit fontWeightChanged(QFont::Normal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,31 +24,31 @@ class QPushButton;
|
||||
|
||||
class TextConfig : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TextConfig(QWidget* parent = nullptr);
|
||||
explicit TextConfig(QWidget* parent = nullptr);
|
||||
|
||||
void setUnderline(const bool u);
|
||||
void setStrikeOut(const bool s);
|
||||
void setWeight(const int w);
|
||||
void setItalic(const bool i);
|
||||
void setUnderline(const bool u);
|
||||
void setStrikeOut(const bool s);
|
||||
void setWeight(const int w);
|
||||
void setItalic(const bool i);
|
||||
|
||||
signals:
|
||||
void fontFamilyChanged(const QString& f);
|
||||
void fontUnderlineChanged(const bool underlined);
|
||||
void fontStrikeOutChanged(const bool dashed);
|
||||
void fontWeightChanged(const QFont::Weight w);
|
||||
void fontItalicChanged(const bool italic);
|
||||
void fontFamilyChanged(const QString& f);
|
||||
void fontUnderlineChanged(const bool underlined);
|
||||
void fontStrikeOutChanged(const bool dashed);
|
||||
void fontWeightChanged(const QFont::Weight w);
|
||||
void fontItalicChanged(const bool italic);
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
void weightButtonPressed(const bool w);
|
||||
void weightButtonPressed(const bool w);
|
||||
|
||||
private:
|
||||
QVBoxLayout* m_layout;
|
||||
QPushButton* m_strikeOutButton;
|
||||
QPushButton* m_underlineButton;
|
||||
QPushButton* m_weightButton;
|
||||
QPushButton* m_italicButton;
|
||||
QVBoxLayout* m_layout;
|
||||
QPushButton* m_strikeOutButton;
|
||||
QPushButton* m_underlineButton;
|
||||
QPushButton* m_weightButton;
|
||||
QPushButton* m_italicButton;
|
||||
};
|
||||
|
||||
@@ -26,246 +26,227 @@ TextTool::TextTool(QObject* parent)
|
||||
, m_size(1)
|
||||
{}
|
||||
|
||||
bool
|
||||
TextTool::isValid() const
|
||||
bool TextTool::isValid() const
|
||||
{
|
||||
return !m_text.isEmpty();
|
||||
return !m_text.isEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
TextTool::closeOnButtonPressed() const
|
||||
bool TextTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TextTool::isSelectable() const
|
||||
bool TextTool::isSelectable() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TextTool::showMousePreview() const
|
||||
bool TextTool::showMousePreview() const
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon
|
||||
TextTool::icon(const QColor& background, bool inEditor) const
|
||||
QIcon TextTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "text.svg");
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "text.svg");
|
||||
}
|
||||
|
||||
QString
|
||||
TextTool::name() const
|
||||
QString TextTool::name() const
|
||||
{
|
||||
return tr("Text");
|
||||
return tr("Text");
|
||||
}
|
||||
|
||||
ToolType
|
||||
TextTool::nameID() const
|
||||
ToolType TextTool::nameID() const
|
||||
{
|
||||
return ToolType::TEXT;
|
||||
return ToolType::TEXT;
|
||||
}
|
||||
|
||||
QString
|
||||
TextTool::description() const
|
||||
QString TextTool::description() const
|
||||
{
|
||||
return tr("Add text to your capture");
|
||||
return tr("Add text to your capture");
|
||||
}
|
||||
|
||||
QWidget*
|
||||
TextTool::widget()
|
||||
QWidget* TextTool::widget()
|
||||
{
|
||||
TextWidget* w = new TextWidget();
|
||||
w->setTextColor(m_color);
|
||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||
w->setFont(m_font);
|
||||
connect(w, &TextWidget::textUpdated, this, &TextTool::updateText);
|
||||
m_widget = w;
|
||||
return w;
|
||||
TextWidget* w = new TextWidget();
|
||||
w->setTextColor(m_color);
|
||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||
w->setFont(m_font);
|
||||
connect(w, &TextWidget::textUpdated, this, &TextTool::updateText);
|
||||
m_widget = w;
|
||||
return w;
|
||||
}
|
||||
|
||||
QWidget*
|
||||
TextTool::configurationWidget()
|
||||
QWidget* TextTool::configurationWidget()
|
||||
{
|
||||
m_confW = new TextConfig();
|
||||
connect(
|
||||
m_confW, &TextConfig::fontFamilyChanged, this, &TextTool::updateFamily);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontItalicChanged, this, &TextTool::updateFontItalic);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontStrikeOutChanged,
|
||||
this,
|
||||
&TextTool::updateFontStrikeOut);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontUnderlineChanged,
|
||||
this,
|
||||
&TextTool::updateFontUnderline);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontWeightChanged, this, &TextTool::updateFontWeight);
|
||||
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;
|
||||
m_confW = new TextConfig();
|
||||
connect(
|
||||
m_confW, &TextConfig::fontFamilyChanged, this, &TextTool::updateFamily);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontItalicChanged,
|
||||
this,
|
||||
&TextTool::updateFontItalic);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontStrikeOutChanged,
|
||||
this,
|
||||
&TextTool::updateFontStrikeOut);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontUnderlineChanged,
|
||||
this,
|
||||
&TextTool::updateFontUnderline);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontWeightChanged,
|
||||
this,
|
||||
&TextTool::updateFontWeight);
|
||||
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*
|
||||
TextTool::copy(QObject* parent)
|
||||
CaptureTool* TextTool::copy(QObject* parent)
|
||||
{
|
||||
TextTool* tt = new TextTool(parent);
|
||||
connect(m_confW, &TextConfig::fontFamilyChanged, tt, &TextTool::updateFamily);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontItalicChanged, tt, &TextTool::updateFontItalic);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontStrikeOutChanged,
|
||||
tt,
|
||||
&TextTool::updateFontStrikeOut);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontUnderlineChanged,
|
||||
tt,
|
||||
&TextTool::updateFontUnderline);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontWeightChanged, tt, &TextTool::updateFontWeight);
|
||||
tt->m_font = m_font;
|
||||
return tt;
|
||||
TextTool* tt = new TextTool(parent);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontFamilyChanged, tt, &TextTool::updateFamily);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontItalicChanged, tt, &TextTool::updateFontItalic);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontStrikeOutChanged,
|
||||
tt,
|
||||
&TextTool::updateFontStrikeOut);
|
||||
connect(m_confW,
|
||||
&TextConfig::fontUnderlineChanged,
|
||||
tt,
|
||||
&TextTool::updateFontUnderline);
|
||||
connect(
|
||||
m_confW, &TextConfig::fontWeightChanged, tt, &TextTool::updateFontWeight);
|
||||
tt->m_font = m_font;
|
||||
return tt;
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::undo(QPixmap& pixmap)
|
||||
void TextTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup);
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
void TextTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (m_text.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFontMetrics fm(m_font);
|
||||
QSize size(fm.boundingRect(QRect(), 0, m_text).size());
|
||||
m_backupArea.setSize(size);
|
||||
if (recordUndo) {
|
||||
m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5));
|
||||
}
|
||||
// draw text
|
||||
painter.setFont(m_font);
|
||||
painter.setPen(m_color);
|
||||
painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text);
|
||||
if (m_text.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFontMetrics fm(m_font);
|
||||
QSize size(fm.boundingRect(QRect(), 0, m_text).size());
|
||||
m_backupArea.setSize(size);
|
||||
if (recordUndo) {
|
||||
m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5));
|
||||
}
|
||||
// draw text
|
||||
painter.setFont(m_font);
|
||||
painter.setPen(m_color);
|
||||
painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
void TextTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::drawEnd(const QPoint& p)
|
||||
void TextTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
m_backupArea.moveTo(p);
|
||||
m_backupArea.moveTo(p);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::drawMove(const QPoint& p)
|
||||
void TextTool::drawMove(const QPoint& p)
|
||||
{
|
||||
m_widget->move(p);
|
||||
m_widget->move(p);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::drawStart(const CaptureContext& context)
|
||||
void TextTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_size = context.thickness;
|
||||
emit requestAction(REQ_ADD_CHILD_WIDGET);
|
||||
m_color = context.color;
|
||||
m_size = context.thickness;
|
||||
emit requestAction(REQ_ADD_CHILD_WIDGET);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::pressed(const CaptureContext& context)
|
||||
void TextTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::colorChanged(const QColor& c)
|
||||
void TextTool::colorChanged(const QColor& c)
|
||||
{
|
||||
m_color = c;
|
||||
if (m_widget) {
|
||||
m_widget->setTextColor(c);
|
||||
}
|
||||
m_color = c;
|
||||
if (m_widget) {
|
||||
m_widget->setTextColor(c);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::thicknessChanged(const int th)
|
||||
void TextTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_size = th;
|
||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_size = th;
|
||||
m_font.setPointSize(m_size + BASE_POINT_SIZE);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateText(const QString& s)
|
||||
void TextTool::updateText(const QString& s)
|
||||
{
|
||||
m_text = s;
|
||||
m_text = s;
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::setFont(const QFont& f)
|
||||
void TextTool::setFont(const QFont& f)
|
||||
{
|
||||
m_font = f;
|
||||
if (m_widget) {
|
||||
m_widget->setFont(f);
|
||||
}
|
||||
m_font = f;
|
||||
if (m_widget) {
|
||||
m_widget->setFont(f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateFamily(const QString& s)
|
||||
void TextTool::updateFamily(const QString& s)
|
||||
{
|
||||
m_font.setFamily(s);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_font.setFamily(s);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateFontUnderline(const bool underlined)
|
||||
void TextTool::updateFontUnderline(const bool underlined)
|
||||
{
|
||||
m_font.setUnderline(underlined);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_font.setUnderline(underlined);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateFontStrikeOut(const bool s)
|
||||
void TextTool::updateFontStrikeOut(const bool s)
|
||||
{
|
||||
m_font.setStrikeOut(s);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_font.setStrikeOut(s);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateFontWeight(const QFont::Weight w)
|
||||
void TextTool::updateFontWeight(const QFont::Weight w)
|
||||
{
|
||||
m_font.setWeight(w);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_font.setWeight(w);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextTool::updateFontItalic(const bool italic)
|
||||
void TextTool::updateFontItalic(const bool italic)
|
||||
{
|
||||
m_font.setItalic(italic);
|
||||
if (m_widget) {
|
||||
m_widget->setFont(m_font);
|
||||
}
|
||||
m_font.setItalic(italic);
|
||||
if (m_widget) {
|
||||
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