diff --git a/data/kjots_config_misc.desktop b/data/kjots_config_misc.desktop
index c080ab9..5df76e5 100644
--- a/data/kjots_config_misc.desktop
+++ b/data/kjots_config_misc.desktop
@@ -1,69 +1,69 @@
[Desktop Entry]
-Icon=kjots
+Icon=preferences-other
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-ModuleType=Library
X-KDE-Library=kcm_kjots
X-KDE-HasReadOnlyMode=false
X-KDE-ParentApp=kjots
X-KDE-ParentComponents=kjots,kontact_kjotsplugin
-X-KDE-CfgDlgHierarchy=Notebooks
+X-KDE-CfgDlgHierarchy=Notes
X-KDE-Weight=200
Name=Misc
Name[ca]=Varis
Name[ca@valencia]=Varis
Name[cs]=Různé
Name[da]=Diverse
Name[de]=Verschiedenes
Name[el]=Διάφορα
Name[en_GB]=Misc
Name[es]=Diversos
Name[et]=Misc
Name[fi]=Sekalaiset
Name[fr]=Divers
Name[gl]=Varios
Name[ia]=Misc
Name[it]=Varie
Name[ko]=기타
Name[nl]=Diversen
Name[pl]=Różne
Name[pt]=Diversos
Name[pt_BR]=Diversos
Name[ru]=Прочее
Name[sk]=Rôzne
Name[sv]=Diverse
Name[tr]=Çeşitli
Name[uk]=Інше
Name[x-test]=xxMiscxx
Name[zh_CN]=基本
Name[zh_TW]=其他
Comment=Setup misc for KJots
Comment[ca]=Arranja els varis pel KJots
Comment[ca@valencia]=Arranja els varis pel KJots
Comment[cs]=Různá nastavení KJots
Comment[da]=Opsætning af diverse til KJots
Comment[de]=Verschiedene Einstellungen für KJots
Comment[el]=Ρύθμιση διαφόρων για το KJots
Comment[en_GB]=Setup misc for KJots
Comment[es]=Configuración diversa par KJots
Comment[et]=KJotsi misci seadistamine
Comment[fi]=Aseta sekalaiset KJots-asetukset
Comment[fr]=Configuration (divers) de KJots
Comment[gl]=Configurar varios aspectos de KJots.
Comment[ia]=Configura Misc pro KJots
Comment[it]=Impostazioni varie per KJots
Comment[ko]=KJots 기타 설정
Comment[nl]=Overige instellingen voor KJots
Comment[pl]=Różne ustawienia dla KJots
Comment[pt]=Configuração diversa do KJots
Comment[pt_BR]=Configurações diversas do KJots
Comment[ru]=Дополнительные параметры KJots
Comment[sk]=Rôzne nastavenie pre KJots
Comment[sv]=Diverse inställningar för Kjots
Comment[tr]=KJots için çeşitli seçenekleri ayarla
Comment[uk]=Різноманітні налаштування Kjots
Comment[x-test]=xxSetup misc for KJotsxx
Comment[zh_CN]=设置 KJots 的杂项
Comment[zh_TW]=設定 KJots 的雜項
diff --git a/src/confpagemisc.ui b/src/confpagemisc.ui
index 70e24b8..c3f39b3 100644
--- a/src/confpagemisc.ui
+++ b/src/confpagemisc.ui
@@ -1,150 +1,83 @@
confPageMisc
0
0
- 289
- 123
+ 417
+ 76
-
-
- 0
-
- -
-
-
- This is the number of minutes KJots will wait before automatically saving changes.
-
-
- 1 minute
-
-
- minutes
-
-
- 1
-
-
- 1440
-
-
-
- -
-
-
- This is the number of minutes KJots will wait before automatically saving changes.
-
-
- S&ave every:
-
-
- false
-
-
- autoSaveInterval
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Expanding
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Expanding
-
-
-
- 20
- 30
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 20
-
-
-
-
- -
-
-
- When "Save changes periodically" is checked, KJots will automatically save changes made to books at the interval defined below.
-
-
- &Save changes periodically
-
-
- true
-
-
+
+
-
+
+
-
+
+
+ This is the number of minutes KJots will wait before automatically saving changes.
+
+
+ S&ave every:
+
+
+ false
+
+
+ kcfg_AutoSaveInterval
+
+
+
+ -
+
+
+ This is the number of minutes KJots will wait before automatically saving changes.
+
+
+ 1 minute
+
+
+ minutes
+
+
+ 1
+
+
+ 1440
+
+
+
+ -
+
+
+ When "Save changes periodically" is checked, KJots will automatically save changes made to books at the interval defined below.
+
+
+ &Save changes periodically
+
+
+ true
+
+
+
+
kcfg_AutoSave
toggled(bool)
kcfg_AutoSaveInterval
setEnabled(bool)
-
-
- 20
- 20
-
-
- 20
- 20
-
-
kcfg_AutoSave
toggled(bool)
textLabel1
setEnabled(bool)
-
-
- 20
- 20
-
-
- 20
- 20
-
-
diff --git a/src/kjotsconfigdlg.cpp b/src/kjotsconfigdlg.cpp
index d44d4e5..f4a006f 100644
--- a/src/kjotsconfigdlg.cpp
+++ b/src/kjotsconfigdlg.cpp
@@ -1,76 +1,35 @@
/*
Copyright (c) 2009 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kjotsconfigdlg.h"
+#include "KJotsSettings.h"
#include
-#include
-#include
-
-KJotsConfigDlg::KJotsConfigDlg(const QString &title, QWidget *parent)
- : KCMultiDialog(parent)
-{
- setWindowTitle(title);
- setFaceType(KPageDialog::List);
- setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
- button(QDialogButtonBox::Ok)->setDefault(true);
-
- addModule(QStringLiteral("kjots_config_misc"));
- connect(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &KJotsConfigDlg::slotOk);
-}
-
-void KJotsConfigDlg::slotOk()
-{
-}
-
KJotsConfigMisc::KJotsConfigMisc(QWidget *parent, const QVariantList &args)
: KCModule(parent, args)
+ , ui(new Ui::confPageMisc)
{
auto *lay = new QHBoxLayout(this);
- miscPage = new confPageMisc(nullptr);
+ auto miscPage = new QWidget(this);
+ ui->setupUi(miscPage);
lay->addWidget(miscPage);
- connect(miscPage->autoSaveInterval, qOverload(&QSpinBox::valueChanged), this, &KJotsConfigMisc::modified);
- connect(miscPage->autoSave, &QCheckBox::stateChanged, this, &KJotsConfigMisc::modified);
+ addConfig(KJotsSettings::self(), miscPage);
load();
}
-void KJotsConfigMisc::modified()
-{
- Q_EMIT changed(true);
-}
-
-void KJotsConfigMisc::load()
-{
- KConfig config(QStringLiteral("kjotsrc"));
- KConfigGroup group = config.group("kjots");
- miscPage->autoSaveInterval->setValue(group.readEntry("AutoSaveInterval", 5));
- miscPage->autoSave->setChecked(group.readEntry("AutoSave", true));
- Q_EMIT changed(false);
-}
-
-void KJotsConfigMisc::save()
-{
- KConfig config(QStringLiteral("kjotsrc"));
- KConfigGroup group = config.group("kjots");
- group.writeEntry("AutoSaveInterval", miscPage->autoSaveInterval->value());
- group.writeEntry("AutoSave", miscPage->autoSave->isChecked());
- group.sync();
- Q_EMIT changed(false);
-}
-
#include "moc_kjotsconfigdlg.cpp"
diff --git a/src/kjotsconfigdlg.h b/src/kjotsconfigdlg.h
index 5ef60e9..c9f1b51 100644
--- a/src/kjotsconfigdlg.h
+++ b/src/kjotsconfigdlg.h
@@ -1,64 +1,37 @@
/*
Copyright (c) 2009 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KJOTSCONFIGDLG_H
#define KJOTSCONFIGDLG_H
#include
#include
#include "ui_confpagemisc.h"
-class confPageMisc : public QWidget, public Ui::confPageMisc
-{
- Q_OBJECT
-
-public:
- explicit confPageMisc(QWidget *parent) : QWidget(parent)
- {
- setupUi(this);
- }
-};
-
class KJotsConfigMisc : public KCModule
{
Q_OBJECT
public:
explicit KJotsConfigMisc(QWidget *parent, const QVariantList &args = QVariantList());
-
- void load() override;
- void save() override;
-private Q_SLOTS:
- void modified();
private:
- confPageMisc *miscPage;
-};
-
-class KJotsConfigDlg : public KCMultiDialog
-{
- Q_OBJECT
-
-public:
- explicit KJotsConfigDlg(const QString &title, QWidget *parent);
-
-public Q_SLOTS:
- void slotOk();
+ std::unique_ptr ui;
};
#endif /* KJOTSCONFIGDLG_H */
diff --git a/src/kjotswidget.cpp b/src/kjotswidget.cpp
index 71b1d84..4bd95b6 100644
--- a/src/kjotswidget.cpp
+++ b/src/kjotswidget.cpp
@@ -1,1262 +1,1266 @@
/*
This file is part of KJots.
Copyright (C) 1997 Christoph Neerfeld
Copyright (C) 2002, 2003 Aaron J. Seigo
Copyright (C) 2003 Stanislav Kljuhhin
Copyright (C) 2005-2006 Jaison Lee
Copyright (C) 2007-2009 Stephen Kelly
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library 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 Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "kjotswidget.h"
// Qt
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Akonadi
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Grantlee
#include
#include
#include
// KDE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include
// KMime
#include
// KJots
#include "kjotsbookmarks.h"
#include "kjotssortproxymodel.h"
#include "kjotsmodel.h"
#include "kjotsedit.h"
#include "kjotstreeview.h"
#include "kjotsconfigdlg.h"
#include "kjotsreplacenextdialog.h"
#include "KJotsSettings.h"
#include "kjotsbrowser.h"
#include "noteshared/notelockattribute.h"
#include "noteshared/standardnoteactionmanager.h"
#include "localresourcecreator.h"
#include
using namespace Akonadi;
using namespace Grantlee;
KJotsWidget::KJotsWidget(QWidget *parent, KXMLGUIClient *xmlGuiClient, Qt::WindowFlags f)
: QWidget(parent, f)
, m_xmlGuiClient(xmlGuiClient)
{
ControlGui::widgetNeedsAkonadi(this);
KConfigGroup config(KSharedConfig::openConfig(), "General");
const bool autoCreate = config.readEntry("AutoCreateResourceOnStart", true);
config.writeEntry("AutoCreateResourceOnStart", autoCreate);
config.sync();
if (autoCreate) {
auto *creator = new LocalResourceCreator(this);
creator->createIfMissing();
}
m_splitter = new QSplitter(this);
m_splitter->setStretchFactor(1, 1);
// I think we can live without this
//m_splitter->setOpaqueResize(KGlobalSettings::opaqueResize());
auto *layout = new QHBoxLayout(this);
layout->setMargin(0);
m_templateEngine = new Engine(this);
// We don't have custom plugins, so this should not be needed
//m_templateEngine->setPluginPaths(KStd.findDirs("lib", QString()));
m_loader = QSharedPointer(new FileSystemTemplateLoader());
m_loader->setTemplateDirs(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
QStringLiteral("kjots/themes"),
QStandardPaths::LocateDirectory));
m_loader->setTheme(QStringLiteral("default"));
m_templateEngine->addTemplateLoader(m_loader);
treeview = new KJotsTreeView(xmlGuiClient, m_splitter);
ItemFetchScope scope;
scope.fetchFullPayload(true); // Need to have full item when adding it to the internal data structure
scope.fetchAttribute< EntityDisplayAttribute >();
scope.fetchAttribute< NoteShared::NoteLockAttribute >();
auto *monitor = new ChangeRecorder(this);
monitor->fetchCollection(true);
monitor->setItemFetchScope(scope);
monitor->setCollectionMonitored(Collection::root());
monitor->setMimeTypeMonitored(NoteUtils::noteMimeType());
m_kjotsModel = new KJotsModel(monitor, this);
m_sortProxyModel = new KJotsSortProxyModel(this);
m_sortProxyModel->setSourceModel(m_kjotsModel);
m_orderProxy = new EntityOrderProxyModel(this);
m_orderProxy->setSourceModel(m_sortProxyModel);
KConfigGroup cfg(KSharedConfig::openConfig(), "KJotsEntityOrder");
m_orderProxy->setOrderConfig(cfg);
treeview->setModel(m_orderProxy);
treeview->setSelectionMode(QAbstractItemView::ExtendedSelection);
treeview->setEditTriggers(QAbstractItemView::DoubleClicked);
selProxy = new KSelectionProxyModel(treeview->selectionModel(), this);
selProxy->setSourceModel(treeview->model());
m_actionManager = new StandardNoteActionManager(xmlGuiClient->actionCollection(), this);
m_actionManager->setCollectionSelectionModel(treeview->selectionModel());
m_actionManager->setItemSelectionModel(treeview->selectionModel());
m_actionManager->createAllActions();
// TODO: Write a QAbstractItemView subclass to render kjots selection.
// TODO: handle dataChanged properly, i.e. if item was changed from outside
connect(selProxy, &KSelectionProxyModel::dataChanged, this, &KJotsWidget::renderSelection);
connect(selProxy, &KSelectionProxyModel::rowsInserted, this, &KJotsWidget::renderSelection);
connect(selProxy, &KSelectionProxyModel::rowsRemoved, this, &KJotsWidget::renderSelection);
stackedWidget = new QStackedWidget(m_splitter);
KActionCollection *actionCollection = xmlGuiClient->actionCollection();
editor = new KJotsEdit(stackedWidget);
connect(editor, &KJotsEdit::linkClicked, this, &KJotsWidget::openLink);
actionCollection->addActions(editor->createActions());
stackedWidget->addWidget(editor);
layout->addWidget(m_splitter);
browser = new KJotsBrowser(m_kjotsModel, stackedWidget);
connect(browser, &KJotsBrowser::linkClicked, this, &KJotsWidget::openLink);
stackedWidget->addWidget(browser);
stackedWidget->setCurrentWidget(browser);
QAction *action;
action = actionCollection->addAction(QStringLiteral("go_next_book"));
action->setText(i18n("Next Book"));
action->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_D));
connect(action, &QAction::triggered, this, &KJotsWidget::nextBook);
connect(this, &KJotsWidget::canGoNextBookChanged, action, &QAction::setEnabled);
action = actionCollection->addAction(QStringLiteral("go_prev_book"));
action->setText(i18n("Previous Book"));
action->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D));
connect(action, &QAction::triggered, this, &KJotsWidget::prevBook);
connect(this, &KJotsWidget::canGoPreviousBookChanged, action, &QAction::setEnabled);
action = KStandardAction::next(this, &KJotsWidget::nextPage, actionCollection);
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_PageDown));
connect(this, &KJotsWidget::canGoNextPageChanged, action, &QAction::setEnabled);
action = KStandardAction::prior(this, &KJotsWidget::prevPage, actionCollection);
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_PageUp));
connect(this, &KJotsWidget::canGoPreviousPageChanged, action, &QAction::setEnabled);
actionCollection->setDefaultShortcut(m_actionManager->action(StandardActionManager::CreateCollection),
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_N));
actionCollection->setDefaultShortcut(m_actionManager->action(StandardActionManager::DeleteCollections),
QKeySequence(Qt::CTRL + Qt::Key_Delete));
actionCollection->setDefaultShortcut(m_actionManager->action(StandardActionManager::DeleteItems),
QKeySequence(Qt::CTRL + Qt::Key_Delete));
KStandardAction::save( editor, &KJotsEdit::savePage, actionCollection);
action = actionCollection->addAction(QStringLiteral("auto_bullet"));
action->setText(i18n("Auto Bullets"));
action->setIcon(QIcon::fromTheme(QStringLiteral("format-list-unordered")));
action->setCheckable(true);
action = actionCollection->addAction(QStringLiteral("auto_decimal"));
action->setText(i18n("Auto Decimal List"));
action->setIcon(QIcon::fromTheme(QStringLiteral("format-list-ordered")));
action->setCheckable(true);
action = actionCollection->addAction(QStringLiteral("manage_link"));
action->setText(i18n("Link"));
action->setIcon(QIcon::fromTheme(QStringLiteral("insert-link")));
action = actionCollection->addAction(QStringLiteral("insert_image"));
action->setText(i18n("Insert Image"));
action->setIcon(QIcon::fromTheme(QStringLiteral("insert-image")));
action = actionCollection->addAction(QStringLiteral("insert_checkmark"));
action->setText(i18n("Insert Checkmark"));
action->setIcon(QIcon::fromTheme(QStringLiteral("checkmark")));
action->setEnabled(false);
KStandardAction::renameFile(treeview, &KJotsTreeView::renameEntry, actionCollection);
action = actionCollection->addAction(QStringLiteral("insert_date"));
action->setText(i18n("Insert Date"));
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
action->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar-time-spent")));
action = actionCollection->addAction(QStringLiteral("sort_children_alpha"));
action->setText(i18n("Sort children alphabetically"));
connect(action, &QAction::triggered, this, &KJotsWidget::actionSortChildrenAlpha);
action = actionCollection->addAction(QStringLiteral("sort_children_by_date"));
action->setText(i18n("Sort children by creation date"));
connect(action, &QAction::triggered, this, &KJotsWidget::actionSortChildrenByDate);
action = KStandardAction::cut(editor, &KJotsEdit::cut, actionCollection);
connect(editor, &KJotsEdit::copyAvailable, action, &QAction::setEnabled);
action->setEnabled(false);
action = KStandardAction::copy(this, [this](){
activeEditor()->copy();
}, actionCollection);
connect(editor, &KJotsEdit::copyAvailable, action, &QAction::setEnabled);
connect(browser, &KJotsBrowser::copyAvailable, action, &QAction::setEnabled);
action->setEnabled(false);
KStandardAction::paste(editor, &KJotsEdit::paste, actionCollection);
KStandardAction::undo(editor, &KJotsEdit::undo, actionCollection);
KStandardAction::redo(editor, &KJotsEdit::redo, actionCollection);
KStandardAction::selectAll(editor, &KJotsEdit::selectAll, actionCollection);
action = actionCollection->addAction(QStringLiteral("copyIntoTitle"));
action->setText(i18n("Copy &into Page Title"));
actionCollection->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_T));
action->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
connect(action, &QAction::triggered, this, &KJotsWidget::copySelectionToTitle);
connect(editor, &KJotsEdit::copyAvailable, action, &QAction::setEnabled);
action->setEnabled(false);
action = actionCollection->addAction(QStringLiteral("paste_plain_text"));
action->setText(i18nc("@action Paste the text in the clipboard without rich text formatting.", "Paste Plain Text"));
connect(action, &QAction::triggered, editor, &KJotsEdit::pastePlainText);
KStandardAction::preferences(this, &KJotsWidget::configure, actionCollection);
bookmarkMenu = actionCollection->add(QStringLiteral("bookmarks"));
bookmarkMenu->setText(i18n("&Bookmarks"));
auto *bookmarks = new KJotsBookmarks(treeview->selectionModel(), this);
connect(bookmarks, &KJotsBookmarks::openLink, this, &KJotsWidget::openLink);
auto *bmm = new KBookmarkMenu(
KBookmarkManager::managerForFile(
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/kjots/bookmarks.xml"),
QStringLiteral("kjots")),
bookmarks, bookmarkMenu->menu());
// "Add bookmark" and "make text bold" actions have conflicting shortcuts (ctrl + b)
// Make add_bookmark use ctrl+shift+b to resolve that.
QAction *bm_action = bmm->addBookmarkAction();
actionCollection->addAction(QStringLiteral("add_bookmark"), bm_action);
actionCollection->setDefaultShortcut(bm_action, Qt::CTRL | Qt::SHIFT | Qt::Key_B);
actionCollection->addAction(QStringLiteral("edit_bookmark"), bmm->editBookmarksAction());
actionCollection->addAction(QStringLiteral("add_bookmarks_list"), bmm->bookmarkTabsAsFolderAction());
KStandardAction::find(this, &KJotsWidget::onShowSearch, actionCollection);
action = KStandardAction::findNext(this, &KJotsWidget::onRepeatSearch, actionCollection);
action->setEnabled(false);
KStandardAction::replace(this, &KJotsWidget::onShowReplace, actionCollection);
auto *exportMenu = actionCollection->add(QStringLiteral("save_to"));
exportMenu->setText(i18n("Export"));
exportMenu->setIcon(QIcon::fromTheme(QStringLiteral("document-export")));
action = actionCollection->addAction(QStringLiteral("save_to_ascii"));
action->setText(i18n("To Text File..."));
action->setIcon(QIcon::fromTheme(QStringLiteral("text-plain")));
connect(action, &QAction::triggered, this, [this](){
exportSelection(QStringLiteral("plain_text"), QStringLiteral("template.txt"));
});
exportMenu->menu()->addAction(action);
action = actionCollection->addAction(QStringLiteral("save_to_html"));
action->setText(i18n("To HTML File..."));
action->setIcon(QIcon::fromTheme(QStringLiteral("text-html")));
connect(action, &QAction::triggered, this, [this](){
exportSelection(QStringLiteral("default"), QStringLiteral("template.html"));
});
exportMenu->menu()->addAction(action);
KStandardAction::print(this, &KJotsWidget::printSelection, actionCollection);
KStandardAction::printPreview(this, &KJotsWidget::printPreviewSelection, actionCollection);
if (!KJotsSettings::splitterSizes().isEmpty()) {
m_splitter->setSizes(KJotsSettings::splitterSizes());
}
QTimer::singleShot(0, this, &KJotsWidget::delayedInitialization);
connect(treeview->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KJotsWidget::updateMenu);
connect(treeview->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KJotsWidget::updateCaption);
connect(treeview->model(), &QAbstractItemModel::dataChanged, this, &KJotsWidget::updateCaption);
connect(editor, &KJotsEdit::documentModified, this, &KJotsWidget::updateCaption);
connect(m_kjotsModel, &EntityTreeModel::modelAboutToBeReset, this, &KJotsWidget::saveState);
connect(m_kjotsModel, &EntityTreeModel::modelReset, this, &KJotsWidget::restoreState);
restoreState();
QDBusConnection::sessionBus().registerObject(QStringLiteral("/KJotsWidget"), this, QDBusConnection::ExportScriptableContents);
}
KJotsWidget::~KJotsWidget()
{
saveState();
}
void KJotsWidget::restoreState()
{
auto *saver = new ETMViewStateSaver;
saver->setView(treeview);
KConfigGroup cfg(KSharedConfig::openConfig(), "TreeState");
saver->restoreState(cfg);
}
void KJotsWidget::saveState()
{
ETMViewStateSaver saver;
saver.setView(treeview);
KConfigGroup cfg(KSharedConfig::openConfig(), "TreeState");
saver.saveState(cfg);
cfg.sync();
}
void KJotsWidget::delayedInitialization()
{
//TODO: Save previous searches in settings file?
searchDialog = new KFindDialog(this, 0, QStringList(), false);
auto *layout = new QGridLayout(searchDialog->findExtension());
layout->setMargin(0);
searchAllPages = new QCheckBox(i18n("Search all pages"), searchDialog->findExtension());
layout->addWidget(searchAllPages, 0, 0);
connect(searchDialog, &KFindDialog::okClicked, this, &KJotsWidget::onStartSearch);
connect(searchDialog, &KFindDialog::cancelClicked, this, &KJotsWidget::onEndSearch);
connect(treeview->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KJotsWidget::onUpdateSearch);
connect(searchDialog, &KFindDialog::optionsChanged, this, &KJotsWidget::onUpdateSearch);
connect(searchAllPages, &QCheckBox::stateChanged, this, &KJotsWidget::onUpdateSearch);
replaceDialog = new KReplaceDialog(this, 0, searchHistory, replaceHistory, false);
auto *layout2 = new QGridLayout(replaceDialog->findExtension());
layout2->setMargin(0);
replaceAllPages = new QCheckBox(i18n("Search all pages"), replaceDialog->findExtension());
layout2->addWidget(replaceAllPages, 0, 0);
connect(replaceDialog, &KReplaceDialog::okClicked, this, &KJotsWidget::onStartReplace);
connect(replaceDialog, &KReplaceDialog::cancelClicked, this, &KJotsWidget::onEndReplace);
connect(replaceDialog, &KReplaceDialog::optionsChanged, this, &KJotsWidget::onUpdateReplace);
connect(replaceAllPages, &QCheckBox::stateChanged, this, &KJotsWidget::onUpdateReplace);
// Actions are enabled or disabled based on whether the selection is a single page, a single book
// multiple selections, or no selection.
//
// The entryActions are enabled for all single pages and single books, and the multiselectionActions
// are enabled when the user has made multiple selections.
//
// Some actions are in neither (eg, new book) and are available even when there is no selection.
//
// Some actions are in both, so that they are available for valid selections, but not available
// for invalid selections (eg, print/find are disabled when there is no selection)
KActionCollection *actionCollection = m_xmlGuiClient->actionCollection();
// Actions for a single item selection.
entryActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Find))));
entryActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Print))));
entryActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::RenameFile))));
entryActions.insert(m_actionManager->action(StandardNoteActionManager::ChangeColor));
entryActions.insert(actionCollection->action(QStringLiteral("save_to")));
entryActions.insert(m_actionManager->action(StandardActionManager::CopyItems));
entryActions.insert(m_actionManager->action(StandardActionManager::CopyCollections));
// Actions that are used only when a page is selected.
pageActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Cut))));
pageActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Paste))));
pageActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Replace))));
pageActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Save))));
pageActions.insert(m_actionManager->action(StandardActionManager::DeleteItems));
pageActions.insert(actionCollection->action(QStringLiteral("insert_date")));
pageActions.insert(actionCollection->action(QStringLiteral("auto_bullet")));
pageActions.insert(actionCollection->action(QStringLiteral("auto_decimal")));
pageActions.insert(actionCollection->action(QStringLiteral("manage_link")));
pageActions.insert(actionCollection->action(QStringLiteral("insert_checkmark")));
// Actions that are used only when a book is selected.
bookActions.insert(m_actionManager->action(StandardActionManager::DeleteCollections));
bookActions.insert(actionCollection->action(QStringLiteral("sort_children_alpha")));
bookActions.insert(actionCollection->action(QStringLiteral("sort_children_by_date")));
// Actions that are used when multiple items are selected.
multiselectionActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Find))));
multiselectionActions.insert(actionCollection->action(QString::fromLatin1(KStandardAction::name(KStandardAction::Print))));
multiselectionActions.insert(actionCollection->action(QStringLiteral("save_to")));
multiselectionActions.insert(m_actionManager->action(StandardNoteActionManager::ChangeColor));
m_autosaveTimer = new QTimer(this);
updateConfiguration();
connect(m_autosaveTimer, &QTimer::timeout, editor, &KJotsEdit::savePage);
connect(treeview->selectionModel(), &QItemSelectionModel::selectionChanged, m_autosaveTimer, qOverload<>(&QTimer::start));
editor->delayedInitialization(m_xmlGuiClient->actionCollection());
browser->delayedInitialization();
// Make sure the editor gets focus again after naming a new book/page.
connect(treeview->itemDelegate(), &QItemDelegate::closeEditor, this, [this](){
activeEditor()->setFocus();
});
updateMenu();
}
inline QTextEdit *KJotsWidget::activeEditor()
{
if (browser->isVisible()) {
return browser;
} else {
return editor;
}
}
void KJotsWidget::updateMenu()
{
QModelIndexList selection = treeview->selectionModel()->selectedRows();
int selectionSize = selection.size();
if (!selectionSize) {
// no (meaningful?) selection
for (QAction *action : qAsConst(multiselectionActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(entryActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(bookActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(pageActions)) {
action->setEnabled(false);
}
editor->setActionsEnabled(false);
} else if (selectionSize > 1) {
for (QAction *action : qAsConst(entryActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(bookActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(pageActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(multiselectionActions)) {
action->setEnabled(true);
}
editor->setActionsEnabled(false);
} else {
for (QAction *action : qAsConst(multiselectionActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(entryActions)) {
action->setEnabled(true);
}
QModelIndex idx = selection.at(0);
Collection col = idx.data(KJotsModel::CollectionRole).value();
if (col.isValid()) {
for (QAction *action : qAsConst(pageActions)) {
action->setEnabled(false);
}
for (QAction *action : qAsConst(bookActions)) {
action->setEnabled(true);
}
editor->setActionsEnabled(false);
} else {
for (QAction *action : qAsConst(pageActions)) {
if (action->objectName() == QString::fromLatin1(name(KStandardAction::Cut))) {
action->setEnabled(activeEditor()->textCursor().hasSelection());
} else {
action->setEnabled(true);
}
}
for (QAction *action : qAsConst(bookActions)) {
action->setEnabled(false);
}
editor->setActionsEnabled(true);
}
}
}
void KJotsWidget::configure()
{
- // create a new preferences dialog...
- auto *dialog = new KJotsConfigDlg(i18n("Settings"), this);
- connect(dialog, qOverload<>(&KJotsConfigDlg::configCommitted), this, &KJotsWidget::updateConfiguration);
+ if (KConfigDialog::showDialog(QStringLiteral("kjotssettings"))) {
+ return;
+ }
+ auto* dialog = new KConfigDialog(this, QStringLiteral("kjotssettings"), KJotsSettings::self());
+ dialog->addPage(new KJotsConfigMisc(dialog), i18nc("@title:window config dialog page", "Misc"), QStringLiteral("preferences-other"));
+ connect(dialog, &KConfigDialog::settingsChanged, this, &KJotsWidget::updateConfiguration);
dialog->show();
}
void KJotsWidget::updateConfiguration()
{
if (KJotsSettings::autoSave()) {
m_autosaveTimer->setInterval(KJotsSettings::autoSaveInterval() * 1000 * 60);
m_autosaveTimer->start();
} else {
m_autosaveTimer->stop();
}
}
void KJotsWidget::copySelectionToTitle()
{
QString newTitle(editor->textCursor().selectedText());
if (!newTitle.isEmpty()) {
QModelIndexList rows = treeview->selectionModel()->selectedRows();
if (rows.size() != 1) {
return;
}
QModelIndex idx = rows.at(0);
treeview->model()->setData(idx, newTitle);
}
}
QString KJotsWidget::renderSelectionTo(const QString &theme, const QString &templ)
{
QList objectList;
const int rows = selProxy->rowCount();
const int column = 0;
for (int row = 0; row < rows; ++row) {
QModelIndex idx = selProxy->index(row, column, QModelIndex());
objectList << idx.data(KJotsModel::GrantleeObjectRole);
}
QHash hash = {{QStringLiteral("entities"), objectList},
{QStringLiteral("i18n_TABLE_OF_CONTENTS"), i18nc("Header for 'Table of contents' section of rendered output", "Table of contents")}};
Context c(hash);
const QString currentTheme = m_loader->themeName();
m_loader->setTheme(theme);
Template t = m_templateEngine->loadByName(templ);
const QString result = t->render(&c);
m_loader->setTheme(currentTheme);
return result;
}
QString KJotsWidget::renderSelectionToHtml()
{
return renderSelectionTo(QStringLiteral("default"), QStringLiteral("template.html"));
}
void KJotsWidget::exportSelection(const QString &theme, const QString &templ)
{
// TODO: dialog captions & etc
QString filename = QFileDialog::getSaveFileName();
if (filename.isEmpty()) {
return;
}
QFile exportFile(filename);
if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
KMessageBox::error(this, i18n("Could not open \"%1\" for writing", filename));
return;
}
exportFile.write(renderSelectionTo(theme, templ).toUtf8());
exportFile.close();
}
std::unique_ptr KJotsWidget::setupPrinter(QPrinter::PrinterMode mode)
{
auto printer = std::make_unique(mode);
printer->setDocName(QStringLiteral("KJots_Print"));
printer->setCreator(QStringLiteral("KJots"));
if (!activeEditor()->textCursor().selection().isEmpty()) {
printer->setPrintRange(QPrinter::Selection);
}
return printer;
}
void KJotsWidget::printPreviewSelection()
{
auto printer = setupPrinter(QPrinter::ScreenResolution);
QPrintPreviewDialog previewdlg(printer.get(), this);
connect(&previewdlg, &QPrintPreviewDialog::paintRequested, this, &KJotsWidget::print);
previewdlg.exec();
}
void KJotsWidget::printSelection()
{
auto printer = setupPrinter(QPrinter::HighResolution);
QPrintDialog printDialog(printer.get(), this);
if (printDialog.exec() == QDialog::Accepted) {
print(printer.get());
}
}
void KJotsWidget::print(QPrinter *printer)
{
QTextDocument printDocument;
if (printer->printRange() == QPrinter::Selection) {
printDocument.setHtml(activeEditor()->textCursor().selection().toHtml());
} else {
QString currentTheme = m_loader->themeName();
m_loader->setTheme(QStringLiteral("default"));
printDocument.setHtml(renderSelectionToHtml());
m_loader->setTheme(currentTheme);
}
printDocument.print(printer);
}
void KJotsWidget::selectNext(int role, int step)
{
QModelIndexList list = treeview->selectionModel()->selectedRows();
Q_ASSERT(list.size() == 1);
QModelIndex idx = list.at(0);
const int column = idx.column();
QModelIndex sibling = idx.sibling(idx.row() + step, column);
while (sibling.isValid()) {
if (sibling.data(role).toInt() >= 0) {
treeview->selectionModel()->select(sibling, QItemSelectionModel::SelectCurrent);
return;
}
sibling = sibling.sibling(sibling.row() + step, column);
}
qWarning() << "No valid selection";
}
void KJotsWidget::nextBook()
{
return selectNext(EntityTreeModel::CollectionIdRole, 1);
}
void KJotsWidget::nextPage()
{
return selectNext(EntityTreeModel::ItemIdRole, 1);
}
void KJotsWidget::prevBook()
{
return selectNext(EntityTreeModel::CollectionIdRole, -1);
}
void KJotsWidget::prevPage()
{
return selectNext(EntityTreeModel::ItemIdRole, -1);
}
bool KJotsWidget::canGo(int role, int step) const
{
QModelIndexList list = treeview->selectionModel()->selectedRows();
if (list.size() != 1) {
return false;
}
QModelIndex currentIdx = list.at(0);
const int column = currentIdx.column();
Q_ASSERT(currentIdx.isValid());
QModelIndex sibling = currentIdx.sibling(currentIdx.row() + step, column);
while (sibling.isValid() && sibling != currentIdx) {
if (sibling.data(role).toInt() >= 0) {
return true;
}
sibling = sibling.sibling(sibling.row() + step, column);
}
return false;
}
bool KJotsWidget::canGoNextPage() const
{
return canGo(EntityTreeModel::ItemIdRole, 1);
}
bool KJotsWidget::canGoPreviousPage() const
{
return canGo(EntityTreeModel::ItemIdRole, -1);
}
bool KJotsWidget::canGoNextBook() const
{
return canGo(EntityTreeModel::CollectionIdRole, 1);
}
bool KJotsWidget::canGoPreviousBook() const
{
return canGo(EntityTreeModel::CollectionIdRole, -1);
}
void KJotsWidget::renderSelection()
{
Q_EMIT canGoNextBookChanged(canGoPreviousBook());
Q_EMIT canGoNextPageChanged(canGoNextPage());
Q_EMIT canGoPreviousBookChanged(canGoPreviousBook());
Q_EMIT canGoPreviousPageChanged(canGoPreviousPage());
const int rows = selProxy->rowCount();
// If the selection is a single page, present it for editing...
if (rows == 1) {
QModelIndex idx = selProxy->index(0, 0, QModelIndex());
if (editor->setModelIndex(selProxy->mapToSource(idx))) {
stackedWidget->setCurrentWidget(editor);
return;
}
// If something went wrong, we show user the browser
}
// ... Otherwise, render the selection read-only.
browser->setHtml(renderSelectionToHtml());
stackedWidget->setCurrentWidget(browser);
}
/*!
Shows the search dialog when "Find" is selected.
*/
void KJotsWidget::onShowSearch()
{
onUpdateSearch();
QTextEdit *browserOrEditor = activeEditor();
if (browserOrEditor->textCursor().hasSelection()) {
searchDialog->setHasSelection(true);
long dialogOptions = searchDialog->options();
dialogOptions |= KFind::SelectedText;
searchDialog->setOptions(dialogOptions);
} else {
searchDialog->setHasSelection(false);
}
searchDialog->setFindHistory(searchHistory);
searchDialog->show();
onUpdateSearch();
}
/*!
Updates the search dialog if the user is switching selections while it is open.
*/
void KJotsWidget::onUpdateSearch()
{
if (searchDialog->isVisible()) {
long searchOptions = searchDialog->options();
if (searchOptions & KFind::SelectedText) {
searchAllPages->setCheckState(Qt::Unchecked);
searchAllPages->setEnabled(false);
} else {
searchAllPages->setEnabled(true);
}
if (searchAllPages->checkState() == Qt::Checked) {
searchOptions &= ~KFind::SelectedText;
searchDialog->setOptions(searchOptions);
searchDialog->setHasSelection(false);
} else {
if (activeEditor()->textCursor().hasSelection()) {
searchDialog->setHasSelection(true);
}
}
if (activeEditor()->textCursor().hasSelection()) {
if (searchAllPages->checkState() == Qt::Unchecked) {
searchDialog->setHasSelection(true);
}
} else {
searchOptions &= ~KFind::SelectedText;
searchDialog->setOptions(searchOptions);
searchDialog->setHasSelection(false);
}
}
}
/*!
Called when the user presses OK in the search dialog.
*/
void KJotsWidget::onStartSearch()
{
QString searchPattern = searchDialog->pattern();
if (!searchHistory.contains(searchPattern)) {
searchHistory.prepend(searchPattern);
}
QTextEdit *browserOrEditor = activeEditor();
QTextCursor cursor = browserOrEditor->textCursor();
long searchOptions = searchDialog->options();
if (searchOptions & KFind::FromCursor) {
searchPos = cursor.position();
searchBeginPos = 0;
cursor.movePosition(QTextCursor::End);
searchEndPos = cursor.position();
} else {
if (searchOptions & KFind::SelectedText) {
searchBeginPos = cursor.selectionStart();
searchEndPos = cursor.selectionEnd();
} else {
searchBeginPos = 0;
cursor.movePosition(QTextCursor::End);
searchEndPos = cursor.position();
}
if (searchOptions & KFind::FindBackwards) {
searchPos = searchEndPos;
} else {
searchPos = searchBeginPos;
}
}
m_xmlGuiClient->actionCollection()->action(QString::fromLatin1(KStandardAction::name(KStandardAction::FindNext)))->setEnabled(true);
onRepeatSearch();
}
/*!
Called when user chooses "Find Next"
*/
void KJotsWidget::onRepeatSearch()
{
if (search(false) == 0) {
KMessageBox::sorry(nullptr, i18n("No matches found."));
m_xmlGuiClient->actionCollection()->action(QString::fromLatin1(KStandardAction::name(KStandardAction::FindNext)))->setEnabled(false);
}
}
/*!
Called when user presses Cancel in find dialog.
*/
void KJotsWidget::onEndSearch()
{
m_xmlGuiClient->actionCollection()->action(QString::fromLatin1(KStandardAction::name(KStandardAction::FindNext)))->setEnabled(false);
}
/*!
Shows the replace dialog when "Replace" is selected.
*/
void KJotsWidget::onShowReplace()
{
Q_ASSERT(editor->isVisible());
if (editor->textCursor().hasSelection()) {
replaceDialog->setHasSelection(true);
long dialogOptions = replaceDialog->options();
dialogOptions |= KFind::SelectedText;
replaceDialog->setOptions(dialogOptions);
} else {
replaceDialog->setHasSelection(false);
}
replaceDialog->setFindHistory(searchHistory);
replaceDialog->setReplacementHistory(replaceHistory);
replaceDialog->show();
onUpdateReplace();
}
/*!
Updates the replace dialog if the user is switching selections while it is open.
*/
void KJotsWidget::onUpdateReplace()
{
if (replaceDialog->isVisible()) {
long replaceOptions = replaceDialog->options();
if (replaceOptions & KFind::SelectedText) {
replaceAllPages->setCheckState(Qt::Unchecked);
replaceAllPages->setEnabled(false);
} else {
replaceAllPages->setEnabled(true);
}
if (replaceAllPages->checkState() == Qt::Checked) {
replaceOptions &= ~KFind::SelectedText;
replaceDialog->setOptions(replaceOptions);
replaceDialog->setHasSelection(false);
} else {
if (activeEditor()->textCursor().hasSelection()) {
replaceDialog->setHasSelection(true);
}
}
}
}
/*!
Called when the user presses OK in the replace dialog.
*/
void KJotsWidget::onStartReplace()
{
QString searchPattern = replaceDialog->pattern();
if (!searchHistory.contains(searchPattern)) {
searchHistory.prepend(searchPattern);
}
QString replacePattern = replaceDialog->replacement();
if (!replaceHistory.contains(replacePattern)) {
replaceHistory.prepend(replacePattern);
}
QTextCursor cursor = editor->textCursor();
long replaceOptions = replaceDialog->options();
if (replaceOptions & KFind::FromCursor) {
replacePos = cursor.position();
replaceBeginPos = 0;
cursor.movePosition(QTextCursor::End);
replaceEndPos = cursor.position();
} else {
if (replaceOptions & KFind::SelectedText) {
replaceBeginPos = cursor.selectionStart();
replaceEndPos = cursor.selectionEnd();
} else {
replaceBeginPos = 0;
cursor.movePosition(QTextCursor::End);
replaceEndPos = cursor.position();
}
if (replaceOptions & KFind::FindBackwards) {
replacePos = replaceEndPos;
} else {
replacePos = replaceBeginPos;
}
}
replaceStartPage = treeview->selectionModel()->selectedRows().first();
//allow KReplaceDialog to exit so the user can see.
QTimer::singleShot(0, this, &KJotsWidget::onRepeatReplace);
}
/*!
Only called after onStartReplace. Kept the name scheme for consistency.
*/
void KJotsWidget::onRepeatReplace()
{
KJotsReplaceNextDialog *dlg = nullptr;
QString searchPattern = replaceDialog->pattern();
QString replacePattern = replaceDialog->replacement();
int found = 0;
int replaced = 0;
long replaceOptions = replaceDialog->options();
if (replaceOptions & KReplaceDialog::PromptOnReplace) {
dlg = new KJotsReplaceNextDialog(this);
}
while (true) {
if (!search(true))
{
break;
}
QTextCursor cursor = editor->textCursor();
if (!cursor.hasSelection())
{
break;
} else {
++found;
}
QString replacementText = replacePattern;
if (replaceOptions & KReplaceDialog::BackReference)
{
QRegExp regExp(searchPattern, (replaceOptions & Qt::CaseSensitive) ?
Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2);
regExp.indexIn(cursor.selectedText());
int capCount = regExp.captureCount();
for (int i = 0; i <= capCount; ++i) {
QString c = QString::fromLatin1("\\%1").arg(i);
replacementText.replace(c, regExp.cap(i));
}
}
if (replaceOptions & KReplaceDialog::PromptOnReplace)
{
dlg->setLabel(cursor.selectedText(), replacementText);
if (!dlg->exec()) {
break;
}
if (dlg->answer() != KJotsReplaceNextDialog::Skip) {
cursor.insertText(replacementText);
editor->setTextCursor(cursor);
++replaced;
}
if (dlg->answer() == KJotsReplaceNextDialog::All) {
replaceOptions |= ~KReplaceDialog::PromptOnReplace;
}
} else {
cursor.insertText(replacementText);
editor->setTextCursor(cursor);
++replaced;
}
}
if (replaced == found) {
KMessageBox::information(nullptr, i18np("Replaced 1 occurrence.", "Replaced %1 occurrences.", replaced));
} else if (replaced < found) {
KMessageBox::information(nullptr,
i18np("Replaced %2 of 1 occurrence.", "Replaced %2 of %1 occurrences.", found, replaced));
}
delete dlg;
}
/*!
Called when user presses Cancel in replace dialog. Just a placeholder for now.
*/
void KJotsWidget::onEndReplace()
{
}
/*!
Searches for the given pattern, with the given options. This is huge and
unwieldly function, but the operation we're performing is huge and unwieldly.
*/
int KJotsWidget::search(bool replacing)
{
int rc = 0;
int *beginPos = replacing ? &replaceBeginPos : &searchBeginPos;
int *endPos = replacing ? &replaceEndPos : &searchEndPos;
long options = replacing ? replaceDialog->options() : searchDialog->options();
QString pattern = replacing ? replaceDialog->pattern() : searchDialog->pattern();
int *curPos = replacing ? &replacePos : &searchPos;
QModelIndex startPage = replacing ? replaceStartPage : treeview->selectionModel()->selectedRows().first();
bool allPages = false;
QCheckBox *box = replacing ? replaceAllPages : searchAllPages;
if (box->isEnabled() && box->checkState() == Qt::Checked) {
allPages = true;
}
QTextDocument::FindFlags findFlags;
if (options & Qt::CaseSensitive) {
findFlags |= QTextDocument::FindCaseSensitively;
}
if (options & KFind::WholeWordsOnly) {
findFlags |= QTextDocument::FindWholeWords;
}
if (options & KFind::FindBackwards) {
findFlags |= QTextDocument::FindBackward;
}
// We will find a match or return 0
int attempts = 0;
while (true) {
++attempts;
QTextEdit *browserOrEditor = activeEditor();
QTextDocument *theDoc = browserOrEditor->document();
QTextCursor cursor;
if (options & KFind::RegularExpression)
{
QRegExp regExp(pattern, (options & Qt::CaseSensitive) ?
Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::RegExp2);
cursor = theDoc->find(regExp, *curPos, findFlags);
} else {
cursor = theDoc->find(pattern, *curPos, findFlags);
}
if (cursor.hasSelection())
{
if (cursor.selectionStart() >= *beginPos && cursor.selectionEnd() <= *endPos) {
browserOrEditor->setTextCursor(cursor);
browserOrEditor->ensureCursorVisible();
*curPos = (options & KFind::FindBackwards) ?
cursor.selectionStart() : cursor.selectionEnd();
rc = 1;
break;
}
}
//No match. Determine what to do next.
if (replacing && !(options & KFind::FromCursor) && !allPages)
{
break;
}
if ((options & KFind::FromCursor) && !allPages)
{
if (KMessageBox::questionYesNo(this,
i18n("End of search area reached. Do you want to wrap around and continue?")) ==
KMessageBox::No) {
rc = 3;
break;
}
}
if (allPages)
{
if (options & KFind::FindBackwards) {
if (canGoPreviousPage()) {
prevPage();
}
} else {
if (canGoNextPage()) {
nextPage();
}
}
if (startPage == treeview->selectionModel()->selectedRows().first()) {
rc = 0;
break;
}
*beginPos = 0;
cursor = editor->textCursor();
cursor.movePosition(QTextCursor::End);
*endPos = cursor.position();
*curPos = (options & KFind::FindBackwards) ? *endPos : *beginPos;
continue;
}
// By now, we should have figured out what to do. In all remaining cases we
// will automatically loop and try to "find next" from the top/bottom, because
// I like this behavior the best.
if (attempts <= 1)
{
*curPos = (options & KFind::FindBackwards) ? *endPos : *beginPos;
} else {
// We've already tried the loop and failed to find anything. Bail.
rc = 0;
break;
}
}
return rc;
}
void KJotsWidget::updateCaption()
{
const QModelIndexList selection = treeview->selectionModel()->selectedRows();
QString caption;
if (selection.size() == 1) {
caption = KJotsModel::itemPath(selection.first());
if (editor->modified()) {
caption.append(QStringLiteral(" *"));
}
} else if (selection.size() > 1) {
caption = i18nc("@title:window", "Multiple selection");
}
Q_EMIT captionChanged(caption);
}
bool KJotsWidget::queryClose()
{
KJotsSettings::setSplitterSizes(m_splitter->sizes());
KJotsSettings::self()->save();
m_orderProxy->saveOrder();
// TODO: we better wait for a result here!
editor->savePage();
return true;
}
void KJotsWidget::actionSortChildrenAlpha()
{
const QModelIndexList selection = treeview->selectionModel()->selectedRows();
for (const QModelIndex &index : selection) {
const QPersistentModelIndex persistent(index);
m_sortProxyModel->sortChildrenAlphabetically(m_orderProxy->mapToSource(index));
m_orderProxy->clearOrder(persistent);
}
}
void KJotsWidget::actionSortChildrenByDate()
{
const QModelIndexList selection = treeview->selectionModel()->selectedRows();
for (const QModelIndex &index : selection) {
const QPersistentModelIndex persistent(index);
m_sortProxyModel->sortChildrenByCreationTime(m_orderProxy->mapToSource(index));
m_orderProxy->clearOrder(persistent);
}
}
void KJotsWidget::openLink(const QUrl &url)
{
if (url.scheme() == QStringLiteral("akonadi")) {
treeview->selectionModel()->select(KJotsModel::modelIndexForUrl(treeview->model(), url), QItemSelectionModel::ClearAndSelect);
} else {
new KRun(url, this);
}
}