mirror of
https://github.com/fergalmoran/flameshot.git
synced 2025-12-22 09:51:06 +00:00
reformatted to Mozilla code style
This commit is contained in:
committed by
borgmanJeremy
parent
c0e2e48db4
commit
c8d15205be
@@ -1,89 +1,2 @@
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: true
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
|
||||
BasedOnStyle: Mozilla
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
90
external/Qt-Color-Widgets/src/color_utils.cpp
vendored
90
external/Qt-Color-Widgets/src/color_utils.cpp
vendored
@@ -24,59 +24,59 @@
|
||||
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
|
||||
|
||||
918
external/Qt-Color-Widgets/src/color_wheel.cpp
vendored
918
external/Qt-Color-Widgets/src/color_wheel.cpp
vendored
File diff suppressed because it is too large
Load Diff
660
external/singleapplication/singleapplication.cpp
vendored
660
external/singleapplication/singleapplication.cpp
vendored
@@ -22,335 +22,351 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QCryptographicHash>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QSemaphore>
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QCryptographicHash>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <lmcons.h>
|
||||
#include <lmcons.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) : q_ptr( q_ptr ) {
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication* q_ptr)
|
||||
: q_ptr(q_ptr)
|
||||
{
|
||||
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() );
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
// 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 );
|
||||
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 {
|
||||
server->setSocketOptions( QLocalServer::WorldAccessOption );
|
||||
appData.addData(
|
||||
QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.join("")
|
||||
.toUtf8());
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QProcess process;
|
||||
process.start(QStringLiteral("whoami"), QStringList{});
|
||||
|
||||
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;
|
||||
if (process.waitForFinished(timeout) &&
|
||||
process.exitCode() == QProcess::NormalExit) {
|
||||
appData.addData(process.readLine());
|
||||
} else {
|
||||
appData.addData(
|
||||
QDir(QStandardPaths::standardLocations(QStandardPaths::HomeLocation)
|
||||
.first())
|
||||
.absolutePath()
|
||||
.toUtf8());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inst->primary = true;
|
||||
inst->primaryPid = q->applicationPid();
|
||||
|
||||
memory->unlock();
|
||||
|
||||
instanceNumber = 0;
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startSecondary()
|
||||
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()
|
||||
{
|
||||
#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()
|
||||
{
|
||||
// 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::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
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::terminate( int signum )
|
||||
{
|
||||
delete ((SingleApplication*)QCoreApplication::instance())->d_ptr;
|
||||
::exit( 128 + signum );
|
||||
}
|
||||
void
|
||||
SingleApplicationPrivate::terminate(int 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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,63 +376,69 @@ void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedS
|
||||
* @param argv
|
||||
* @param {bool} allowSecondaryInstances
|
||||
*/
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout )
|
||||
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
|
||||
SingleApplication::SingleApplication(int& argc,
|
||||
char* argv[],
|
||||
bool allowSecondary,
|
||||
Options options,
|
||||
int timeout)
|
||||
: 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 );
|
||||
// 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();
|
||||
return;
|
||||
} else {
|
||||
// Attempt to attach to the memory segment
|
||||
if( d->memory->attach() ) {
|
||||
d->memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
|
||||
}
|
||||
|
||||
if( ! inst->primary ) {
|
||||
d->startPrimary( false );
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
// 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->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
|
||||
delete d;
|
||||
::exit( EXIT_SUCCESS );
|
||||
d->memory->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
d->connectToPrimary(timeout, SingleApplicationPrivate::NewInstance);
|
||||
delete d;
|
||||
::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,46 +446,52 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
155
external/singleapplication/singleapplication.h
vendored
155
external/singleapplication/singleapplication.h
vendored
@@ -27,7 +27,7 @@
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#ifndef QAPPLICATION_CLASS
|
||||
#define QAPPLICATION_CLASS QCoreApplication
|
||||
#define QAPPLICATION_CLASS QCoreApplication
|
||||
#endif
|
||||
|
||||
#include QT_STRINGIFY(QAPPLICATION_CLASS)
|
||||
@@ -41,93 +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)
|
||||
|
||||
69
external/singleapplication/singleapplication_p.h
vendored
69
external/singleapplication/singleapplication_p.h
vendored
@@ -32,54 +32,57 @@
|
||||
#ifndef SINGLEAPPLICATION_P_H
|
||||
#define SINGLEAPPLICATION_P_H
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include "singleapplication.h"
|
||||
|
||||
struct InstancesInfo {
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
struct InstancesInfo
|
||||
{
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
};
|
||||
|
||||
class SingleApplicationPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
class SingleApplicationPrivate : public QObject
|
||||
{
|
||||
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
|
||||
|
||||
@@ -17,38 +17,46 @@
|
||||
|
||||
#include "commandargument.h"
|
||||
|
||||
CommandArgument::CommandArgument() {
|
||||
CommandArgument::CommandArgument() {}
|
||||
|
||||
}
|
||||
CommandArgument::CommandArgument(const QString& name,
|
||||
const QString& description)
|
||||
: m_name(name)
|
||||
, m_description(description)
|
||||
{}
|
||||
|
||||
CommandArgument::CommandArgument(const QString &name,
|
||||
const QString &description) :
|
||||
m_name(name), m_description(description)
|
||||
void
|
||||
CommandArgument::setName(const QString& name)
|
||||
{
|
||||
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void CommandArgument::setName(const QString &name) {
|
||||
m_name = name;
|
||||
QString
|
||||
CommandArgument::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
QString CommandArgument::name() const {
|
||||
return m_name;
|
||||
void
|
||||
CommandArgument::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
void CommandArgument::setDescription(const QString &description) {
|
||||
m_description = description;
|
||||
QString
|
||||
CommandArgument::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
QString CommandArgument::description() const {
|
||||
return m_description;
|
||||
bool
|
||||
CommandArgument::isRoot() const
|
||||
{
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
}
|
||||
|
||||
bool CommandArgument::isRoot() const {
|
||||
return m_name.isEmpty() && m_description.isEmpty();
|
||||
}
|
||||
|
||||
bool CommandArgument::operator ==(const CommandArgument &arg) const {
|
||||
return m_description == arg.m_description
|
||||
&& m_name == arg.m_name;
|
||||
bool
|
||||
CommandArgument::operator==(const CommandArgument& arg) const
|
||||
{
|
||||
return m_description == arg.m_description && m_name == arg.m_name;
|
||||
}
|
||||
|
||||
@@ -19,22 +19,23 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
class CommandArgument {
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -19,384 +19,405 @@
|
||||
#include <QApplication>
|
||||
#include <QTextStream>
|
||||
|
||||
CommandLineParser::CommandLineParser() :
|
||||
m_description(qApp->applicationName())
|
||||
{
|
||||
|
||||
}
|
||||
CommandLineParser::CommandLineParser()
|
||||
: m_description(qApp->applicationName())
|
||||
{}
|
||||
|
||||
namespace {
|
||||
|
||||
QTextStream out(stdout);
|
||||
QTextStream err(stderr);
|
||||
|
||||
auto versionOption = CommandOption({"v", "version"},
|
||||
QStringLiteral("Displays version information"));
|
||||
auto helpOption = CommandOption({"h", "help"},
|
||||
QStringLiteral("Displays this help"));
|
||||
auto versionOption =
|
||||
CommandOption({ "v", "version" },
|
||||
QStringLiteral("Displays version information"));
|
||||
auto helpOption =
|
||||
CommandOption({ "h", "help" }, QStringLiteral("Displays this help"));
|
||||
|
||||
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());
|
||||
}
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
}
|
||||
dashedOptionList << joinedDashedOptions;
|
||||
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());
|
||||
}
|
||||
// check the length of the arguments
|
||||
for (auto const &arg: arguments) {
|
||||
if(arg.name().length() > size)
|
||||
size = arg.name().length();
|
||||
if (joinedDashedOptions.length() > size) {
|
||||
size = joinedDashedOptions.length();
|
||||
}
|
||||
// generate the text
|
||||
QString result;
|
||||
if(!dashedOptionList.isEmpty()) {
|
||||
result += QLatin1String("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");
|
||||
}
|
||||
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 += QLatin1String("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("Arguments:\n");
|
||||
result += QLatin1String("\n");
|
||||
}
|
||||
for (int i = 0; i < arguments.length(); ++i) {
|
||||
result += QStringLiteral(" %1 %2\n")
|
||||
}
|
||||
if (!arguments.isEmpty()) {
|
||||
result += QLatin1String("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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
arg = isDoubleDashed ? arg.remove(0, 2) : arg.remove(0, 1);
|
||||
// get option
|
||||
auto endIt = actualNode->options.cend();
|
||||
auto optionIt = endIt;
|
||||
for (auto i = actualNode->options.cbegin(); i != endIt; ++i) {
|
||||
if ((*i).names().contains(arg)) {
|
||||
optionIt = i;
|
||||
break;
|
||||
}
|
||||
// check format -x --xx...
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
Node child;
|
||||
child.argument = arg;
|
||||
n->subNodes.append(child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CommandLineParser::AddOption(const CommandOption &option,
|
||||
const CommandArgument &parent)
|
||||
{
|
||||
bool res = true;
|
||||
Node *n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
n->options.append(option);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CommandLineParser::AddOptions(const QList<CommandOption> &options,
|
||||
const CommandArgument &parent)
|
||||
{
|
||||
bool res = true;
|
||||
for (auto const &option: options) {
|
||||
if (!AddOption(option, parent)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void CommandLineParser::setGeneralErrorMessage(const QString &msg) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 (optionIt == endIt) {
|
||||
QString argName = actualNode->argument.name();
|
||||
if (argName.isEmpty()) {
|
||||
argName = qApp->applicationName();
|
||||
argName = qApp->applicationName();
|
||||
}
|
||||
QString argText = node->subNodes.isEmpty() ? "" : "[arguments]";
|
||||
helpText += QStringLiteral("Usage: %1 [%2-options] %3\n\n")
|
||||
.arg(args.join(QStringLiteral(" ")))
|
||||
.arg(argName).arg(argText);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
CommandLineParser::Node* CommandLineParser::recursiveParentSearch(
|
||||
const CommandArgument &parent, Node &node) const
|
||||
{
|
||||
Node * res = nullptr;
|
||||
if (node.argument == parent) {
|
||||
res = &node;
|
||||
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 {
|
||||
for (auto i = node.subNodes.begin(); i != node.subNodes.end(); ++i){
|
||||
res = recursiveParentSearch(parent, *i);
|
||||
if (res != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
out << QStringLiteral("Expected value after the option '%1'.").arg(arg);
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
return res;
|
||||
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::processIfOptionIsHelp(
|
||||
const QStringList &args,
|
||||
QStringList::const_iterator &actualIt,
|
||||
Node * &actualNode)
|
||||
bool
|
||||
CommandLineParser::parse(const QStringList& args)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
Node child;
|
||||
child.argument = arg;
|
||||
n->subNodes.append(child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::AddOption(const CommandOption& option,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
Node* n = findParent(parent);
|
||||
if (n == nullptr) {
|
||||
res = false;
|
||||
} else {
|
||||
n->options.append(option);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandLineParser::AddOptions(const QList<CommandOption>& options,
|
||||
const CommandArgument& parent)
|
||||
{
|
||||
bool res = true;
|
||||
for (auto const& option : options) {
|
||||
if (!AddOption(option, parent)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLineParser::setGeneralErrorMessage(const QString& msg)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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() ? "" : "[arguments]";
|
||||
helpText += QStringLiteral("Usage: %1 [%2-options] %3\n\n")
|
||||
.arg(args.join(QStringLiteral(" ")))
|
||||
.arg(argName)
|
||||
.arg(argText);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
CommandLineParser::Node*
|
||||
CommandLineParser::recursiveParentSearch(const CommandArgument& parent,
|
||||
Node& node) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -21,69 +21,72 @@
|
||||
#include "src/cli/commandoption.h"
|
||||
#include <QMap>
|
||||
|
||||
class CommandLineParser {
|
||||
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,
|
||||
const CommandArgument &parent = CommandArgument());
|
||||
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 {
|
||||
return argument == n.argument &&
|
||||
options == n.options &&
|
||||
subNodes == n.subNodes;
|
||||
}
|
||||
CommandArgument argument;
|
||||
QList<CommandOption> options;
|
||||
QList<Node> subNodes;
|
||||
};
|
||||
struct Node
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -17,96 +17,124 @@
|
||||
|
||||
#include "commandoption.h"
|
||||
|
||||
CommandOption::CommandOption(const QString &name, const QString &description,
|
||||
const QString &valueName,
|
||||
const QString &defaultValue) :
|
||||
m_names(name), m_description(description), m_valueName(valueName),
|
||||
m_value(defaultValue)
|
||||
CommandOption::CommandOption(const QString& name,
|
||||
const QString& description,
|
||||
const QString& valueName,
|
||||
const QString& defaultValue)
|
||||
: m_names(name)
|
||||
, m_description(description)
|
||||
, m_valueName(valueName)
|
||||
, m_value(defaultValue)
|
||||
{
|
||||
m_checker = [](QString const&){ return true; };
|
||||
m_checker = [](QString const&) { return true; };
|
||||
}
|
||||
|
||||
CommandOption::CommandOption(const QStringList &names,
|
||||
const QString &description,
|
||||
const QString &valueName,
|
||||
const QString &defaultValue) :
|
||||
m_names(names), m_description(description), m_valueName(valueName),
|
||||
m_value(defaultValue)
|
||||
CommandOption::CommandOption(const QStringList& names,
|
||||
const QString& description,
|
||||
const QString& valueName,
|
||||
const QString& defaultValue)
|
||||
: m_names(names)
|
||||
, m_description(description)
|
||||
, 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) {
|
||||
m_names = QStringList() << name;
|
||||
}
|
||||
|
||||
void CommandOption::setNames(const QStringList &names) {
|
||||
m_names = names;
|
||||
}
|
||||
|
||||
QStringList CommandOption::names() const {
|
||||
return m_names;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CommandOption::setValueName(const QString &name) {
|
||||
m_valueName = name;
|
||||
}
|
||||
|
||||
QString CommandOption::valueName() const {
|
||||
return m_valueName;
|
||||
}
|
||||
|
||||
void CommandOption::setValue(const QString &value) {
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
QString CommandOption::value() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void CommandOption::addChecker(const function<bool (const QString &)> checker,
|
||||
const QString &errMsg)
|
||||
void
|
||||
CommandOption::setName(const QString& name)
|
||||
{
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
m_names = QStringList() << name;
|
||||
}
|
||||
|
||||
bool CommandOption::checkValue(const QString &value) const {
|
||||
return m_checker(value);
|
||||
}
|
||||
|
||||
QString CommandOption::description() const
|
||||
void
|
||||
CommandOption::setNames(const QStringList& names)
|
||||
{
|
||||
return m_description;
|
||||
m_names = names;
|
||||
}
|
||||
|
||||
void CommandOption::setDescription(const QString &description)
|
||||
QStringList
|
||||
CommandOption::names() const
|
||||
{
|
||||
m_description = description;
|
||||
return m_names;
|
||||
}
|
||||
|
||||
QString CommandOption::errorMsg() const {
|
||||
return m_errorMsg;
|
||||
}
|
||||
|
||||
bool CommandOption::operator ==(const CommandOption &option) const
|
||||
QStringList
|
||||
CommandOption::dashedNames() const
|
||||
{
|
||||
return m_description == option.m_description
|
||||
&& m_names == option.m_names
|
||||
&& m_valueName == option.m_valueName;
|
||||
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)
|
||||
{
|
||||
m_valueName = name;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::valueName() const
|
||||
{
|
||||
return m_valueName;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setValue(const QString& value)
|
||||
{
|
||||
if (m_valueName.isEmpty()) {
|
||||
m_valueName = QLatin1String("value");
|
||||
}
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::addChecker(const function<bool(const QString&)> checker,
|
||||
const QString& errMsg)
|
||||
{
|
||||
m_checker = checker;
|
||||
m_errorMsg = errMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::checkValue(const QString& value) const
|
||||
{
|
||||
return m_checker(value);
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void
|
||||
CommandOption::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
QString
|
||||
CommandOption::errorMsg() const
|
||||
{
|
||||
return m_errorMsg;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandOption::operator==(const CommandOption& option) const
|
||||
{
|
||||
return m_description == option.m_description && m_names == option.m_names &&
|
||||
m_valueName == option.m_valueName;
|
||||
}
|
||||
|
||||
@@ -22,43 +22,47 @@
|
||||
|
||||
using std::function;
|
||||
|
||||
class CommandOption {
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -21,85 +21,97 @@
|
||||
#include <QListWidgetItem>
|
||||
#include <algorithm>
|
||||
|
||||
ButtonListView::ButtonListView(QWidget *parent) : QListWidget(parent) {
|
||||
setMouseTracking(true);
|
||||
setFlow(QListWidget::TopToBottom);
|
||||
initButtonList();
|
||||
updateComponents();
|
||||
connect(this, &QListWidget::itemClicked, this,
|
||||
&ButtonListView::reverseItemCheck);
|
||||
ButtonListView::ButtonListView(QWidget* parent)
|
||||
: QListWidget(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setFlow(QListWidget::TopToBottom);
|
||||
initButtonList();
|
||||
updateComponents();
|
||||
connect(
|
||||
this, &QListWidget::itemClicked, this, &ButtonListView::reverseItemCheck);
|
||||
}
|
||||
|
||||
void ButtonListView::initButtonList() {
|
||||
ToolFactory factory;
|
||||
auto listTypes = CaptureButton::getIterableButtonTypes();
|
||||
void
|
||||
ButtonListView::initButtonList()
|
||||
{
|
||||
ToolFactory factory;
|
||||
auto listTypes = CaptureButton::getIterableButtonTypes();
|
||||
|
||||
for (const CaptureButton::ButtonType t: listTypes) {
|
||||
CaptureTool *tool = factory.CreateTool(t);
|
||||
for (const CaptureButton::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();
|
||||
}
|
||||
m_buttonItem->setText(tool->name());
|
||||
m_buttonItem->setToolTip(tool->description());
|
||||
tool->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonListView::updateActiveButtons(QListWidgetItem *item) {
|
||||
CaptureButton::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 = CaptureButton::ButtonType;
|
||||
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b){
|
||||
return CaptureButton::getPriorityByButton(a) <
|
||||
CaptureButton::getPriorityByButton(b);
|
||||
});
|
||||
void
|
||||
ButtonListView::updateActiveButtons(QListWidgetItem* item)
|
||||
{
|
||||
CaptureButton::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 = CaptureButton::ButtonType;
|
||||
std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) {
|
||||
return CaptureButton::getPriorityByButton(a) <
|
||||
CaptureButton::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 = CaptureButton::getIterableButtonTypes();
|
||||
for (int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
auto elem = static_cast<CaptureButton::ButtonType>(listTypes.at(i));
|
||||
if (m_listButtons.contains(elem)) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
} 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 = CaptureButton::getIterableButtonTypes();
|
||||
for(int i = 0; i < this->count(); ++i) {
|
||||
QListWidgetItem* item = this->item(i);
|
||||
auto elem = static_cast<CaptureButton::ButtonType>(listTypes.at(i));
|
||||
if (m_listButtons.contains(elem)) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,23 +20,24 @@
|
||||
#include "src/widgets/capture/capturebutton.h"
|
||||
#include <QListWidget>
|
||||
|
||||
class ButtonListView : public QListWidget {
|
||||
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<CaptureButton::ButtonType> m_listButtons;
|
||||
QMap<QString, CaptureButton::ButtonType> m_buttonTypeByName;
|
||||
QVector<CaptureButton::ButtonType> m_listButtons;
|
||||
QMap<QString, CaptureButton::ButtonType> m_buttonTypeByName;
|
||||
|
||||
void updateActiveButtons(QListWidgetItem *);
|
||||
void updateActiveButtons(QListWidgetItem*);
|
||||
};
|
||||
|
||||
@@ -17,14 +17,18 @@
|
||||
|
||||
#include "clickablelabel.h"
|
||||
|
||||
ClickableLabel::ClickableLabel(QWidget *parent) : QLabel(parent) {
|
||||
ClickableLabel::ClickableLabel(QWidget* parent)
|
||||
: QLabel(parent)
|
||||
{}
|
||||
|
||||
ClickableLabel::ClickableLabel(QString s, QWidget* parent)
|
||||
: QLabel(parent)
|
||||
{
|
||||
setText(s);
|
||||
}
|
||||
|
||||
ClickableLabel::ClickableLabel(QString s, QWidget *parent) : QLabel(parent) {
|
||||
setText(s);
|
||||
}
|
||||
|
||||
void ClickableLabel::mousePressEvent(QMouseEvent *) {
|
||||
emit clicked();
|
||||
void
|
||||
ClickableLabel::mousePressEvent(QMouseEvent*)
|
||||
{
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
class ClickableLabel : public QLabel {
|
||||
Q_OBJECT
|
||||
class ClickableLabel : public QLabel
|
||||
{
|
||||
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*);
|
||||
};
|
||||
|
||||
@@ -16,73 +16,81 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "configwindow.h"
|
||||
#include "src/utils/colorutils.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/pathinfo.h"
|
||||
#include "src/widgets/capture/capturebutton.h"
|
||||
#include "src/config/geneneralconf.h"
|
||||
#include "src/config/filenameeditor.h"
|
||||
#include "src/config/geneneralconf.h"
|
||||
#include "src/config/strftimechooserwidget.h"
|
||||
#include "src/config/visualseditor.h"
|
||||
#include "src/utils/colorutils.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include <QIcon>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QKeyEvent>
|
||||
#include "src/utils/pathinfo.h"
|
||||
#include "src/widgets/capture/capturebutton.h"
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
// ConfigWindow contains the menus where you can configure the application
|
||||
|
||||
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"));
|
||||
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"));
|
||||
|
||||
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();
|
||||
|
||||
// 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"));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void ConfigWindow::keyPressEvent(QKeyEvent *e) {
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
close();
|
||||
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();
|
||||
|
||||
// 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"));
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void
|
||||
ConfigWindow::keyPressEvent(QKeyEvent* e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,20 +24,21 @@ class GeneneralConf;
|
||||
class QFileSystemWatcher;
|
||||
class VisualsEditor;
|
||||
|
||||
class ConfigWindow : public QTabWidget {
|
||||
Q_OBJECT
|
||||
class ConfigWindow : public QTabWidget
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -17,34 +17,41 @@
|
||||
|
||||
#include "extendedslider.h"
|
||||
|
||||
ExtendedSlider::ExtendedSlider(QWidget *parent)
|
||||
: QSlider(parent)
|
||||
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) {
|
||||
qreal progress =
|
||||
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
||||
return min + (max - min) * progress;
|
||||
int
|
||||
ExtendedSlider::mappedValue(int min, int max)
|
||||
{
|
||||
qreal progress =
|
||||
((value() - minimum())) / static_cast<qreal>(maximum() - minimum());
|
||||
return min + (max - min) * progress;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
void ExtendedSlider::updateTooltip() {
|
||||
setToolTip(QString::number(value())+"%");
|
||||
void
|
||||
ExtendedSlider::updateTooltip()
|
||||
{
|
||||
setToolTip(QString::number(value()) + "%");
|
||||
}
|
||||
|
||||
void ExtendedSlider::fireTimer() {
|
||||
m_timer.start(500);
|
||||
void
|
||||
ExtendedSlider::fireTimer()
|
||||
{
|
||||
m_timer.start(500);
|
||||
}
|
||||
|
||||
@@ -20,21 +20,22 @@
|
||||
#include <QSlider>
|
||||
#include <QTimer>
|
||||
|
||||
class ExtendedSlider : public QSlider {
|
||||
Q_OBJECT
|
||||
class ExtendedSlider : public QSlider
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -16,100 +16,122 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "filenameeditor.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/config/strftimechooserwidget.h"
|
||||
#include <QVBoxLayout>
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
FileNameEditor::FileNameEditor(QWidget *parent) : QWidget(parent) {
|
||||
initWidgets();
|
||||
initLayout();
|
||||
FileNameEditor::FileNameEditor(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
initWidgets();
|
||||
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);
|
||||
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);
|
||||
|
||||
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() {
|
||||
m_nameHandler = new FileNameHandler(this);
|
||||
void
|
||||
FileNameEditor::initWidgets()
|
||||
{
|
||||
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"));}
|
||||
|
||||
void FileNameEditor::savePattern() {
|
||||
QString pattern = m_nameEditor->text();
|
||||
m_nameHandler->setPattern(pattern);
|
||||
// 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::showParsedPattern(const QString &p) {
|
||||
QString output = m_nameHandler->parseFilename(p);
|
||||
m_outputLabel->setText(output);
|
||||
void
|
||||
FileNameEditor::savePattern()
|
||||
{
|
||||
QString pattern = m_nameEditor->text();
|
||||
m_nameHandler->setPattern(pattern);
|
||||
}
|
||||
|
||||
void FileNameEditor::resetName() {
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
void
|
||||
FileNameEditor::showParsedPattern(const QString& p)
|
||||
{
|
||||
QString output = m_nameHandler->parseFilename(p);
|
||||
m_outputLabel->setText(output);
|
||||
}
|
||||
|
||||
void FileNameEditor::addToNameEditor(QString s) {
|
||||
m_nameEditor->setText(m_nameEditor->text() + s);
|
||||
m_nameEditor->setFocus();
|
||||
void
|
||||
FileNameEditor::resetName()
|
||||
{
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
}
|
||||
|
||||
void FileNameEditor::updateComponents() {
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
||||
void
|
||||
FileNameEditor::addToNameEditor(QString s)
|
||||
{
|
||||
m_nameEditor->setText(m_nameEditor->text() + s);
|
||||
m_nameEditor->setFocus();
|
||||
}
|
||||
|
||||
void
|
||||
FileNameEditor::updateComponents()
|
||||
{
|
||||
m_nameEditor->setText(ConfigHandler().filenamePatternValue());
|
||||
m_outputLabel->setText(m_nameHandler->parsedPattern());
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
|
||||
class QVBoxLayout;
|
||||
class QLineEdit;
|
||||
@@ -26,30 +26,31 @@ class FileNameHandler;
|
||||
class QPushButton;
|
||||
class StrftimeChooserWidget;
|
||||
|
||||
class FileNameEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
class FileNameEditor : public QWidget
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -16,224 +16,269 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "geneneralconf.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/core/controller.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include "src/utils/confighandler.h"
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
#include <QTextCodec>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QTextCodec>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
GeneneralConf::GeneneralConf(QWidget *parent) : QWidget(parent) {
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->setAlignment(Qt::AlignTop);
|
||||
initShowHelp();
|
||||
initShowDesktopNotification();
|
||||
initShowTrayIcon();
|
||||
initAutostart();
|
||||
initCloseAfterCapture();
|
||||
initCopyAndCloseAfterUpload();
|
||||
|
||||
// this has to be at the end
|
||||
initConfingButtons();
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void GeneneralConf::updateComponents() {
|
||||
ConfigHandler config;
|
||||
m_helpMessage->setChecked(config.showHelpValue());
|
||||
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
||||
m_autostart->setChecked(config.startupLaunchValue());
|
||||
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
||||
m_copyAndCloseAfterUpload->setChecked(config.copyAndCloseAfterUploadEnabled());
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
m_showTray->setChecked(!config.disabledTrayIconValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeneneralConf::showHelpChanged(bool checked) {
|
||||
ConfigHandler().setShowHelp(checked);
|
||||
}
|
||||
|
||||
void GeneneralConf::showDesktopNotificationChanged(bool checked) {
|
||||
ConfigHandler().setDesktopNotification(checked);
|
||||
}
|
||||
|
||||
void GeneneralConf::showTrayIconChanged(bool checked) {
|
||||
auto controller = Controller::getInstance();
|
||||
if (checked) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void GeneneralConf::autostartChanged(bool checked) {
|
||||
ConfigHandler().setStartupLaunch(checked);
|
||||
}
|
||||
|
||||
void GeneneralConf::closeAfterCaptureChanged(bool checked) {
|
||||
ConfigHandler().setCloseAfterScreenshot(checked);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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() {
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
|
||||
QStringLiteral("flameshot.conf"));
|
||||
|
||||
// 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."));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
connect(m_helpMessage, &QCheckBox::clicked, this,
|
||||
&GeneneralConf::showHelpChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_sysNotifications, &QCheckBox::clicked, this,
|
||||
&GeneneralConf::showDesktopNotificationChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_showTray, &QCheckBox::stateChanged, this,
|
||||
&GeneneralConf::showTrayIconChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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_resetButton = new QPushButton(tr("Reset"));
|
||||
buttonLayout->addWidget(m_resetButton);
|
||||
connect(m_resetButton, &QPushButton::clicked, this,
|
||||
&GeneneralConf::resetConfiguration);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_autostart, &QCheckBox::clicked, this,
|
||||
&GeneneralConf::autostartChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_closeAfterCapture, &QCheckBox::clicked, this,
|
||||
&GeneneralConf::closeAfterCaptureChanged);
|
||||
}
|
||||
|
||||
void GeneneralConf::initCopyAndCloseAfterUpload()
|
||||
GeneneralConf::GeneneralConf(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
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_layout = new QVBoxLayout(this);
|
||||
m_layout->setAlignment(Qt::AlignTop);
|
||||
initShowHelp();
|
||||
initShowDesktopNotification();
|
||||
initShowTrayIcon();
|
||||
initAutostart();
|
||||
initCloseAfterCapture();
|
||||
initCopyAndCloseAfterUpload();
|
||||
|
||||
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
||||
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
||||
});
|
||||
// this has to be at the end
|
||||
initConfingButtons();
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::updateComponents()
|
||||
{
|
||||
ConfigHandler config;
|
||||
m_helpMessage->setChecked(config.showHelpValue());
|
||||
m_sysNotifications->setChecked(config.desktopNotificationValue());
|
||||
m_autostart->setChecked(config.startupLaunchValue());
|
||||
m_closeAfterCapture->setChecked(config.closeAfterScreenshotValue());
|
||||
m_copyAndCloseAfterUpload->setChecked(
|
||||
config.copyAndCloseAfterUploadEnabled());
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
m_showTray->setChecked(!config.disabledTrayIconValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showHelpChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setShowHelp(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showDesktopNotificationChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setDesktopNotification(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::showTrayIconChanged(bool checked)
|
||||
{
|
||||
auto controller = Controller::getInstance();
|
||||
if (checked) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::autostartChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setStartupLaunch(checked);
|
||||
}
|
||||
|
||||
void
|
||||
GeneneralConf::closeAfterCaptureChanged(bool checked)
|
||||
{
|
||||
ConfigHandler().setCloseAfterScreenshot(checked);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this, tr("Save File"), QStringLiteral("flameshot.conf"));
|
||||
|
||||
// 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."));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(
|
||||
m_helpMessage, &QCheckBox::clicked, this, &GeneneralConf::showHelpChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_sysNotifications,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::showDesktopNotificationChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_showTray,
|
||||
&QCheckBox::stateChanged,
|
||||
this,
|
||||
&GeneneralConf::showTrayIconChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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_resetButton = new QPushButton(tr("Reset"));
|
||||
buttonLayout->addWidget(m_resetButton);
|
||||
connect(m_resetButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&GeneneralConf::resetConfiguration);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(
|
||||
m_autostart, &QCheckBox::clicked, this, &GeneneralConf::autostartChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_closeAfterCapture,
|
||||
&QCheckBox::clicked,
|
||||
this,
|
||||
&GeneneralConf::closeAfterCaptureChanged);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
connect(m_copyAndCloseAfterUpload, &QCheckBox::clicked, [](bool checked) {
|
||||
ConfigHandler().setCopyAndCloseAfterUploadEnabled(checked);
|
||||
});
|
||||
}
|
||||
@@ -23,41 +23,42 @@ class QVBoxLayout;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
|
||||
class GeneneralConf : public QWidget {
|
||||
Q_OBJECT
|
||||
class GeneneralConf : public QWidget
|
||||
{
|
||||
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 showDesktopNotificationChanged(bool checked);
|
||||
void showTrayIconChanged(bool checked);
|
||||
void autostartChanged(bool checked);
|
||||
void closeAfterCaptureChanged(bool checked);
|
||||
void importConfiguration();
|
||||
void exportFileConfiguration();
|
||||
void resetConfiguration();
|
||||
void showHelpChanged(bool checked);
|
||||
void showDesktopNotificationChanged(bool checked);
|
||||
void showTrayIconChanged(bool checked);
|
||||
void autostartChanged(bool checked);
|
||||
void closeAfterCaptureChanged(bool checked);
|
||||
void importConfiguration();
|
||||
void exportFileConfiguration();
|
||||
void resetConfiguration();
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_layout;
|
||||
QCheckBox *m_sysNotifications;
|
||||
QCheckBox *m_showTray;
|
||||
QCheckBox *m_helpMessage;
|
||||
QCheckBox *m_autostart;
|
||||
QCheckBox *m_closeAfterCapture;
|
||||
QCheckBox *m_copyAndCloseAfterUpload;
|
||||
QPushButton *m_importButton;
|
||||
QPushButton *m_exportButton;
|
||||
QPushButton *m_resetButton;
|
||||
QVBoxLayout* m_layout;
|
||||
QCheckBox* m_sysNotifications;
|
||||
QCheckBox* m_showTray;
|
||||
QCheckBox* m_helpMessage;
|
||||
QCheckBox* m_autostart;
|
||||
QCheckBox* m_closeAfterCapture;
|
||||
QCheckBox* m_copyAndCloseAfterUpload;
|
||||
QPushButton* m_importButton;
|
||||
QPushButton* m_exportButton;
|
||||
QPushButton* m_resetButton;
|
||||
|
||||
void initShowHelp();
|
||||
void initShowDesktopNotification();
|
||||
void initShowTrayIcon();
|
||||
void initConfingButtons();
|
||||
void initAutostart();
|
||||
void initCloseAfterCapture();
|
||||
void initCopyAndCloseAfterUpload();
|
||||
void initShowHelp();
|
||||
void initShowDesktopNotification();
|
||||
void initShowTrayIcon();
|
||||
void initConfingButtons();
|
||||
void initAutostart();
|
||||
void initCloseAfterCapture();
|
||||
void initCopyAndCloseAfterUpload();
|
||||
};
|
||||
|
||||
@@ -16,53 +16,56 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "strftimechooserwidget.h"
|
||||
#include <QMap>
|
||||
#include <QGridLayout>
|
||||
#include <QMap>
|
||||
#include <QPushButton>
|
||||
|
||||
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);});
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
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"},
|
||||
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" },
|
||||
};
|
||||
|
||||
@@ -19,14 +19,15 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class StrftimeChooserWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
class StrftimeChooserWidget : public QWidget
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -15,151 +15,176 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "uicoloreditor.h"
|
||||
#include "clickablelabel.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMap>
|
||||
#include <QSpacerItem>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
UIcolorEditor::UIcolorEditor(QWidget *parent) : QGroupBox(parent) {
|
||||
setTitle(tr("UI Color Editor"));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_hLayout = new QHBoxLayout;
|
||||
m_vLayout = new QVBoxLayout;
|
||||
UIcolorEditor::UIcolorEditor(QWidget* parent)
|
||||
: QGroupBox(parent)
|
||||
{
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// updateUIcolor updates the appearance of the buttons
|
||||
void UIcolorEditor::updateUIcolor() {
|
||||
ConfigHandler config;
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
config.setUIMainColor(m_uiColor);
|
||||
} else {
|
||||
config.setUIContrastColor(m_contrastColor);
|
||||
}
|
||||
void
|
||||
UIcolorEditor::updateUIcolor()
|
||||
{
|
||||
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) {
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_uiColor = c;
|
||||
} else {
|
||||
m_contrastColor = c;
|
||||
}
|
||||
m_lastButtonPressed->setColor(c);
|
||||
void
|
||||
UIcolorEditor::updateLocalColor(const QColor c)
|
||||
{
|
||||
if (m_lastButtonPressed == m_buttonMainColor) {
|
||||
m_uiColor = c;
|
||||
} else {
|
||||
m_contrastColor = c;
|
||||
}
|
||||
m_lastButtonPressed->setColor(c);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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() {
|
||||
const int extraSize = GlobalValues::buttonBaseSize() / 3;
|
||||
int frameSize = GlobalValues::buttonBaseSize() + extraSize;
|
||||
void
|
||||
UIcolorEditor::initButtons()
|
||||
{
|
||||
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 CaptureButton(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 CaptureButton(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 CaptureButton(m_buttonIconType, frame2);
|
||||
m_buttonContrast->move(m_buttonContrast->x() + extraSize/2,
|
||||
m_buttonContrast->y() + extraSize/2);
|
||||
QGroupBox* frame2 = new QGroupBox();
|
||||
m_buttonContrast = new CaptureButton(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, &CaptureButton::pressedButton,
|
||||
this, &UIcolorEditor::changeLastButton);
|
||||
connect(m_buttonContrast, &CaptureButton::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,
|
||||
&CaptureButton::pressedButton,
|
||||
this,
|
||||
&UIcolorEditor::changeLastButton);
|
||||
connect(m_buttonContrast,
|
||||
&CaptureButton::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(CaptureButton *b) {
|
||||
if (m_lastButtonPressed != b) {
|
||||
m_lastButtonPressed = b;
|
||||
void
|
||||
UIcolorEditor::changeLastButton(CaptureButton* 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);
|
||||
}
|
||||
b->setIcon(b->icon());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,33 +26,35 @@ class QHBoxLayout;
|
||||
class CaptureButton;
|
||||
class ClickableLabel;
|
||||
|
||||
class UIcolorEditor : public QGroupBox {
|
||||
Q_OBJECT
|
||||
class UIcolorEditor : public QGroupBox
|
||||
{
|
||||
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(CaptureButton *);
|
||||
void updateUIcolor();
|
||||
void updateLocalColor(const QColor);
|
||||
void changeLastButton(CaptureButton*);
|
||||
|
||||
private:
|
||||
QColor m_uiColor, m_contrastColor;
|
||||
CaptureButton *m_buttonMainColor;
|
||||
ClickableLabel *m_labelMain;
|
||||
CaptureButton *m_buttonContrast;
|
||||
ClickableLabel *m_labelContrast;
|
||||
CaptureButton *m_lastButtonPressed;
|
||||
color_widgets::ColorWheel *m_colorWheel;
|
||||
QColor m_uiColor, m_contrastColor;
|
||||
CaptureButton* m_buttonMainColor;
|
||||
ClickableLabel* m_labelMain;
|
||||
CaptureButton* m_buttonContrast;
|
||||
ClickableLabel* m_labelContrast;
|
||||
CaptureButton* m_lastButtonPressed;
|
||||
color_widgets::ColorWheel* m_colorWheel;
|
||||
|
||||
static const CaptureButton::ButtonType m_buttonIconType = CaptureButton::TYPE_CIRCLE;
|
||||
static const CaptureButton::ButtonType m_buttonIconType =
|
||||
CaptureButton::TYPE_CIRCLE;
|
||||
|
||||
QHBoxLayout *m_hLayout;
|
||||
QVBoxLayout *m_vLayout;
|
||||
QHBoxLayout* m_hLayout;
|
||||
QVBoxLayout* m_vLayout;
|
||||
|
||||
void initColorWheel();
|
||||
void initButtons();
|
||||
void initColorWheel();
|
||||
void initButtons();
|
||||
};
|
||||
|
||||
@@ -17,71 +17,85 @@
|
||||
|
||||
#include "visualseditor.h"
|
||||
#include "src/config/buttonlistview.h"
|
||||
#include "src/config/extendedslider.h"
|
||||
#include "src/config/uicoloreditor.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/config/extendedslider.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
VisualsEditor::VisualsEditor(QWidget *parent) : QWidget(parent) {
|
||||
m_layout= new QVBoxLayout();
|
||||
setLayout(m_layout);
|
||||
initWidgets();
|
||||
VisualsEditor::VisualsEditor(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_layout = new QVBoxLayout();
|
||||
setLayout(m_layout);
|
||||
initWidgets();
|
||||
}
|
||||
|
||||
void VisualsEditor::updateComponents() {
|
||||
m_buttonList->updateComponents();
|
||||
m_colorEditor->updateComponents();
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
void
|
||||
VisualsEditor::updateComponents()
|
||||
{
|
||||
m_buttonList->updateComponents();
|
||||
m_colorEditor->updateComponents();
|
||||
int opacity = ConfigHandler().contrastOpacityValue();
|
||||
m_opacitySlider->setMapedValue(0, opacity, 255);
|
||||
}
|
||||
|
||||
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%")));
|
||||
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%")));
|
||||
|
||||
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() {
|
||||
int value = m_opacitySlider->mappedValue(0, 255);
|
||||
ConfigHandler().setContrastOpacity(value);
|
||||
void
|
||||
VisualsEditor::saveOpacity()
|
||||
{
|
||||
int value = m_opacitySlider->mappedValue(0, 255);
|
||||
ConfigHandler().setContrastOpacity(value);
|
||||
}
|
||||
|
||||
void VisualsEditor::initWidgets() {
|
||||
m_colorEditor = new UIcolorEditor();
|
||||
m_layout->addWidget(m_colorEditor);
|
||||
void
|
||||
VisualsEditor::initWidgets()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -24,23 +24,24 @@ class QVBoxLayout;
|
||||
class ButtonListView;
|
||||
class UIcolorEditor;
|
||||
|
||||
class VisualsEditor : public QWidget {
|
||||
Q_OBJECT
|
||||
class VisualsEditor : public QWidget
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -17,70 +17,89 @@
|
||||
|
||||
#include "capturerequest.h"
|
||||
#include "src/utils/screenshotsaver.h"
|
||||
#include <QVector>
|
||||
#include <QDateTime>
|
||||
#include <QVector>
|
||||
|
||||
CaptureRequest::CaptureRequest(CaptureRequest::CaptureMode mode,
|
||||
const uint delay, const QString &path,
|
||||
const QVariant &data,
|
||||
CaptureRequest::ExportTask tasks) :
|
||||
m_mode(mode), m_delay(delay), m_path(path), m_tasks(tasks),
|
||||
m_data(data), m_forcedID(false), m_id(0)
|
||||
const uint delay,
|
||||
const QString& path,
|
||||
const QVariant& data,
|
||||
CaptureRequest::ExportTask tasks)
|
||||
: m_mode(mode)
|
||||
, m_delay(delay)
|
||||
, m_path(path)
|
||||
, m_tasks(tasks)
|
||||
, m_data(data)
|
||||
, m_forcedID(false)
|
||||
, m_id(0)
|
||||
{}
|
||||
|
||||
void
|
||||
CaptureRequest::setStaticID(uint id)
|
||||
{
|
||||
|
||||
m_forcedID = true;
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
void CaptureRequest::setStaticID(uint id) {
|
||||
m_forcedID = true;
|
||||
m_id = id;
|
||||
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;
|
||||
}
|
||||
|
||||
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_tasks & ExportTask::CLIPBOARD_SAVE_TASK) != ExportTask::NO_TASK) {
|
||||
ScreenshotSaver().saveToClipboard(p);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,64 +17,72 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
class CaptureRequest {
|
||||
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) {
|
||||
return static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
inline eTask
|
||||
operator|(const eTask& a, const eTask& b)
|
||||
{
|
||||
return static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline eTask operator&(const eTask &a, const eTask &b) {
|
||||
return static_cast<eTask>(static_cast<int>(a) & static_cast<int>(b));
|
||||
inline eTask
|
||||
operator&(const eTask& a, const eTask& b)
|
||||
{
|
||||
return static_cast<eTask>(static_cast<int>(a) & static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline eTask& operator|=(eTask &a, const eTask &b) {
|
||||
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
return a;
|
||||
inline eTask&
|
||||
operator|=(eTask& a, const eTask& b)
|
||||
{
|
||||
a = static_cast<eTask>(static_cast<int>(a) | static_cast<int>(b));
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "controller.h"
|
||||
#include "src/widgets/capture/capturewidget.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/widgets/infowindow.h"
|
||||
#include "src/config/configwindow.h"
|
||||
#include "src/widgets/capture/capturebutton.h"
|
||||
#include "src/widgets/capturelauncher.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/screengrabber.h"
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QSystemTrayIcon>
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include "src/widgets/capture/capturebutton.h"
|
||||
#include "src/widgets/capture/capturewidget.h"
|
||||
#include "src/widgets/capturelauncher.h"
|
||||
#include "src/widgets/infowindow.h"
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QFile>
|
||||
#include <QMenu>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "src/core/globalshortcutfilter.h"
|
||||
@@ -38,241 +38,280 @@
|
||||
// Controller is the core component of Flameshot, creates the trayIcon and
|
||||
// launches the capture widget
|
||||
|
||||
Controller::Controller() : m_captureWindow(nullptr) {
|
||||
qApp->setQuitOnLastWindowClosed(false);
|
||||
Controller::Controller()
|
||||
: m_captureWindow(nullptr)
|
||||
{
|
||||
qApp->setQuitOnLastWindowClosed(false);
|
||||
|
||||
// init tray icon
|
||||
// init tray icon
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
if (!ConfigHandler().disabledTrayIconValue()) {
|
||||
enableTrayIcon();
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
if (!ConfigHandler().disabledTrayIconValue()) {
|
||||
enableTrayIcon();
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
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() {
|
||||
static Controller c;
|
||||
return &c;
|
||||
Controller*
|
||||
Controller::getInstance()
|
||||
{
|
||||
static Controller c;
|
||||
return &c;
|
||||
}
|
||||
|
||||
void Controller::enableExports() {
|
||||
connect(this, &Controller::captureTaken,
|
||||
this, &Controller::handleCaptureTaken);
|
||||
connect(this, &Controller::captureFailed,
|
||||
this, &Controller::handleCaptureFailed);
|
||||
void
|
||||
Controller::enableExports()
|
||||
{
|
||||
connect(
|
||||
this, &Controller::captureTaken, this, &Controller::handleCaptureTaken);
|
||||
connect(
|
||||
this, &Controller::captureFailed, this, &Controller::handleCaptureFailed);
|
||||
}
|
||||
|
||||
void Controller::requestCapture(const CaptureRequest &request) {
|
||||
uint id = request.id();
|
||||
m_requestMap.insert(id, request);
|
||||
void
|
||||
Controller::requestCapture(const CaptureRequest& request)
|
||||
{
|
||||
uint id = request.id();
|
||||
m_requestMap.insert(id, request);
|
||||
|
||||
switch (request.captureMode()) {
|
||||
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
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// creation of a new capture in GUI mode
|
||||
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);
|
||||
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);
|
||||
|
||||
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) {
|
||||
bool ok = true;
|
||||
int n = screenNumber;
|
||||
void
|
||||
Controller::startScreenGrab(const uint id, const int 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() {
|
||||
if (!m_configWindow) {
|
||||
m_configWindow = new ConfigWindow();
|
||||
m_configWindow->show();
|
||||
}
|
||||
void
|
||||
Controller::openConfigWindow()
|
||||
{
|
||||
if (!m_configWindow) {
|
||||
m_configWindow = new ConfigWindow();
|
||||
m_configWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
// creation of the window of information
|
||||
void Controller::openInfoWindow() {
|
||||
if (!m_infoWindow) {
|
||||
m_infoWindow = new InfoWindow();
|
||||
void
|
||||
Controller::openInfoWindow()
|
||||
{
|
||||
if (!m_infoWindow) {
|
||||
m_infoWindow = new InfoWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Controller::openLauncherWindow()
|
||||
{
|
||||
CaptureLauncher* w = new CaptureLauncher();
|
||||
w->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("&Information"), 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::openLauncherWindow() {
|
||||
CaptureLauncher *w = new CaptureLauncher();
|
||||
w->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("&Information"), 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() {
|
||||
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() {
|
||||
if (m_configWindow) {
|
||||
m_configWindow->updateChildren();
|
||||
}
|
||||
void
|
||||
Controller::updateConfigComponents()
|
||||
{
|
||||
if (m_configWindow) {
|
||||
m_configWindow->updateChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::startFullscreenCapture(const uint id) {
|
||||
bool ok = true;
|
||||
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
|
||||
if (ok) {
|
||||
emit captureTaken(id, p);
|
||||
} else {
|
||||
emit captureFailed(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);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::handleCaptureFailed(uint id) {
|
||||
m_requestMap.remove(id);
|
||||
void
|
||||
Controller::handleCaptureFailed(uint id)
|
||||
{
|
||||
m_requestMap.remove(id);
|
||||
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
if (ConfigHandler().closeAfterScreenshotValue()) {
|
||||
QApplication::quit();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/core/capturerequest.h"
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QPixmap>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QPointer>
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
|
||||
@@ -32,54 +32,56 @@ class QSystemTrayIcon;
|
||||
|
||||
using lambda = std::function<void(void)>;
|
||||
|
||||
class Controller : public QObject {
|
||||
Q_OBJECT
|
||||
class Controller : public QObject
|
||||
{
|
||||
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<ConfigWindow> m_configWindow;
|
||||
QPointer<QSystemTrayIcon> m_trayIcon;
|
||||
QMap<uint, CaptureRequest> m_requestMap;
|
||||
QPointer<CaptureWidget> m_captureWindow;
|
||||
QPointer<InfoWindow> m_infoWindow;
|
||||
QPointer<ConfigWindow> m_configWindow;
|
||||
QPointer<QSystemTrayIcon> m_trayIcon;
|
||||
};
|
||||
|
||||
@@ -16,90 +16,111 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "flameshotdbusadapter.h"
|
||||
#include "src/core/controller.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/screengrabber.h"
|
||||
#include "src/core/controller.h"
|
||||
#include "src/utils/screenshotsaver.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include <QBuffer>
|
||||
FlameshotDBusAdapter::FlameshotDBusAdapter(QObject *parent)
|
||||
: QDBusAbstractAdaptor(parent)
|
||||
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() {
|
||||
FlameshotDBusAdapter::~FlameshotDBusAdapter() {}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void FlameshotDBusAdapter::fullScreen(
|
||||
QString path, bool toClipboard, int delay, uint id)
|
||||
void
|
||||
FlameshotDBusAdapter::graphicCapture(QString path, 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::GRAPHICAL_MODE, delay, path);
|
||||
// if (toClipboard) {
|
||||
// req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
// }
|
||||
req.setStaticID(id);
|
||||
Controller::getInstance()->requestCapture(req);
|
||||
}
|
||||
|
||||
void FlameshotDBusAdapter::openLauncher() {
|
||||
Controller::getInstance()->openLauncherWindow();
|
||||
}
|
||||
|
||||
void FlameshotDBusAdapter::captureScreen(int number, QString path,
|
||||
bool toClipboard, int delay, uint id)
|
||||
void
|
||||
FlameshotDBusAdapter::fullScreen(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::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::openConfig() {
|
||||
Controller::getInstance()->openConfigWindow();
|
||||
void
|
||||
FlameshotDBusAdapter::openLauncher()
|
||||
{
|
||||
Controller::getInstance()->openLauncherWindow();
|
||||
}
|
||||
|
||||
void FlameshotDBusAdapter::trayIconEnabled(bool enabled) {
|
||||
auto controller = Controller::getInstance();
|
||||
if (enabled) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
void
|
||||
FlameshotDBusAdapter::openConfig()
|
||||
{
|
||||
Controller::getInstance()->openConfigWindow();
|
||||
}
|
||||
|
||||
void FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap &p) {
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
p.save(&buffer, "PNG");
|
||||
emit captureTaken(id, byteArray);
|
||||
void
|
||||
FlameshotDBusAdapter::trayIconEnabled(bool enabled)
|
||||
{
|
||||
auto controller = Controller::getInstance();
|
||||
if (enabled) {
|
||||
controller->enableTrayIcon();
|
||||
} else {
|
||||
controller->disableTrayIcon();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void
|
||||
FlameshotDBusAdapter::handleCaptureTaken(uint id, const QPixmap& p)
|
||||
{
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
p.save(&buffer, "PNG");
|
||||
emit captureTaken(id, byteArray);
|
||||
}
|
||||
|
||||
@@ -17,30 +17,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtDBus/QDBusAbstractAdaptor>
|
||||
#include "src/core/controller.h"
|
||||
#include <QtDBus/QDBusAbstractAdaptor>
|
||||
|
||||
class FlameshotDBusAdapter : public QDBusAbstractAdaptor {
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.dharkael.Flameshot")
|
||||
class FlameshotDBusAdapter : public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.dharkael.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);
|
||||
};
|
||||
|
||||
@@ -19,33 +19,33 @@
|
||||
#include "src/core/controller.h"
|
||||
#include <qt_windows.h>
|
||||
|
||||
GlobalShortcutFilter::GlobalShortcutFilter(QObject *parent) :
|
||||
QObject(parent)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -17,22 +17,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QObject>
|
||||
|
||||
class GlobalShortcutFilter : public QObject, public QAbstractNativeEventFilter {
|
||||
Q_OBJECT
|
||||
class GlobalShortcutFilter
|
||||
: public QObject
|
||||
, public QAbstractNativeEventFilter
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
788
src/main.cpp
788
src/main.cpp
@@ -15,424 +15,456 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "src/core/controller.h"
|
||||
#include "singleapplication.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/cli/commandlineparser.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include "src/utils/pathinfo.h"
|
||||
#include "src/core/capturerequest.h"
|
||||
#include "src/core/controller.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/pathinfo.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QLibraryInfo>
|
||||
#include <QTranslator>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
|
||||
#include "src/core/flameshotdbusadapter.h"
|
||||
#include "src/utils/dbusutils.h"
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#endif
|
||||
|
||||
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));
|
||||
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));
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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("Dharkael"));
|
||||
|
||||
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.dharkael.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();
|
||||
for (const QString& path : trPaths) {
|
||||
bool match = translator.load(QLocale(),
|
||||
QStringLiteral("Internationalization"),
|
||||
QStringLiteral("_"),
|
||||
path);
|
||||
if (match) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
/*--------------|
|
||||
* CLI parsing |
|
||||
* ------------*/
|
||||
QCoreApplication app(argc, argv);
|
||||
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("Dharkael"));
|
||||
app.setApplicationVersion(qApp->applicationVersion());
|
||||
CommandLineParser parser;
|
||||
// Add description
|
||||
parser.setDescription(
|
||||
QStringLiteral("Powerful yet simple to use screenshot software."));
|
||||
parser.setGeneralErrorMessage(QStringLiteral("See 'flameshot --help'."));
|
||||
// Arguments
|
||||
CommandArgument fullArgument(QStringLiteral("full"), QStringLiteral("Capture the entire desktop."));
|
||||
CommandArgument launcherArgument(QStringLiteral("launcher"), QStringLiteral("Open the capture launcher."));
|
||||
CommandArgument guiArgument(QStringLiteral("gui"), QStringLiteral("Start a manual capture in GUI mode."));
|
||||
CommandArgument configArgument(QStringLiteral("config"), QStringLiteral("Configure flameshot."));
|
||||
CommandArgument screenArgument(QStringLiteral("screen"), QStringLiteral("Capture a single screen."));
|
||||
|
||||
// Options
|
||||
CommandOption pathOption(
|
||||
{"p", "path"},
|
||||
QStringLiteral("Path where the capture will be saved"),
|
||||
QStringLiteral("path"));
|
||||
CommandOption clipboardOption(
|
||||
{"c", "clipboard"},
|
||||
QStringLiteral("Save the capture to the clipboard"));
|
||||
CommandOption delayOption(
|
||||
{"d", "delay"},
|
||||
QStringLiteral("Delay time in milliseconds"),
|
||||
QStringLiteral("milliseconds"));
|
||||
CommandOption filenameOption(
|
||||
{"f", "filename"},
|
||||
QStringLiteral("Set the filename pattern"),
|
||||
QStringLiteral("pattern"));
|
||||
CommandOption trayOption(
|
||||
{"t", "trayicon"},
|
||||
QStringLiteral("Enable or disable the trayicon"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption autostartOption(
|
||||
{"a", "autostart"},
|
||||
QStringLiteral("Enable or disable run at startup"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption showHelpOption(
|
||||
{"s", "showhelp"},
|
||||
QStringLiteral("Show the help message in the capture mode"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption mainColorOption(
|
||||
{"m", "maincolor"},
|
||||
QStringLiteral("Define the main UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption contrastColorOption(
|
||||
{"k", "contrastcolor"},
|
||||
QStringLiteral("Define the contrast UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption rawImageOption(
|
||||
{"r", "raw"},
|
||||
QStringLiteral("Print raw PNG capture"));
|
||||
CommandOption screenNumberOption(
|
||||
{"n", "number"},
|
||||
QStringLiteral("Define the screen to capture,\ndefault: screen containing the cursor"),
|
||||
QStringLiteral("Screen number"), QStringLiteral("-1"));
|
||||
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.dharkael.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();
|
||||
}
|
||||
|
||||
// Add checkers
|
||||
auto colorChecker = [](const QString &colorCode) -> bool {
|
||||
QColor parsedColor(colorCode);
|
||||
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
||||
};
|
||||
QString colorErr = "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'";
|
||||
#ifndef Q_OS_WIN
|
||||
/*--------------|
|
||||
* CLI parsing |
|
||||
* ------------*/
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationName(QStringLiteral("flameshot"));
|
||||
app.setOrganizationName(QStringLiteral("Dharkael"));
|
||||
app.setApplicationVersion(qApp->applicationVersion());
|
||||
CommandLineParser parser;
|
||||
// Add description
|
||||
parser.setDescription(
|
||||
QStringLiteral("Powerful yet simple to use screenshot software."));
|
||||
parser.setGeneralErrorMessage(QStringLiteral("See 'flameshot --help'."));
|
||||
// Arguments
|
||||
CommandArgument fullArgument(QStringLiteral("full"),
|
||||
QStringLiteral("Capture the entire desktop."));
|
||||
CommandArgument launcherArgument(
|
||||
QStringLiteral("launcher"), QStringLiteral("Open the capture launcher."));
|
||||
CommandArgument guiArgument(
|
||||
QStringLiteral("gui"),
|
||||
QStringLiteral("Start a manual capture in GUI mode."));
|
||||
CommandArgument configArgument(QStringLiteral("config"),
|
||||
QStringLiteral("Configure flameshot."));
|
||||
CommandArgument screenArgument(QStringLiteral("screen"),
|
||||
QStringLiteral("Capture a single screen."));
|
||||
|
||||
const QString delayErr = QStringLiteral("Invalid delay, it must be higher than 0");
|
||||
const QString numberErr = QStringLiteral("Invalid screen number, it must be non negative");
|
||||
auto numericChecker = [](const QString &delayValue) -> bool {
|
||||
int value = delayValue.toInt();
|
||||
return value >= 0;
|
||||
};
|
||||
// Options
|
||||
CommandOption pathOption(
|
||||
{ "p", "path" },
|
||||
QStringLiteral("Path where the capture will be saved"),
|
||||
QStringLiteral("path"));
|
||||
CommandOption clipboardOption(
|
||||
{ "c", "clipboard" }, QStringLiteral("Save the capture to the clipboard"));
|
||||
CommandOption delayOption({ "d", "delay" },
|
||||
QStringLiteral("Delay time in milliseconds"),
|
||||
QStringLiteral("milliseconds"));
|
||||
CommandOption filenameOption({ "f", "filename" },
|
||||
QStringLiteral("Set the filename pattern"),
|
||||
QStringLiteral("pattern"));
|
||||
CommandOption trayOption({ "t", "trayicon" },
|
||||
QStringLiteral("Enable or disable the trayicon"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption autostartOption(
|
||||
{ "a", "autostart" },
|
||||
QStringLiteral("Enable or disable run at startup"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption showHelpOption(
|
||||
{ "s", "showhelp" },
|
||||
QStringLiteral("Show the help message in the capture mode"),
|
||||
QStringLiteral("bool"));
|
||||
CommandOption mainColorOption({ "m", "maincolor" },
|
||||
QStringLiteral("Define the main UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption contrastColorOption(
|
||||
{ "k", "contrastcolor" },
|
||||
QStringLiteral("Define the contrast UI color"),
|
||||
QStringLiteral("color-code"));
|
||||
CommandOption rawImageOption({ "r", "raw" },
|
||||
QStringLiteral("Print raw PNG capture"));
|
||||
CommandOption screenNumberOption(
|
||||
{ "n", "number" },
|
||||
QStringLiteral(
|
||||
"Define the screen to capture,\ndefault: screen containing the cursor"),
|
||||
QStringLiteral("Screen number"),
|
||||
QStringLiteral("-1"));
|
||||
|
||||
const QString pathErr = QStringLiteral("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;
|
||||
};
|
||||
// Add checkers
|
||||
auto colorChecker = [](const QString& colorCode) -> bool {
|
||||
QColor parsedColor(colorCode);
|
||||
return parsedColor.isValid() && parsedColor.alphaF() == 1.0;
|
||||
};
|
||||
QString colorErr = "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 booleanErr = QStringLiteral("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 delayErr =
|
||||
QStringLiteral("Invalid delay, it must be higher than 0");
|
||||
const QString numberErr =
|
||||
QStringLiteral("Invalid screen number, it must be non negative");
|
||||
auto numericChecker = [](const QString& delayValue) -> bool {
|
||||
int value = delayValue.toInt();
|
||||
return value >= 0;
|
||||
};
|
||||
|
||||
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);
|
||||
const QString pathErr =
|
||||
QStringLiteral("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;
|
||||
};
|
||||
|
||||
// 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;
|
||||
const QString booleanErr =
|
||||
QStringLiteral("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);
|
||||
|
||||
// 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.dharkael.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.dharkael.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;
|
||||
}
|
||||
|
||||
// PROCESS DATA
|
||||
//--------------
|
||||
if (parser.isSet(helpOption) || parser.isSet(versionOption)) {
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
else if (parser.isSet(launcherArgument)) { // LAUNCHER
|
||||
QDBusMessage m = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.Flameshot"),
|
||||
QStringLiteral("/"), QLatin1String(""), QStringLiteral("openLauncher"));
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
if (!sessionBus.isConnected()) {
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr("Unable to connect via DBus"));
|
||||
}
|
||||
sessionBus.call(m);
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
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();
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
|
||||
// Send message
|
||||
QDBusMessage m = QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.Flameshot"),
|
||||
QStringLiteral("/"), QLatin1String(""), QStringLiteral("graphicCapture"));
|
||||
m << pathValue << delay << id;
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
dbusUtils.checkDBusConnection(sessionBus);
|
||||
sessionBus.call(m);
|
||||
// Send message
|
||||
QDBusMessage m =
|
||||
QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.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);
|
||||
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();
|
||||
}
|
||||
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(fullArgument)) { // FULL
|
||||
QString pathValue = parser.value(pathOption);
|
||||
int delay = parser.value(delayOption).toInt();
|
||||
bool toClipboard = parser.isSet(clipboardOption);
|
||||
bool isRaw = parser.isSet(rawImageOption);
|
||||
// Not a valid command
|
||||
if (!isRaw && !toClipboard && pathValue.isEmpty()) {
|
||||
QTextStream out(stdout);
|
||||
out << "Invalid format, set where to save the content with one of "
|
||||
<< "the following flags:\n "
|
||||
<< pathOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
||||
<< rawImageOption.dashedNames().join(QStringLiteral(", ")) << "\n "
|
||||
<< clipboardOption.dashedNames().join(QStringLiteral(", ")) << "\n\n";
|
||||
parser.parse(QStringList() << argv[0] << QStringLiteral("full") << QStringLiteral("-h"));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
CaptureRequest req(CaptureRequest::FULLSCREEN_MODE, delay, pathValue);
|
||||
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.dharkael.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(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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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.dharkael.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();
|
||||
}
|
||||
CaptureRequest req(CaptureRequest::SCREEN_MODE, delay, pathValue, number);
|
||||
if (toClipboard) {
|
||||
req.addTask(CaptureRequest::CLIPBOARD_SAVE_TASK);
|
||||
}
|
||||
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.dharkael.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.dharkael.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.dharkael.Flameshot"),
|
||||
QStringLiteral("/"), QLatin1String(""), QStringLiteral("openConfig"));
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
if (!sessionBus.isConnected()) {
|
||||
SystemNotification().sendMessage(
|
||||
QObject::tr("Unable to connect via DBus"));
|
||||
}
|
||||
sessionBus.call(m);
|
||||
}
|
||||
if (!pathValue.isEmpty()) {
|
||||
req.addTask(CaptureRequest::FILESYSTEM_SAVE_TASK);
|
||||
}
|
||||
uint id = req.id();
|
||||
DBusUtils dbusUtils;
|
||||
|
||||
// Send message
|
||||
QDBusMessage m =
|
||||
QDBusMessage::createMethodCall(QStringLiteral("org.dharkael.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.dharkael.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.dharkael.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.dharkael.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;
|
||||
}
|
||||
|
||||
@@ -17,55 +17,78 @@
|
||||
|
||||
#include "abstractactiontool.h"
|
||||
|
||||
AbstractActionTool::AbstractActionTool(QObject *parent) : CaptureTool(parent) {
|
||||
AbstractActionTool::AbstractActionTool(QObject* parent)
|
||||
: CaptureTool(parent)
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
bool AbstractActionTool::isValid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractActionTool::isSelectable() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractActionTool::showMousePreview() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AbstractActionTool::undo(QPixmap &pixmap) {
|
||||
Q_UNUSED(pixmap);
|
||||
}
|
||||
|
||||
void AbstractActionTool::process(QPainter &painter, const QPixmap &pixmap, bool recordUndo) {
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(pixmap);
|
||||
Q_UNUSED(recordUndo);
|
||||
}
|
||||
|
||||
void AbstractActionTool::paintMousePreview(
|
||||
QPainter &painter, const CaptureContext &context)
|
||||
bool
|
||||
AbstractActionTool::isValid() const
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AbstractActionTool::drawEnd(const QPoint &p) {
|
||||
Q_UNUSED(p);
|
||||
bool
|
||||
AbstractActionTool::isSelectable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AbstractActionTool::drawMove(const QPoint &p) {
|
||||
Q_UNUSED(p);
|
||||
bool
|
||||
AbstractActionTool::showMousePreview() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AbstractActionTool::drawStart(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
AbstractActionTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
Q_UNUSED(pixmap);
|
||||
}
|
||||
|
||||
void AbstractActionTool::colorChanged(const QColor &c) {
|
||||
Q_UNUSED(c);
|
||||
void
|
||||
AbstractActionTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(pixmap);
|
||||
Q_UNUSED(recordUndo);
|
||||
}
|
||||
|
||||
void AbstractActionTool::thicknessChanged(const int th) {
|
||||
Q_UNUSED(th);
|
||||
void
|
||||
AbstractActionTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawMove(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::colorChanged(const QColor& c)
|
||||
{
|
||||
Q_UNUSED(c);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractActionTool::thicknessChanged(const int th)
|
||||
{
|
||||
Q_UNUSED(th);
|
||||
}
|
||||
|
||||
@@ -19,23 +19,27 @@
|
||||
|
||||
#include "capturetool.h"
|
||||
|
||||
class AbstractActionTool : public CaptureTool {
|
||||
Q_OBJECT
|
||||
class AbstractActionTool : public CaptureTool
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -17,68 +17,89 @@
|
||||
|
||||
#include "abstractpathtool.h"
|
||||
|
||||
AbstractPathTool::AbstractPathTool(QObject *parent) :
|
||||
CaptureTool(parent), m_thickness(0), m_padding(0)
|
||||
AbstractPathTool::AbstractPathTool(QObject* parent)
|
||||
: CaptureTool(parent)
|
||||
, m_thickness(0)
|
||||
, m_padding(0)
|
||||
{}
|
||||
|
||||
bool
|
||||
AbstractPathTool::isValid() const
|
||||
{
|
||||
|
||||
return m_points.length() > 1;
|
||||
}
|
||||
|
||||
bool AbstractPathTool::isValid() const {
|
||||
return m_points.length() > 1;
|
||||
bool
|
||||
AbstractPathTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractPathTool::closeOnButtonPressed() const {
|
||||
return false;
|
||||
bool
|
||||
AbstractPathTool::isSelectable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractPathTool::isSelectable() const {
|
||||
return true;
|
||||
bool
|
||||
AbstractPathTool::showMousePreview() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractPathTool::showMousePreview() const {
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
void
|
||||
AbstractPathTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void AbstractPathTool::drawEnd(const QPoint &p) {
|
||||
Q_UNUSED(p);
|
||||
void
|
||||
AbstractPathTool::drawMove(const QPoint& p)
|
||||
{
|
||||
addPoint(p);
|
||||
}
|
||||
|
||||
void AbstractPathTool::drawMove(const QPoint &p) {
|
||||
addPoint(p);
|
||||
void
|
||||
AbstractPathTool::colorChanged(const QColor& c)
|
||||
{
|
||||
m_color = c;
|
||||
}
|
||||
|
||||
void AbstractPathTool::colorChanged(const QColor &c) {
|
||||
m_color = c;
|
||||
void
|
||||
AbstractPathTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_thickness = th;
|
||||
}
|
||||
|
||||
void AbstractPathTool::thicknessChanged(const int th) {
|
||||
m_thickness = th;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -19,33 +19,34 @@
|
||||
|
||||
#include "capturetool.h"
|
||||
|
||||
class AbstractPathTool : public CaptureTool {
|
||||
Q_OBJECT
|
||||
class AbstractPathTool : public CaptureTool
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -23,113 +23,145 @@ namespace {
|
||||
const double ADJ_UNIT = std::atan(1.0);
|
||||
const int DIRS_NUMBER = 4;
|
||||
|
||||
enum UNIT {
|
||||
HORIZ_DIR = 0,
|
||||
DIAG1_DIR = 1,
|
||||
VERT_DIR = 2,
|
||||
DIAG2_DIR = 3
|
||||
enum UNIT
|
||||
{
|
||||
HORIZ_DIR = 0,
|
||||
DIAG1_DIR = 1,
|
||||
VERT_DIR = 2,
|
||||
DIAG2_DIR = 3
|
||||
};
|
||||
|
||||
const double ADJ_DIAG_UNIT = 2 * ADJ_UNIT;
|
||||
const int DIAG_DIRS_NUMBER = 2;
|
||||
|
||||
enum DIAG_UNIT {
|
||||
DIR1 = 0,
|
||||
DIR2 = 1
|
||||
enum DIAG_UNIT
|
||||
{
|
||||
DIR1 = 0,
|
||||
DIR2 = 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
AbstractTwoPointTool::AbstractTwoPointTool(QObject *parent) :
|
||||
CaptureTool(parent), m_thickness(0), m_padding(0)
|
||||
AbstractTwoPointTool::AbstractTwoPointTool(QObject* parent)
|
||||
: CaptureTool(parent)
|
||||
, m_thickness(0)
|
||||
, m_padding(0)
|
||||
{}
|
||||
|
||||
bool
|
||||
AbstractTwoPointTool::isValid() const
|
||||
{
|
||||
|
||||
return (m_points.first != m_points.second);
|
||||
}
|
||||
|
||||
bool AbstractTwoPointTool::isValid() const {
|
||||
return (m_points.first != m_points.second);
|
||||
bool
|
||||
AbstractTwoPointTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractTwoPointTool::closeOnButtonPressed() const {
|
||||
return false;
|
||||
bool
|
||||
AbstractTwoPointTool::isSelectable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractTwoPointTool::isSelectable() const {
|
||||
return true;
|
||||
bool
|
||||
AbstractTwoPointTool::showMousePreview() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractTwoPointTool::showMousePreview() const {
|
||||
return true;
|
||||
void
|
||||
AbstractTwoPointTool::undo(QPixmap& pixmap)
|
||||
{
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
}
|
||||
|
||||
void AbstractTwoPointTool::undo(QPixmap &pixmap) {
|
||||
QPainter p(&pixmap);
|
||||
p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup);
|
||||
void
|
||||
AbstractTwoPointTool::drawEnd(const QPoint& p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
}
|
||||
|
||||
void AbstractTwoPointTool::drawEnd(const QPoint &p) {
|
||||
Q_UNUSED(p);
|
||||
void
|
||||
AbstractTwoPointTool::drawMove(const QPoint& p)
|
||||
{
|
||||
m_points.second = 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::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::colorChanged(const QColor &c) {
|
||||
m_color = c;
|
||||
void
|
||||
AbstractTwoPointTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_thickness = th;
|
||||
}
|
||||
|
||||
void AbstractTwoPointTool::thicknessChanged(const int th) {
|
||||
m_thickness = th;
|
||||
void
|
||||
AbstractTwoPointTool::updateBackup(const QPixmap& pixmap)
|
||||
{
|
||||
m_pixmapBackup = pixmap.copy(backupRect(pixmap.rect()));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
return v;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@@ -19,39 +19,40 @@
|
||||
|
||||
#include "capturetool.h"
|
||||
|
||||
class AbstractTwoPointTool : public CaptureTool {
|
||||
Q_OBJECT
|
||||
class AbstractTwoPointTool : public CaptureTool
|
||||
{
|
||||
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;
|
||||
|
||||
private:
|
||||
QPoint adjustedVector(QPoint v) const;
|
||||
QPoint adjustedVector(QPoint v) const;
|
||||
};
|
||||
|
||||
@@ -24,97 +24,123 @@ namespace {
|
||||
const int ArrowWidth = 10;
|
||||
const int ArrowHeight = 18;
|
||||
|
||||
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());
|
||||
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());
|
||||
|
||||
// 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) {
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
ArrowTool::ArrowTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
m_padding = ArrowWidth / 2;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
ArrowTool::ArrowTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_padding = ArrowWidth / 2;
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon ArrowTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
||||
QIcon
|
||||
ArrowTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "arrow-bottom-left.svg");
|
||||
}
|
||||
QString ArrowTool::name() const {
|
||||
return tr("Arrow");
|
||||
QString
|
||||
ArrowTool::name() const
|
||||
{
|
||||
return tr("Arrow");
|
||||
}
|
||||
|
||||
QString ArrowTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
ArrowTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString ArrowTool::description() const {
|
||||
return tr("Set the Arrow as the paint tool");
|
||||
QString
|
||||
ArrowTool::description() const
|
||||
{
|
||||
return tr("Set the Arrow as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool* ArrowTool::copy(QObject *parent) {
|
||||
return new ArrowTool(parent);
|
||||
CaptureTool*
|
||||
ArrowTool::copy(QObject* parent)
|
||||
{
|
||||
return new ArrowTool(parent);
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
void ArrowTool::paintMousePreview(QPainter &painter, const CaptureContext &context) {
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
void
|
||||
ArrowTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void ArrowTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
ArrowTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -21,22 +21,25 @@
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
class ArrowTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class ArrowTool : public AbstractTwoPointTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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,41 +23,59 @@
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
|
||||
BlurTool::BlurTool(QObject *parent) : AbstractTwoPointTool(parent) {}
|
||||
BlurTool::BlurTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{}
|
||||
|
||||
QIcon BlurTool::icon(const QColor &background, bool inEditor) const
|
||||
QIcon
|
||||
BlurTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "blur.svg");
|
||||
}
|
||||
QString BlurTool::name() const { return tr("Blur"); }
|
||||
QString
|
||||
BlurTool::name() const
|
||||
{
|
||||
return tr("Blur");
|
||||
}
|
||||
|
||||
QString BlurTool::nameID() { return QLatin1String(""); }
|
||||
QString
|
||||
BlurTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString BlurTool::description() const
|
||||
QString
|
||||
BlurTool::description() const
|
||||
{
|
||||
return tr("Set Blur as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool *BlurTool::copy(QObject *parent) { return new BlurTool(parent); }
|
||||
CaptureTool*
|
||||
BlurTool::copy(QObject* parent)
|
||||
{
|
||||
return new BlurTool(parent);
|
||||
}
|
||||
|
||||
void write_block(QImage &image, int x_start, int y_start, int pixel_size,
|
||||
QRgb block_color)
|
||||
void
|
||||
write_block(QImage& image,
|
||||
int x_start,
|
||||
int y_start,
|
||||
int pixel_size,
|
||||
QRgb block_color)
|
||||
{
|
||||
assert(x_start + pixel_size < image.width());
|
||||
assert(y_start + pixel_size < image.height());
|
||||
|
||||
for (auto x = x_start; x < x_start + pixel_size; x++)
|
||||
{
|
||||
for (auto y = y_start; y < y_start + pixel_size; y++)
|
||||
{
|
||||
for (auto x = x_start; x < x_start + pixel_size; x++) {
|
||||
for (auto y = y_start; y < y_start + pixel_size; y++) {
|
||||
image.setPixel(x, y, block_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QRgb calculate_block_averge(QImage &image, int x_start, int y_start,
|
||||
int pixel_size)
|
||||
QRgb
|
||||
calculate_block_averge(QImage& image, int x_start, int y_start, int pixel_size)
|
||||
{
|
||||
assert(x_start + pixel_size < image.width());
|
||||
assert(y_start + pixel_size < image.height());
|
||||
@@ -66,10 +84,8 @@ QRgb calculate_block_averge(QImage &image, int x_start, int y_start,
|
||||
int blue_count = 0;
|
||||
int green_count = 0;
|
||||
int pixel_count = 0;
|
||||
for (auto x = x_start; x < x_start + pixel_size; x++)
|
||||
{
|
||||
for (auto y = y_start; y < y_start + pixel_size; y++)
|
||||
{
|
||||
for (auto x = x_start; x < x_start + pixel_size; x++) {
|
||||
for (auto y = y_start; y < y_start + pixel_size; y++) {
|
||||
auto pixel = image.pixel(x, y);
|
||||
|
||||
red_count += qRed(pixel);
|
||||
@@ -78,51 +94,46 @@ QRgb calculate_block_averge(QImage &image, int x_start, int y_start,
|
||||
pixel_count++;
|
||||
}
|
||||
}
|
||||
return (qRgb(red_count / pixel_count, green_count / pixel_count,
|
||||
return (qRgb(red_count / pixel_count,
|
||||
green_count / pixel_count,
|
||||
blue_count / pixel_count));
|
||||
}
|
||||
void BlurTool::process(QPainter &painter, const QPixmap &pixmap,
|
||||
bool recordUndo)
|
||||
void
|
||||
BlurTool::process(QPainter& painter, const QPixmap& pixmap, bool recordUndo)
|
||||
{
|
||||
if (recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
QPoint &p0 = m_points.first;
|
||||
QPoint &p1 = m_points.second;
|
||||
QPoint& p0 = m_points.first;
|
||||
QPoint& p1 = m_points.second;
|
||||
auto pixelRatio = pixmap.devicePixelRatio();
|
||||
|
||||
QRect selection = QRect(p0, p1).normalized();
|
||||
QRect selectionScaled = QRect(p0 * pixelRatio, p1 * pixelRatio).normalized();
|
||||
|
||||
QPixmap *source = new QPixmap(pixmap.copy(selectionScaled));
|
||||
QPixmap* source = new QPixmap(pixmap.copy(selectionScaled));
|
||||
|
||||
QImage original_image{source->toImage()};
|
||||
QImage imageResult{source->toImage()};
|
||||
QImage original_image{ source->toImage() };
|
||||
QImage imageResult{ source->toImage() };
|
||||
unsigned int pixel_size = m_thickness;
|
||||
if (pixel_size < 1)
|
||||
{
|
||||
pixel_size =1;
|
||||
if (pixel_size < 1) {
|
||||
pixel_size = 1;
|
||||
}
|
||||
|
||||
|
||||
const unsigned int width = source->width();
|
||||
const unsigned int height = source->height();
|
||||
|
||||
// Don't start pixelating until the region is at least as big as the pixel
|
||||
if ((width > pixel_size) && (height > pixel_size))
|
||||
{
|
||||
for (unsigned int x = 0; x < (width - pixel_size); x += pixel_size)
|
||||
{
|
||||
for (unsigned int y = 0; y < (height - pixel_size); y += pixel_size)
|
||||
{
|
||||
if ((width > pixel_size) && (height > pixel_size)) {
|
||||
for (unsigned int x = 0; x < (width - pixel_size); x += pixel_size) {
|
||||
for (unsigned int y = 0; y < (height - pixel_size); y += pixel_size) {
|
||||
auto block_color =
|
||||
calculate_block_averge(original_image, x, y, pixel_size);
|
||||
write_block(imageResult, x, y, pixel_size, block_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
QPixmap result{QPixmap::fromImage(imageResult)};
|
||||
QPixmap result{ QPixmap::fromImage(imageResult) };
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.addPixmap(result);
|
||||
@@ -130,18 +141,23 @@ void BlurTool::process(QPainter &painter, const QPixmap &pixmap,
|
||||
scene.render(&painter, selection, QRectF());
|
||||
}
|
||||
|
||||
void BlurTool::paintMousePreview(QPainter &painter,
|
||||
const CaptureContext &context)
|
||||
void
|
||||
BlurTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
Q_UNUSED(painter);
|
||||
}
|
||||
|
||||
void BlurTool::drawStart(const CaptureContext &context)
|
||||
void
|
||||
BlurTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_thickness = context.thickness;
|
||||
m_points.first = context.mousePos;
|
||||
m_points.second = context.mousePos;
|
||||
}
|
||||
|
||||
void BlurTool::pressed(const CaptureContext &context) { Q_UNUSED(context); }
|
||||
void
|
||||
BlurTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -19,22 +19,25 @@
|
||||
|
||||
#include "src/tools/abstracttwopointtool.h"
|
||||
|
||||
class BlurTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class BlurTool : public AbstractTwoPointTool
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BlurTool(QObject *parent = nullptr);
|
||||
explicit BlurTool(QObject* parent = nullptr);
|
||||
|
||||
QIcon icon(const QColor &background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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,11 +17,12 @@
|
||||
|
||||
#include "capturecontext.h"
|
||||
|
||||
QPixmap CaptureContext::selectedScreenshotArea() const {
|
||||
if (selection.isNull()) {
|
||||
return screenshot;
|
||||
} else {
|
||||
return screenshot.copy(selection);
|
||||
}
|
||||
QPixmap
|
||||
CaptureContext::selectedScreenshotArea() const
|
||||
{
|
||||
if (selection.isNull()) {
|
||||
return screenshot;
|
||||
} else {
|
||||
return screenshot.copy(selection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,33 +17,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QRect>
|
||||
#include <QPoint>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
QPixmap selectedScreenshotArea() const ;
|
||||
QPixmap selectedScreenshotArea() const;
|
||||
};
|
||||
|
||||
@@ -23,131 +23,128 @@
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
|
||||
class CaptureTool : public QObject {
|
||||
Q_OBJECT
|
||||
class CaptureTool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Request actions on the main widget
|
||||
enum Request {
|
||||
// Call close() in the editor.
|
||||
REQ_CLOSE_GUI,
|
||||
// Call hide() in the editor.
|
||||
REQ_HIDE_GUI,
|
||||
// Select the whole screen.
|
||||
REQ_SELECT_ALL,
|
||||
// Disable the selection.
|
||||
REQ_HIDE_SELECTION,
|
||||
// Undo the last active modification in the stack.
|
||||
REQ_UNDO_MODIFICATION,
|
||||
// Redo the next modification in the stack.
|
||||
REQ_REDO_MODIFICATION,
|
||||
// Remove all the modifications.
|
||||
REQ_CLEAR_MODIFICATIONS,
|
||||
// Disable the active tool.
|
||||
REQ_MOVE_MODE,
|
||||
// Open the color picker under the mouse.
|
||||
REQ_SHOW_COLOR_PICKER,
|
||||
// Open/Close the side-panel.
|
||||
REQ_TOGGLE_SIDEBAR,
|
||||
// Call update() in the editor.
|
||||
REQ_REDRAW,
|
||||
// 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,
|
||||
};
|
||||
|
||||
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
|
||||
static QString nameID();
|
||||
// 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
|
||||
static QString nameID();
|
||||
// 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;
|
||||
};
|
||||
|
||||
@@ -22,50 +22,70 @@ namespace {
|
||||
#define PADDING_VALUE 2
|
||||
}
|
||||
|
||||
CircleTool::CircleTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
m_supportsDiagonalAdj = true;
|
||||
CircleTool::CircleTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon CircleTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circle-outline.svg");
|
||||
QIcon
|
||||
CircleTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circle-outline.svg");
|
||||
}
|
||||
QString CircleTool::name() const {
|
||||
return tr("Circle");
|
||||
QString
|
||||
CircleTool::name() const
|
||||
{
|
||||
return tr("Circle");
|
||||
}
|
||||
|
||||
QString CircleTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
CircleTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString CircleTool::description() const {
|
||||
return tr("Set the Circle as the paint tool");
|
||||
QString
|
||||
CircleTool::description() const
|
||||
{
|
||||
return tr("Set the Circle as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool* CircleTool::copy(QObject *parent) {
|
||||
return new CircleTool(parent);
|
||||
CaptureTool*
|
||||
CircleTool::copy(QObject* parent)
|
||||
{
|
||||
return new CircleTool(parent);
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
void CircleTool::paintMousePreview(QPainter &painter, const CaptureContext &context) {
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
void
|
||||
CircleTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void CircleTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
CircleTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -19,22 +19,25 @@
|
||||
|
||||
#include "src/tools/abstracttwopointtool.h"
|
||||
|
||||
class CircleTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class CircleTool : public AbstractTwoPointTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -21,55 +21,82 @@ namespace {
|
||||
#define PADDING_VALUE 2
|
||||
}
|
||||
|
||||
CircleCountTool::CircleCountTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
m_count = 0;
|
||||
CircleCountTool::CircleCountTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
QIcon CircleCountTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
||||
QIcon
|
||||
CircleCountTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "circlecount-outline.svg");
|
||||
}
|
||||
QString CircleCountTool::name() const {
|
||||
return tr("Circle Counter");
|
||||
QString
|
||||
CircleCountTool::name() const
|
||||
{
|
||||
return tr("Circle Counter");
|
||||
}
|
||||
|
||||
QString CircleCountTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
CircleCountTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString CircleCountTool::description() const {
|
||||
return tr("Add an autoincrementing counter bubble");
|
||||
QString
|
||||
CircleCountTool::description() const
|
||||
{
|
||||
return tr("Add an autoincrementing counter bubble");
|
||||
}
|
||||
|
||||
CaptureTool* CircleCountTool::copy(QObject *parent) {
|
||||
return new CircleCountTool(parent);
|
||||
CaptureTool*
|
||||
CircleCountTool::copy(QObject* parent)
|
||||
{
|
||||
return new CircleCountTool(parent);
|
||||
}
|
||||
|
||||
void CircleCountTool::process(QPainter &painter, const QPixmap &pixmap, bool recordUndo) {
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setBrush(m_color);
|
||||
void
|
||||
CircleCountTool::process(QPainter& painter,
|
||||
const QPixmap& pixmap,
|
||||
bool recordUndo)
|
||||
{
|
||||
if (recordUndo) {
|
||||
updateBackup(pixmap);
|
||||
}
|
||||
painter.setBrush(m_color);
|
||||
|
||||
int bubble_size=16;
|
||||
painter.drawEllipse(m_points.first,bubble_size,bubble_size);
|
||||
painter.drawText(QRectF(m_points.first.x()-bubble_size/2, m_points.first.y()-bubble_size/2, bubble_size, bubble_size), Qt::AlignCenter, QString::number(m_count));
|
||||
int bubble_size = 16;
|
||||
painter.drawEllipse(m_points.first, bubble_size, bubble_size);
|
||||
painter.drawText(QRectF(m_points.first.x() - bubble_size / 2,
|
||||
m_points.first.y() - bubble_size / 2,
|
||||
bubble_size,
|
||||
bubble_size),
|
||||
Qt::AlignCenter,
|
||||
QString::number(m_count));
|
||||
}
|
||||
|
||||
void CircleCountTool::paintMousePreview(QPainter &painter, const CaptureContext &context) {
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
void
|
||||
CircleCountTool::paintMousePreview(QPainter& painter,
|
||||
const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void CircleCountTool::drawStart(const CaptureContext &context) {
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_count = context.circleCount;
|
||||
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
||||
|
||||
void
|
||||
CircleCountTool::drawStart(const CaptureContext& context)
|
||||
{
|
||||
m_color = context.color;
|
||||
m_thickness = context.thickness + PADDING_VALUE;
|
||||
m_points.first = context.mousePos;
|
||||
m_count = context.circleCount;
|
||||
emit requestAction(REQ_INCREMENT_CIRCLE_COUNT);
|
||||
}
|
||||
|
||||
void CircleCountTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
CircleCountTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -19,23 +19,27 @@
|
||||
|
||||
#include "src/tools/abstracttwopointtool.h"
|
||||
|
||||
class CircleCountTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class CircleCountTool : public AbstractTwoPointTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -19,35 +19,49 @@
|
||||
#include "src/utils/screenshotsaver.h"
|
||||
#include <QPainter>
|
||||
|
||||
CopyTool::CopyTool(QObject *parent) : AbstractActionTool(parent) {
|
||||
CopyTool::CopyTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
CopyTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CopyTool::closeOnButtonPressed() const {
|
||||
return true;
|
||||
QIcon
|
||||
CopyTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-copy.svg");
|
||||
}
|
||||
QString
|
||||
CopyTool::name() const
|
||||
{
|
||||
return tr("Copy");
|
||||
}
|
||||
|
||||
QIcon CopyTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "content-copy.svg");
|
||||
}
|
||||
QString CopyTool::name() const {
|
||||
return tr("Copy");
|
||||
QString
|
||||
CopyTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString CopyTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
CopyTool::description() const
|
||||
{
|
||||
return tr("Copy the selection into the clipboard");
|
||||
}
|
||||
|
||||
QString CopyTool::description() const {
|
||||
return tr("Copy the selection into the clipboard");
|
||||
CaptureTool*
|
||||
CopyTool::copy(QObject* parent)
|
||||
{
|
||||
return new CopyTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* CopyTool::copy(QObject *parent) {
|
||||
return new CopyTool(parent);
|
||||
}
|
||||
|
||||
void CopyTool::pressed(const CaptureContext &context) {
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
||||
void
|
||||
CopyTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
ScreenshotSaver().saveToClipboard(context.selectedScreenshotArea());
|
||||
}
|
||||
|
||||
@@ -19,20 +19,21 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class CopyTool : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class CopyTool : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -18,35 +18,49 @@
|
||||
#include "exittool.h"
|
||||
#include <QPainter>
|
||||
|
||||
ExitTool::ExitTool(QObject *parent) : AbstractActionTool(parent) {
|
||||
ExitTool::ExitTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
ExitTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExitTool::closeOnButtonPressed() const {
|
||||
return true;
|
||||
QIcon
|
||||
ExitTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "close.svg");
|
||||
}
|
||||
QString
|
||||
ExitTool::name() const
|
||||
{
|
||||
return tr("Exit");
|
||||
}
|
||||
|
||||
QIcon ExitTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "close.svg");
|
||||
}
|
||||
QString ExitTool::name() const {
|
||||
return tr("Exit");
|
||||
QString
|
||||
ExitTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString ExitTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
ExitTool::description() const
|
||||
{
|
||||
return tr("Leave the capture screen");
|
||||
}
|
||||
|
||||
QString ExitTool::description() const {
|
||||
return tr("Leave the capture screen");
|
||||
CaptureTool*
|
||||
ExitTool::copy(QObject* parent)
|
||||
{
|
||||
return new ExitTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* ExitTool::copy(QObject *parent) {
|
||||
return new ExitTool(parent);
|
||||
}
|
||||
|
||||
void ExitTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_CLOSE_GUI);
|
||||
void
|
||||
ExitTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_CLOSE_GUI);
|
||||
}
|
||||
|
||||
@@ -19,20 +19,21 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class ExitTool : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class ExitTool : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -16,167 +16,194 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "imguruploader.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include "src/widgets/loadspinner.h"
|
||||
#include "src/widgets/imagelabel.h"
|
||||
#include "src/widgets/loadspinner.h"
|
||||
#include "src/widgets/notificationwidget.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include <QApplication>
|
||||
#include <QBuffer>
|
||||
#include <QClipboard>
|
||||
#include <QDesktopServices>
|
||||
#include <QShortcut>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QDrag>
|
||||
#include <QMimeData>
|
||||
#include <QBuffer>
|
||||
#include <QUrlQuery>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
#include <QHBoxLayout>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QMimeData>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QPushButton>
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QUrlQuery>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
ImgurUploader::ImgurUploader(const QPixmap &capture, QWidget *parent) :
|
||||
QWidget(parent), m_pixmap(capture)
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
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();
|
||||
} else {
|
||||
m_infoLabel->setText(reply->errorString());
|
||||
onUploadOk();
|
||||
}
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
} else {
|
||||
m_infoLabel->setText(reply->errorString());
|
||||
}
|
||||
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
|
||||
}
|
||||
|
||||
void ImgurUploader::startDrag() {
|
||||
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();
|
||||
}
|
||||
|
||||
void ImgurUploader::upload() {
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void ImgurUploader::onUploadOk() {
|
||||
m_infoLabel->deleteLater();
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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() {
|
||||
bool successful = QDesktopServices::openUrl(m_imageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
}
|
||||
|
||||
void ImgurUploader::copyURL() {
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
m_notification->showMessage(tr("URL copied to clipboard."));
|
||||
}
|
||||
|
||||
void ImgurUploader::openDeleteURL()
|
||||
void
|
||||
ImgurUploader::startDrag()
|
||||
{
|
||||
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
void ImgurUploader::copyImage() {
|
||||
QApplication::clipboard()->setPixmap(m_pixmap);
|
||||
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
||||
void
|
||||
ImgurUploader::upload()
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::onUploadOk()
|
||||
{
|
||||
m_infoLabel->deleteLater();
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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()
|
||||
{
|
||||
bool successful = QDesktopServices::openUrl(m_imageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::copyURL()
|
||||
{
|
||||
QApplication::clipboard()->setText(m_imageURL.toString());
|
||||
m_notification->showMessage(tr("URL copied to clipboard."));
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::openDeleteURL()
|
||||
{
|
||||
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
|
||||
if (!successful) {
|
||||
m_notification->showMessage(tr("Unable to open the URL."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImgurUploader::copyImage()
|
||||
{
|
||||
QApplication::clipboard()->setPixmap(m_pixmap);
|
||||
m_notification->showMessage(tr("Screenshot copied to clipboard."));
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QUrl>
|
||||
#include <QWidget>
|
||||
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
@@ -30,38 +30,39 @@ class QPushButton;
|
||||
class QUrl;
|
||||
class NotificationWidget;
|
||||
|
||||
class ImgurUploader : public QWidget {
|
||||
Q_OBJECT
|
||||
class ImgurUploader : public QWidget
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -19,40 +19,56 @@
|
||||
#include "imguruploader.h"
|
||||
#include <QPainter>
|
||||
|
||||
ImgurUploaderTool::ImgurUploaderTool(QObject *parent) : AbstractActionTool(parent) {
|
||||
ImgurUploaderTool::ImgurUploaderTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
ImgurUploaderTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImgurUploaderTool::closeOnButtonPressed() const {
|
||||
return true;
|
||||
QIcon
|
||||
ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cloud-upload.svg");
|
||||
}
|
||||
QString
|
||||
ImgurUploaderTool::name() const
|
||||
{
|
||||
return tr("Image Uploader");
|
||||
}
|
||||
|
||||
QIcon ImgurUploaderTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cloud-upload.svg");
|
||||
}
|
||||
QString ImgurUploaderTool::name() const {
|
||||
return tr("Image Uploader");
|
||||
QString
|
||||
ImgurUploaderTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString ImgurUploaderTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
ImgurUploaderTool::description() const
|
||||
{
|
||||
return tr("Upload the selection to Imgur");
|
||||
}
|
||||
|
||||
QString ImgurUploaderTool::description() const {
|
||||
return tr("Upload the selection to Imgur");
|
||||
QWidget*
|
||||
ImgurUploaderTool::widget()
|
||||
{
|
||||
return new ImgurUploader(capture);
|
||||
}
|
||||
|
||||
QWidget* ImgurUploaderTool::widget() {
|
||||
return new ImgurUploader(capture);
|
||||
CaptureTool*
|
||||
ImgurUploaderTool::copy(QObject* parent)
|
||||
{
|
||||
return new ImgurUploaderTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* ImgurUploaderTool::copy(QObject *parent) {
|
||||
return new ImgurUploaderTool(parent);
|
||||
}
|
||||
|
||||
void ImgurUploaderTool::pressed(const CaptureContext &context) {
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
void
|
||||
ImgurUploaderTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
}
|
||||
|
||||
@@ -19,25 +19,26 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class ImgurUploaderTool : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class ImgurUploaderTool : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
QWidget* widget() 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;
|
||||
|
||||
private:
|
||||
QPixmap capture;
|
||||
QPixmap capture;
|
||||
};
|
||||
|
||||
@@ -18,40 +18,56 @@
|
||||
#include "applaunchertool.h"
|
||||
#include "applauncherwidget.h"
|
||||
|
||||
AppLauncher::AppLauncher(QObject *parent) : AbstractActionTool(parent) {
|
||||
AppLauncher::AppLauncher(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
AppLauncher::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppLauncher::closeOnButtonPressed() const {
|
||||
return true;
|
||||
QIcon
|
||||
AppLauncher::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "open_with.svg");
|
||||
}
|
||||
QString
|
||||
AppLauncher::name() const
|
||||
{
|
||||
return tr("App Launcher");
|
||||
}
|
||||
|
||||
QIcon AppLauncher::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "open_with.svg");
|
||||
}
|
||||
QString AppLauncher::name() const {
|
||||
return tr("App Launcher");
|
||||
QString
|
||||
AppLauncher::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString AppLauncher::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
AppLauncher::description() const
|
||||
{
|
||||
return tr("Choose an app to open the capture");
|
||||
}
|
||||
|
||||
QString AppLauncher::description() const {
|
||||
return tr("Choose an app to open the capture");
|
||||
QWidget*
|
||||
AppLauncher::widget()
|
||||
{
|
||||
return new AppLauncherWidget(capture);
|
||||
}
|
||||
|
||||
QWidget* AppLauncher::widget() {
|
||||
return new AppLauncherWidget(capture);
|
||||
CaptureTool*
|
||||
AppLauncher::copy(QObject* parent)
|
||||
{
|
||||
return new AppLauncher(parent);
|
||||
}
|
||||
|
||||
CaptureTool* AppLauncher::copy(QObject *parent) {
|
||||
return new AppLauncher(parent);
|
||||
}
|
||||
|
||||
void AppLauncher::pressed(const CaptureContext &context) {
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
void
|
||||
AppLauncher::pressed(const CaptureContext& context)
|
||||
{
|
||||
capture = context.selectedScreenshotArea();
|
||||
emit requestAction(REQ_CAPTURE_DONE_OK);
|
||||
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
|
||||
}
|
||||
|
||||
@@ -19,25 +19,26 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class AppLauncher : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class AppLauncher : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
QWidget* widget() 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;
|
||||
|
||||
private:
|
||||
QPixmap capture;
|
||||
QPixmap capture;
|
||||
};
|
||||
|
||||
@@ -16,233 +16,253 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "applauncherwidget.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/tools/launcher/launcheritemdelegate.h"
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include "terminallauncher.h"
|
||||
#include <QDir>
|
||||
#include <QList>
|
||||
#include <QProcess>
|
||||
#include <QPixmap>
|
||||
#include <QListView>
|
||||
#include <QTabWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QHBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QList>
|
||||
#include <QListView>
|
||||
#include <QListWidgetItem>
|
||||
#include <QMessageBox>
|
||||
#include <QPixmap>
|
||||
#include <QProcess>
|
||||
#include <QTabWidget>
|
||||
|
||||
namespace {
|
||||
|
||||
QMap<QString, QString> catIconNames({
|
||||
{ "Multimedia", "applications-multimedia" },
|
||||
{ "Development","applications-development" },
|
||||
{ "Graphics", "applications-graphics" },
|
||||
{ "Network", "preferences-system-network" },
|
||||
{ "Office", "applications-office" },
|
||||
{ "Science", "applications-science" },
|
||||
{ "Settings", "preferences-desktop" },
|
||||
{ "System", "preferences-system" },
|
||||
{ "Utility", "applications-utilities" }
|
||||
});
|
||||
QMap<QString, QString> catIconNames(
|
||||
{ { "Multimedia", "applications-multimedia" },
|
||||
{ "Development", "applications-development" },
|
||||
{ "Graphics", "applications-graphics" },
|
||||
{ "Network", "preferences-system-network" },
|
||||
{ "Office", "applications-office" },
|
||||
{ "Science", "applications-science" },
|
||||
{ "Settings", "preferences-desktop" },
|
||||
{ "System", "preferences-system" },
|
||||
{ "Utility", "applications-utilities" } });
|
||||
}
|
||||
|
||||
AppLauncherWidget::AppLauncherWidget(const QPixmap &p, QWidget *parent):
|
||||
QWidget(parent), m_pixmap(p)
|
||||
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;
|
||||
// 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()) {
|
||||
m_filterList->hide();
|
||||
configureListView(m_filterList);
|
||||
connect(m_filterList, &QListWidget::clicked, this, &AppLauncherWidget::launch);
|
||||
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->addWidget(m_filterList);
|
||||
m_layout->addWidget(m_tabWidget);
|
||||
m_layout->addWidget(m_lineEdit);
|
||||
m_layout->addWidget(m_keepOpenCheckbox);
|
||||
m_layout->addWidget(m_terminalCheckbox);
|
||||
m_lineEdit->setFocus();
|
||||
}
|
||||
|
||||
void AppLauncherWidget::launch(const QModelIndex &index) {
|
||||
if (!QFileInfo(m_tempFile).isReadable()) {
|
||||
m_tempFile = FileNameHandler().generateAbsolutePath(QDir::tempPath()) + ".png";
|
||||
bool ok = m_pixmap.save(m_tempFile);
|
||||
if (!ok) {
|
||||
QMessageBox::about(this, tr("Error"), tr("Unable to write in")
|
||||
+ QDir::tempPath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
QString command = index.data(Qt::UserRole).toString().replace(
|
||||
QRegExp("(\\%.)"), '"' + m_tempFile + '"');
|
||||
|
||||
QString app_name = index.data(Qt::UserRole).toString().split(" ").at(0);
|
||||
bool inTerminal = index.data(Qt::UserRole+1).toBool() ||
|
||||
m_terminalCheckbox->isChecked();
|
||||
if (inTerminal) {
|
||||
bool ok = TerminalLauncher::launchDetached(command);
|
||||
if (!ok) {
|
||||
QMessageBox::about(this, tr("Error"),
|
||||
tr("Unable to launch in terminal."));
|
||||
}
|
||||
} else {
|
||||
QProcess::startDetached(app_name,{m_tempFile});
|
||||
}
|
||||
if (!m_keepOpen) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void AppLauncherWidget::checkboxClicked(const bool enabled) {
|
||||
m_keepOpen = enabled;
|
||||
ConfigHandler().setKeepOpenAppLauncher(enabled);
|
||||
m_keepOpenCheckbox->setChecked(enabled);
|
||||
}
|
||||
|
||||
void AppLauncherWidget::searchChanged(const QString &text) {
|
||||
if (text.isEmpty()) {
|
||||
m_filterList->hide();
|
||||
m_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));
|
||||
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;
|
||||
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);
|
||||
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::initAppMap() {
|
||||
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);
|
||||
}
|
||||
|
||||
void AppLauncherWidget::configureListView(QListWidget *widget) {
|
||||
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::addAppsToListWidget(
|
||||
QListWidget *widget, const QVector<DesktopAppData> &appList)
|
||||
void
|
||||
AppLauncherWidget::initListWidget()
|
||||
{
|
||||
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);
|
||||
m_tabWidget = new QTabWidget;
|
||||
const int size = GlobalValues::buttonBaseSize();
|
||||
m_tabWidget->setIconSize(QSize(size, size));
|
||||
|
||||
buttonItem->setIcon(app.icon);
|
||||
buttonItem->setText(app.name);
|
||||
buttonItem->setToolTip(app.description);
|
||||
for (auto const& i : catIconNames.toStdMap()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncherWidget::initAppMap()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
AppLauncherWidget::configureListView(QListWidget* widget)
|
||||
{
|
||||
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::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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/utils/desktopfileparse.h"
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
#include <QWidget>
|
||||
|
||||
class QTabWidget;
|
||||
class QCheckBox;
|
||||
@@ -27,32 +27,33 @@ class QVBoxLayout;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
|
||||
class AppLauncherWidget: public QWidget {
|
||||
Q_OBJECT
|
||||
class AppLauncherWidget : public QWidget
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -19,48 +19,49 @@
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include <QPainter>
|
||||
|
||||
LauncherItemDelegate::LauncherItemDelegate(QObject *parent) :
|
||||
QStyledItemDelegate(parent)
|
||||
LauncherItemDelegate::LauncherItemDelegate(QObject* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
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 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());
|
||||
}
|
||||
|
||||
void LauncherItemDelegate::paint(
|
||||
QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
QSize
|
||||
LauncherItemDelegate::sizeHint(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 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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -20,14 +20,16 @@
|
||||
#include "src/utils/desktopfileparse.h"
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class LauncherItemDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
class LauncherItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -15,40 +15,42 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "openwithprogram.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <windows.h>
|
||||
#include <Shlobj.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib, "Shell32.lib")
|
||||
#else
|
||||
#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,4 +19,5 @@
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
void showOpenWithMenu(const QPixmap &capture);
|
||||
void
|
||||
showOpenWithMenu(const QPixmap& capture);
|
||||
|
||||
@@ -16,45 +16,50 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "terminallauncher.h"
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QStandardPaths>
|
||||
|
||||
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" },
|
||||
};
|
||||
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" },
|
||||
};
|
||||
}
|
||||
|
||||
TerminalLauncher::TerminalLauncher(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
TerminalLauncher::TerminalLauncher(QObject* parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
TerminalApp TerminalLauncher::getPreferedTerminal() {
|
||||
TerminalApp res;
|
||||
for (const TerminalApp &app : terminalApps) {
|
||||
QString path = QStandardPaths::findExecutable(app.name);
|
||||
if (!path.isEmpty()) {
|
||||
res = app;
|
||||
break;
|
||||
}
|
||||
TerminalApp
|
||||
TerminalLauncher::getPreferedTerminal()
|
||||
{
|
||||
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) {
|
||||
TerminalApp app = getPreferedTerminal();
|
||||
QString s = app.name + " " + app.arg + " " + command;
|
||||
return QProcess::startDetached(app.name, {app.arg,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 });
|
||||
}
|
||||
|
||||
@@ -19,17 +19,20 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
struct TerminalApp {
|
||||
QString name;
|
||||
QString arg;
|
||||
struct TerminalApp
|
||||
{
|
||||
QString name;
|
||||
QString arg;
|
||||
};
|
||||
|
||||
class TerminalLauncher : public QObject {
|
||||
Q_OBJECT
|
||||
class TerminalLauncher : public QObject
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -24,51 +24,71 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
LineTool::LineTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
LineTool::LineTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon LineTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "line.svg");
|
||||
QIcon
|
||||
LineTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "line.svg");
|
||||
}
|
||||
QString LineTool::name() const {
|
||||
return tr("Line");
|
||||
QString
|
||||
LineTool::name() const
|
||||
{
|
||||
return tr("Line");
|
||||
}
|
||||
|
||||
QString LineTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
LineTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString LineTool::description() const {
|
||||
return tr("Set the Line as the paint tool");
|
||||
QString
|
||||
LineTool::description() const
|
||||
{
|
||||
return tr("Set the Line as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool* LineTool::copy(QObject *parent) {
|
||||
return new LineTool(parent);
|
||||
CaptureTool*
|
||||
LineTool::copy(QObject* parent)
|
||||
{
|
||||
return new LineTool(parent);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
void LineTool::paintMousePreview(QPainter &painter, const CaptureContext &context) {
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
void
|
||||
LineTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, PADDING_VALUE + context.thickness));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void LineTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
LineTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -19,22 +19,25 @@
|
||||
|
||||
#include "src/tools/abstracttwopointtool.h"
|
||||
|
||||
class LineTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class LineTool : public AbstractTwoPointTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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,59 +24,81 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
MarkerTool::MarkerTool(QObject *parent) : AbstractTwoPointTool(parent) {
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
MarkerTool::MarkerTool(QObject* parent)
|
||||
: AbstractTwoPointTool(parent)
|
||||
{
|
||||
m_supportsOrthogonalAdj = true;
|
||||
m_supportsDiagonalAdj = true;
|
||||
}
|
||||
|
||||
QIcon MarkerTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "marker.svg");
|
||||
QIcon
|
||||
MarkerTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "marker.svg");
|
||||
}
|
||||
QString MarkerTool::name() const {
|
||||
return tr("Marker");
|
||||
QString
|
||||
MarkerTool::name() const
|
||||
{
|
||||
return tr("Marker");
|
||||
}
|
||||
|
||||
QString MarkerTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
MarkerTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString MarkerTool::description() const {
|
||||
return tr("Set the Marker as the paint tool");
|
||||
QString
|
||||
MarkerTool::description() const
|
||||
{
|
||||
return tr("Set the Marker as the paint tool");
|
||||
}
|
||||
|
||||
CaptureTool* MarkerTool::copy(QObject *parent) {
|
||||
return new MarkerTool(parent);
|
||||
CaptureTool*
|
||||
MarkerTool::copy(QObject* parent)
|
||||
{
|
||||
return new MarkerTool(parent);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
void MarkerTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
MarkerTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
void MarkerTool::thicknessChanged(const int th) {
|
||||
m_thickness = th + PADDING_VALUE;
|
||||
void
|
||||
MarkerTool::thicknessChanged(const int th)
|
||||
{
|
||||
m_thickness = th + PADDING_VALUE;
|
||||
}
|
||||
|
||||
@@ -19,23 +19,26 @@
|
||||
|
||||
#include "src/tools/abstracttwopointtool.h"
|
||||
|
||||
class MarkerTool : public AbstractTwoPointTool {
|
||||
Q_OBJECT
|
||||
class MarkerTool : public AbstractTwoPointTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -18,35 +18,49 @@
|
||||
#include "movetool.h"
|
||||
#include <QPainter>
|
||||
|
||||
MoveTool::MoveTool(QObject *parent) : AbstractActionTool(parent) {
|
||||
MoveTool::MoveTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
MoveTool::closeOnButtonPressed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MoveTool::closeOnButtonPressed() const {
|
||||
return false;
|
||||
QIcon
|
||||
MoveTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cursor-move.svg");
|
||||
}
|
||||
QString
|
||||
MoveTool::name() const
|
||||
{
|
||||
return tr("Move");
|
||||
}
|
||||
|
||||
QIcon MoveTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "cursor-move.svg");
|
||||
}
|
||||
QString MoveTool::name() const {
|
||||
return tr("Move");
|
||||
QString
|
||||
MoveTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString MoveTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
MoveTool::description() const
|
||||
{
|
||||
return tr("Move the selection area");
|
||||
}
|
||||
|
||||
QString MoveTool::description() const {
|
||||
return tr("Move the selection area");
|
||||
CaptureTool*
|
||||
MoveTool::copy(QObject* parent)
|
||||
{
|
||||
return new MoveTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* MoveTool::copy(QObject *parent) {
|
||||
return new MoveTool(parent);
|
||||
}
|
||||
|
||||
void MoveTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_MOVE_MODE);
|
||||
void
|
||||
MoveTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
emit requestAction(REQ_MOVE_MODE);
|
||||
}
|
||||
|
||||
@@ -19,20 +19,21 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class MoveTool : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class MoveTool : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -18,51 +18,69 @@
|
||||
#include "penciltool.h"
|
||||
#include <QPainter>
|
||||
|
||||
PencilTool::PencilTool(QObject *parent) : AbstractPathTool(parent) {
|
||||
PencilTool::PencilTool(QObject* parent)
|
||||
: AbstractPathTool(parent)
|
||||
{}
|
||||
|
||||
QIcon
|
||||
PencilTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pencil.svg");
|
||||
}
|
||||
QString
|
||||
PencilTool::name() const
|
||||
{
|
||||
return tr("Pencil");
|
||||
}
|
||||
|
||||
QIcon PencilTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pencil.svg");
|
||||
}
|
||||
QString PencilTool::name() const {
|
||||
return tr("Pencil");
|
||||
QString
|
||||
PencilTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString PencilTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
PencilTool::description() const
|
||||
{
|
||||
return tr("Set the Pencil as the paint tool");
|
||||
}
|
||||
|
||||
QString PencilTool::description() const {
|
||||
return tr("Set the Pencil as the paint tool");
|
||||
CaptureTool*
|
||||
PencilTool::copy(QObject* parent)
|
||||
{
|
||||
return new PencilTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* PencilTool::copy(QObject *parent) {
|
||||
return new PencilTool(parent);
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
void
|
||||
PencilTool::paintMousePreview(QPainter& painter, const CaptureContext& context)
|
||||
{
|
||||
painter.setPen(QPen(context.color, context.thickness + 2));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
}
|
||||
|
||||
void PencilTool::paintMousePreview(QPainter &painter, const CaptureContext &context) {
|
||||
painter.setPen(QPen(context.color, context.thickness + 2));
|
||||
painter.drawLine(context.mousePos, context.mousePos);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void PencilTool::pressed(const CaptureContext &context) {
|
||||
Q_UNUSED(context);
|
||||
void
|
||||
PencilTool::pressed(const CaptureContext& context)
|
||||
{
|
||||
Q_UNUSED(context);
|
||||
}
|
||||
|
||||
@@ -19,23 +19,26 @@
|
||||
|
||||
#include "src/tools/abstractpathtool.h"
|
||||
|
||||
class PencilTool : public AbstractPathTool {
|
||||
Q_OBJECT
|
||||
class PencilTool : public AbstractPathTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
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;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -18,47 +18,62 @@
|
||||
#include "pintool.h"
|
||||
#include "src/tools/pin/pinwidget.h"
|
||||
|
||||
PinTool::PinTool(QObject *parent) : AbstractActionTool(parent) {
|
||||
PinTool::PinTool(QObject* parent)
|
||||
: AbstractActionTool(parent)
|
||||
{}
|
||||
|
||||
bool
|
||||
PinTool::closeOnButtonPressed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PinTool::closeOnButtonPressed() const {
|
||||
return true;
|
||||
QIcon
|
||||
PinTool::icon(const QColor& background, bool inEditor) const
|
||||
{
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pin.svg");
|
||||
}
|
||||
QString
|
||||
PinTool::name() const
|
||||
{
|
||||
return tr("Pin Tool");
|
||||
}
|
||||
|
||||
QIcon PinTool::icon(const QColor &background, bool inEditor) const {
|
||||
Q_UNUSED(inEditor);
|
||||
return QIcon(iconPath(background) + "pin.svg");
|
||||
}
|
||||
QString PinTool::name() const {
|
||||
return tr("Pin Tool");
|
||||
QString
|
||||
PinTool::nameID()
|
||||
{
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
QString PinTool::nameID() {
|
||||
return QLatin1String("");
|
||||
QString
|
||||
PinTool::description() const
|
||||
{
|
||||
return tr("Pin image on the desktop");
|
||||
}
|
||||
|
||||
QString PinTool::description() const {
|
||||
return tr("Pin image on the desktop");
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
CaptureTool*
|
||||
PinTool::copy(QObject* parent)
|
||||
{
|
||||
return new PinTool(parent);
|
||||
}
|
||||
|
||||
CaptureTool* PinTool::copy(QObject *parent) {
|
||||
return new PinTool(parent);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
27
src/tools/pin/pintool.h
Executable file → Normal file
27
src/tools/pin/pintool.h
Executable file → Normal file
@@ -19,26 +19,27 @@
|
||||
|
||||
#include "src/tools/abstractactiontool.h"
|
||||
|
||||
class PinTool : public AbstractActionTool {
|
||||
Q_OBJECT
|
||||
class PinTool : public AbstractActionTool
|
||||
{
|
||||
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;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
QIcon icon(const QColor& background, bool inEditor) const override;
|
||||
QString name() const override;
|
||||
static QString nameID();
|
||||
QString description() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
QWidget* widget() 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;
|
||||
|
||||
private:
|
||||
QRect m_geometry;
|
||||
QPixmap m_pixmap;
|
||||
QRect m_geometry;
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user