Коммит 6a6793d0 создал по автору OMP Education's avatar OMP Education Зафиксировано автором Alexey Andreyev
Просмотр файлов

[Bookmarks] Implement bookmarks model

Contributes to:

https://gitlab.com/omprussia/libraries/amberpdf-qml-plugin/-/issues/10
владелец 1519b54b
......@@ -57,6 +57,7 @@ Rectangle {
property alias status: pdfView.status
property alias contentX: viewFlick.contentX
property alias contentY: viewFlick.contentY
property alias bookmarksModel: pdfView.bookmarksModel
signal clicked()
signal clickedUrl(string url)
......
......@@ -60,6 +60,8 @@ VIEW_HEADERS += \
src/interface/baseannotation.h \
src/pdfsimpleannotation.h \
src/pdfsimplenote.h \
src/bookmarksmodel.h \
src/interface/basebookmark.h \
PROVIDER_HEADERS += \
src/pdfium-provider/pagepreloader.h \
......@@ -78,6 +80,7 @@ VIEW_SOURCES += \
src/interface/baseannotation.cpp \
src/pdfsimpleannotation.cpp \
src/pdfsimplenote.cpp \
src/bookmarksmodel.cpp \
PROVIDER_SOURCES += \
src/pdfium-provider/pagepreloader.cpp \
......
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
**
** This file is part of the AmberPDF-QML-Plugin project.
**
** $QT_BEGIN_LICENSE:BSD$
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Open Mobile Platform LLC copyright holder nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "interface/basebookmark.h"
#include "bookmarksmodel.h"
BookmarksModel::BookmarksModel(QObject *parent) : QAbstractListModel(parent) { }
int BookmarksModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_data.size();
}
QVariant BookmarksModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= m_data.size())
return { };
const auto *bookmark = m_data.at(index.row());
if (bookmark == nullptr)
return { };
switch (role) {
case LevelRole : return QVariant::fromValue(bookmark->level);
case TitleRole: return QVariant::fromValue(bookmark->title);
case PageIndexRole: return QVariant::fromValue(bookmark->pageIndex);
case InPageXRole: return QVariant::fromValue(bookmark->positionInPage.x());
case InPageYRole: return QVariant::fromValue(bookmark->positionInPage.y());
}
return { };
}
QHash<int, QByteArray> BookmarksModel::roleNames() const
{
return {
{ LevelRole, "level" },
{ TitleRole, "title" },
{ PageIndexRole, "pageIndex" },
{ InPageXRole, "pageX" },
{ InPageYRole, "pageY" }
};
}
void BookmarksModel::setNewData(const QVector<BaseBookmark *> &newData)
{
beginResetModel();
m_data.clear();
m_data = newData;
endResetModel();
}
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
**
** This file is part of the AmberPDF-QML-Plugin project.
**
** $QT_BEGIN_LICENSE:BSD$
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Open Mobile Platform LLC copyright holder nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef BOOKMARKSMODEL_H
#define BOOKMARKSMODEL_H
#include <QAbstractListModel>
#include <QVector>
struct BaseBookmark;
class BookmarksModel : public QAbstractListModel
{
Q_OBJECT
public:
enum FilePropertyRoles
{
LevelRole = Qt::UserRole + 1,
TitleRole,
PageIndexRole,
InPageXRole,
InPageYRole
};
explicit BookmarksModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
void setNewData(const QVector<BaseBookmark *> &newData);
private:
QVector<BaseBookmark *> m_data;
};
#endif // BOOKMARKSMODEL_H
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
**
** This file is part of the AmberPDF project.
**
** $QT_BEGIN_LICENSE:BSD$
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Open Mobile Platform LLC copyright holder nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef BASEBOOKMARK_H
#define BASEBOOKMARK_H
#include <QString>
#include <QPointF>
struct BaseBookmark
{
QString title;
int pageIndex {-1};
int level {-1};
QPointF positionInPage;
};
#endif // BASEBOOKMARK_H
......@@ -44,6 +44,7 @@
#include <QSharedPointer>
class BasePage;
class BaseBookmark;
class BaseDocument : public QObject
{
Q_OBJECT
......@@ -77,6 +78,8 @@ public:
virtual QSizeF pageSize(int pageNumber) const = 0;
virtual int count() const = 0;
virtual QSharedPointer<BasePage> loadPage(int pageIndex) = 0;
virtual void startLoadBookmarks() const = 0;
virtual QVector<BaseBookmark *> bookmarks() const = 0;
public slots:
virtual void setPath(const QString &path) = 0;
......@@ -85,6 +88,7 @@ signals:
void statusChanged(DocumentStatus status);
void pathChanged(const QString &path);
void pageLoaded(int pageNumber, PageLoadStatus loadStatus);
void bookmarksLoaded();
protected:
DocumentStatus m_status;
......
......@@ -43,10 +43,12 @@
#include <QThreadPool>
#include <amberpdf/pdfdocument.h>
#include <amberpdf/pdfbookmark.h>
#include "pagessizesloader.h"
#include "pagepreloader.h"
#include "basepage.h"
#include "basebookmark.h"
#include "pdfdocumentitem.h"
......@@ -102,6 +104,43 @@ QSharedPointer<BasePage> PdfDocumentItem::loadPage(int pageIndex)
return { };
}
void PdfDocumentItem::startLoadBookmarks() const
{
auto *bookmarksWatcher = new QFutureWatcher<QVector<PdfBookmark>>();
connect(bookmarksWatcher, &QFutureWatcher<QVector<PdfBookmark>>::finished,
this, [bookmarksWatcher, ctx = const_cast<PdfDocumentItem *>(this)]() {
if (bookmarksWatcher == nullptr)
return;
if (bookmarksWatcher->isFinished() && !bookmarksWatcher->isCanceled()) {
auto bookmarks = bookmarksWatcher->result();
if (bookmarks.isEmpty()) {
bookmarksWatcher->deleteLater();
return;
}
qDeleteAll(ctx->m_baseBookmarks);
ctx->m_baseBookmarks.clear();
for (const auto &bookmark : bookmarks) {
ctx->m_baseBookmarks.push_back(new BaseBookmark{ bookmark.title, bookmark.page,
bookmark.level, bookmark.locationInPage
});
}
emit ctx->bookmarksLoaded();
}
bookmarksWatcher->deleteLater();
});
bookmarksWatcher->setFuture(m_pdfiumDocument->bookmarks());
}
QVector<BaseBookmark *> PdfDocumentItem::bookmarks() const
{
return m_baseBookmarks;
}
void PdfDocumentItem::setPath(const QString &path)
{
if (m_pdfiumDocument && (m_pdfiumDocument->path() == path))
......
......@@ -44,6 +44,7 @@
#include <QSharedPointer>
#include <QHash>
#include <QSet>
#include <QVector>
#include "basedocument.h"
#include "pdfpageitem.h"
......@@ -62,6 +63,8 @@ public:
QSizeF pageSize(int pageNumber) const override;
int count() const override;
QSharedPointer<BasePage> loadPage(int pageIndex) override;
void startLoadBookmarks() const override;
QVector<BaseBookmark *> bookmarks() const override;
public slots:
void setPath(const QString &path) override;
......@@ -72,6 +75,7 @@ private:
QHash<int, QSharedPointer<BasePage>> m_loadedPages;
QSet<int> m_pagesInProcess;
int m_lastLoadedPage;
QVector<BaseBookmark *> m_baseBookmarks;
};
#endif // PDFDOCUMENTITEM_H
......@@ -43,6 +43,7 @@
#include "basedocument.h"
#include "documentmapper.h"
#include "pdfpagecontainer.h"
#include "bookmarksmodel.h"
#include "pdfview.h"
......@@ -82,6 +83,8 @@ PdfView::PdfView(QQuickItem *parent) : QQuickItem(parent),
m_timer->setSingleShot(true);
emit statusChanged(BaseDocument::DocumentStatus::Null);
m_bookmarksModel = new BookmarksModel(this);
}
PdfView::~PdfView() = default;
......@@ -220,6 +223,11 @@ qreal PdfView::contentTopMargin() const
return m_contentTopMargin;
}
BookmarksModel *PdfView::bookmarksModel() const
{
return m_bookmarksModel;
}
QString PdfView::pdfPath() const
{
return m_pdfPath;
......@@ -378,10 +386,16 @@ void PdfView::setDocumentProvider(BaseDocument *documentProvider)
}
});
connect(m_documentProvider, &BaseDocument::bookmarksLoaded, this, [this]() {
m_bookmarksModel->setNewData(m_documentProvider->bookmarks());
emit bookmarksModelChanged(m_bookmarksModel);
});
connect(m_documentProvider, &BaseDocument::statusChanged, this, [this](BaseDocument::DocumentStatus status) {
if (status == BaseDocument::DocumentStatus::Ready) {
m_mapper->setDocumentProvider(m_documentProvider);
m_count = m_documentProvider->count();
m_documentProvider->startLoadBookmarks();
emit countChanged(m_count);
}
......
......@@ -45,6 +45,8 @@
#include "basedocument.h"
class DocumentMapper;
class BaseAnnotation;
class BookmarksModel;
class PdfView : public QQuickItem
{
Q_OBJECT
......@@ -59,10 +61,13 @@ class PdfView : public QQuickItem
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
Q_PROPERTY(qreal lastPageIndent READ lastPageIndent NOTIFY lastPageIndentChanged)
Q_PROPERTY(qreal itemScale READ itemScale WRITE setItemScale NOTIFY itemScaleChanged)
Q_PROPERTY(bool annotationsPaint READ annotationsPaint WRITE setAnnotationsPaint NOTIFY annotationsPaintChanged)
Q_PROPERTY(bool notesPaint READ notesPaint WRITE setNotesPaint NOTIFY notesPaintChanged)
Q_PROPERTY(BaseDocument* documentProvider READ documentProvider WRITE setDocumentProvider NOTIFY documentProviderChanged)
Q_PROPERTY(QString pdfPath READ pdfPath WRITE setPdfPath NOTIFY pdfPathChanged)
Q_PROPERTY(BaseDocument::DocumentStatus status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal contentTopMargin READ contentTopMargin NOTIFY contentTopMarginChanged)
Q_PROPERTY(BookmarksModel* bookmarksModel READ bookmarksModel NOTIFY bookmarksModelChanged)
public:
explicit PdfView(QQuickItem *parent = nullptr);
......@@ -81,10 +86,13 @@ public:
Qt::Orientation orientation() const;
qreal lastPageIndent() const;
qreal itemScale() const;
bool annotationsPaint() const;
bool notesPaint() const;
BaseDocument* documentProvider() const;
QString pdfPath() const;
BaseDocument::DocumentStatus status() const;
qreal contentTopMargin() const;
BookmarksModel *bookmarksModel() const;
public slots:
void setContentY(qreal contentY);
......@@ -94,6 +102,8 @@ public slots:
void setOrientation(Qt::Orientation orientation);
void setItemScale(qreal itemScale);
void scaleAroundPoint(const QPointF &center, qreal newScale);
void setAnnotationsPaint(bool annotationsPaint);
void setNotesPaint(bool notesPaint);
void setDocumentProvider(BaseDocument* documentProvider);
void setPdfPath(QString pdfPath);
......@@ -111,13 +121,16 @@ signals:
void orientationChanged(Qt::Orientation orientation);
void lastPageIndentChanged(qreal lastPageIndent);
void itemScaleChanged(qreal itemScale);
void annotationsPaintChanged(bool annotationsPaint);
void clickedUrl(QString url) const;
void clickedGoToPage(int pageNumber, QPointF coordinateOnPage) const;
void notesPaintChanged(bool notesPaint);
void noteActivated(QString noteText, QString author);
void documentProviderChanged(BaseDocument* documentProvider);
void pdfPathChanged(QString pdfPath);
void statusChanged(BaseDocument::DocumentStatus status);
void contentTopMarginChanged(qreal contentTopMargin);
void bookmarksModelChanged(BookmarksModel *bookmarksModel);
private slots:
void _updateContentSize();
......@@ -127,6 +140,7 @@ private slots:
void _preparePages();
void _calculateVisible();
void _updateCurrentIndex();
void _processActivatedAnnotation(BaseAnnotation *annotation);
void _loadDocument();
private:
......@@ -146,10 +160,13 @@ private:
Qt::Orientation m_orientation;
qreal m_lastPageIndent;
qreal m_itemScale;
bool m_annotationsPaint;
bool m_notesPaint;
BaseDocument* m_documentProvider;
QString m_pdfPath;
qreal m_contentTopMargin;
QTimer *m_timer;
BookmarksModel *m_bookmarksModel;
};
#endif // PDFVIEW_H
......@@ -43,6 +43,7 @@
#include "basedocument.h"
#include "pdfview.h"
#include "pdfdocumentitem.h"
#include "bookmarksmodel.h"
class Q_DECL_EXPORT AmberpdfQmlPlugin : public QQmlExtensionPlugin
{
......@@ -60,6 +61,7 @@ public:
// @uri ru.omp.amberpdf
qmlRegisterType<PdfView>(uri, 1, 0, "PdfViewPrivate");
qmlRegisterType<PdfDocumentItem>(uri, 1, 0, "PdfDocument");
qmlRegisterType<BookmarksModel>(uri, 1, 0, "BookmarksModel");
qmlRegisterInterface<BaseDocument>("BaseDocument");
}
};
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать