Commit 03026df2 authored by Bharadwaj Raju's avatar Bharadwaj Raju Committed by Nate Graham
Browse files

Add feature to annotate existing screenshots

Can be accessed:
* Using a button in the notification, if saved to file
* From the new CLI flag `--edit-existing <file>`

BUG: 431257
FIXED-IN: 22.04
parent 9a0b4155
Pipeline #104396 passed with stage
in 43 seconds
......@@ -4,3 +4,4 @@ Description=Spectacle screenshot capture utility
[Service]
ExecStart=@CMAKE_INSTALL_PREFIX@/bin/spectacle --dbus
BusName=org.kde.Spectacle
KillMode=process
......@@ -387,7 +387,7 @@ void KSMainWindow::captureScreenshot(Spectacle::CaptureMode theCaptureMode, int
delayAnimation->start();
}
void KSMainWindow::setScreenshotAndShow(const QPixmap &pixmap)
void KSMainWindow::setScreenshotAndShow(const QPixmap &pixmap, bool showAnnotator)
{
if (!pixmap.isNull()) {
mKSWidget->setScreenshotPixmap(pixmap);
......@@ -405,6 +405,9 @@ void KSMainWindow::setScreenshotAndShow(const QPixmap &pixmap)
if (!pixmap.isNull()) {
resize(QSize(windowWidth(pixmap), DEFAULT_WINDOW_HEIGHT));
}
if (showAnnotator) {
mAnnotateButton->click();
}
}
void KSMainWindow::showPrintDialog()
......
......@@ -63,7 +63,7 @@ private Q_SLOTS:
public Q_SLOTS:
void setScreenshotAndShow(const QPixmap &pixmap);
void setScreenshotAndShow(const QPixmap &pixmap, bool showAnnotator);
void imageSaved(const QUrl &location);
void imageSavedAndCopied(const QUrl &location);
void screenshotFailed();
......
......@@ -86,6 +86,7 @@ void SpectacleCore::onActivateRequested(QStringList arguments, const QString & /
parser->parse(arguments);
mStartMode = SpectacleCore::StartMode::Gui;
mExistingLoaded = false;
mNotify = true;
qint64 lDelayMsec = 0;
......@@ -96,6 +97,18 @@ void SpectacleCore::onActivateRequested(QStringList arguments, const QString & /
mStartMode = SpectacleCore::StartMode::DBus;
}
mEditExisting = parser->isSet(QStringLiteral("edit-existing"));
if (mEditExisting) {
QString lExistingFileName = parser->value(QStringLiteral("edit-existing"));
if (!(lExistingFileName.isEmpty() || lExistingFileName.isNull())) {
if (QDir::isRelativePath(lExistingFileName)) {
lExistingFileName = QDir::current().absoluteFilePath(lExistingFileName);
}
setFilename(lExistingFileName);
mSaveToOutput = true;
}
}
auto lOnClickAvailable = mPlatform->supportedShutterModes().testFlag(Platform::ShutterMode::OnClick);
if ((!lOnClickAvailable) && (lDelayMsec < 0)) {
lDelayMsec = 0;
......@@ -121,10 +134,11 @@ void SpectacleCore::onActivateRequested(QStringList arguments, const QString & /
} else if (parser->isSet(QStringLiteral("transientonly"))) {
lCaptureMode = Spectacle::CaptureMode::WindowUnderCursor;
} else if (mStartMode == SpectacleCore::StartMode::Gui
&& (parser->isSet(QStringLiteral("launchonly")) || Settings::onLaunchAction() == Settings::EnumOnLaunchAction::DoNotTakeScreenshot)) {
&& (parser->isSet(QStringLiteral("launchonly")) || Settings::onLaunchAction() == Settings::EnumOnLaunchAction::DoNotTakeScreenshot)
&& !mEditExisting) {
initGuiNoScreenshot();
return;
} else if (Settings::onLaunchAction() == Settings::EnumOnLaunchAction::UseLastUsedCapturemode) {
} else if (Settings::onLaunchAction() == Settings::EnumOnLaunchAction::UseLastUsedCapturemode && !mEditExisting) {
lCaptureMode = Settings::captureMode();
if (Settings::onClickChecked()) {
lDelayMsec = -1;
......@@ -316,6 +330,12 @@ void SpectacleCore::screenshotsUpdated(const QVector<QImage> &imgs)
void SpectacleCore::screenshotUpdated(const QPixmap &thePixmap)
{
QPixmap existingPixmap;
const QPixmap &pixmapUsed = (mEditExisting && !mExistingLoaded) ? existingPixmap : thePixmap;
if (mEditExisting && !mExistingLoaded) {
existingPixmap.load(filename());
}
auto lExportManager = ExportManager::instance();
if (lExportManager->captureMode() == Spectacle::CaptureMode::RectangularRegion) {
......@@ -325,7 +345,7 @@ void SpectacleCore::screenshotUpdated(const QPixmap &thePixmap)
}
}
lExportManager->setPixmap(thePixmap);
lExportManager->setPixmap(pixmapUsed);
lExportManager->updatePixmapTimestamp();
switch (mStartMode) {
......@@ -357,12 +377,12 @@ void SpectacleCore::screenshotUpdated(const QPixmap &thePixmap)
}
} break;
case StartMode::Gui:
if (thePixmap.isNull()) {
mMainWindow->setScreenshotAndShow(thePixmap);
if (pixmapUsed.isNull()) {
mMainWindow->setScreenshotAndShow(pixmapUsed, false);
mMainWindow->setPlaceholderTextOnLaunch();
return;
}
mMainWindow->setScreenshotAndShow(thePixmap);
mMainWindow->setScreenshotAndShow(pixmapUsed, mEditExisting);
bool autoSaveImage = Settings::autoSaveImage();
mCopyImageToClipboard = Settings::clipboardGroup() == Settings::EnumClipboardGroup::PostScreenshotCopyImage;
......@@ -378,6 +398,12 @@ void SpectacleCore::screenshotUpdated(const QPixmap &thePixmap)
lExportManager->doCopyLocationToClipboard(false);
}
}
if (mEditExisting && !mExistingLoaded) {
Settings::setLastSaveLocation(mFileNameUrl);
mMainWindow->imageSaved(mFileNameUrl);
mExistingLoaded = true;
}
}
void SpectacleCore::screenshotCanceled()
......@@ -385,7 +411,7 @@ void SpectacleCore::screenshotCanceled()
mQuickEditor->hide();
mQuickEditor.reset(nullptr);
if (mStartMode == StartMode::Gui) {
mMainWindow->setScreenshotAndShow(QPixmap());
mMainWindow->setScreenshotAndShow(QPixmap(), false);
} else {
Q_EMIT allDone();
}
......@@ -409,7 +435,7 @@ void SpectacleCore::screenshotFailed()
return;
case StartMode::Gui:
mMainWindow->screenshotFailed();
mMainWindow->setScreenshotAndShow(QPixmap());
mMainWindow->setScreenshotAndShow(QPixmap(), false);
}
}
......@@ -459,16 +485,21 @@ void SpectacleCore::doNotify(const QUrl &theSavedAt)
if (!theSavedAt.isEmpty()) {
lNotify->setUrls({theSavedAt});
lNotify->setDefaultAction(i18nc("Open the screenshot we just saved", "Open"));
connect(lNotify, QOverload<uint>::of(&KNotification::activated), this, [this, theSavedAt](uint index) {
if (index == 0) {
auto job = new KIO::OpenUrlJob(theSavedAt);
job->start();
QTimer::singleShot(250, this, [this] {
if (!mIsGuiInited || Settings::quitAfterSaveCopyExport()) {
Q_EMIT allDone();
}
});
}
connect(lNotify, &KNotification::defaultActivated, this, [this, theSavedAt]() {
auto job = new KIO::OpenUrlJob(theSavedAt);
job->start();
QTimer::singleShot(250, this, [this] {
if (!mIsGuiInited || Settings::quitAfterSaveCopyExport()) {
emit allDone();
}
});
});
lNotify->setActions({i18n("Annotate")});
connect(lNotify, &KNotification::action1Activated, this, [this, theSavedAt]() {
QProcess newInstance;
newInstance.setProgram(QStringLiteral("spectacle"));
newInstance.setArguments({QStringLiteral("--new-instance"), QStringLiteral("--edit-existing"), theSavedAt.toLocalFile()});
newInstance.startDetached();
});
}
......@@ -512,6 +543,7 @@ void SpectacleCore::populateCommandLineParser(QCommandLineParser *lCmdLineParser
{{QStringLiteral("i"), QStringLiteral("new-instance")}, i18n("Starts a new GUI instance of spectacle without registering to DBus")},
{{QStringLiteral("p"), QStringLiteral("pointer")}, i18n("In background mode, include pointer in the screenshot")},
{{QStringLiteral("e"), QStringLiteral("no-decoration")}, i18n("In background mode, exclude decorations in the screenshot")},
{{QStringLiteral("E"),QStringLiteral("edit-existing")}, i18n("Open and edit existing screenshot file"), QStringLiteral("existingFileName")},
});
}
......
......@@ -84,6 +84,8 @@ private:
bool mCopyImageToClipboard;
bool mCopyLocationToClipboard;
bool mSaveToOutput;
bool mEditExisting;
bool mExistingLoaded;
KWayland::Client::PlasmaShell *mWaylandPlasmashell = nullptr;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment