diff --git a/src/kjotsbrowser.h b/src/kjotsbrowser.h --- a/src/kjotsbrowser.h +++ b/src/kjotsbrowser.h @@ -31,7 +31,7 @@ { Q_OBJECT public: - explicit KJotsBrowser(QItemSelectionModel *selectionModel, QWidget *); + explicit KJotsBrowser(QWidget *); void delayedInitialization(); diff --git a/src/kjotsbrowser.cpp b/src/kjotsbrowser.cpp --- a/src/kjotsbrowser.cpp +++ b/src/kjotsbrowser.cpp @@ -29,8 +29,8 @@ #include #include -KJotsBrowser::KJotsBrowser(QItemSelectionModel *selectionModel, QWidget *parent) - : QTextBrowser(parent), m_itemSelectionModel(selectionModel) +KJotsBrowser::KJotsBrowser(QWidget *parent) + : QTextBrowser(parent) { setWordWrapMode(QTextOption::WordWrap); } diff --git a/src/kjotsedit.h b/src/kjotsedit.h --- a/src/kjotsedit.h +++ b/src/kjotsedit.h @@ -36,12 +36,17 @@ { Q_OBJECT public: - explicit KJotsEdit(QItemSelectionModel *selectionModel, QWidget *); + explicit KJotsEdit(QWidget *); void delayedInitialization(KActionCollection *); bool canInsertFromMimeData(const QMimeData *) const override; void insertFromMimeData(const QMimeData *) override; - + /** + * Load document based on KJotsModel index + * + * @returns true if loaded sucessfully + */ + bool setModelIndex(const QModelIndex &index); protected: /* To be able to change cursor when hoverng over links */ void mouseMoveEvent(QMouseEvent *event) override; @@ -59,8 +64,6 @@ void tooltipEvent(QHelpEvent *event); public Q_SLOTS: - void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - void tryDisableEditing(); void onAutoBullet(void); void onLinkify(void); void addCheckmark(void); @@ -78,7 +81,7 @@ void createAutoDecimalList(); KActionCollection *actionCollection; bool allowAutoDecimal; - QItemSelectionModel *m_selectionModel; + std::unique_ptr m_index; bool m_cursorChanged = false; }; diff --git a/src/kjotsedit.cpp b/src/kjotsedit.cpp --- a/src/kjotsedit.cpp +++ b/src/kjotsedit.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -54,16 +53,14 @@ #include "noteshared/notelockattribute.h" #include "noteshared/noteeditorutils.h" -Q_DECLARE_METATYPE(QTextDocument *) Q_DECLARE_METATYPE(QTextCursor) using namespace Akonadi; -KJotsEdit::KJotsEdit(QItemSelectionModel *selectionModel, QWidget *parent) +KJotsEdit::KJotsEdit(QWidget *parent) : KRichTextWidget(parent), actionCollection(nullptr), - allowAutoDecimal(false), - m_selectionModel(selectionModel) + allowAutoDecimal(false) { setMouseTracking(true); setAcceptRichText(true); @@ -76,9 +73,6 @@ | SupportFormatPainting); setFocusPolicy(Qt::StrongFocus); - - connect(m_selectionModel, &QItemSelectionModel::selectionChanged, this, &KJotsEdit::selectionChanged); - connect(m_selectionModel->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(tryDisableEditing())); } void KJotsEdit::contextMenuEvent(QContextMenuEvent *event) @@ -132,35 +126,49 @@ NoteShared::NoteEditorUtils().insertImage(document(), cursor, this); } -void KJotsEdit::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +bool KJotsEdit::setModelIndex(const QModelIndex &index) { - Q_UNUSED(selected) - Q_UNUSED(deselected) - tryDisableEditing(); -} - -void KJotsEdit::tryDisableEditing() -{ - if (!m_selectionModel->hasSelection()) { - return setReadOnly(true); + bool newDocument = m_index && (*m_index != index); + // Saving the old document, if it wa changed + if (newDocument) { + savePage(); } - - QModelIndexList list = m_selectionModel->selectedRows(); - if (list.size() != 1) { - return setReadOnly(true); + m_index = std::make_unique(index); + // Loading document + auto document = m_index->data(KJotsModel::DocumentRole).value(); + if (!document) { + setReadOnly(true); + return false; } - - Item item = list.first().data(EntityTreeModel::ItemRole).value(); - - if (!item.isValid()) { - return setReadOnly(true); + setDocument(document); + // Setting cursor + auto cursor = document->property("textCursor").value(); + if (!cursor.isNull()) { + setTextCursor(cursor); + } else { + // This is a work-around for QTextEdit bug. If the first letter of the document is formatted, + // QTextCursor doesn't follow this format. One can either move the cursor 1 symbol to the right + // and then 1 symbol to the left as a workaround, or just explicitly move it to the start. + // Submitted to qt-bugs, id 192886. + // -- (don't know the fate of this bug, as for April 2020 it is unaccessible) + moveCursor(QTextCursor::Start); } - - if (item.hasAttribute()) { - return setReadOnly(true); + // Setting focus if document was changed + if (newDocument) { + setFocus(); + } + // Setting ReadOnly + auto item = m_index->data(EntityTreeModel::ItemRole).value(); + if (!item.isValid()) { + setReadOnly(true); + return false; + } else if (item.hasAttribute()) { + setReadOnly(true); + return true; + } else { + setReadOnly(false); + return true; } - - setReadOnly(false); } void KJotsEdit::onAutoBullet(void) @@ -231,8 +239,12 @@ void KJotsEdit::onLinkify(void) { + // Nothing is yet opened, ignoring + if (!m_index) { + return; + } selectLinkText(); - QPointer linkDialog = new KJotsLinkDialog(const_cast(m_selectionModel->model()), this); + QPointer linkDialog = new KJotsLinkDialog(const_cast(m_index->model()), this); linkDialog->setLinkText(currentLinkText()); linkDialog->setLinkUrl(currentLinkUrl()); @@ -350,6 +362,10 @@ void KJotsEdit::tooltipEvent(QHelpEvent *event) { + // Nothing is opened, ignoring + if (!m_index) { + return; + } QUrl url(anchorAt(event->pos())); QString message; @@ -385,29 +401,14 @@ return; } - QModelIndexList rows = m_selectionModel->selectedRows(); - - if (rows.size() != 1) { - return; - } - - QModelIndex index = rows.at(0); - - Item item = index.data(EntityTreeModel::ItemRole).value(); - - if (!item.isValid()) { - return; - } - - if (!item.hasPayload()) { + auto item = m_index->data(EntityTreeModel::ItemRole).value(); + if (!item.isValid() || !item.hasPayload()) { return; } - - QAbstractItemModel *model = const_cast(m_selectionModel->model()); - + auto model = const_cast(m_index->model()); document()->setModified(false); document()->setProperty("textCursor", QVariant::fromValue(textCursor())); - model->setData(index, QVariant::fromValue(document()), KJotsModel::DocumentRole); + model->setData(*m_index, QVariant::fromValue(document()), KJotsModel::DocumentRole); } /* ex: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab: */ diff --git a/src/kjotswidget.h b/src/kjotswidget.h --- a/src/kjotswidget.h +++ b/src/kjotswidget.h @@ -121,6 +121,9 @@ std::unique_ptr setupPrinter(QPrinter::PrinterMode mode = QPrinter::ScreenResolution); protected Q_SLOTS: + /** + * Renders contents on either KJotsEdit or KJotsBrowser based on KJotsTreeView selection + */ void renderSelection(); void changeTheme(); void exportSelectionToHtml(); @@ -136,7 +139,6 @@ void openLink(const QUrl &url); private Q_SLOTS: void delayedInitialization(); - void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void bookshelfEditItemFinished(QWidget *, QAbstractItemDelegate::EndEditHint); bool canGo(int role, int step) const; diff --git a/src/kjotswidget.cpp b/src/kjotswidget.cpp --- a/src/kjotswidget.cpp +++ b/src/kjotswidget.cpp @@ -176,28 +176,28 @@ treeview->setSelectionMode(QAbstractItemView::ExtendedSelection); treeview->setEditTriggers(QAbstractItemView::DoubleClicked); - connect(treeview->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection))); - selProxy = new KSelectionProxyModel(treeview->selectionModel(), this); selProxy->setSourceModel(treeview->model()); // 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(treeview->selectionModel(), stackedWidget); + 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(treeview->selectionModel(), stackedWidget); + browser = new KJotsBrowser(stackedWidget); connect(browser, &KJotsBrowser::linkClicked, this, &KJotsWidget::openLink); stackedWidget->addWidget(browser); stackedWidget->setCurrentWidget(browser); @@ -955,44 +955,6 @@ return result; } -void KJotsWidget::renderSelection() -{ - 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()); - - QTextDocument *document = idx.data(KJotsModel::DocumentRole).value(); - - if (document) { - editor->setDocument(document); - QTextCursor textCursor = document->property("textCursor").value(); - if (!textCursor.isNull()) { - editor->setTextCursor(textCursor); - } else { - // This is a work-around for QTextEdit bug. If the first letter of the document is formatted, - // QTextCursor doesn't follow this format. One can either move the cursor 1 symbol to the right - // and then 1 symbol to the left as a workaround, or just explicitly move it to the start. - // Submitted to qt-bugs, id 192886. - // -- (don't know the fate of this bug, as for April 2020 it is unaccessible) - editor->moveCursor(QTextCursor::Start); - } - stackedWidget->setCurrentWidget(editor); - editor->setFocus(); - return; - } // else fallthrough - } - - // ... Otherwise, render the selection read-only. - - QTextDocument doc; - QTextCursor cursor(&doc); - - browser->setHtml(renderSelectionToHtml()); - stackedWidget->setCurrentWidget(browser); -} - QString KJotsWidget::getThemeFromUser() { return QString(); @@ -1211,21 +1173,27 @@ return canGo(EntityTreeModel::CollectionIdRole, -1); } -void KJotsWidget::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +void KJotsWidget::renderSelection() { - Q_UNUSED(selected) - Q_EMIT canGoNextBookChanged(canGoPreviousBook()); Q_EMIT canGoNextPageChanged(canGoNextPage()); Q_EMIT canGoPreviousBookChanged(canGoPreviousBook()); Q_EMIT canGoPreviousPageChanged(canGoPreviousPage()); - if (deselected.size() == 1) { - editor->document()->setProperty("textCursor", QVariant::fromValue(editor->textCursor())); - if (editor->document()->isModified()) { - treeview->model()->setData(deselected.indexes().first(), QVariant::fromValue(editor->document()), KJotsModel::DocumentRole); + 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(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); } /*!