diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af32724..0811112 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::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) +target_link_libraries(kcm_knote knotesprivate KF5::AkonadiCore KF5::KCMUtils KF5::NewStuff 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/apps/knotesapp.cpp b/src/apps/knotesapp.cpp index c6eec08..fbc1f89 100644 --- a/src/apps/knotesapp.cpp +++ b/src/apps/knotesapp.cpp @@ -1,749 +1,748 @@ /******************************************************************* 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 "knotesapp.h" #include "knotes_debug.h" #include "knotesadaptor.h" #include "knotesglobalconfig.h" #include "notesharedglobalconfig.h" #include "akonadi/noteschangerecorder.h" #include "akonadi/notesakonaditreemodel.h" #include "apps/knotesakonaditray.h" #include "attributes/notealarmattribute.h" #include "attributes/notedisplayattribute.h" #include "attributes/notelockattribute.h" #include "attributes/showfoldernotesattribute.h" #include "configdialog/knoteconfigdialog.h" #include "dialog/knotedeleteselectednotesdialog.h" #include "dialog/knoteskeydialog.h" #include "finddialog/knotefinddialog.h" #include "job/createnewnotejob.h" #include "notes/knote.h" #include "print/knoteprinter.h" #include "print/knoteprintselectednotesdialog.h" #include "resources/localresourcecreator.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 static bool qActionLessThan(const QAction *a1, const QAction *a2) { return a1->text() < a2->text(); } KNotesApp::KNotesApp(QWidget *parent) : QWidget(parent) { Akonadi::ControlGui::widgetNeedsAkonadi(this); mDebugAkonadiSearch = !qEnvironmentVariableIsEmpty("KDEPIM_DEBUGGING"); if (KNotesGlobalConfig::self()->autoCreateResourceOnStart()) { NoteShared::LocalResourceCreator *creator = new NoteShared::LocalResourceCreator(this); creator->createIfMissing(); } new KNotesAdaptor(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/KNotes"), this); qApp->setQuitOnLastWindowClosed(false); // create the GUI... QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18n("New Note"), this); actionCollection()->addAction(QStringLiteral("new_note"), action); KGlobalAccel::setGlobalShortcut(action, QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_N)); connect(action, &QAction::triggered, this, [this]() { newNote(); }); action = new QAction(QIcon::fromTheme(QStringLiteral("edit-paste")), i18n("New Note From Clipboard"), this); actionCollection()->addAction(QStringLiteral("new_note_clipboard"), action); KGlobalAccel::setGlobalShortcut(action, QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_C)); connect(action, &QAction::triggered, this, &KNotesApp::newNoteFromClipboard); action = new QAction(QIcon::fromTheme(QStringLiteral("document-open")), i18n("New Note From Text File..."), this); actionCollection()->addAction(QStringLiteral("new_note_from_text_file"), action); connect(action, &QAction::triggered, this, &KNotesApp::newNoteFromTextFile); action = new QAction(QIcon::fromTheme(QStringLiteral("knotes")), i18n("Show All Notes"), this); actionCollection()->addAction(QStringLiteral("show_all_notes"), action); KGlobalAccel::setGlobalShortcut(action, QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_S)); connect(action, &QAction::triggered, this, &KNotesApp::showAllNotes); action = new QAction(QIcon::fromTheme(QStringLiteral("window-close")), i18n("Hide All Notes"), this); actionCollection()->addAction(QStringLiteral("hide_all_notes"), action); KGlobalAccel::setGlobalShortcut(action, QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_H)); connect(action, &QAction::triggered, this, &KNotesApp::hideAllNotes); action = new QAction(QIcon::fromTheme(QStringLiteral("document-print")), i18nc("@action:inmenu", "Print Selected Notes..."), this); actionCollection()->addAction(QStringLiteral("print_selected_notes"), action); connect(action, &QAction::triggered, this, &KNotesApp::slotPrintSelectedNotes); QAction *act = KStandardAction::find(this, &KNotesApp::slotOpenFindDialog, actionCollection()); action = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18nc("@action:inmenu", "Delete Selected Notes..."), this); actionCollection()->addAction(QStringLiteral("delete_selected_notes"), action); connect(action, &QAction::triggered, this, &KNotesApp::slotDeleteSelectedNotes); //REmove shortcut here. act->setShortcut(0); KHelpMenu *menu = new KHelpMenu(this, KAboutData::applicationData(), false); KActionCollection *actions = actionCollection(); QAction *helpContentsAction = menu->action(KHelpMenu::menuHelpContents); QAction *whatsThisAction = menu->action(KHelpMenu::menuWhatsThis); QAction *reportBugAction = menu->action(KHelpMenu::menuReportBug); QAction *switchLanguageAction = menu->action(KHelpMenu::menuSwitchLanguage); QAction *aboutAppAction = menu->action(KHelpMenu::menuAboutApp); QAction *aboutKdeAction = menu->action(KHelpMenu::menuAboutKDE); QAction *donateAction = menu->action(KHelpMenu::menuDonate); if (helpContentsAction) { actions->addAction(helpContentsAction->objectName(), helpContentsAction); } if (whatsThisAction) { actions->addAction(whatsThisAction->objectName(), whatsThisAction); } if (reportBugAction) { actions->addAction(reportBugAction->objectName(), reportBugAction); } if (switchLanguageAction) { actions->addAction(switchLanguageAction->objectName(), switchLanguageAction); } if (aboutAppAction) { actions->addAction(aboutAppAction->objectName(), aboutAppAction); } if (aboutKdeAction) { actions->addAction(aboutKdeAction->objectName(), aboutKdeAction); } if (donateAction) { actions->addAction(donateAction->objectName(), donateAction); } KStandardAction::preferences(this, &KNotesApp::slotPreferences, actionCollection()); KStandardAction::keyBindings(this, &KNotesApp::slotConfigureAccels, actionCollection()); //FIXME: no shortcut removing!? KStandardAction::quit(this, &KNotesApp::slotQuit, actionCollection())->setShortcut(0); setXMLFile(QStringLiteral("knotesappui.rc")); m_guiBuilder = new KXMLGUIBuilder(this); m_guiFactory = new KXMLGUIFactory(m_guiBuilder, this); m_guiFactory->addClient(this); QMenu *contextMenu = static_cast(m_guiFactory->container( QStringLiteral("knotes_context"), this)); m_noteMenu = static_cast(m_guiFactory->container( QStringLiteral("notes_menu"), this)); // get the most recent XML UI file QString xmlFileName(componentName() + QLatin1String("ui.rc")); #pragma message("port QT5") QString filter(QLatin1String("kxmlgui5/knotes/") + xmlFileName);//QT5 = componentData().componentName() + QLatin1Char('/') + xmlFileName; const QStringList fileList = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, filter) + QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, xmlFileName);//QT5 = #pragma message("port QT5") //QT5 componentData().dirs()->findAllResources( "data", filter ) + #pragma message("port QT5") //QT5 componentData().dirs()->findAllResources( "data", xmlFileName ); qCDebug(KNOTES_LOG) << " fileList :" << fileList << " filter :" << filter; QString doc; KXMLGUIClient::findMostRecentXMLFile(fileList, doc); m_noteGUI.setContent(doc); // set up the alarm reminder - do it after loading the notes because this // is used as a check if updateNoteActions has to be called for a new note updateNetworkListener(); Akonadi::Session *session = new Akonadi::Session("KNotes Session", this); mNoteRecorder = new NoteShared::NotesChangeRecorder(this); mNoteRecorder->changeRecorder()->setSession(session); mTray = new KNotesAkonadiTray(nullptr); connect(mTray, &KStatusNotifierItem::activateRequested, this, &KNotesApp::slotActivateRequested); connect(mTray, &KStatusNotifierItem::secondaryActivateRequested, this, &KNotesApp::slotSecondaryActivateRequested); mTray->setContextMenu(contextMenu); mNoteTreeModel = new NoteShared::NotesAkonadiTreeModel(mNoteRecorder->changeRecorder(), this); connect(mNoteTreeModel, &QAbstractItemModel::rowsInserted, this, &KNotesApp::slotRowInserted); connect(mNoteRecorder->changeRecorder(), &Akonadi::Monitor::itemChanged, this, &KNotesApp::slotItemChanged); connect(mNoteRecorder->changeRecorder(), &Akonadi::Monitor::itemRemoved, this, &KNotesApp::slotItemRemoved); connect(mNoteRecorder->changeRecorder(), qOverload &>(&Akonadi::ChangeRecorder::collectionChanged), this, &KNotesApp::slotCollectionChanged); connect(qApp, &QGuiApplication::commitDataRequest, this, &KNotesApp::slotCommitData, Qt::DirectConnection); QGuiApplication::setFallbackSessionManagementEnabled(false); updateNoteActions(); } KNotesApp::~KNotesApp() { qDeleteAll(m_noteActions); m_noteActions.clear(); saveNotes(); delete m_guiBuilder; delete mTray; qDeleteAll(mNotes); mNotes.clear(); delete m_publisher; m_publisher = nullptr; } void KNotesApp::slotDeleteSelectedNotes() { QPointer dlg = new KNoteDeleteSelectedNotesDialog(this); Akonadi::Item::List lst; QHashIterator i(mNotes); while (i.hasNext()) { i.next(); Akonadi::Item item = i.value()->item(); if (!item.hasAttribute()) { lst.append(item); } } dlg->setNotes(lst); if (dlg->exec()) { const Akonadi::Item::List lst = dlg->selectedNotes(); if (!lst.isEmpty()) { Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(lst, this); connect(deleteJob, &KJob::result, this, &KNotesApp::slotNoteDeleteFinished); } } delete dlg; } void KNotesApp::slotItemRemoved(const Akonadi::Item &item) { qCDebug(KNOTES_LOG) << " note removed" << item.id(); if (mNotes.contains(item.id())) { delete mNotes.find(item.id()).value(); mNotes.remove(item.id()); updateNoteActions(); updateSystray(); } } void KNotesApp::slotItemChanged(const Akonadi::Item &item, const QSet &set) { if (mNotes.contains(item.id())) { qCDebug(KNOTES_LOG) << " item changed " << item.id() << " info " << set.toList(); KNote *note = mNotes.value(item.id()); note->setChangeItem(item, set); } } void KNotesApp::slotRowInserted(const QModelIndex &parent, int start, int end) { bool needUpdate = false; for (int i = start; i <= end; ++i) { if (mNoteTreeModel->hasIndex(i, 0, parent)) { const QModelIndex child = mNoteTreeModel->index(i, 0, parent); Akonadi::Item item = mNoteTreeModel->data(child, Akonadi::EntityTreeModel::ItemRole).value(); Akonadi::Collection parentCollection = mNoteTreeModel->data(child, Akonadi::EntityTreeModel::ParentCollectionRole).value(); if (parentCollection.hasAttribute()) { createNote(item); needUpdate = true; } } } if (needUpdate) { updateNoteActions(); updateSystray(); } } void KNotesApp::createNote(const Akonadi::Item &item) { if (item.hasPayload() && !mNotes.contains(item.id())) { KNote *note = new KNote(m_noteGUI, item, mDebugAkonadiSearch); mNotes.insert(item.id(), note); connect(note, &KNote::sigShowNextNote, this, &KNotesApp::slotWalkThroughNotes); connect(note, &KNote::sigRequestNewNote, this, [this] { newNote(); }); connect(note, &KNote::sigNameChanged, this, &KNotesApp::updateNoteActions); connect(note, &KNote::sigColorChanged, this, &KNotesApp::updateNoteActions); connect(note, &KNote::sigKillNote, this, &KNotesApp::slotNoteKilled); } } void KNotesApp::updateSystray() { if (KNotesGlobalConfig::self()->systemTrayShowNotes()) { mTray->updateNumberOfNotes(mNotes.count()); } } void KNotesApp::newNote(const QString &name, const QString &text) { NoteShared::CreateNewNoteJob *job = new NoteShared::CreateNewNoteJob(this, this); job->setRichText(KNotesGlobalConfig::self()->richText()); job->setNote(name, text); job->start(); } void KNotesApp::showNote(Akonadi::Item::Id id) const { KNote *note = mNotes.value(id); if (note) { showNote(note); } else { qCWarning(KNOTES_LOG) << "hideNote: no note with id:" << id; } } void KNotesApp::showNote(KNote *note) const { note->show(); #if KDEPIM_HAVE_X11 if (!note->isDesktopAssigned()) { note->toDesktop(KWindowSystem::currentDesktop()); } else { KWindowSystem::setCurrentDesktop( KWindowInfo(note->winId(), NET::WMDesktop).desktop()); } KWindowSystem::forceActiveWindow(note->winId()); #endif note->setFocus(); } void KNotesApp::hideNote(Akonadi::Item::Id id) const { KNote *note = mNotes.value(id); if (note) { note->hide(); } else { qCWarning(KNOTES_LOG) << "hideNote: no note with id:" << id; } } void KNotesApp::hideAllNotes() const { QHashIterator i(mNotes); while (i.hasNext()) { i.next(); i.value()->slotClose(); } } void KNotesApp::showAllNotes() const { QHashIterator i(mNotes); while (i.hasNext()) { i.next(); // workaround to BUG 149116 i.value()->hide(); i.value()->show(); } } void KNotesApp::newNoteFromClipboard() { const QString &text = QApplication::clipboard()->text(); newNote(QString(), text); } void KNotesApp::newNoteFromTextFile() { QString text; const QString filename = QFileDialog::getOpenFileName(this, i18n("Select Text File"), QString(), QStringLiteral("%1 (*.txt)").arg(i18n("Text File"))); if (!filename.isEmpty()) { QFile f(filename); if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { text = QString::fromUtf8(f.readAll()); } else { KMessageBox::error(this, i18n("Error during open text file: %1", f.errorString()), i18n("Open Text File")); return; } newNote(i18n("Note from file '%1'", filename), text); } } void KNotesApp::updateNetworkListener() { delete m_publisher; m_publisher = nullptr; if (NoteShared::NoteSharedGlobalConfig::receiveNotes()) { // create the socket and start listening for connections m_publisher = new KDNSSD::PublicService(NoteShared::NoteSharedGlobalConfig::senderID(), QStringLiteral("_knotes._tcp"), NoteShared::NoteSharedGlobalConfig::port()); m_publisher->publishAsync(); } } QString KNotesApp::name(Akonadi::Item::Id id) const { KNote *note = mNotes.value(id); if (note) { return note->name(); } return QString(); } QString KNotesApp::text(Akonadi::Item::Id id) const { KNote *note = mNotes.value(id); if (note) { return note->text(); } return QString(); } void KNotesApp::setName(Akonadi::Item::Id id, const QString &newName) { KNote *note = mNotes.value(id); if (note) { note->setName(newName); } else { qCWarning(KNOTES_LOG) << "setName: no note with id:" << id; } } void KNotesApp::setText(Akonadi::Item::Id id, const QString &newText) { KNote *note = mNotes.value(id); if (note) { note->setText(newText); } else { qCWarning(KNOTES_LOG) << "setText: no note with id:" << id; } } void KNotesApp::updateNoteActions() { unplugActionList(QStringLiteral("notes")); m_noteActions.clear(); QHashIterator i(mNotes); while (i.hasNext()) { i.next(); KNote *note = i.value(); QString replaceText; QString realName = note->name(); if (realName.count() > 50) { replaceText = realName.left(50) + QLatin1String("..."); } else { replaceText = realName; } QAction *action = new QAction(replaceText.replace(QLatin1String("&"), QStringLiteral("&&")), this); action->setToolTip(realName); action->setObjectName(QString::number(note->noteId())); connect(action, &QAction::triggered, this, &KNotesApp::slotShowNote); KIconEffect effect; QPixmap icon - = effect.apply(qApp->windowIcon().pixmap(IconSize(KIconLoader::Small), - IconSize(KIconLoader::Small)), + = effect.apply(qApp->windowIcon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)), KIconEffect::Colorize, 1, note->palette().color(note->backgroundRole()), false); action->setIcon(icon); m_noteActions.append(action); } if (m_noteActions.isEmpty()) { actionCollection()->action(QStringLiteral("hide_all_notes"))->setEnabled(false); actionCollection()->action(QStringLiteral("show_all_notes"))->setEnabled(false); actionCollection()->action(QStringLiteral("print_selected_notes"))->setEnabled(false); actionCollection()->action(QStringLiteral("edit_find"))->setEnabled(false); QAction *action = new QAction(i18n("No Notes"), this); action->setEnabled(false); m_noteActions.append(action); } else { std::sort(m_noteActions.begin(), m_noteActions.end(), qActionLessThan); actionCollection()->action(QStringLiteral("hide_all_notes"))->setEnabled(true); actionCollection()->action(QStringLiteral("show_all_notes"))->setEnabled(true); actionCollection()->action(QStringLiteral("print_selected_notes"))->setEnabled(true); actionCollection()->action(QStringLiteral("edit_find"))->setEnabled(true); } plugActionList(QStringLiteral("notes"), m_noteActions); } void KNotesApp::slotActivateRequested(bool, const QPoint &) { if (mNotes.size() == 1) { showNote(mNotes.begin().value()); } else { m_noteMenu->popup(QCursor::pos()); } } void KNotesApp::slotSecondaryActivateRequested(const QPoint &) { newNote(); } void KNotesApp::slotShowNote() { // tell the WM to give this note focus showNote(sender()->objectName().toLongLong()); } void KNotesApp::slotWalkThroughNotes() { QHashIterator i(mNotes); while (i.hasNext()) { i.next(); KNote *note = i.value(); if (note->hasFocus()) { if (i.value() != mNotes.end().value()) { showNote(i.value()); } else { showNote(mNotes.begin().value()); } break; } } } void KNotesApp::slotPreferences() { // create a new preferences dialog... KNoteConfigDialog *dialog = new KNoteConfigDialog(i18n("Settings"), this); connect(dialog, qOverload<>(&KCMultiDialog::configCommitted), this, &KNotesApp::slotConfigUpdated); dialog->show(); } void KNotesApp::slotConfigUpdated() { updateNetworkListener(); KNoteUtils::updateConfiguration(); //Force update if we disable or enable show number in systray mTray->updateNumberOfNotes(mNotes.count()); } void KNotesApp::slotCollectionChanged(const Akonadi::Collection &col, const QSet &set) { if (set.contains("showfoldernotesattribute")) { //qCDebug(KNOTES_LOG)<<" collection Changed "<()) { fetchNotesFromCollection(col); } else { QHashIterator i(mNotes); while (i.hasNext()) { i.next(); Akonadi::Item item = i.value()->item(); if (item.parentCollection() == col) { slotItemRemoved(item); } } } } } void KNotesApp::slotConfigureAccels() { QPointer keys = new KNotesKeyDialog(actionCollection(), this); KActionCollection *actionCollection = nullptr; if (!mNotes.isEmpty()) { actionCollection = mNotes.begin().value()->actionCollection(); keys->insert(actionCollection); } if (keys->exec()) { keys->save(); // update GUI doc for new notes m_noteGUI.setContent( KXMLGUIFactory::readConfigFile(componentName() + QLatin1String("ui.rc"), componentName()) ); if (actionCollection) { QHashIterator i(mNotes); while (i.hasNext()) { i.next(); const auto lst = actionCollection->actions(); for (QAction *action : lst) { QAction *toChange = i.value()->actionCollection()->action(action->objectName()); if (toChange) { toChange->setShortcuts(action->shortcuts()); } } } } } delete keys; } void KNotesApp::slotNoteKilled(Akonadi::Item::Id id) { Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(Akonadi::Item(id), this); connect(deleteJob, &KJob::result, this, &KNotesApp::slotNoteDeleteFinished); } void KNotesApp::slotNoteDeleteFinished(KJob *job) { if (job->error()) { qCWarning(KNOTES_LOG) << job->errorString(); return; } } void KNotesApp::slotPrintSelectedNotes() { QPointer dlg = new KNotePrintSelectedNotesDialog(this); dlg->setNotes(mNotes); if (dlg->exec()) { const QList lst = dlg->selectedNotes(); if (!lst.isEmpty()) { const QString selectedTheme = dlg->selectedTheme(); KNotePrinter printer; printer.printNotes(lst, selectedTheme, dlg->preview()); qDeleteAll(lst); } } delete dlg; } void KNotesApp::saveNotes(bool force, bool sync) { KNotesGlobalConfig::self()->save(); QHashIterator i(mNotes); while (i.hasNext()) { i.next(); i.value()->saveNote(force, sync); } } void KNotesApp::slotQuit() { saveNotes(true, true); qApp->quit(); } void KNotesApp::slotCommitData(QSessionManager &) { saveNotes(true, true); } void KNotesApp::slotSelectNote(Akonadi::Item::Id id) { showNote(id); } void KNotesApp::slotOpenFindDialog() { if (!mFindDialog) { mFindDialog = new KNoteFindDialog(this); connect(mFindDialog.data(), &KNoteFindDialog::noteSelected, this, &KNotesApp::slotSelectNote); } QHash lst; QHashIterator i(mNotes); while (i.hasNext()) { i.next(); lst.insert(i.key(), i.value()->item()); } mFindDialog->setExistingNotes(lst); mFindDialog->show(); } void KNotesApp::fetchNotesFromCollection(const Akonadi::Collection &col) { Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(col); job->fetchScope().fetchFullPayload(true); job->fetchScope().fetchAttribute(); job->fetchScope().fetchAttribute(); job->fetchScope().fetchAttribute(); job->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent); connect(job, &KJob::result, this, &KNotesApp::slotItemFetchFinished); } void KNotesApp::slotItemFetchFinished(KJob *job) { if (job->error()) { qCDebug(KNOTES_LOG) << "Error occurred during item fetch:" << job->errorString(); return; } Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); const Akonadi::Item::List items = fetchJob->items(); for (const Akonadi::Item &item : items) { createNote(item); } if (!items.isEmpty()) { updateNoteActions(); updateSystray(); } } diff --git a/src/configdialog/knoteconfigdialog.cpp b/src/configdialog/knoteconfigdialog.cpp index 7a60543..8a471d7 100644 --- a/src/configdialog/knoteconfigdialog.cpp +++ b/src/configdialog/knoteconfigdialog.cpp @@ -1,332 +1,323 @@ /******************************************************************* KNotes -- Notes for the KDE project Copyright (c) 1997-2005, 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 "knoteconfigdialog.h" #include "notesharedglobalconfig.h" #include "knotecollectionconfigwidget.h" #include "knotedisplayconfigwidget.h" #include "knoteeditorconfigwidget.h" #include "knotesglobalconfig.h" #include "config/noteactionconfig.h" #include "config/notenetworkconfig.h" #include "print/knoteprintselectthemecombobox.h" #include -#include #include #include -#include #include #include #include #include #include #include #include #include KNoteConfigDialog::KNoteConfigDialog(const QString &title, QWidget *parent) : KCMultiDialog(parent) { setFaceType(KPageDialog::List); setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); button(QDialogButtonBox::Ok)->setDefault(true); setWindowTitle(title); - KWindowSystem::setIcons(winId(), - qApp->windowIcon().pixmap( - IconSize(KIconLoader::Desktop), - IconSize(KIconLoader::Desktop)), - qApp->windowIcon().pixmap( - IconSize(KIconLoader::Small), - IconSize(KIconLoader::Small))); addModule(QStringLiteral("knote_config_display")); addModule(QStringLiteral("knote_config_editor")); addModule(QStringLiteral("knote_config_action")); addModule(QStringLiteral("knote_config_network")); addModule(QStringLiteral("knote_config_print")); addModule(QStringLiteral("knote_config_collection")); addModule(QStringLiteral("knote_config_misc")); connect(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &KNoteConfigDialog::slotOk); connect(button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &KNoteConfigDialog::slotDefaultClicked); } KNoteConfigDialog::~KNoteConfigDialog() { } void KNoteConfigDialog::slotOk() { NoteShared::NoteSharedGlobalConfig::self()->save(); KNotesGlobalConfig::self()->save(); } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_display(QWidget *parent) { return new KNoteDisplayConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_collection(QWidget *parent) { return new KNoteCollectionConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_editor(QWidget *parent) { return new KNoteEditorConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_action(QWidget *parent) { return new NoteShared::NoteActionConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_network(QWidget *parent) { return new NoteShared::NoteNetworkConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_print(QWidget *parent) { return new KNotePrintConfig(parent); } } extern "C" { Q_DECL_EXPORT KCModule *create_knote_config_misc(QWidget *parent) { return new KNoteMiscConfig(parent); } } KNoteDisplayConfig::KNoteDisplayConfig(QWidget *parent) : KCModule(parent) { QVBoxLayout *lay = new QVBoxLayout(this); QWidget *w = new KNoteDisplayConfigWidget(true); lay->addWidget(w); lay->addStretch(); addConfig(KNotesGlobalConfig::self(), w); load(); } void KNoteDisplayConfig::load() { KCModule::load(); } void KNoteDisplayConfig::save() { KCModule::save(); } KNoteEditorConfig::KNoteEditorConfig(QWidget *parent) : KCModule(parent) { QVBoxLayout *lay = new QVBoxLayout(this); QWidget *w = new KNoteEditorConfigWidget(this); lay->addWidget(w); lay->addStretch(); addConfig(KNotesGlobalConfig::self(), w); load(); } void KNoteEditorConfig::save() { KCModule::save(); } void KNoteEditorConfig::load() { KCModule::load(); } KNoteMiscConfig::KNoteMiscConfig(QWidget *parent) : KCModule(parent) { QVBoxLayout *lay = new QVBoxLayout(this); lay->setContentsMargins(0, 0, 0, 0); QCheckBox *kcfg_SystemTrayShowNotes = new QCheckBox(i18n("Show number of notes in tray icon"), this); kcfg_SystemTrayShowNotes->setObjectName(QStringLiteral("kcfg_SystemTrayShowNotes")); lay->addWidget(kcfg_SystemTrayShowNotes); QHBoxLayout *hbox = new QHBoxLayout; lay->addLayout(hbox); QLabel *label_DefaultTitle = new QLabel(i18n("Default Title:"), this); hbox->addWidget(label_DefaultTitle); mDefaultTitle = new QLineEdit(this); label_DefaultTitle->setBuddy(mDefaultTitle); hbox->addWidget(mDefaultTitle); QLabel *howItWorks = new QLabel(i18n("How does this work?")); connect(howItWorks, &QLabel::linkActivated, this, &KNoteMiscConfig::slotHelpLinkClicked); lay->addWidget(howItWorks); addConfig(KNotesGlobalConfig::self(), this); howItWorks->setContextMenuPolicy(Qt::NoContextMenu); lay->addStretch(); load(); connect(mDefaultTitle, &QLineEdit::textChanged, this, &KNoteMiscConfig::markAsChanged); } void KNoteMiscConfig::load() { KCModule::load(); mDefaultTitle->setText(NoteShared::NoteSharedGlobalConfig::self()->defaultTitle()); } void KNoteMiscConfig::save() { KCModule::save(); NoteShared::NoteSharedGlobalConfig::self()->setDefaultTitle(mDefaultTitle->text()); NoteShared::NoteSharedGlobalConfig::self()->save(); } void KNoteMiscConfig::defaults() { KCModule::defaults(); const bool bUseDefaults = NoteShared::NoteSharedGlobalConfig::self()->useDefaults(true); mDefaultTitle->setText(NoteShared::NoteSharedGlobalConfig::self()->defaultTitle()); NoteShared::NoteSharedGlobalConfig::self()->useDefaults(bUseDefaults); } void KNoteMiscConfig::slotHelpLinkClicked(const QString &) { const QString help = i18n("" "

You can customize title note. " "You can use:

" "
    " "
  • %d current date (short format)
  • " "
  • %l current date (long format)
  • " "
  • %t current time
  • " "
" "
"); QWhatsThis::showText(QCursor::pos(), help); } KNotePrintConfig::KNotePrintConfig(QWidget *parent) : KCModule(parent) { QVBoxLayout *lay = new QVBoxLayout(this); QWidget *w = new QWidget(this); lay->addWidget(w); QGridLayout *layout = new QGridLayout(w); layout->setContentsMargins(0, 0, 0, 0); QLabel *label_PrintAction = new QLabel(i18n("Theme:"), this); layout->addWidget(label_PrintAction, 0, 0); mSelectTheme = new KNotePrintSelectThemeComboBox(this); connect(mSelectTheme, qOverload(&QComboBox::activated), this, &KNotePrintConfig::slotThemeChanged); label_PrintAction->setBuddy(mSelectTheme); layout->addWidget(mSelectTheme, 0, 1); if (KAuthorized::authorize(QStringLiteral("ghns"))) { QToolButton *getNewTheme = new QToolButton; getNewTheme->setIcon(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff"))); getNewTheme->setToolTip(i18n("Download new printing themes")); connect(getNewTheme, &QToolButton::clicked, this, &KNotePrintConfig::slotDownloadNewThemes); layout->addWidget(getNewTheme, 0, 2); } lay->addStretch(); load(); } void KNotePrintConfig::slotDownloadNewThemes() { QPointer downloadThemesDialog = new KNS3::DownloadDialog(QStringLiteral("knotes_printing_theme.knsrc")); if (downloadThemesDialog->exec()) { if (!downloadThemesDialog->changedEntries().isEmpty()) { mSelectTheme->loadThemes(); } } delete downloadThemesDialog; } void KNotePrintConfig::slotThemeChanged() { Q_EMIT changed(true); } void KNotePrintConfig::save() { KNotesGlobalConfig::self()->setTheme(mSelectTheme->selectedTheme()); } void KNotePrintConfig::load() { mSelectTheme->loadThemes(); } void KNotePrintConfig::defaults() { mSelectTheme->selectDefaultTheme(); Q_EMIT changed(true); } KNoteCollectionConfig::KNoteCollectionConfig(QWidget *parent) : KCModule(parent) { QHBoxLayout *lay = new QHBoxLayout(this); mCollectionConfigWidget = new KNoteCollectionConfigWidget; lay->addWidget(mCollectionConfigWidget); connect(mCollectionConfigWidget, &KNoteCollectionConfigWidget::emitChanged, this, &KNoteCollectionConfig::markAsChanged); load(); } void KNoteCollectionConfig::save() { mCollectionConfigWidget->save(); } void KNoteCollectionConfig::load() { //Nothing } diff --git a/src/configdialog/knotesimpleconfigdialog.cpp b/src/configdialog/knotesimpleconfigdialog.cpp index 6d8de9e..24b37c6 100644 --- a/src/configdialog/knotesimpleconfigdialog.cpp +++ b/src/configdialog/knotesimpleconfigdialog.cpp @@ -1,114 +1,104 @@ /* Copyright (C) 2013-2019 Montel Laurent 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "knotesimpleconfigdialog.h" #include "knoteconfigdialog.h" #include "knotedisplayconfigwidget.h" #include "knoteeditorconfigwidget.h" #include "attributes/notedisplayattribute.h" #include "attributes/notelockattribute.h" #include -#include #include #include -#include #include #include #include #include #include KNoteSimpleConfigDialog::KNoteSimpleConfigDialog(const QString &title, QWidget *parent) : QDialog(parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(buttonBox, &QDialogButtonBox::accepted, this, &KNoteSimpleConfigDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &KNoteSimpleConfigDialog::reject); - setWindowTitle(title); - KWindowSystem::setIcons(winId(), - qApp->windowIcon().pixmap( - IconSize(KIconLoader::Desktop), - IconSize(KIconLoader::Desktop)), - qApp->windowIcon().pixmap( - IconSize(KIconLoader::Small), - IconSize(KIconLoader::Small))); mTabWidget = new QTabWidget; mEditorConfigWidget = new KNoteEditorConfigWidget(this); mTabWidget->addTab(mEditorConfigWidget, i18n("Editor Settings")); mDisplayConfigWidget = new KNoteDisplayConfigWidget(true, this); mTabWidget->addTab(mDisplayConfigWidget, i18n("Display Settings")); mainLayout->addWidget(mTabWidget); mainLayout->addWidget(buttonBox); readConfig(); } KNoteSimpleConfigDialog::~KNoteSimpleConfigDialog() { writeConfig(); } void KNoteSimpleConfigDialog::load(Akonadi::Item &item, bool isRichText) { NoteShared::NoteDisplayAttribute *attr = item.attribute(); mEditorConfigWidget->load(attr, isRichText); mDisplayConfigWidget->load(attr); } void KNoteSimpleConfigDialog::slotUpdateCaption(const QString &name) { setWindowTitle(name); } void KNoteSimpleConfigDialog::save(Akonadi::Item &item, bool &isRichText) { NoteShared::NoteDisplayAttribute *attr = item.attribute(Akonadi::Item::AddIfMissing); mEditorConfigWidget->save(attr, isRichText); mDisplayConfigWidget->save(attr); } void KNoteSimpleConfigDialog::readConfig() { KConfigGroup group(KSharedConfig::openConfig(), "KNoteSimpleConfigDialog"); const QSize size = group.readEntry("Size", QSize(600, 400)); if (size.isValid()) { resize(size); } } void KNoteSimpleConfigDialog::writeConfig() { KConfigGroup group(KSharedConfig::openConfig(), "KNoteSimpleConfigDialog"); group.writeEntry("Size", size()); group.sync(); } diff --git a/src/notes/knote.cpp b/src/notes/knote.cpp index 55b9c84..6c97178 100644 --- a/src/notes/knote.cpp +++ b/src/notes/knote.cpp @@ -1,1247 +1,1238 @@ /******************************************************************* 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 #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 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->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)), + const QPixmap icon = effect.apply(qApp->windowIcon().pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize)), KIconEffect::Colorize, 1, col, false); - const QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap( - IconSize(KIconLoader::Small), - IconSize(KIconLoader::Small)), + const QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)), 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)), + QPixmap icon = effect.apply(qApp->windowIcon().pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize)), KIconEffect::Colorize, 1, bg, false); - QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap( - IconSize(KIconLoader::Small), - IconSize(KIconLoader::Small)), + QPixmap miniIcon = effect.apply(qApp->windowIcon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)), 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(); }