compile
[kdegraphics.git] / okular / ui / bookmarklist.cpp
blob941b144c91ac15b19bbdf3e55b2ad5455cf399df
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 "bookmarklist.h"
12 // qt/kde includes
13 #include <qaction.h>
14 #include <qcursor.h>
15 #include <qheaderview.h>
16 #include <qlayout.h>
17 #include <qtoolbar.h>
18 #include <qtreewidget.h>
20 #include <kdebug.h>
21 #include <kicon.h>
22 #include <klocale.h>
23 #include <kmenu.h>
24 #include <ktreewidgetsearchline.h>
26 #include "pageitemdelegate.h"
27 #include "core/action.h"
28 #include "core/bookmarkmanager.h"
29 #include "core/document.h"
31 static const int BookmarkItemType = QTreeWidgetItem::UserType + 1;
32 static const int FileItemType = QTreeWidgetItem::UserType + 2;
33 static const int UrlRole = Qt::UserRole + 1;
35 class BookmarkItem : public QTreeWidgetItem
37 public:
38 BookmarkItem( const KBookmark& bm )
39 : QTreeWidgetItem( BookmarkItemType ), m_bookmark( bm )
41 setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable );
42 m_url = m_bookmark.url();
43 m_viewport = Okular::DocumentViewport( m_url.htmlRef() );
44 m_url.setHTMLRef( QString() );
45 setText( 0, m_bookmark.fullText() );
46 if ( m_viewport.isValid() )
47 setData( 0, PageItemDelegate::PageRole, QString::number( m_viewport.pageNumber + 1 ) );
50 virtual QVariant data( int column, int role ) const
52 switch ( role )
54 case Qt::ToolTipRole:
55 return m_bookmark.fullText();
57 return QTreeWidgetItem::data( column, role );
60 KBookmark& bookmark()
62 return m_bookmark;
65 const Okular::DocumentViewport& viewport() const
67 return m_viewport;
70 KUrl url() const
72 return m_url;
75 private:
76 KBookmark m_bookmark;
77 KUrl m_url;
78 Okular::DocumentViewport m_viewport;
82 BookmarkList::BookmarkList( Okular::Document *document, QWidget *parent )
83 : QWidget( parent ), m_document( document ), m_currentDocumentItem( 0 )
85 QVBoxLayout *mainlay = new QVBoxLayout( this );
86 mainlay->setMargin( 0 );
87 mainlay->setSpacing( 6 );
89 m_searchLine = new KTreeWidgetSearchLine( this );
90 mainlay->addWidget( m_searchLine );
92 m_tree = new QTreeWidget( this );
93 mainlay->addWidget( m_tree );
94 QStringList cols;
95 cols.append( "Bookmarks" );
96 m_tree->setContextMenuPolicy( Qt::CustomContextMenu );
97 m_tree->setHeaderLabels( cols );
98 m_tree->setSortingEnabled( false );
99 m_tree->setRootIsDecorated( true );
100 m_tree->setAlternatingRowColors( true );
101 m_tree->setItemDelegate( new PageItemDelegate( m_tree ) );
102 m_tree->header()->hide();
103 m_tree->setSelectionBehavior( QAbstractItemView::SelectRows );
104 m_tree->setEditTriggers( QAbstractItemView::EditKeyPressed );
105 connect( m_tree, SIGNAL( itemActivated( QTreeWidgetItem *, int ) ), this, SLOT( slotExecuted( QTreeWidgetItem * ) ) );
106 connect( m_tree, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( slotContextMenu( const QPoint& ) ) );
107 m_searchLine->addTreeWidget( m_tree );
109 QToolBar * bookmarkController = new QToolBar( this );
110 mainlay->addWidget( bookmarkController );
111 bookmarkController->setObjectName( "BookmarkControlBar" );
112 // change toolbar appearance
113 bookmarkController->setIconSize( QSize( 16, 16 ) );
114 bookmarkController->setMovable( false );
115 QSizePolicy sp = bookmarkController->sizePolicy();
116 sp.setVerticalPolicy( QSizePolicy::Minimum );
117 bookmarkController->setSizePolicy( sp );
118 // insert a togglebutton [show only bookmarks in the current document]
119 m_showBoomarkOnlyAction = bookmarkController->addAction( KIcon( "bookmarks" ), i18n( "Current document only" ) );
120 m_showBoomarkOnlyAction->setCheckable( true );
121 connect( m_showBoomarkOnlyAction, SIGNAL( toggled( bool ) ), this, SLOT( slotFilterBookmarks( bool ) ) );
123 connect( m_document->bookmarkManager(), SIGNAL( bookmarksChanged( const KUrl& ) ), this, SLOT( slotBookmarksChanged( const KUrl& ) ) );
125 rebuildTree( m_showBoomarkOnlyAction->isChecked() );
128 BookmarkList::~BookmarkList()
132 uint BookmarkList::observerId() const
134 return BOOKMARKLIST_ID;
137 void BookmarkList::notifySetup( const QVector< Okular::Page * > & pages, int setupFlags )
139 if ( !( setupFlags & Okular::DocumentObserver::DocumentChanged ) )
140 return;
142 // clear contents
143 m_searchLine->clear();
145 if ( m_showBoomarkOnlyAction->isChecked() )
147 rebuildTree( m_showBoomarkOnlyAction->isChecked() );
149 else
151 disconnect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
152 if ( m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem() )
154 m_currentDocumentItem->setIcon( 0, QIcon() );
156 m_currentDocumentItem = itemForUrl( m_document->currentDocument() );
157 if ( m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem() )
159 m_currentDocumentItem->setIcon( 0, KIcon( "bookmarks" ) );
160 m_currentDocumentItem->setExpanded( true );
162 connect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
166 void BookmarkList::slotFilterBookmarks( bool on )
168 rebuildTree( on );
171 void BookmarkList::slotExecuted( QTreeWidgetItem * item )
173 BookmarkItem* bmItem = dynamic_cast<BookmarkItem*>( item );
174 if ( !bmItem || !bmItem->viewport().isValid() )
175 return;
177 goTo( bmItem );
180 void BookmarkList::slotChanged( QTreeWidgetItem * item )
182 BookmarkItem* bmItem = dynamic_cast<BookmarkItem*>( item );
183 if ( !bmItem || !bmItem->viewport().isValid() )
184 return;
186 bmItem->bookmark().setFullText( bmItem->text( 0 ) );
187 m_document->bookmarkManager()->save();
190 void BookmarkList::slotContextMenu( const QPoint& p )
192 QTreeWidgetItem * item = m_tree->itemAt( p );
193 BookmarkItem* bmItem = item ? dynamic_cast<BookmarkItem*>( item ) : 0;
194 if ( !bmItem || !bmItem->viewport().isValid() )
195 return;
197 KMenu menu( this );
198 QAction * gotobm = menu.addAction( i18n( "Go to This Bookmark" ) );
199 QAction * editbm = menu.addAction( KIcon( "edit-rename" ), i18n( "Rename Bookmark" ) );
200 QAction * removebm = menu.addAction( KIcon( "list-remove" ), i18n( "Remove Bookmark" ) );
201 QAction * res = menu.exec( QCursor::pos() );
202 if ( !res )
203 return;
205 if ( res == gotobm )
206 goTo( bmItem );
207 else if ( res == editbm )
208 m_tree->editItem( item, 0 );
209 else if ( res == removebm )
210 m_document->bookmarkManager()->removeBookmark( bmItem->url(), bmItem->bookmark() );
213 void BookmarkList::slotBookmarksChanged( const KUrl& url )
215 // special case here, as m_currentDocumentItem could represent
216 // the invisible root item
217 if ( url == m_document->currentDocument() )
219 selectiveUrlUpdate( m_document->currentDocument(), m_currentDocumentItem );
220 return;
223 // we are showing the bookmarks for the current document only
224 if ( m_showBoomarkOnlyAction->isChecked() )
225 return;
227 QTreeWidgetItem *item = itemForUrl( url );
228 if ( item )
230 selectiveUrlUpdate( url, item );
234 QList<QTreeWidgetItem*> createItems( const KUrl& baseurl, const KBookmark::List& bmlist )
236 (void)baseurl;
237 QList<QTreeWidgetItem*> ret;
238 foreach ( const KBookmark& bm, bmlist )
240 // kDebug().nospace() << "checking '" << tmp << "'";
241 // kDebug().nospace() << " vs '" << baseurl << "'";
242 // TODO check that bm and baseurl are the same (#ref excluded)
243 QTreeWidgetItem * item = new BookmarkItem( bm );
244 ret.append( item );
246 return ret;
249 void BookmarkList::rebuildTree( bool filter )
251 // disconnect and reconnect later, otherwise we'll get many itemChanged()
252 // signals for all the current items
253 disconnect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
255 m_currentDocumentItem = 0;
256 m_tree->clear();
258 KUrl::List urls = m_document->bookmarkManager()->files();
259 if ( filter )
261 if ( m_document->isOpened() )
263 foreach ( const KUrl& url, urls )
265 if ( url == m_document->currentDocument() )
267 m_tree->addTopLevelItems( createItems( url, m_document->bookmarkManager()->bookmarks( url ) ) );
268 m_currentDocumentItem = m_tree->invisibleRootItem();
269 break;
274 else
276 QTreeWidgetItem * currenturlitem = 0;
277 foreach ( const KUrl& url, urls )
279 QList<QTreeWidgetItem*> subitems = createItems( url, m_document->bookmarkManager()->bookmarks( url ) );
280 if ( !subitems.isEmpty() )
282 QTreeWidgetItem * item = new QTreeWidgetItem( m_tree, FileItemType );
283 QString fileString = url.isLocalFile() ? url.path() : url.prettyUrl();
284 item->setText( 0, fileString );
285 item->setToolTip( 0, i18ncp( "%1 is the file name", "%1\n\nOne bookmark", "%1\n\n%2 bookmarks", fileString, subitems.count() ) );
286 item->setData( 0, UrlRole, qVariantFromValue( url ) );
287 item->addChildren( subitems );
288 if ( !currenturlitem && url == m_document->currentDocument() )
290 currenturlitem = item;
294 if ( currenturlitem )
296 currenturlitem->setExpanded( true );
297 currenturlitem->setIcon( 0, KIcon( "bookmarks" ) );
298 m_tree->scrollToItem( currenturlitem, QAbstractItemView::PositionAtTop );
299 m_currentDocumentItem = currenturlitem;
303 connect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
306 void BookmarkList::goTo( BookmarkItem * item )
308 if ( item->url() == m_document->currentDocument() )
310 m_document->setViewport( item->viewport() );
312 else
314 Okular::GotoAction action( item->url().pathOrUrl(), item->viewport() );
315 m_document->processAction( &action );
319 void BookmarkList::selectiveUrlUpdate( const KUrl& url, QTreeWidgetItem*& item )
321 disconnect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
323 const KBookmark::List urlbookmarks = m_document->bookmarkManager()->bookmarks( url );
324 if ( urlbookmarks.isEmpty() )
326 if ( item != m_tree->invisibleRootItem() )
328 m_tree->invisibleRootItem()->removeChild( item );
329 item = 0;
331 else if ( item )
333 for ( int i = item->childCount(); i >= 0; --i )
335 item->removeChild( item->child( i ) );
339 else
341 const QString fileString = url.isLocalFile() ? url.path() : url.prettyUrl();
342 if ( item )
344 for ( int i = item->childCount(); i >= 0; --i )
346 item->removeChild( item->child( i ) );
349 else
351 item = new QTreeWidgetItem( m_tree, FileItemType );
352 item->setIcon( 0, KIcon( "bookmarks" ) );
353 item->setExpanded( true );
354 item->setText( 0, fileString );
356 item->addChildren( createItems( url, urlbookmarks ) );
357 if ( item != m_tree->invisibleRootItem() )
359 item->setToolTip( 0, i18ncp( "%1 is the file name", "%1\n\nOne bookmark", "%1\n\n%2 bookmarks", fileString, item->childCount() ) );
363 connect( m_tree, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, SLOT( slotChanged( QTreeWidgetItem * ) ) );
366 QTreeWidgetItem* BookmarkList::itemForUrl( const KUrl& url ) const
368 const int count = m_tree->topLevelItemCount();
369 for ( int i = 0; i < count; ++i )
371 QTreeWidgetItem *item = m_tree->topLevelItem( i );
372 const KUrl itemurl = item->data( 0, UrlRole ).value< KUrl >();
373 if ( itemurl.isValid() && itemurl == url )
375 return item;
378 return 0;
381 #include "bookmarklist.moc"