diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,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 @@ -110,4 +110,8 @@ ) endif() +if(KIMAGEANNOTATOR_FOUND) + target_link_libraries(spectacle 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 @@ -112,4 +114,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 @@ -73,6 +73,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 @@ -142,6 +146,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 QGridLayout; class QHBoxLayout; @@ -35,10 +36,15 @@ class QCheckBox; class QLabel; class QPushButton; +class QStackedLayout; class KSImageWidget; class SmartSpinBox; +namespace kImageAnnotator { + class KImageAnnotator; +} + class KSWidget : public QWidget { Q_OBJECT @@ -61,6 +67,11 @@ void lockOnClickDisabled(); void lockOnClickEnabled(); +#ifdef KIMAGEANNOTATOR_FOUND + void showAnnotator(); + void hideAnnotator(); +#endif + private Q_SLOTS: void newScreenshotClicked(); @@ -86,4 +97,9 @@ QLabel *mCaptureModeLabel { nullptr }; QLabel *mContentOptionsLabel { nullptr }; bool mTransientWithParentAvailable { false }; + 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 @@ -23,6 +23,8 @@ #include "KSImageWidget.h" #include "SmartSpinBox.h" #include "SpectacleConfig.h" +#include "ExportManager.h" +#include "Config.h" #include #include @@ -33,6 +35,11 @@ #include #include #include +#include + +#ifdef KIMAGEANNOTATOR_FOUND +#include +#endif #include @@ -42,11 +49,19 @@ // get a handle to the configuration manager SpectacleConfig *lConfigMgr = SpectacleConfig::instance(); + 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); @@ -146,12 +161,22 @@ 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); mMainLayout->setColumnMinimumWidth(1, 320); + placeHolder = new QWidget(); + placeHolder->setLayout(mMainLayout); + + mStack->addWidget(placeHolder); + +#ifdef KIMAGEANNOTATOR_FOUND + mStack->addWidget(mAnnotator); +#endif + // and read in the saved checkbox states and capture mode indices mMousePointer->setChecked (lConfigMgr->includePointerChecked()); mWindowDecorations->setChecked (lConfigMgr->includeDecorationsChecked()); @@ -256,3 +281,20 @@ break; } } + +#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