support bookmarks with complete viewport

This commit is contained in:
Marco Martin 2012-10-05 15:59:08 +02:00
parent a69ba957c9
commit ae5ddd097c
7 changed files with 158 additions and 20 deletions

View file

@ -21,5 +21,5 @@ import QtQuick 1.1
ThumbnailsBase {
model: documentItem.bookmarks
model: documentItem.bookmarkedPages
}

View file

@ -232,7 +232,7 @@ MobileComponents.OverlayDrawer {
}
PlasmaComponents.TabButton {
id: bookmarksButton
enabled: documentItem.bookmarks.length > 0
enabled: documentItem.bookmarkedPages.length > 0
text: i18n("Bookmarks")
tab: tableOfContents
onCheckedChanged: {

View file

@ -140,6 +140,7 @@ MouseEventListener {
Okular.PageItem {
id: mainPage
document: documentItem
flickable: mainFlickable
anchors.centerIn: parent
property real ratio: implicitWidth / implicitHeight

View file

@ -37,8 +37,8 @@ DocumentItem::DocumentItem(QObject *parent)
connect(m_document, SIGNAL(searchFinished(int,Okular::Document::SearchStatus)),
this, SLOT(searchFinished(int,Okular::Document::SearchStatus)));
connect(m_document->bookmarkManager(), SIGNAL(bookmarksChanged(KUrl)),
this, SIGNAL(bookmarksChanged()));
connect(m_document->bookmarkManager(), SIGNAL(bookmarkedPagesChanged(KUrl)),
this, SIGNAL(bookmarkedPagesChanged()));
}
@ -121,12 +121,14 @@ TOCModel *DocumentItem::tableOfContents() const
return m_tocModel;
}
QList<int> DocumentItem::bookmarks() const
QList<int> DocumentItem::bookmarkedPages() const
{
QList<int> list;
QSet<int> pages;
foreach (const KBookmark &bookmark, m_document->bookmarkManager()->bookmarks()) {
list << bookmark.url().fragment().split(";").first().toInt();
pages << bookmark.url().fragment().split(";").first().toInt();
}
list = pages.toList();
qSort(list);
return list;
}

View file

@ -86,7 +86,7 @@ class DocumentItem : public QObject
/**
* List of pages that contain a bookmark
*/
Q_PROPERTY(QList<int> bookmarks READ bookmarks NOTIFY bookmarksChanged)
Q_PROPERTY(QList<int> bookmarkedPages READ bookmarkedPages NOTIFY bookmarkedPagesChanged)
public:
@ -113,7 +113,7 @@ public:
TOCModel *tableOfContents() const;
QList<int> bookmarks() const;
QList<int> bookmarkedPages() const;
//This could be a property, but maybe we want to have parameter for searchText
/**
@ -140,7 +140,7 @@ Q_SIGNALS:
void matchingPagesChanged();
void currentPageChanged();
void supportsSearchingChanged();
void bookmarksChanged();
void bookmarkedPagesChanged();
void windowTitleForDocumentChanged();
private Q_SLOTS:

View file

@ -38,7 +38,6 @@ PageItem::PageItem(QDeclarativeItem *parent)
: QDeclarativeItem(parent),
Okular::View( QString::fromLatin1( "PageView" ) ),
m_page(0),
m_pageNumber(0),
m_smooth(false),
m_intentionalDraw(true),
m_bookmarked(false)
@ -56,6 +55,44 @@ PageItem::~PageItem()
{
}
void PageItem::setFlickable(QDeclarativeItem *flickable)
{
if (m_flickable.data() == flickable) {
return;
}
//check the object can act as a flickable
if (!flickable->property("contentX").isValid() ||
!flickable->property("contentY").isValid()) {
return;
}
if (m_flickable) {
disconnect(m_flickable.data(), 0, this, 0);
}
//check the object can act as a flickable
if (!flickable->property("contentX").isValid() ||
!flickable->property("contentY").isValid()) {
m_flickable.clear();
return;
}
m_flickable = flickable;
if (flickable) {
connect(flickable, SIGNAL(contentXChanged()), this, SLOT(contentXChanged()));
connect(flickable, SIGNAL(contentYChanged()), this, SLOT(contentYChanged()));
}
emit flickableChanged();
}
QDeclarativeItem *PageItem::flickable() const
{
return m_flickable.data();
}
DocumentItem *PageItem::document() const
{
return m_documentItem.data();
@ -81,12 +118,12 @@ void PageItem::setDocument(DocumentItem *doc)
int PageItem::pageNumber() const
{
return m_pageNumber;
return m_viewPort.pageNumber;
}
void PageItem::setPageNumber(int number)
{
if ((m_page && m_pageNumber == number) ||
if ((m_page && m_viewPort.pageNumber == number) ||
!m_documentItem ||
!m_documentItem.data()->isOpened() ||
number < 0 ||
@ -94,7 +131,7 @@ void PageItem::setPageNumber(int number)
return;
}
m_pageNumber = number;
m_viewPort.pageNumber = number;
m_page = m_documentItem.data()->document()->page(number);
emit pageNumberChanged();
@ -150,14 +187,53 @@ void PageItem::setBookmarked(bool bookmarked)
}
if (bookmarked) {
m_documentItem.data()->document()->bookmarkManager()->addBookmark(m_pageNumber);
m_documentItem.data()->document()->bookmarkManager()->addBookmark(m_viewPort.pageNumber);
} else {
m_documentItem.data()->document()->bookmarkManager()->removeBookmark(m_pageNumber);
m_documentItem.data()->document()->bookmarkManager()->removeBookmark(m_viewPort.pageNumber);
}
m_bookmarked = bookmarked;
emit bookmarkedChanged();
}
QStringList PageItem::bookmarks() const
{
QStringList list;
foreach(const KBookmark &bookmark, m_documentItem.data()->document()->bookmarkManager()->bookmarks(m_viewPort.pageNumber)) {
list << bookmark.url().fragment();
}
return list;
}
void PageItem::goToBookmark(const QString &bookmark)
{
Okular::DocumentViewport viewPort(bookmark);
setPageNumber(viewPort.pageNumber);
//Are we in a flickable?
if (m_flickable) {
//normalizedX is a proportion, so contentX will be the difference between document and viewport times normalizedX
m_flickable.data()->setProperty("contentX", qMax((qreal)0, width() - m_flickable.data()->width()) * viewPort.rePos.normalizedX);
m_flickable.data()->setProperty("contentY", qMax((qreal)0, height() - m_flickable.data()->height()) * viewPort.rePos.normalizedY);
}
}
void PageItem::setBookmarkAtPos(qreal x, qreal y)
{
Okular::DocumentViewport viewPort(m_viewPort);
viewPort.rePos.normalizedX = x;
viewPort.rePos.normalizedY = y;
m_documentItem.data()->document()->bookmarkManager()->addBookmark(viewPort);
emit bookmarksChanged();
}
void PageItem::removeBookmark(const QString &bookmark)
{
m_documentItem.data()->document()->bookmarkManager()->removeBookmark(bookmark);
emit bookmarksChanged();
}
//Reimplemented
void PageItem::geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry)
@ -193,7 +269,7 @@ void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
if (m_intentionalDraw) {
QLinkedList< Okular::PixmapRequest * > requestedPixmaps;
requestedPixmaps.push_back(new Okular::PixmapRequest(m_observerId, m_pageNumber, width(), height(), priority, true));
requestedPixmaps.push_back(new Okular::PixmapRequest(m_observerId, m_viewPort.pageNumber, width(), height(), priority, true));
m_documentItem.data()->document()->requestPixmaps( requestedPixmaps );
}
m_intentionalDraw = false;
@ -217,7 +293,7 @@ void PageItem::delayedRedraw()
void PageItem::pageHasChanged( int page, int flags )
{
Q_UNUSED(flags)
if (m_pageNumber == page) {
if (m_viewPort.pageNumber == page) {
m_redrawTimer->start(REDRAW_TIMEOUT);
}
}
@ -228,11 +304,32 @@ void PageItem::checkBookmarksChanged()
return;
}
bool newBookmarked = m_documentItem.data()->document()->bookmarkManager()->isBookmarked(m_pageNumber);
bool newBookmarked = m_documentItem.data()->document()->bookmarkManager()->isBookmarked(m_viewPort.pageNumber);
if (m_bookmarked != newBookmarked) {
m_bookmarked = newBookmarked;
emit bookmarkedChanged();
}
//TODO: check the page
emit bookmarksChanged();
}
void PageItem::contentXChanged()
{
if (!m_flickable || !m_flickable.data()->property("contentX").isValid()) {
return;
}
m_viewPort.rePos.normalizedX = m_flickable.data()->property("contentX").toReal();
}
void PageItem::contentYChanged()
{
if (!m_flickable || !m_flickable.data()->property("contentY").isValid()) {
return;
}
m_viewPort.rePos.normalizedY = m_flickable.data()->property("contentY").toReal();
}
#include "pageitem.moc"

View file

@ -22,6 +22,7 @@
#include <QDeclarativeItem>
#include <core/document.h>
#include <core/view.h>
class QTimer;
@ -37,6 +38,11 @@ class PageItem : public QDeclarativeItem, public Okular::View
{
Q_OBJECT
/**
* If this page is in a Flickable, assign it in this property, to make goToBookmark work
*/
Q_PROPERTY(QDeclarativeItem *flickable READ flickable WRITE setFlickable NOTIFY flickableChanged)
/**
* The document this page belongs to
*/
@ -63,15 +69,24 @@ class PageItem : public QDeclarativeItem, public Okular::View
Q_PROPERTY(int implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
/**
* True if the page contains a bookmark
* True if the page contains at least a bookmark.
* Writing true to tis property idds a bookmark at the beginning of the page (if needed).
* Writing false, all bookmarks for this page will be removed
*/
Q_PROPERTY(bool bookmarked READ isBookmarked WRITE setBookmarked NOTIFY bookmarkedChanged)
/**
* list of bookmarks urls valid on this page
*/
Q_PROPERTY(QStringList bookmarks READ bookmarks NOTIFY bookmarksChanged)
public:
PageItem(QDeclarativeItem *parent=0);
~PageItem();
void setFlickable(QDeclarativeItem *flickable);
QDeclarativeItem *flickable() const;
int implicitWidth() const;
int implicitHeight() const;
@ -88,6 +103,24 @@ public:
bool isBookmarked();
void setBookmarked(bool bookmarked);
QStringList bookmarks() const;
/**
* loads a page bookmark and tries to ensure the bookmarked position is visible
* @param bookmark Url for the bookmark
*/
Q_INVOKABLE void goToBookmark(const QString &bookmark);
/**
* Add a new bookmark ar a given position of the current page
*/
Q_INVOKABLE void setBookmarkAtPos(qreal x, qreal y);
/**
* Remove a bookmark at a given position, if any
*/
Q_INVOKABLE void removeBookmark(const QString &bookmark);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
// inherited from View
@ -100,23 +133,28 @@ private Q_SLOTS:
void delayedRedraw();
void pageHasChanged(int page, int flags);
void checkBookmarksChanged();
void contentXChanged();
void contentYChanged();
Q_SIGNALS:
void flickableChanged();
void implicitWidthChanged();
void implicitHeightChanged();
void documentChanged();
void pageNumberChanged();
void bookmarkedChanged();
void bookmarksChanged();
private:
const Okular::Page *m_page;
int m_pageNumber;
bool m_smooth;
bool m_intentionalDraw;
bool m_bookmarked;
QWeakPointer<DocumentItem> m_documentItem;
QTimer *m_redrawTimer;
int m_observerId;
QWeakPointer <QDeclarativeItem> m_flickable;
Okular::DocumentViewport m_viewPort;
friend class ThumbnailItem;
};