compile
[kdegraphics.git] / okular / core / bookmarkmanager.cpp
blobd9972944c6779d36aa67e3d25900f32cb3cbebc7
1 /***************************************************************************
2 * Copyright (C) 2006 by Pino Toscano <pino@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 ***************************************************************************/
10 #include "bookmarkmanager.h"
12 // qt/kde includes
13 #include <qhash.h>
14 #include <qset.h>
15 #include <kbookmarkmanager.h>
16 #include <kbookmarkmenu.h>
17 #include <kdebug.h>
18 #include <kglobal.h>
19 #include <kstandarddirs.h>
21 // local includes
22 #include "document_p.h"
23 #include "observer.h"
25 using namespace Okular;
27 #define foreachObserver( cmd ) {\
28 QMap< int, DocumentObserver * >::const_iterator it = d->document->m_observers.begin(), end = d->document->m_observers.end();\
29 for ( ; it != end ; ++ it ) { (*it)-> cmd ; } }
31 class OkularBookmarkAction : public KBookmarkAction
33 public:
34 OkularBookmarkAction( const Okular::DocumentViewport& vp, const KBookmark& bk, KBookmarkOwner* owner, QObject *parent )
35 : KBookmarkAction( bk, owner, parent )
37 if ( vp.isValid() )
38 setText( QString::number( vp.pageNumber + 1 ) + " - " + text() );
42 class BookmarkManager::Private : public KBookmarkOwner
44 public:
45 Private( BookmarkManager * qq )
46 : KBookmarkOwner(), q( qq ), document( 0 ), manager( 0 )
50 ~Private()
52 knownFiles.clear();
53 // no need to delete the manager, it's automatically done by KBookmarkManager
54 // delete manager;
57 virtual QString currentUrl() const;
58 virtual QString currentTitle() const;
59 virtual bool enableOption(BookmarkOption option) const;
60 virtual void openBookmark( const KBookmark & bm, Qt::MouseButtons, Qt::KeyboardModifiers );
62 QHash<KUrl, KBookmarkGroup>::iterator bookmarkFind( const KUrl& url, bool doCreate );
64 BookmarkManager * q;
65 KUrl url;
66 QSet<int> urlBookmarks;
67 DocumentPrivate * document;
68 QString file;
69 KBookmarkManager * manager;
70 QHash<KUrl, KBookmarkGroup> knownFiles;
73 BookmarkManager::BookmarkManager( DocumentPrivate * document )
74 : QObject( document->m_parent ), d( new Private( this ) )
76 setObjectName( "Okular::BookmarkManager" );
78 d->document = document;
80 d->file = KStandardDirs::locateLocal( "data", "okular/bookmarks.xml" );
82 d->manager = KBookmarkManager::managerForFile( d->file, "okular" );
83 d->manager->setEditorOptions( KGlobal::caption(), false );
84 d->manager->setUpdate( true );
87 BookmarkManager::~BookmarkManager()
89 save();
90 delete d;
93 //BEGIN Reimplementations from KBookmarkOwner
94 QString BookmarkManager::Private::currentUrl() const
96 return url.prettyUrl();
99 QString BookmarkManager::Private::currentTitle() const
101 return url.isLocalFile() ? url.path() : url.prettyUrl();
104 bool BookmarkManager::Private::enableOption(BookmarkOption option) const
106 Q_UNUSED( option )
107 return false;
110 void BookmarkManager::Private::openBookmark( const KBookmark & bm, Qt::MouseButtons, Qt::KeyboardModifiers )
112 emit q->openUrl( bm.url() );
114 //END Reimplementations from KBookmarkOwner
116 KUrl::List BookmarkManager::files() const
118 KUrl::List ret;
119 KBookmarkGroup group = d->manager->root();
120 for ( KBookmark bm = group.first(); !bm.isNull(); bm = group.next( bm ) )
122 if ( bm.isSeparator() || !bm.isGroup() )
123 continue;
125 ret.append( KUrl( bm.fullText() ) );
127 return ret;
130 KBookmark::List BookmarkManager::bookmarks( const KUrl& url ) const
132 KBookmark::List ret;
133 KBookmarkGroup group = d->manager->root();
134 for ( KBookmark bm = group.first(); !bm.isNull(); bm = group.next( bm ) )
136 if ( !bm.isGroup() || KUrl( bm.fullText() ) != url )
137 continue;
139 KBookmarkGroup group = bm.toGroup();
140 for ( KBookmark b = group.first(); !b.isNull(); b = group.next( b ) )
142 if ( b.isSeparator() || b.isGroup() )
143 continue;
145 ret.append( b );
147 break;
149 return ret;
152 void BookmarkManager::save() const
154 d->manager->save( false );
155 emit const_cast<BookmarkManager*>( this )->saved();
158 QHash<KUrl, KBookmarkGroup>::iterator BookmarkManager::Private::bookmarkFind( const KUrl& url, bool doCreate )
160 QHash<KUrl, KBookmarkGroup>::iterator it = knownFiles.find( url );
161 if ( it == knownFiles.end() )
163 // if the url we want to add a new entry for is not in the hash of the
164 // known files, then first try to find the file among the top-level
165 // "folder" names
166 bool found = false;
167 KBookmarkGroup root = manager->root();
168 for ( KBookmark bm = root.first(); !found && !bm.isNull(); bm = root.next( bm ) )
170 if ( bm.isSeparator() || !bm.isGroup() )
171 continue;
173 KUrl tmpurl( bm.fullText() );
174 if ( tmpurl == url )
176 // got it! place it the hash of known files
177 it = knownFiles.insert( url, bm.toGroup() );
178 found = true;
179 break;
182 if ( !found && doCreate )
184 // folder not found :(
185 // then, in a single step create a new folder and add it in our cache :)
186 QString purl = url.isLocalFile() ? url.path() : url.prettyUrl();
187 it = knownFiles.insert( url, root.createNewFolder( purl ) );
190 return it;
193 void BookmarkManager::addBookmark( int n )
195 if ( n >= 0 && n < (int)d->document->m_pagesVector.count() )
197 if ( setPageBookmark( n ) )
198 foreachObserver( notifyPageChanged( n, DocumentObserver::Bookmark ) );
202 bool BookmarkManager::addBookmark( const KUrl& referurl, const Okular::DocumentViewport& vp, const QString& title )
204 if ( !referurl.isValid() || !vp.isValid() )
205 return false;
207 QHash<KUrl, KBookmarkGroup>::iterator it = d->bookmarkFind( referurl, true );
208 Q_ASSERT( it != d->knownFiles.end() );
210 QString newtitle;
211 if ( title.isEmpty() )
213 // if we have no title specified for the new bookmark, then give it the
214 // name '#n' where n is the index of this bookmark among the ones of
215 // its file
216 int count = 0;
217 for ( KBookmark bm = it.value().first(); !bm.isNull(); bm = it.value().next( bm ) )
219 if ( !bm.isSeparator() && !bm.isGroup() )
220 ++count;
222 newtitle = QString( "#%1" ).arg( count + 1 );
224 else
225 newtitle = title;
226 KUrl newurl = referurl;
227 newurl.setHTMLRef( vp.toString() );
228 it.value().addBookmark( newtitle, newurl, QString() );
229 if ( referurl == d->document->m_url )
231 d->urlBookmarks.insert( vp.pageNumber );
232 foreachObserver( notifyPageChanged( vp.pageNumber, DocumentObserver::Bookmark ) );
234 emit bookmarksChanged( referurl );
235 return true;
238 void BookmarkManager::removeBookmark( int n )
240 if ( n >= 0 && n < (int)d->document->m_pagesVector.count() )
242 if ( removePageBookmark( n ) )
243 foreachObserver( notifyPageChanged( n, DocumentObserver::Bookmark ) );
247 int BookmarkManager::removeBookmark( const KUrl& referurl, const KBookmark& bm )
249 if ( !referurl.isValid() || bm.isNull() || bm.isGroup() || bm.isSeparator() )
250 return -1;
252 DocumentViewport vp( bm.url().htmlRef() );
253 if ( !vp.isValid() )
254 return -1;
256 QHash<KUrl, KBookmarkGroup>::iterator it = d->bookmarkFind( referurl, false );
257 if ( it == d->knownFiles.end() )
258 return -1;
260 it.value().deleteBookmark( bm );
261 if ( referurl == d->document->m_url )
263 d->urlBookmarks.remove( vp.pageNumber );
264 foreachObserver( notifyPageChanged( vp.pageNumber, DocumentObserver::Bookmark ) );
266 emit bookmarksChanged( referurl );
268 return vp.pageNumber;
271 QList< QAction * > BookmarkManager::actionsForUrl( const KUrl& url ) const
273 QList< QAction * > ret;
274 KBookmarkGroup group = d->manager->root();
275 for ( KBookmark bm = group.first(); !bm.isNull(); bm = group.next( bm ) )
277 if ( !bm.isGroup() || KUrl( bm.fullText() ) != url )
278 continue;
280 KBookmarkGroup group = bm.toGroup();
281 for ( KBookmark b = group.first(); !b.isNull(); b = group.next( b ) )
283 if ( b.isSeparator() || b.isGroup() )
284 continue;
286 ret.append( new OkularBookmarkAction( DocumentViewport( b.url().htmlRef() ), b, d, 0 ) );
288 break;
290 return ret;
293 void BookmarkManager::setUrl( const KUrl& url )
295 d->url = url;
296 d->urlBookmarks.clear();
297 QHash<KUrl, KBookmarkGroup>::iterator it = d->bookmarkFind( url, false );
298 if ( it != d->knownFiles.end() )
300 for ( KBookmark bm = it.value().first(); !bm.isNull(); bm = it.value().next( bm ) )
302 if ( bm.isSeparator() || bm.isGroup() )
303 continue;
305 DocumentViewport vp( bm.url().htmlRef() );
306 if ( !vp.isValid() )
307 continue;
309 d->urlBookmarks.insert( vp.pageNumber );
314 bool BookmarkManager::setPageBookmark( int page )
316 QHash<KUrl, KBookmarkGroup>::iterator it = d->bookmarkFind( d->url, true );
317 Q_ASSERT( it != d->knownFiles.end() );
319 bool found = false;
320 bool added = false;
321 for ( KBookmark bm = it.value().first(); !found && !bm.isNull(); bm = it.value().next( bm ) )
323 if ( bm.isSeparator() || bm.isGroup() )
324 continue;
326 DocumentViewport vp( bm.url().htmlRef() );
327 if ( vp.isValid() && vp.pageNumber == page )
328 found = true;
331 if ( !found )
333 d->urlBookmarks.insert( page );
334 DocumentViewport vp;
335 vp.pageNumber = page;
336 KUrl newurl = d->url;
337 newurl.setHTMLRef( vp.toString() );
338 it.value().addBookmark( QString::fromLatin1( "#" ) + QString::number( vp.pageNumber + 1 ), newurl, QString() );
339 added = true;
340 emit bookmarksChanged( d->url );
342 return added;
345 bool BookmarkManager::removePageBookmark( int page )
347 QHash<KUrl, KBookmarkGroup>::iterator it = d->bookmarkFind( d->url, false );
348 if ( it == d->knownFiles.end() )
349 return false;
351 bool found = false;
352 for ( KBookmark bm = it.value().first(); !found && !bm.isNull(); bm = it.value().next( bm ) )
354 if ( bm.isSeparator() || bm.isGroup() )
355 continue;
357 DocumentViewport vp( bm.url().htmlRef() );
358 if ( vp.isValid() && vp.pageNumber == page )
360 found = true;
361 it.value().deleteBookmark( bm );
362 d->urlBookmarks.remove( page );
363 emit bookmarksChanged( d->url );
366 return found;
369 bool BookmarkManager::isBookmarked( int page ) const
371 return d->urlBookmarks.contains( page );
374 #include "bookmarkmanager.moc"