diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,12 @@ set(XCB_COMPONENTS_FOUND FALSE) endif() +find_package(kImageAnnotator) + +if(kImageAnnotator_FOUND) + set(KIMAGEANNOTATOR_FOUND 1) +endif() + # fail build if none of the platform backends can be found if (NOT XCB_FOUND OR NOT XCB_COMPONENTS_FOUND) message(FATAL_ERROR "No suitable backend platform was found. Currently supported platforms are: XCB Components Required: ${XCB_COMPONENTS_ERRORS}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,4 +115,8 @@ ) endif() +if(KIMAGEANNOTATOR_FOUND) + target_link_libraries(spectacle kImageAnnotator::kImageAnnotator) +endif() + install(TARGETS spectacle ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/Config.h.in b/src/Config.h.in --- a/src/Config.h.in +++ b/src/Config.h.in @@ -13,4 +13,7 @@ /* Set the Spectacle version from CMake */ #cmakedefine SPECTACLE_VERSION "@SPECTACLE_VERSION@" +/* Define to 1 if we have kImageAnnotator */ +#cmakedefine KIMAGEANNOTATOR_FOUND 1 + #endif diff --git a/src/Gui/KSMainWindow.h b/src/Gui/KSMainWindow.h --- a/src/Gui/KSMainWindow.h +++ b/src/Gui/KSMainWindow.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include "KSWidget.h" #include "ExportMenu.h" #include "Platforms/Platform.h" +#include "Config.h" #include @@ -118,4 +120,10 @@ ExportMenu *mExportMenu; Platform::ShutterModes mShutterModes; QTimer *mHideMessageWidgetTimer; + QStackedLayout *mStack; + +#ifdef KIMAGEANNOTATOR_FOUND + QToolButton *mAnnotateButton; + bool mAnnotatorActive; +#endif }; diff --git a/src/Gui/KSMainWindow.cpp b/src/Gui/KSMainWindow.cpp --- a/src/Gui/KSMainWindow.cpp +++ b/src/Gui/KSMainWindow.cpp @@ -80,6 +80,10 @@ mScreenRecorderToolsMenu(new QMenu(this)), mExportMenu(new ExportMenu(this)), mShutterModes(theShutterModes) +#ifdef KIMAGEANNOTATOR_FOUND + ,mAnnotateButton(new QToolButton(this)) + ,mAnnotatorActive(false) +#endif { // before we do anything, we need to set a window property // that skips the close/hide window animation on kwin. this @@ -152,6 +156,31 @@ mConfigureButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mDialogButtonBox->addButton(mConfigureButton, QDialogButtonBox::ResetRole); +#ifdef KIMAGEANNOTATOR_FOUND + mAnnotateButton->setText(i18n("Annotate")); + mAnnotateButton->setToolTip(i18n("Add annotation to the screenshot")); + mAnnotateButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mAnnotateButton->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); + connect(mAnnotateButton, &QToolButton::pressed, this, [this] { + + if (mAnnotatorActive) { + mKSWidget->hideAnnotator(); + mAnnotateButton->setText(i18n("Annotate")); + } else { + mKSWidget->showAnnotator(); + mAnnotateButton->setText(i18n("Annotation done")); + } + mAnnotatorActive = !mAnnotatorActive; + + mToolsButton->setEnabled(!mAnnotatorActive); + mSendToButton->setEnabled(!mAnnotatorActive); + mClipboardButton->setEnabled(!mAnnotatorActive); + mSaveButton->setEnabled(!mAnnotatorActive); + }); + + mDialogButtonBox->addButton(mAnnotateButton, QDialogButtonBox::ActionRole); +#endif + KGuiItem::assign(mToolsButton, KGuiItem(i18n("Tools"))); mToolsButton->setIcon(QIcon::fromTheme(QStringLiteral("tools"), QIcon::fromTheme(QStringLiteral("application-menu")))); diff --git a/src/Gui/KSWidget.h b/src/Gui/KSWidget.h --- a/src/Gui/KSWidget.h +++ b/src/Gui/KSWidget.h @@ -26,6 +26,7 @@ #include "SpectacleCommon.h" #include "Platforms/Platform.h" +#include "Config.h" class QAction; class QGridLayout; @@ -35,13 +36,18 @@ class QComboBox; class QCheckBox; class QLabel; - class KConfigDialogManager; +class QPushButton; +class QStackedLayout; class KSImageWidget; class ProgressButton; class SmartSpinBox; +namespace kImageAnnotator { + class KImageAnnotator; +} + class KSWidget : public QWidget { Q_OBJECT @@ -73,6 +79,11 @@ void setButtonState(State state); void setProgress(double progress); +#ifdef KIMAGEANNOTATOR_FOUND + void showAnnotator(); + void hideAnnotator(); +#endif + private Q_SLOTS: void newScreenshotClicked(); @@ -101,4 +112,9 @@ QAction *mTakeNewScreenshotAction; QAction *mCancelAction; KConfigDialogManager *mConfigManager; + QStackedLayout *mStack { nullptr }; + QWidget *placeHolder; +#ifdef KIMAGEANNOTATOR_FOUND + kImageAnnotator::KImageAnnotator *mAnnotator { nullptr }; +#endif }; diff --git a/src/Gui/KSWidget.cpp b/src/Gui/KSWidget.cpp --- a/src/Gui/KSWidget.cpp +++ b/src/Gui/KSWidget.cpp @@ -25,6 +25,8 @@ #include "settings.h" #include "SmartSpinBox.h" #include "ProgressButton.h" +#include "ExportManager.h" +#include "Config.h" #include #include @@ -35,18 +37,31 @@ #include #include #include +#include + +#ifdef KIMAGEANNOTATOR_FOUND +#include +#endif #include #include KSWidget::KSWidget(const Platform::GrabModes &theGrabModes, QWidget *parent) : QWidget(parent) { + mStack = new QStackedLayout(this); + // we'll init the widget that holds the image first mImageWidget = new KSImageWidget(this); mImageWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); connect(mImageWidget, &KSImageWidget::dragInitiated, this, &KSWidget::dragInitiated); +#ifdef KIMAGEANNOTATOR_FOUND + mAnnotator = new kImageAnnotator::KImageAnnotator(); + mAnnotator->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + mStack->addWidget(mAnnotator); +#endif + // the capture mode options first mCaptureModeLabel = new QLabel(i18n("Capture Mode"), this); mCaptureArea = new QComboBox(this); @@ -158,7 +173,8 @@ mRightLayout->addWidget(mTakeScreenshotButton, 1, Qt::AlignHCenter); mRightLayout->setContentsMargins(10, 0, 0, 10); - mMainLayout = new QGridLayout(this); + mMainLayout = new QGridLayout(); + mMainLayout->addWidget(mImageWidget, 0, 0, 1, 1); mMainLayout->addLayout(mRightLayout, 0, 1, 1, 1); mMainLayout->setColumnMinimumWidth(0, 320); @@ -168,6 +184,15 @@ mCaptureArea->setCurrentIndex(index >= 0 ? index : 0); auto mConfigManager = new KConfigDialogManager(this, Settings::self()); connect(mConfigManager, &KConfigDialogManager::widgetModified, mConfigManager, &KConfigDialogManager::updateSettings); + + placeHolder = new QWidget(); + placeHolder->setLayout(mMainLayout); + + mStack->addWidget(placeHolder); + +#ifdef KIMAGEANNOTATOR_FOUND + mStack->addWidget(mAnnotator); +#endif } int KSWidget::imagePaddingWidth() const @@ -281,3 +306,19 @@ mTakeScreenshotButton->setProgress(progress); } +#ifdef KIMAGEANNOTATOR_FOUND +void KSWidget::showAnnotator() +{ + mStack->setCurrentIndex(1); + mAnnotator->loadImage(ExportManager::instance()->pixmap()); +} + +void KSWidget::hideAnnotator() +{ + mStack->setCurrentIndex(0); + QImage image = mAnnotator->image(); + QPixmap px = QPixmap::fromImage(image); + setScreenshotPixmap(px); + ExportManager::instance()->setPixmap(px); +} +#endif