Коммит 16643590 создал по автору OMP Education's avatar OMP Education Зафиксировано автором k.sagalakova
Просмотр файлов

[View] Add preview of selected pages.



Co-Authored-By: default avatarKira Sagalakova <k.sagalakova@omp.ru>
владелец 6ed128dc
......@@ -54,6 +54,7 @@ Rectangle {
property alias zoom: pdfView.itemScale
property alias contentTopMargin: pdfView.contentTopMargin
property alias pdfPath: pdfView.pdfPath
property alias pageRange: pdfView.pageRange
property alias status: pdfView.status
property alias contentX: viewFlick.contentX
property alias contentY: viewFlick.contentY
......
......@@ -92,6 +92,7 @@ Module {
Property { name: "notesPaint"; type: "bool" }
Property { name: "documentProvider"; type: "BaseDocument"; isPointer: true }
Property { name: "pdfPath"; type: "string" }
Property { name: "pageRange"; type: "string" }
Property { name: "status"; type: "BaseDocument::DocumentStatus"; isReadonly: true }
Property { name: "contentTopMargin"; type: "float"; isReadonly: true }
Property { name: "bookmarksModel"; type: "BookmarksModel"; isReadonly: true; isPointer: true }
......@@ -173,6 +174,10 @@ Module {
name: "pdfPathChanged"
Parameter { name: "pdfPath"; type: "string" }
}
Signal {
name: "pageRangeChanged"
Parameter { name: "pageRange"; type: "string" }
}
Signal {
name: "statusChanged"
Parameter { name: "status"; type: "BaseDocument::DocumentStatus" }
......@@ -248,6 +253,10 @@ Module {
name: "setPdfPath"
Parameter { name: "pdfPath"; type: "string" }
}
Method {
name: "setPageRange"
Parameter { name: "pageRange"; type: "string" }
}
Method {
name: "saveDocumentAs"
Parameter { name: "path"; type: "string" }
......
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
** SPDX-FileCopyrightText: 2022-2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
**
** This file is part of the AmberPDF-QML-Plugin project.
**
......@@ -145,6 +145,15 @@ void DocumentMapper::setOrientation(Qt::Orientation orientation)
_mapPages();
}
void DocumentMapper::setSpecialPageIndexes(const std::map<int, int> &specialRangeIndexes,
const std::set<int> &specialIndexes)
{
m_spacialRangeIndexes = specialRangeIndexes;
m_specialIndexes = specialIndexes;
_mapPages();
}
void DocumentMapper::_mapPages()
{
if (width() <= 0 || height() <= 0)
......@@ -159,8 +168,13 @@ void DocumentMapper::_mapPages()
PagePosition position;
switch (m_orientation) {
case Qt::Vertical : {
case Qt::Vertical: {
for (auto &page : m_originalPagesMap.pages) {
if (isHasSpecial() && !isIndexSpecal(pageIndex)) {
++pageIndex;
continue;
}
position.end += width() * page.heightToWidthRatio() + m_spacing;
m_actualPagesCoordinates.insert(pageIndex, position);
m_lastPageActualSize = position.end - position.start - m_spacing;
......@@ -174,6 +188,11 @@ void DocumentMapper::_mapPages()
}
case Qt::Horizontal : {
for (auto &page : m_originalPagesMap.pages) {
if (isHasSpecial() && !isIndexSpecal(pageIndex)) {
++pageIndex;
continue;
}
auto fitHeight = qMin(width() * page.heightToWidthRatio(), height());
position.end += fitHeight / page.heightToWidthRatio() + m_spacing;
m_actualPagesCoordinates.insert(pageIndex, position);
......@@ -210,6 +229,55 @@ void DocumentMapper::_updateSize()
setHeight(parentItem()->height());
}
bool DocumentMapper::isIndexSpecal(int pageIndex) const
{
auto it = std::find_if(m_spacialRangeIndexes.begin(),
m_spacialRangeIndexes.end(),
[pageIndex](const std::pair<int, int> &t) -> bool {
return pageIndex >= t.first && pageIndex <= t.second;
});
return m_specialIndexes.find(pageIndex) != m_specialIndexes.end() ||
it != m_spacialRangeIndexes.end();
}
bool DocumentMapper::isHasSpecial() const
{
return !(m_spacialRangeIndexes.empty() && m_specialIndexes.empty());
}
int DocumentMapper::minSpecialIndex() const
{
int firstMin = m_specialIndexes.empty() ? 0 : *m_specialIndexes.begin();
if (m_spacialRangeIndexes.empty())
return firstMin;
return std::min(firstMin,
std::min(m_spacialRangeIndexes.begin()->first, m_documentProvider->count() - 1));
}
int DocumentMapper::maxSpecialIndex() const
{
int firstMax = m_specialIndexes.empty() ? 0 : *m_specialIndexes.rbegin();
if (m_spacialRangeIndexes.empty())
return firstMax;
if (m_spacialRangeIndexes.size() == 1)
return std::max(firstMax,
std::min(m_spacialRangeIndexes.begin()->second,
m_documentProvider->count() - 1));
auto it = std::max_element(m_spacialRangeIndexes.begin(),
m_spacialRangeIndexes.end(),
[](const std::pair<int, int> &a, const std::pair<int, int> &b) {
return a.second < b.second;
});
return std::min(std::max(firstMax, it->second), m_documentProvider->count() - 1);
}
PagePosition DocumentMapper::actualPagePosition(int pageIndex) const
{
if (!m_actualPagesCoordinates.contains(pageIndex))
......
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
** SPDX-FileCopyrightText: 2022-2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
**
** This file is part of the AmberPDF-QML-Plugin project.
**
......@@ -44,6 +44,8 @@
#include <QSizeF>
#include <QPointF>
#include <QHash>
#include <set>
#include <map>
#include "pdfviewtypes.h"
......@@ -66,10 +68,16 @@ public:
qreal spacing() const;
qreal lastPageActualSize() const;
void forceUpdate();
bool isIndexSpecal(int pageIndex) const;
bool isHasSpecial() const;
int minSpecialIndex() const;
int maxSpecialIndex() const;
public slots:
void setDocumentProvider(BaseDocument *documentProvider);
void setOrientation(Qt::Orientation orientation);
void setSpecialPageIndexes(const std::map<int,int> &specialRangeIndexes,
const std::set<int> &specialIndexes);
signals:
void contentWidthChanged(qreal);
......@@ -89,6 +97,8 @@ private:
qreal m_contentHeight;
qreal m_contentWidth;
qreal m_lastPageActualSize;
std::set<int> m_specialIndexes;
std::map<int,int> m_spacialRangeIndexes;
};
#endif // DOCUMENTMAPPER_H
/****************************************************************************
**
** Copyright (C) 2022 - 2023 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
** SPDX-FileCopyrightText: 2022-2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
**
** This file is part of the AmberPDF-QML-Plugin project.
**
......@@ -140,7 +140,7 @@ void PdfView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeomet
newContentY += (oldGeometry.height() - newGeometry.height()) / 2.0f;
if (m_currentIndex == m_count - 1) {
auto pagePosition = m_mapper->actualPagePosition(m_count - 1);
auto pagePosition = m_mapper->actualPagePosition(m_mapper->isHasSpecial() ? m_mapper->maxSpecialIndex() : m_count - 1);
newContentY = pagePosition.start * m_itemScale - m_catchBound + 1;
}
......@@ -151,7 +151,7 @@ void PdfView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeomet
newContentX += (oldGeometry.width() - newGeometry.width()) / 2.0f;
if (m_currentIndex == m_count - 1) {
auto pagePosition = m_mapper->actualPagePosition(m_count - 1);
auto pagePosition = m_mapper->actualPagePosition(m_mapper->isHasSpecial() ? m_mapper->maxSpecialIndex() : m_count - 1);
newContentX = pagePosition.start * m_itemScale - m_catchBound - 1;
}
......@@ -343,6 +343,11 @@ QString PdfView::pdfPath() const
return m_pdfPath;
}
QString PdfView::pageRange() const
{
return m_pageRange;
}
BaseDocument::DocumentStatus PdfView::status() const
{
return m_documentProvider == nullptr ? BaseDocument::DocumentStatus::Null : m_documentProvider->status();
......@@ -394,6 +399,14 @@ void PdfView::positionViewAtIndex(int index)
if (index < 0 || index > m_count)
return;
if (m_mapper->isHasSpecial()) {
if (index == 0)
index = m_mapper->minSpecialIndex();
if (index == m_count - 1)
index = m_mapper->maxSpecialIndex();
}
if (m_currentIndex != index) {
m_currentIndex = index;
emit currentIndexChanged(m_currentIndex);
......@@ -562,6 +575,31 @@ void PdfView::setPdfPath(QString pdfPath)
_loadDocument();
}
void PdfView::setPageRange(const QString &pageRange)
{
if (m_pageRange == pageRange)
return;
m_pageRange = pageRange;
if (m_pageRange.isEmpty())
return;
std::map<int, int> indexIntervals;
std::set<int> pageIndexes;
QStringList ranges = pageRange.split(',');
for (const auto &range : ranges) {
QStringList rangeInterval = range.split('-');
if (rangeInterval.size() == 2) {
indexIntervals[std::min(rangeInterval[0].toInt(), rangeInterval[1].toInt())]
= std::max(rangeInterval[0].toInt(), rangeInterval[1].toInt());
} else {
if (rangeInterval.size() == 1)
pageIndexes.insert(rangeInterval[0].toInt());
}
}
m_mapper->setSpecialPageIndexes(indexIntervals, pageIndexes);
}
void PdfView::_updateContentSize()
{
if (!qFuzzyCompare(double(m_contentWidth), double(m_mapper->contentWidth())) && m_mapper->contentWidth() > 0.0f) {
......@@ -586,10 +624,14 @@ void PdfView::_positionPages()
paintStart = (width() - m_paintedItemsSize) / 2.0f;
auto maxSize = -1.0f;
for(auto pageIndex : m_paintedPages) {
for (auto pageIndex : m_paintedPages) {
if (!m_pages.contains(pageIndex))
continue;
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(pageIndex)) {
continue;
}
auto page = m_pages.value(pageIndex);
if (page == nullptr)
continue;
......@@ -677,12 +719,17 @@ void PdfView::_calculateVisible()
auto endVisibleArea = startVisibleArea + (m_orientation == Qt::Vertical ? height() : width());
auto startPaintedPage = -1;
auto endPaintedPage = -1;
auto maxPageIndex = m_mapper->isHasSpecial() ? m_mapper->maxSpecialIndex() : m_count - 1;
if (m_moveDirection <= 0) {
if (!m_paintedPages.isEmpty())
minPageIndex = qMax(0, *std::min_element(m_paintedPages.begin(), m_paintedPages.end()));
for (int i = minPageIndex; i < m_count; ++i) {
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(i)) {
continue;
}
auto pageCoordinates = m_mapper->actualPagePosition(i);
if (pageCoordinates.end * m_itemScale >= startVisibleArea && pageCoordinates.start * m_itemScale <= startVisibleArea) {
......@@ -697,9 +744,14 @@ void PdfView::_calculateVisible()
}
} else {
if (!m_paintedPages.isEmpty())
minPageIndex = qMax(m_count - 1, *std::max_element(m_paintedPages.begin(), m_paintedPages.end()));
minPageIndex = qMax(maxPageIndex,
*std::max_element(m_paintedPages.begin(), m_paintedPages.end()));
for (int i = minPageIndex; i >= 0; --i) {
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(i)) {
continue;
}
auto pageCoordinates = m_mapper->actualPagePosition(i);
if (pageCoordinates.end * m_itemScale >= startVisibleArea && pageCoordinates.start * m_itemScale <= startVisibleArea) {
......@@ -710,6 +762,10 @@ void PdfView::_calculateVisible()
}
for (int i = startPaintedPage; i < m_count; ++i) {
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(i)) {
continue;
}
auto pageCoordinate = m_mapper->actualPagePosition(i);
if (pageCoordinate.start * m_itemScale > startVisibleArea && pageCoordinate.end * m_itemScale <= endVisibleArea)
endPaintedPage = i;
......@@ -720,13 +776,13 @@ void PdfView::_calculateVisible()
}
}
if (startPaintedPage == m_count - 1)
if (startPaintedPage == maxPageIndex)
endPaintedPage = startPaintedPage;
if (startPaintedPage < 0)
startPaintedPage = minPageIndex;
endPaintedPage = qMin(endPaintedPage + 1, m_count - 1);
endPaintedPage = qMin(endPaintedPage + 1, maxPageIndex);
m_paintedPages.clear();
for (int i = qMax(0, startPaintedPage - 1); i <= endPaintedPage; ++i)
......@@ -750,7 +806,10 @@ void PdfView::_calculateVisible()
}
m_paintedItemsSize = 0;
for(auto pageIndex : m_paintedPages) {
for (auto pageIndex : m_paintedPages) {
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(pageIndex)) {
continue;
}
auto pageGeometry = m_mapper->actualPagePosition(pageIndex);
m_paintedItemsSize += (pageGeometry.end - pageGeometry.start) * m_itemScale;
}
......@@ -765,6 +824,10 @@ void PdfView::_updateCurrentIndex()
if (!m_pages.contains(pageIndex))
continue;
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(pageIndex)) {
continue;
}
auto page = m_pages.value(pageIndex);
if (page == nullptr)
continue;
......@@ -869,6 +932,10 @@ void PdfView::_preparePages()
bool needPositioning = false;
for (const auto &pageIndex : m_paintedPages) {
if (m_mapper->isHasSpecial() && !m_mapper->isIndexSpecal(pageIndex)) {
continue;
}
if (m_pages.keys().contains(pageIndex)) {
auto pageContainer = qobject_cast<PdfPageContainer *>(m_pages.value(pageIndex));
if (!pageContainer->source()) {
......
/****************************************************************************
**
** Copyright (C) 2022 Open Mobile Platform LLC.
** Contact: https://community.omprussia.ru/open-source
** SPDX-FileCopyrightText: 2022-2023 Open Mobile Platform LLC <community@omp.ru>
** SPDX-License-Identifier: BSD-3-Clause
**
** This file is part of the AmberPDF-QML-Plugin project.
**
......@@ -66,6 +66,7 @@ class PdfView : public QQuickItem
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(QString pageRange READ pageRange WRITE setPageRange NOTIFY pageRangeChanged)
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)
......@@ -94,6 +95,7 @@ public:
bool notesPaint() const;
BaseDocument* documentProvider() const;
QString pdfPath() const;
QString pageRange() const;
BaseDocument::DocumentStatus status() const;
qreal contentTopMargin() const;
BookmarksModel *bookmarksModel() const;
......@@ -121,6 +123,7 @@ public slots:
void setNotesPaint(bool notesPaint);
void setDocumentProvider(BaseDocument* documentProvider);
void setPdfPath(QString pdfPath);
void setPageRange(const QString &pageRange);
signals:
void modelChanged(QObject* model);
......@@ -143,6 +146,7 @@ signals:
void noteActivated(QString noteText, QString author);
void documentProviderChanged(BaseDocument* documentProvider);
void pdfPathChanged(QString pdfPath);
void pageRangeChanged(QString pageRange);
void statusChanged(BaseDocument::DocumentStatus status);
void contentTopMarginChanged(qreal contentTopMargin);
void bookmarksModelChanged(BookmarksModel *bookmarksModel);
......@@ -186,6 +190,7 @@ private:
bool m_notesPaint;
BaseDocument* m_documentProvider;
QString m_pdfPath;
QString m_pageRange;
qreal m_contentTopMargin;
QTimer *m_timer;
BookmarksModel *m_bookmarksModel;
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать