diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bc1be6..3f67aa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,127 +1,126 @@ set(KDEPIM_VERSION_NUMBER "5.11.80") cmake_minimum_required(VERSION 3.5) project(knotes VERSION ${KDEPIM_VERSION_NUMBER}) set(KF5_MIN_VERSION "5.60.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${knotes_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH}) include(ECMInstallIcons) include(ECMSetupVersion) include(ECMAddTests) include(GenerateExportHeader) include(ECMGenerateHeaders) include(FeatureSummary) include(CheckFunctionExists) include(ECMGeneratePriFile) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMAddAppIcon) include(ECMQtDeclareLoggingCategory) # Do NOT add quote set(KDEPIM_DEV_VERSION beta) # add an extra space if(DEFINED KDEPIM_DEV_VERSION) set(KDEPIM_DEV_VERSION " ${KDEPIM_DEV_VERSION}") endif() set(KDEPIM_VERSION "${KDEPIM_VERSION_NUMBER}${KDEPIM_DEV_VERSION}") set(KDEPIM_LIB_VERSION "${KDEPIM_VERSION_NUMBER}") set(KDEPIM_LIB_SOVERSION "5") set(AKONADINOTES_LIB_VERSION "5.11.80") set(AKONADI_VERSION "5.11.80") set(CALENDARUTILS_LIB_VERSION "5.11.80") set(KDEPIM_APPS_LIB_VERSION "5.11.80") set(KONTACTINTERFACE_LIB_VERSION "5.11.80") set(KPIMTEXTEDIT_LIB_VERSION "5.11.80") set(LIBKDEPIM_LIB_VERSION "5.11.80") set(KMIME_LIB_VERSION "5.11.80") set(PIMCOMMON_LIB_VERSION "5.11.80") set(GRANTLEETHEME_LIB_VERSION "5.11.80") set(QT_REQUIRED_VERSION "5.11.0") find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED DBus Network PrintSupport Test Widgets Xml) find_package(Qt5X11Extras NO_MODULE) find_package(Grantlee5 "5.1" CONFIG REQUIRED) # Find KF5 package find_package(KF5Completion ${KF5_MIN_VERSION} REQUIRED) find_package(KF5Config ${KF5_MIN_VERSION} REQUIRED) find_package(KF5ConfigWidgets ${KF5_MIN_VERSION} REQUIRED) find_package(KF5CoreAddons ${KF5_MIN_VERSION} REQUIRED) find_package(KF5Crash ${KF5_MIN_VERSION} REQUIRED) find_package(KF5DBusAddons ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5DNSSD ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5DocTools ${KF5_MIN_VERSION} REQUIRED) find_package(KF5GlobalAccel ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5ItemModels ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5ItemViews ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5KCMUtils ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5NewStuff ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Notifications ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5NotifyConfig ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Parts ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5TextWidgets ${KF5_MIN_VERSION} REQUIRED) find_package(KF5WidgetsAddons ${KF5_MIN_VERSION} REQUIRED) find_package(KF5WindowSystem ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5XmlGui ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Notifications ${KF5_MIN_VERSION} CONFIG REQUIRED) -find_package(KF5KDELibs4Support ${KF5_MIN_VERSION} CONFIG REQUIRED) # Find KdepimLibs Package find_package(KF5Akonadi ${AKONADI_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiNotes ${AKONADINOTES_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5KontactInterface ${KONTACTINTERFACE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Libkdepim ${LIBKDEPIM_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5PimCommonAkonadi ${PIMCOMMON_LIB_VERSION} CONFIG REQUIRED) find_package(KF5PimTextEdit ${KPIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5GrantleeTheme ${GRANTLEETHEME_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiSearch "5.11.80" CONFIG REQUIRED) set_package_properties(KF5AkonadiSearch PROPERTIES DESCRIPTION "The Akonadi Search libraries" URL "https://kde.org/" TYPE REQUIRED PURPOSE "Provides search capabilities in KMail and Akonadi") if (NOT APPLE) find_package(X11) endif() set(KDEPIM_HAVE_X11 ${X11_FOUND}) set(CMAKE_MODULE_PATH ${knotes_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH}) find_package(Xsltproc) set_package_properties(Xsltproc PROPERTIES DESCRIPTION "XSLT processor from libxslt" TYPE REQUIRED PURPOSE "Required to generate D-Bus interfaces for all Akonadi resources.") include_directories(${knotes_SOURCE_DIR} ${knotes_BINARY_DIR}) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) add_definitions(-DQT_NO_FOREACH) set(CMAKE_CXX_STANDARD 14) configure_file(knotes-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/knotes-version.h @ONLY) add_subdirectory(noteshared) add_subdirectory(src) add_subdirectory(notesagent) install(FILES knotes.categories knotes.renamecategories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) add_subdirectory(doc) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 118d93c..af32724 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,143 +1,143 @@ add_definitions(-DTRANSLATION_DOMAIN=\"knotes\") configure_file(config-knotes.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-knotes.h ) add_subdirectory(icons) if (BUILD_TESTING) add_subdirectory(print/autotests) endif() add_subdirectory(kontactplugin) add_subdirectory(kconf_update) ########### next target ############### set(libknotesprivate_config_lib_SRCS configdialog/knotesimpleconfigdialog.cpp configdialog/knoteconfigdialog.cpp configdialog/knotedisplayconfigwidget.cpp configdialog/knoteeditorconfigwidget.cpp configdialog/knotecollectionconfigwidget.cpp ) set(libknotesprivate_print_lib_SRCS print/knoteprintselectthemedialog.cpp print/knoteprintselectthemecombobox.cpp print/knoteprinter.cpp print/knoteprintobject.cpp print/knotegrantleeprint.cpp ) set(libknotesprivate_lib_SRCS ${libknotesprivate_config_lib_SRCS} ${libknotesprivate_print_lib_SRCS} knoteedit.cpp knotes_debug.cpp notes/knotedisplaysettings.cpp utils/knoteutils.cpp notes/knoteinterface.cpp notes/knotesmigrateapplication.cpp finddialog/knotefinddialog.cpp ) configure_file(settings/knotesglobalconfig.kcfg.cmake ${CMAKE_CURRENT_BINARY_DIR}/knotesglobalconfig.kcfg ) set( libknotesprivate_kcfg_lib_SRCS settings/knotesglobalconfig.kcfgc ) kconfig_add_kcfg_files(libknotesprivate_kcfg_lib_SRCS ${libknotesprivate_kcfg_lib_SRCS}) ecm_qt_declare_logging_category(libknotesprivate_lib_SRCS HEADER knotes_debug.h IDENTIFIER KNOTES_LOG CATEGORY_NAME org.kde.pim.knotes) add_library(knotesprivate ${libknotesprivate_lib_SRCS} ${libknotesprivate_kcfg_lib_SRCS} ) generate_export_header(knotesprivate BASE_NAME knotes) target_link_libraries(knotesprivate PUBLIC KF5::IconThemes PRIVATE KF5::PimCommon KF5::KCMUtils Grantlee5::Templates KF5::NewStuff KF5::WindowSystem Qt5::PrintSupport KF5::TextWidgets KF5::I18n notesharedprivate KF5::AkonadiSearchPIM KF5::AkonadiNotes KF5::PimTextEdit KF5::AkonadiWidgets KF5::GrantleeTheme ) set_target_properties(knotesprivate PROPERTIES VERSION ${KDEPIM_LIB_VERSION} SOVERSION ${KDEPIM_LIB_SOVERSION} ) install(TARGETS knotesprivate ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) set(knotes_SRCS knotes_debug.cpp apps/main.cpp apps/application.cpp apps/knotesapp.cpp apps/knotesakonaditray.cpp dialog/knoteskeydialog.cpp dialog/knotedeleteselectednotesdialog.cpp notes/knotebutton.cpp print/knoteprintselectednotesdialog.cpp notes/knote.cpp dialog/knoteselectednotesdialog.cpp ) qt5_add_dbus_adaptor(knotes_SRCS apps/org.kde.KNotes.xml apps/knotesapp.h KNotesApp ) file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-knotes.png") ecm_add_app_icon(knotes_SRCS ICONS ${ICONS_SRCS}) add_executable(knotes ${knotes_SRCS}) target_link_libraries(knotes knotesprivate KF5::KCMUtils KF5::PimCommon KF5::DNSSD KF5::KontactInterface notesharedprivate KF5::AkonadiCore KF5::Mime KF5::GlobalAccel KF5::Notifications KF5::WindowSystem - KF5::KDELibs4Support + KF5::KIOFileWidgets KF5::AkonadiSearchDebug KF5::AkonadiNotes KF5::Crash KF5::AkonadiWidgets ) if (Qt5X11Extras_FOUND) target_link_libraries(knotes Qt5::X11Extras ${X11_LIBRARIES}) endif() install(TARGETS knotes ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) ########### next target ############### set(kcm_knotes_PART_SRCS configdialog/knoteconfigdialog.cpp configdialog/knotedisplayconfigwidget.cpp configdialog/knoteeditorconfigwidget.cpp configdialog/knotecollectionconfigwidget.cpp knotes_debug.cpp) add_library(kcm_knote MODULE ${kcm_knotes_PART_SRCS} ) target_link_libraries(kcm_knote knotesprivate KF5::AkonadiCore KF5::KCMUtils KF5::NewStuff KF5::WindowSystem notesharedprivate KF5::AkonadiNotes KF5::PimCommon KF5::I18n KF5::AkonadiWidgets) install(TARGETS kcm_knote DESTINATION ${KDE_INSTALL_PLUGINDIR}) install(FILES data/knote_config_action.desktop data/knote_config_display.desktop data/knote_config_editor.desktop data/knote_config_network.desktop data/knote_config_print.desktop data/knote_config_collection.desktop data/knote_config_misc.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) ########### install files ############### install( PROGRAMS data/org.kde.knotes.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install( FILES data/org.kde.knotes.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/knotesglobalconfig.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) install( FILES data/knotesappui.rc data/knotesui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/knotes) install( FILES apps/org.kde.KNotes.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) install( FILES data/knotes_printing_theme.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} ) install(DIRECTORY print/themes/ DESTINATION ${KDE_INSTALL_DATADIR}/knotes/print/themes ) diff --git a/src/notes/knote.cpp b/src/notes/knote.cpp index cc763e3..55b9c84 100644 --- a/src/notes/knote.cpp +++ b/src/notes/knote.cpp @@ -1,1245 +1,1247 @@ /******************************************************************* KNotes -- Notes for the KDE project Copyright (c) 1997-2013, The KNotes Developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *******************************************************************/ #include #include "knote.h" #include "knotes_debug.h" #include "knotedisplaysettings.h" #include "knoteedit.h" #include "knotesglobalconfig.h" #include "noteutils.h" #include "alarms/notealarmdialog.h" #include "attributes/notealarmattribute.h" #include "attributes/notedisplayattribute.h" #include "attributes/notelockattribute.h" #include "configdialog/knotesimpleconfigdialog.h" #include "notes/knotebutton.h" #include "print/knoteprinter.h" #include "print/knoteprintobject.h" #include "print/knoteprintselectthemedialog.h" #include "utils/knoteutils.h" #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if KDEPIM_HAVE_X11 #include #endif //#define DEBUG_SAVE_NOTE 1 KNote::KNote(const QDomDocument &buildDoc, const Akonadi::Item &item, bool allowAkonadiSearchDebug, QWidget *parent) : QFrame(parent, Qt::FramelessWindowHint) , mItem(item) , m_label(nullptr) , m_grip(nullptr) , m_button(nullptr) , m_tool(nullptr) , m_editor(nullptr) , m_kwinConf(KSharedConfig::openConfig(QStringLiteral("kwinrc"))) , mDisplayAttribute(new KNoteDisplaySettings) , mAllowDebugAkonadiSearch(allowAkonadiSearchDebug) { if (mItem.hasAttribute()) { mDisplayAttribute->setDisplayAttribute(mItem.attribute()); } else { setDisplayDefaultValue(); //save default display value } setAcceptDrops(true); setAttribute(Qt::WA_DeleteOnClose); setDOMDocument(buildDoc); setXMLFile(componentName() + QLatin1String("ui.rc"), false, false); // create the main layout m_noteLayout = new QVBoxLayout(this); m_noteLayout->setContentsMargins(0, 0, 0, 0); createActions(); buildGui(); prepare(); } KNote::~KNote() { delete mDisplayAttribute; } void KNote::setDisplayDefaultValue() { KNoteUtils::setDefaultValue(mItem); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "setDisplayDefaultValue slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } void KNote::setChangeItem(const Akonadi::Item &item, const QSet &set) { mItem = item; if (item.hasAttribute()) { mDisplayAttribute->setDisplayAttribute(item.attribute()); } if (set.contains("KJotsLockAttribute")) { m_editor->setReadOnly(item.hasAttribute()); } if (set.contains("PLD:RFC822")) { loadNoteContent(item); } if (set.contains("NoteDisplayAttribute")) { qCDebug(KNOTES_LOG) << " ATR:NoteDisplayAttribute"; slotApplyConfig(); } //TODO update display/content etc. updateLabelAlignment(); } void KNote::slotKill(bool force) { if (!force && KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete note %1?", m_label->text()), i18n("Confirm Delete"), KGuiItem(i18n("&Delete"), QStringLiteral("edit-delete")), KStandardGuiItem::cancel(), QStringLiteral("ConfirmDeleteNote")) != KMessageBox::Continue) { return; } Q_EMIT sigKillNote(mItem.id()); } // -------------------- public member functions -------------------- // void KNote::saveNote(bool force, bool sync) { if (!force && !m_editor->document()->isModified()) { return; } bool needToSave = false; NoteShared::NoteDisplayAttribute *attribute = mItem.attribute(Akonadi::Item::AddIfMissing); const QPoint notePosition = pos(); if (attribute->position() != notePosition) { needToSave = true; attribute->setPosition(notePosition); } const QSize currentSize(QSize(width(), height())); if (attribute->size() != currentSize) { needToSave = true; attribute->setSize(currentSize); } #if KDEPIM_HAVE_X11 KWindowInfo info(winId(), NET::WMDesktop); const int count = KWindowSystem::numberOfDesktops(); for (int n = 1; n <= count; ++n) { if (info.isOnDesktop(n)) { if (attribute->desktop() != n) { needToSave = true; attribute->setDesktop(n); break; } } } #endif if (m_editor->document()->isModified()) { needToSave = true; saveNoteContent(); } if (needToSave) { #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "save Note slotClose() slotNoteSaved(KJob*) : sync" << sync; #endif Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); if (sync) { job->exec(); } else { #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "save Note slotClose() slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } } } void KNote::slotNoteSaved(KJob *job) { qCDebug(KNOTES_LOG) << " void KNote::slotNoteSaved(KJob *job)"; if (job->error()) { qCDebug(KNOTES_LOG) << " problem during save note:" << job->errorString(); } else { m_editor->document()->setModified(false); } } Akonadi::Item::Id KNote::noteId() const { return mItem.id(); } QString KNote::name() const { return m_label->text(); } QString KNote::text() const { return m_editor->text(); } void KNote::setName(const QString &name) { m_label->setText(name); updateLabelAlignment(); if (m_editor) { // not called from CTOR? saveNote(); } setWindowTitle(name); Q_EMIT sigNameChanged(name); } void KNote::setText(const QString &text) { m_editor->setText(text); saveNote(); } bool KNote::isDesktopAssigned() const { return mDisplayAttribute->rememberDesktop(); } bool KNote::isModified() const { return m_editor->document()->isModified(); } // ------------------ private slots (menu actions) ------------------ // void KNote::slotRename() { // pop up dialog to get the new name bool ok; const QString oldName = m_label->text(); const QString newName = QInputDialog::getText(this, QString(), i18n("Please enter the new name:"), QLineEdit::Normal, m_label->text(), &ok); if (!ok || (oldName == newName)) { // handle cancel return; } setName(newName); } void KNote::slotUpdateReadOnly() { const bool readOnly = m_readOnly->isChecked(); m_editor->setReadOnly(readOnly); if (mItem.hasAttribute()) { if (!readOnly) { mItem.removeAttribute(); } } else { if (readOnly) { mItem.attribute(Akonadi::Item::AddIfMissing); } } if (!mBlockSave) { updateAllAttributes(); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << " void KNote::slotUpdateReadOnly() slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } // enable/disable actions accordingly actionCollection()->action(QStringLiteral("configure_note"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("delete_note"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_bold"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_italic"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_underline"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_strikeout"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_alignleft"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_aligncenter"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_alignright"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_alignblock"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_list"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_super"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_sub"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_increaseindent"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_decreaseindent"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("text_background_color"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_size"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("format_color"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("rename_note"))->setEnabled(!readOnly); actionCollection()->action(QStringLiteral("set_alarm"))->setEnabled(!readOnly); m_keepAbove->setEnabled(!readOnly); m_keepBelow->setEnabled(!readOnly); #if KDEPIM_HAVE_X11 m_toDesktop->setEnabled(!readOnly); #endif updateFocus(); } void KNote::updateAllAttributes() { #if KDEPIM_HAVE_X11 NoteShared::NoteDisplayAttribute *attribute = mItem.attribute(Akonadi::Item::AddIfMissing); KWindowInfo info(winId(), NET::WMDesktop); const int count = KWindowSystem::numberOfDesktops(); for (int n = 1; n <= count; ++n) { if (info.isOnDesktop(n)) { attribute->setDesktop(n); } } #endif saveNoteContent(); attribute->setIsHidden(true); attribute->setPosition(pos()); const QSize currentSize(QSize(width(), height())); if (attribute->size() != currentSize) { attribute->setSize(currentSize); } } void KNote::slotClose() { updateAllAttributes(); m_editor->clearFocus(); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "slotClose() slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); hide(); } void KNote::slotSetAlarm() { QPointer dlg = new NoteShared::NoteAlarmDialog(name(), this); if (mItem.hasAttribute()) { dlg->setAlarm(mItem.attribute()->dateTime()); } if (dlg->exec()) { bool needToModify = true; QDateTime dateTime = dlg->alarm(); if (dateTime.isValid()) { NoteShared::NoteAlarmAttribute *attribute = mItem.attribute(Akonadi::Item::AddIfMissing); attribute->setDateTime(dateTime); } else { if (mItem.hasAttribute()) { mItem.removeAttribute(); } else { needToModify = false; } } if (needToModify) { //Verify it! saveNoteContent(); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "setAlarm() slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } } delete dlg; } void KNote::saveNoteContent() { KMime::Message::Ptr message = mItem.payload(); const QByteArray encoding("utf-8"); message->subject(true)->fromUnicodeString(name(), encoding); message->contentType(true)->setMimeType(m_editor->acceptRichText() ? "text/html" : "text/plain"); message->contentType()->setCharset(encoding); message->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEquPr); message->date(true)->setDateTime(QDateTime::currentDateTime()); message->mainBodyPart()->fromUnicodeString(text().isEmpty() ? QStringLiteral(" ") : text()); KMime::Headers::Generic *header = new KMime::Headers::Generic("X-Cursor-Position"); header->fromUnicodeString(QString::number(m_editor->cursorPositionFromStart()), "utf-8"); message->setHeader(header); message->assemble(); mItem.setPayload(message); } void KNote::slotPreferences() { // create a new preferences dialog... QPointer dialog = new KNoteSimpleConfigDialog(name(), this); NoteShared::NoteDisplayAttribute *attribute = mItem.attribute(Akonadi::Item::AddIfMissing); attribute->setSize(QSize(width(), height())); dialog->load(mItem, m_editor->acceptRichText()); connect(this, &KNote::sigNameChanged, dialog.data(), &KNoteSimpleConfigDialog::slotUpdateCaption); if (dialog->exec()) { bool isRichText; dialog->save(mItem, isRichText); m_editor->setAcceptRichText(isRichText); saveNoteContent(); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "slotPreference slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } delete dialog; } void KNote::slotSend() { NoteShared::NoteUtils noteUtils; noteUtils.sendToNetwork(this, name(), text()); } void KNote::slotMail() { NoteShared::NoteUtils noteUtils; noteUtils.sendToMail(this, m_label->text(), m_editor->toPlainText()); } void KNote::slotPrint() { print(false); } void KNote::slotPrintPreview() { print(true); } void KNote::print(bool preview) { QString content; if (!Qt::mightBeRichText(m_editor->text())) { content = Qt::convertFromPlainText(m_editor->text()); } else { content = m_editor->text(); } if (isModified()) { saveNote(); } KNotesGlobalConfig *globalConfig = KNotesGlobalConfig::self(); QString printingTheme = globalConfig->theme(); if (printingTheme.isEmpty()) { QPointer dlg = new KNotePrintSelectThemeDialog(this); if (dlg->exec()) { printingTheme = dlg->selectedTheme(); } delete dlg; } if (!printingTheme.isEmpty()) { KNotePrinter printer(this); QList lst; lst.append(new KNotePrintObject(mItem)); printer.setDefaultFont(mDisplayAttribute->font()); printer.printNotes(lst, printingTheme, preview); qDeleteAll(lst); } } void KNote::slotSaveAs() { // TODO: where to put pdf file support? In the printer??!??! QCheckBox *convert = nullptr; if (m_editor->acceptRichText()) { convert = new QCheckBox(nullptr); convert->setText(i18n("Save note as plain text")); } QUrl url; - QPointer dlg = new KFileDialog(url, QString(), this, convert); - dlg->setOperationMode(KFileDialog::Saving); + QPointer dlg = new KFileCustomDialog(this); + dlg->setCustomWidget(convert); + dlg->setUrl(url); + dlg->setOperationMode(KFileWidget::Saving); dlg->setWindowTitle(i18n("Save As")); if (!dlg->exec()) { delete dlg; return; } - const QString fileName = dlg->selectedFile(); + const QString fileName = dlg->fileWidget()->selectedFile(); const bool htmlFormatAndSaveAsHtml = (convert && !convert->isChecked()); delete dlg; if (fileName.isEmpty()) { return; } QFile file(fileName); if (file.exists() && KMessageBox::warningContinueCancel(this, i18n("A file named %1 already exists.
" "Are you sure you want to overwrite it?
", QFileInfo(file).fileName())) != KMessageBox::Continue) { return; } if (file.open(QIODevice::WriteOnly)) { QTextStream stream(&file); if (htmlFormatAndSaveAsHtml) { QString htmlStr = m_editor->toHtml(); htmlStr.replace(QStringLiteral("meta name=\"qrichtext\" content=\"1\""), QStringLiteral("meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"")); stream << htmlStr; } else { stream << m_editor->toPlainText(); } } } void KNote::slotPopupActionToDesktop(QAction *act) { const int id = act->data().toInt(); toDesktop(id); // compensate for the menu separator, -1 == all desktops } // ------------------ private slots (configuration) ------------------ // void KNote::slotApplyConfig() { m_label->setFont(mDisplayAttribute->titleFont()); m_editor->setTextFont(mDisplayAttribute->font()); m_editor->setTabStop(mDisplayAttribute->tabSize()); m_editor->setAutoIndentMode(mDisplayAttribute->autoIndent()); setColor(mDisplayAttribute->foregroundColor(), mDisplayAttribute->backgroundColor()); updateLayout(); slotUpdateShowInTaskbar(); resize(mDisplayAttribute->size()); } void KNote::slotKeepAbove() { if (m_keepBelow->isChecked()) { m_keepBelow->setChecked(false); } updateKeepAboveBelow(); } void KNote::slotKeepBelow() { if (m_keepAbove->isChecked()) { m_keepAbove->setChecked(false); } updateKeepAboveBelow(); } void KNote::updateKeepAboveBelow(bool save) { #if KDEPIM_HAVE_X11 NET::States state = KWindowInfo(winId(), NET::WMState).state(); #else NET::States state = 0; // neutral state, TODO #endif NoteShared::NoteDisplayAttribute *attribute = mItem.attribute(Akonadi::Item::AddIfMissing); if (m_keepAbove->isChecked()) { attribute->setKeepAbove(true); attribute->setKeepBelow(false); KWindowSystem::setState(winId(), state | NET::KeepAbove); } else if (m_keepBelow->isChecked()) { attribute->setKeepAbove(false); attribute->setKeepBelow(true); KWindowSystem::setState(winId(), state | NET::KeepBelow); } else { attribute->setKeepAbove(false); attribute->setKeepBelow(false); KWindowSystem::clearState(winId(), NET::KeepAbove); KWindowSystem::clearState(winId(), NET::KeepBelow); } if (!mBlockSave && save) { saveNoteContent(); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "slotUpdateKeepAboveBelow slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } } void KNote::slotUpdateShowInTaskbar() { #if KDEPIM_HAVE_X11 if (!mDisplayAttribute->showInTaskbar()) { KWindowSystem::setState(winId(), KWindowInfo(winId(), NET::WMState).state() | NET::SkipTaskbar); } else { KWindowSystem::clearState(winId(), NET::SkipTaskbar); } #endif } void KNote::slotUpdateDesktopActions() { m_toDesktop->clear(); QAction *act = m_toDesktop->addAction(i18n("&All Desktops")); KWindowInfo info(winId(), NET::WMDesktop); if (info.onAllDesktops()) { act->setChecked(true); act->setData(NETWinInfo::OnAllDesktops); } QAction *separator = new QAction(m_toDesktop); separator->setSeparator(true); m_toDesktop->addAction(separator); const int count = KWindowSystem::numberOfDesktops(); for (int n = 1; n <= count; ++n) { QAction *desktopAct = m_toDesktop->addAction(QStringLiteral("&%1 %2").arg(n).arg(KWindowSystem::desktopName(n))); desktopAct->setData(n); if (info.isOnDesktop(n)) { desktopAct->setChecked(true); } } } // -------------------- private methods -------------------- // void KNote::buildGui() { createNoteHeader(); createNoteEditor(QString()); KXMLGUIBuilder builder(this); KXMLGUIFactory factory(&builder, this); factory.addClient(this); m_menu = qobject_cast(factory.container(QStringLiteral("note_context"), this)); m_tool = qobject_cast(factory.container(QStringLiteral("note_tool"), this)); createNoteFooter(); } void KNote::createActions() { // create the menu items for the note - not the editor... // rename, mail, print, save as, insert date, alarm, close, delete, new note QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18n("New"), this); actionCollection()->addAction(QStringLiteral("new_note"), action); connect(action, &QAction::triggered, this, &KNote::slotRequestNewNote); action = new QAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename..."), this); actionCollection()->addAction(QStringLiteral("rename_note"), action); connect(action, &QAction::triggered, this, &KNote::slotRename); m_readOnly = new KToggleAction(QIcon::fromTheme(QStringLiteral("object-locked")), i18n("Lock"), this); actionCollection()->addAction(QStringLiteral("lock_note"), m_readOnly); connect(m_readOnly, &KToggleAction::triggered, this, &KNote::slotUpdateReadOnly); m_readOnly->setCheckedState(KGuiItem(i18n("Unlock"), QStringLiteral("object-unlocked"))); action = new QAction(QIcon::fromTheme(QStringLiteral("window-close")), i18n("Hide"), this); actionCollection()->addAction(QStringLiteral("hide_note"), action); connect(action, &QAction::triggered, this, &KNote::slotClose); actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::Key_Escape)); action = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete"), this); actionCollection()->addAction(QStringLiteral("delete_note"), action); connect(action, &QAction::triggered, this, &KNote::slotKill); action = new QAction(QIcon::fromTheme(QStringLiteral("knotes_alarm")), i18n("Set Alarm..."), this); actionCollection()->addAction(QStringLiteral("set_alarm"), action); connect(action, &QAction::triggered, this, &KNote::slotSetAlarm); action = new QAction(QIcon::fromTheme(QStringLiteral("network-wired")), i18n("Send..."), this); actionCollection()->addAction(QStringLiteral("send_note"), action); connect(action, &QAction::triggered, this, &KNote::slotSend); action = new QAction(QIcon::fromTheme(QStringLiteral("mail-send")), i18n("Mail..."), this); actionCollection()->addAction(QStringLiteral("mail_note"), action); connect(action, &QAction::triggered, this, &KNote::slotMail); action = new QAction(QIcon::fromTheme(QStringLiteral("document-save-as")), i18n("Save As..."), this); actionCollection()->addAction(QStringLiteral("save_note"), action); connect(action, &QAction::triggered, this, &KNote::slotSaveAs); action = actionCollection()->addAction(KStandardAction::Print, QStringLiteral("print_note")); connect(action, &QAction::triggered, this, &KNote::slotPrint); action = actionCollection()->addAction(KStandardAction::PrintPreview, QStringLiteral("print_preview_note")); connect(action, &QAction::triggered, this, &KNote::slotPrintPreview); action = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Preferences..."), this); actionCollection()->addAction(QStringLiteral("configure_note"), action); connect(action, &QAction::triggered, this, &KNote::slotPreferences); m_keepAbove = new KToggleAction(QIcon::fromTheme(QStringLiteral("go-up")), i18n("Keep Above Others"), this); actionCollection()->addAction(QStringLiteral("keep_above"), m_keepAbove); connect(m_keepAbove, &KToggleAction::triggered, this, &KNote::slotKeepAbove); m_keepBelow = new KToggleAction(QIcon::fromTheme(QStringLiteral("go-down")), i18n("Keep Below Others"), this); actionCollection()->addAction(QStringLiteral("keep_below"), m_keepBelow); connect(m_keepBelow, &KToggleAction::triggered, this, &KNote::slotKeepBelow); #if KDEPIM_HAVE_X11 m_toDesktop = new KSelectAction(i18n("To Desktop"), this); actionCollection()->addAction(QStringLiteral("to_desktop"), m_toDesktop); connect(m_toDesktop, qOverload(&KSelectAction::triggered), this, &KNote::slotPopupActionToDesktop); connect(m_toDesktop->menu(), &QMenu::aboutToShow, this, &KNote::slotUpdateDesktopActions); // initially populate it, otherwise stays disabled slotUpdateDesktopActions(); #endif // invisible action to walk through the notes to make this configurable action = new QAction(i18n("Walk Through Notes"), this); actionCollection()->addAction(QStringLiteral("walk_notes"), action); connect(action, &QAction::triggered, this, &KNote::sigShowNextNote); actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::SHIFT + Qt::Key_Backtab)); actionCollection()->addAssociatedWidget(this); const auto lst = actionCollection()->actions(); for (QAction *action : lst) { action->setShortcutContext(Qt::WidgetWithChildrenShortcut); } if (mAllowDebugAkonadiSearch) { //Don't translate it it's just for debugging action = new QAction(QStringLiteral("Debug Akonadi Search..."), this); actionCollection()->addAction(QStringLiteral("debug_akonadi_search"), action); connect(action, &QAction::triggered, this, &KNote::slotDebugAkonadiSearch); } } void KNote::createNoteHeader() { // load style configuration KConfigGroup styleGroup(m_kwinConf, "Style"); QBoxLayout::Direction headerLayoutDirection = QBoxLayout::LeftToRight; if (styleGroup.readEntry("CustomButtonPositions", false)) { if (styleGroup.readEntry("ButtonsOnLeft").contains(QLatin1Char('X'))) { headerLayoutDirection = QBoxLayout::RightToLeft; } } QBoxLayout *headerLayout = new QBoxLayout(headerLayoutDirection); // create header label m_label = new QLabel(this); headerLayout->addWidget(m_label); m_label->setFrameStyle(NoFrame); m_label->setBackgroundRole(QPalette::Base); m_label->setLineWidth(0); m_label->setAutoFillBackground(true); m_label->installEventFilter(this); // receive events ( for dragging & // action menu ) m_button = new KNoteButton(QStringLiteral("knotes_close"), this); headerLayout->addWidget(m_button); connect(m_button, &KNoteButton::clicked, this, &KNote::slotClose); m_noteLayout->addItem(headerLayout); } void KNote::createNoteEditor(const QString &configFile) { Q_UNUSED(configFile); m_editor = new KNoteEdit(actionCollection(), this); m_noteLayout->addWidget(m_editor); m_editor->setNote(this); m_editor->installEventFilter(this); // receive focus events for modified setFocusProxy(m_editor); } void KNote::slotRequestNewNote() { //Be sure to save before to request a new note saveNote(); Q_EMIT sigRequestNewNote(); } void KNote::createNoteFooter() { if (m_tool) { m_tool->setIconSize(QSize(10, 10)); m_tool->setFixedHeight(24); m_tool->setToolButtonStyle(Qt::ToolButtonIconOnly); } // create size grip QHBoxLayout *gripLayout = new QHBoxLayout; m_grip = new QSizeGrip(this); m_grip->setFixedSize(m_grip->sizeHint()); if (m_tool) { gripLayout->addWidget(m_tool); gripLayout->setAlignment(m_tool, Qt::AlignBottom | Qt::AlignLeft); m_tool->hide(); } gripLayout->addWidget(m_grip); gripLayout->setAlignment(m_grip, Qt::AlignBottom | Qt::AlignRight); m_noteLayout->addItem(gripLayout); // if there was just a way of making KComboBox adhere the toolbar height... if (m_tool) { const auto comboboxs = m_tool->findChildren(); for (KComboBox *combo : comboboxs) { QFont font = combo->font(); font.setPointSize(7); combo->setFont(font); combo->setFixedHeight(14); } } } void KNote::loadNoteContent(const Akonadi::Item &item) { KMime::Message::Ptr noteMessage = item.payload(); const KMime::Headers::Subject *const subject = noteMessage ? noteMessage->subject(false) : nullptr; setName(subject ? subject->asUnicodeString() : QString()); if (noteMessage->contentType()->isHTMLText()) { m_editor->setAcceptRichText(true); m_editor->setAutoFormatting(QTextEdit::AutoAll); m_editor->setHtml(noteMessage->mainBodyPart()->decodedText()); } else { m_editor->setAcceptRichText(false); m_editor->setAutoFormatting(QTextEdit::AutoNone); m_editor->setPlainText(noteMessage->mainBodyPart()->decodedText()); } if (auto hrd = noteMessage->headerByType("X-Cursor-Position")) { m_editor->setCursorPositionFromStart(hrd->asUnicodeString().toInt()); } } void KNote::prepare() { mBlockSave = true; loadNoteContent(mItem); resize(mDisplayAttribute->size()); const QPoint &position = mDisplayAttribute->position(); QRect desk = qApp->desktop()->rect(); desk.adjust(10, 10, -10, -10); if (desk.intersects(QRect(position, mDisplayAttribute->size()))) { move(position); // do before calling show() to avoid flicker } if (mDisplayAttribute->isHidden()) { hide(); } else { show(); } // read configuration settings... slotApplyConfig(); if (mItem.hasAttribute()) { m_editor->setReadOnly(true); m_readOnly->setChecked(true); } else { m_readOnly->setChecked(false); } slotUpdateReadOnly(); // if this is a new note put on current desktop - we can't use defaults // in KConfig XT since only _changes_ will be stored in the config file int desktop = mDisplayAttribute->desktop(); #if KDEPIM_HAVE_X11 if ((desktop < 0 && desktop != NETWinInfo::OnAllDesktops) || !mDisplayAttribute->rememberDesktop()) { desktop = KWindowSystem::currentDesktop(); } #endif // show the note if desired if (desktop != 0 && !mDisplayAttribute->isHidden()) { // to avoid flicker, call this before show() toDesktop(desktop); show(); // because KWin forgets about that for hidden windows #if KDEPIM_HAVE_X11 if (desktop == NETWinInfo::OnAllDesktops) { toDesktop(desktop); } #endif } if (mDisplayAttribute->keepAbove()) { m_keepAbove->setChecked(true); } else if (mDisplayAttribute->keepBelow()) { m_keepBelow->setChecked(true); } else { m_keepAbove->setChecked(false); m_keepBelow->setChecked(false); } updateKeepAboveBelow(); // HACK: update the icon color - again after showing the note, to make kicker // aware of the new colors KIconEffect effect; const QColor col = mDisplayAttribute->backgroundColor(); const QPixmap icon = effect.apply(qApp->windowIcon().pixmap( IconSize(KIconLoader::Desktop), IconSize(KIconLoader::Desktop)), KIconEffect::Colorize, 1, col, false); const QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap( IconSize(KIconLoader::Small), IconSize(KIconLoader::Small)), KIconEffect::Colorize, 1, col, false); KWindowSystem::setIcons(winId(), icon, miniIcon); // set up the look&feel of the note setFrameStyle(Panel | Raised); setMinimumSize(20, 20); setBackgroundRole(QPalette::Base); m_editor->setContentsMargins(0, 0, 0, 0); m_editor->setBackgroundRole(QPalette::Base); m_editor->setFrameStyle(NoFrame); m_editor->document()->setModified(false); mBlockSave = false; } void KNote::toDesktop(int desktop) { if (desktop == 0) { return; } #if KDEPIM_HAVE_X11 if (desktop == NETWinInfo::OnAllDesktops) { KWindowSystem::setOnAllDesktops(winId(), true); } else { KWindowSystem::setOnDesktop(winId(), desktop); } #endif } void KNote::setColor(const QColor &fg, const QColor &bg) { m_editor->setColor(fg, bg); QPalette p = palette(); // better: from light(150) to light(100) to light(75) // QLinearGradient g( width()/2, 0, width()/2, height() ); // g.setColorAt( 0, bg ); // g.setColorAt( 1, bg.darker(150) ); p.setColor(QPalette::Window, bg); // p.setBrush( QPalette::Window, g ); p.setColor(QPalette::Base, bg); // p.setBrush( QPalette::Base, g ); p.setColor(QPalette::WindowText, fg); p.setColor(QPalette::Text, fg); p.setColor(QPalette::Button, bg.darker(116)); p.setColor(QPalette::ButtonText, fg); //p.setColor( QPalette::Highlight, bg ); //p.setColor( QPalette::HighlightedText, fg ); // order: Light, Midlight, Button, Mid, Dark, Shadow // the shadow p.setColor(QPalette::Light, bg.lighter(180)); p.setColor(QPalette::Midlight, bg.lighter(150)); p.setColor(QPalette::Mid, bg.lighter(150)); p.setColor(QPalette::Dark, bg.darker(108)); p.setColor(QPalette::Shadow, bg.darker(116)); setPalette(p); // darker values for the active label p.setColor(QPalette::Active, QPalette::Base, bg.darker(116)); m_label->setPalette(p); // set the text color m_editor->setTextColor(fg); // update the icon color KIconEffect effect; QPixmap icon = effect.apply(qApp->windowIcon().pixmap( IconSize(KIconLoader::Desktop), IconSize(KIconLoader::Desktop)), KIconEffect::Colorize, 1, bg, false); QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap( IconSize(KIconLoader::Small), IconSize(KIconLoader::Small)), KIconEffect::Colorize, 1, bg, false); KWindowSystem::setIcons(winId(), icon, miniIcon); // update the color of the title updateFocus(); Q_EMIT sigColorChanged(); } void KNote::updateLabelAlignment() { // if the name is too long to fit, left-align it, otherwise center it (#59028) const QString labelText = m_label->text(); if (m_label->fontMetrics().boundingRect(labelText).width() > m_label->width()) { m_label->setAlignment(Qt::AlignLeft); } else { m_label->setAlignment(Qt::AlignHCenter); } } void KNote::updateFocus() { if (hasFocus()) { if (!m_editor->isReadOnly()) { if (m_tool && m_tool->isHidden() && m_editor->acceptRichText()) { m_tool->show(); updateLayout(); } m_grip->show(); } else { if (m_tool && !m_tool->isHidden()) { m_tool->hide(); updateLayout(); // to update the minimum height } m_grip->hide(); } } else { m_grip->hide(); if (m_tool && !m_tool->isHidden()) { m_tool->hide(); updateLayout(); // to update the minimum height } } } void KNote::updateLayout() { // TODO: remove later if no longer needed. updateLabelAlignment(); } // -------------------- protected methods -------------------- // void KNote::contextMenuEvent(QContextMenuEvent *e) { if (m_menu) { m_menu->popup(e->globalPos()); } } void KNote::showEvent(QShowEvent *) { if (mDisplayAttribute->isHidden()) { // KWin does not preserve these properties for hidden windows updateKeepAboveBelow(false); slotUpdateShowInTaskbar(); toDesktop(mDisplayAttribute->desktop()); move(mDisplayAttribute->position()); NoteShared::NoteDisplayAttribute *attr = mItem.attribute(Akonadi::Item::AddIfMissing); saveNoteContent(); attr->setIsHidden(false); if (!mBlockSave) { Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "showEvent slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } } } void KNote::resizeEvent(QResizeEvent *qre) { QFrame::resizeEvent(qre); updateLayout(); } void KNote::closeEvent(QCloseEvent *event) { if (qApp->isSavingSession()) { return; } event->ignore(); //We don't want to close (and delete the widget). Just hide it slotClose(); } void KNote::dragEnterEvent(QDragEnterEvent *e) { if (!m_editor->isReadOnly()) { e->setAccepted(e->mimeData()->hasColor()); } } void KNote::dropEvent(QDropEvent *e) { if (m_editor->isReadOnly()) { return; } const QMimeData *md = e->mimeData(); if (md->hasColor()) { const QColor bg = qvariant_cast(md->colorData()); NoteShared::NoteDisplayAttribute *attr = mItem.attribute(Akonadi::Item::AddIfMissing); saveNoteContent(); attr->setBackgroundColor(bg); Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob(mItem); #ifdef DEBUG_SAVE_NOTE qCDebug(KNOTES_LOG) << "dropEvent slotNoteSaved(KJob*)"; #endif connect(job, &Akonadi::ItemModifyJob::result, this, &KNote::slotNoteSaved); } } bool KNote::event(QEvent *ev) { if (ev->type() == QEvent::LayoutRequest) { updateLayout(); return true; } else { return QFrame::event(ev); } } bool KNote::eventFilter(QObject *o, QEvent *ev) { if (ev->type() == QEvent::DragEnter && static_cast(ev)->mimeData()->hasColor()) { dragEnterEvent(static_cast(ev)); return true; } if (ev->type() == QEvent::Drop && static_cast(ev)->mimeData()->hasColor()) { dropEvent(static_cast(ev)); return true; } if (o == m_label) { QMouseEvent *e = (QMouseEvent *)ev; if (ev->type() == QEvent::MouseButtonDblClick) { if (!m_editor->isReadOnly()) { slotRename(); } } if (ev->type() == QEvent::MouseButtonPress && ( (e->buttons() & Qt::LeftButton) == Qt::LeftButton || (e->buttons() & Qt::MidButton) == Qt::MidButton)) { mOrigPos = e->pos(); return false; } if (ev->type() == QEvent::MouseMove && ( (e->buttons() & Qt::LeftButton) == Qt::LeftButton || (e->buttons() & Qt::MidButton) == Qt::MidButton)) { QPoint newPos = e->globalPos() - mOrigPos - QPoint(1, 1); move(newPos); return true; } if (ev->type() == QEvent::MouseButtonRelease && ( (e->buttons() & Qt::LeftButton) == Qt::LeftButton || (e->buttons() & Qt::MidButton) == Qt::MidButton)) { QPoint newPos = e->globalPos() - mOrigPos - QPoint(1, 1); move(newPos); return false; } return false; } if (o == m_editor) { if (ev->type() == QEvent::FocusOut) { QFocusEvent *fe = static_cast(ev); if (fe->reason() != Qt::PopupFocusReason && fe->reason() != Qt::MouseFocusReason) { updateFocus(); if (!mBlockSave) { saveNote(true); } } } else if (ev->type() == QEvent::FocusIn) { updateFocus(); } return false; } return false; } Akonadi::Item KNote::item() const { return mItem; } void KNote::slotDebugAkonadiSearch() { QPointer dlg = new Akonadi::Search::AkonadiSearchDebugDialog; dlg->setAkonadiId(mItem.id()); dlg->setAttribute(Qt::WA_DeleteOnClose); dlg->setSearchType(Akonadi::Search::AkonadiSearchDebugSearchPathComboBox::Notes); dlg->doSearch(); dlg->show(); }