Commit d52a07c9 authored by Albert Astals Cid's avatar Albert Astals Cid

Merge remote-tracking branch 'origin/gsoc2015_layer_feature'

parents 558b4bb7 5b62bc71
......@@ -213,6 +213,7 @@ set(okularpart_SRCS
ui/toolaction.cpp
ui/tts.cpp
ui/videowidget.cpp
ui/layers.cpp
)
kde4_add_ui_files(okularpart_SRCS
......
......@@ -26,6 +26,14 @@
<default>false</default>
</entry>
</group>
<group name="Layers" >
<entry key="LayersSearchCaseSensitive" type="Bool">
<default>false</default>
</entry>
<entry key="LayersSearchRegularExpression" type="Bool">
<default>false</default>
</entry>
</group>
<group name="Reviews" >
<entry key="ReviewsSearchCaseSensitive" type="Bool">
<default>false</default>
......
......@@ -3739,6 +3739,15 @@ void Document::editFormButtons( int pageNumber, const QList< FormFieldButton* >&
d->m_undoStack->push( uc );
}
void Document::reloadDocument() const
{
const int numOfPages = pages();
for( int i = currentPage(); i >= 0; i -- )
d->refreshPixmaps( i );
for( int i = currentPage() + 1; i < numOfPages; i ++ )
d->refreshPixmaps( i );
}
BookmarkManager * Document::bookmarkManager() const
{
return d->m_bookmarkManager;
......@@ -4563,6 +4572,11 @@ void Document::walletDataForFile( const QString &fileName, QString *walletName,
}
}
QAbstractItemModel * Document::layersModel() const
{
return d->m_generator ? d->m_generator->layersModel() : NULL;
}
void DocumentPrivate::requestDone( PixmapRequest * req )
{
if ( !req )
......
......@@ -31,6 +31,7 @@ class KConfigDialog;
class KXMLGUIClient;
class KUrl;
class DocumentItem;
class QAbstractItemModel;
namespace Okular {
......@@ -842,6 +843,13 @@ class OKULAR_EXPORT Document : public QObject
*/
void walletDataForFile( const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey ) const;
/**
* Returns the model for rendering layers (NULL if the document has no layers)
*
* @since 0.24
*/
QAbstractItemModel * layersModel() const;
public Q_SLOTS:
/**
* This slot is called whenever the user changes the @p rotation of
......@@ -918,6 +926,13 @@ class OKULAR_EXPORT Document : public QObject
const QList< Okular::FormFieldButton* > & formButtons,
const QList< bool > & newButtonStates );
/**
* Reloads the pixmaps for whole document
*
* @since 0.24
*/
void reloadDocument() const;
Q_SIGNALS:
/**
* This signal is emitted whenever an action requests a
......
......@@ -454,6 +454,11 @@ QSizeF Generator::dpi() const
return d->m_dpi;
}
QAbstractItemModel * Generator::layersModel() const
{
return 0;
}
PixmapRequest::PixmapRequest( DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features )
: d( new PixmapRequestPrivate )
{
......
......@@ -432,6 +432,14 @@ class OKULAR_EXPORT Generator : public QObject
*/
void setDPI(const QSizeF &dpi);
/**
* Returns the 'layers model' object of the document or NULL if
* layers model is not available.
*
* @since 0.24
*/
virtual QAbstractItemModel * layersModel() const;
Q_SIGNALS:
/**
* This signal should be emitted whenever an error occurred in the generator.
......
......@@ -776,6 +776,11 @@ const QList<Okular::EmbeddedFile*> *PDFGenerator::embeddedFiles() const
return &docEmbeddedFiles;
}
QAbstractItemModel* PDFGenerator::layersModel() const
{
return pdfdoc->hasOptionalContent() ? pdfdoc->optionalContentModel() : NULL;
}
bool PDFGenerator::isAllowed( Okular::Permission permission ) const
{
bool b = true;
......
......@@ -67,6 +67,7 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, p
Okular::FontInfo::List fontsForPage( int page );
const QList<Okular::EmbeddedFile*> * embeddedFiles() const;
PageSizeMetric pagesSizeMetric() const { return Pixels; }
QAbstractItemModel * layersModel() const;
// [INHERITED] document information
bool isAllowed( Okular::Permission permission ) const;
......
......@@ -85,6 +85,7 @@
#include "ui/sidebar.h"
#include "ui/fileprinterpreview.h"
#include "ui/guiutils.h"
#include "ui/layers.h"
#include "conf/preferencesdialog.h"
#include "settings.h"
#include "core/action.h"
......@@ -372,13 +373,18 @@ m_cliPresentation(false), m_cliPrint(false), m_embedMode(detectEmbedMode(parentW
// sLabel->setBuddy( m_searchWidget );
// m_searchToolBar->setStretchableWidget( m_searchWidget );
int tbIndex;
// [left toolbox: Table of Contents] | []
m_toc = new TOC( 0, m_document );
connect( m_toc, SIGNAL(hasTOC(bool)), this, SLOT(enableTOC(bool)) );
tbIndex = m_sidebar->addItem( m_toc, KIcon(QApplication::isLeftToRight() ? "format-justify-left" : "format-justify-right"), i18n("Contents") );
m_sidebar->addItem( m_toc, KIcon(QApplication::isLeftToRight() ? "format-justify-left" : "format-justify-right"), i18n("Contents") );
enableTOC( false );
// [left toolbox: Layers] | []
m_layers = new Layers( 0, m_document );
connect( m_layers, SIGNAL(hasLayers(bool)), this, SLOT(enableLayers(bool)) );
m_sidebar->addItem( m_layers, KIcon( "draw-freehand" ), i18n( "Layers" ) );
enableLayers( false );
// [left toolbox: Thumbnails and Bookmarks] | []
KVBox * thumbsBox = new ThumbnailsBox( 0 );
thumbsBox->setSpacing( 6 );
......@@ -386,18 +392,19 @@ m_cliPresentation(false), m_cliPrint(false), m_embedMode(detectEmbedMode(parentW
m_thumbnailList = new ThumbnailList( thumbsBox, m_document );
// ThumbnailController * m_tc = new ThumbnailController( thumbsBox, m_thumbnailList );
connect( m_thumbnailList, SIGNAL(rightClick(const Okular::Page*,QPoint)), this, SLOT(slotShowMenu(const Okular::Page*,QPoint)) );
tbIndex = m_sidebar->addItem( thumbsBox, KIcon( "view-preview" ), i18n("Thumbnails") );
m_sidebar->setCurrentIndex( tbIndex );
m_sidebar->addItem( thumbsBox, KIcon( "view-preview" ), i18n("Thumbnails") );
m_sidebar->setCurrentItem( thumbsBox );
// [left toolbox: Reviews] | []
m_reviewsWidget = new Reviews( 0, m_document );
m_sidebar->addItem( m_reviewsWidget, KIcon("draw-freehand"), i18n("Reviews") );
m_sidebar->setItemEnabled( 2, false );
m_sidebar->setItemEnabled( m_reviewsWidget, false );
// [left toolbox: Bookmarks] | []
m_bookmarkList = new BookmarkList( m_document, 0 );
m_sidebar->addItem( m_bookmarkList, KIcon("bookmarks"), i18n("Bookmarks") );
m_sidebar->setItemEnabled( 3, false );
m_sidebar->setItemEnabled( m_bookmarkList, false );
// widgets: [../miniBarContainer] | []
#ifdef OKULAR_ENABLE_MINIBAR
......@@ -457,6 +464,7 @@ m_cliPresentation(false), m_cliPrint(false), m_embedMode(detectEmbedMode(parentW
connect( m_document, SIGNAL(sourceReferenceActivated(const QString&,int,int,bool*)), this, SLOT(slotHandleActivatedSourceReference(const QString&,int,int,bool*)) );
connect( m_pageView, SIGNAL(fitWindowToPage(QSize,QSize)), this, SIGNAL(fitWindowToPage(QSize,QSize)) );
rightLayout->addWidget( m_pageView );
m_layers->setPageView( m_pageView );
m_findBar = new FindBar( m_document, rightContainer );
rightLayout->addWidget( m_findBar );
m_bottomBar = new QWidget( rightContainer );
......@@ -854,6 +862,7 @@ Part::~Part()
Part::closeUrl( false );
delete m_toc;
delete m_layers;
delete m_pageView;
delete m_thumbnailList;
delete m_miniBar;
......@@ -1452,9 +1461,9 @@ bool Part::openFile()
}
// if the 'OpenTOC' flag is set, open the TOC
if ( m_document->metaData( "OpenTOC" ).toBool() && m_sidebar->isItemEnabled( 0 ) && !m_sidebar->isCollapsed() && m_sidebar->currentIndex() != 0 )
if ( m_document->metaData( "OpenTOC" ).toBool() && m_sidebar->isItemEnabled( m_toc ) && !m_sidebar->isCollapsed() && m_sidebar->currentItem() != m_toc )
{
m_sidebar->setCurrentIndex( 0, Sidebar::DoNotUncollapseIfCollapsed );
m_sidebar->setCurrentItem( m_toc, Sidebar::DoNotUncollapseIfCollapsed );
}
// if the 'StartFullScreen' flag is set, or the command line flag was
// specified, start presentation
......@@ -1734,7 +1743,7 @@ void Part::slotDoFileDirty()
m_viewportDirty = m_document->viewport();
// store the current toolbox pane
m_dirtyToolboxIndex = m_sidebar->currentIndex();
m_dirtyToolboxItem = m_sidebar->currentItem();
m_wasSidebarVisible = m_sidebar->isSidebarVisible();
m_wasSidebarCollapsed = m_sidebar->isCollapsed();
......@@ -1780,10 +1789,10 @@ void Part::slotDoFileDirty()
m_oldUrl = KUrl();
m_viewportDirty.pageNumber = -1;
m_document->setRotation( m_dirtyPageRotation );
if ( m_sidebar->currentIndex() != m_dirtyToolboxIndex && m_sidebar->isItemEnabled( m_dirtyToolboxIndex )
if ( m_sidebar->currentItem() != m_dirtyToolboxItem && m_sidebar->isItemEnabled( m_dirtyToolboxItem )
&& !m_sidebar->isCollapsed() )
{
m_sidebar->setCurrentIndex( m_dirtyToolboxIndex );
m_sidebar->setCurrentItem( m_dirtyToolboxItem );
}
if ( m_sidebar->isSidebarVisible() != m_wasSidebarVisible )
{
......@@ -1921,12 +1930,12 @@ void Part::updateBookmarksActions()
void Part::enableTOC(bool enable)
{
m_sidebar->setItemEnabled(0, enable);
m_sidebar->setItemEnabled(m_toc, enable);
// If present, show the TOC when a document is opened
if ( enable && m_sidebar->currentIndex() != 0 )
if ( enable && m_sidebar->currentItem() != m_toc )
{
m_sidebar->setCurrentIndex( 0, Sidebar::DoNotUncollapseIfCollapsed );
m_sidebar->setCurrentItem( m_toc, Sidebar::DoNotUncollapseIfCollapsed );
}
}
......@@ -1935,6 +1944,11 @@ void Part::slotRebuildBookmarkMenu()
rebuildBookmarkMenu();
}
void Part::enableLayers(bool enable)
{
m_sidebar->setItemVisible( m_layers, enable );
}
void Part::slotShowFindBar()
{
m_findBar->show();
......@@ -2362,7 +2376,7 @@ void Part::slotNewConfig()
m_document->reparseConfig();
// update TOC settings
if ( m_sidebar->isItemEnabled(0) )
if ( m_sidebar->isItemEnabled(m_toc) )
m_toc->reparseConfig();
// update ThumbnailList contents
......@@ -2370,7 +2384,7 @@ void Part::slotNewConfig()
m_thumbnailList->updateWidgets();
// update Reviews settings
if ( m_sidebar->isItemEnabled(2) )
if ( m_sidebar->isItemEnabled(m_reviewsWidget) )
m_reviewsWidget->reparseConfig();
setWindowTitleFromDocument ();
......@@ -2818,8 +2832,8 @@ void Part::unsetDummyMode()
if ( m_embedMode == PrintPreviewMode )
return;
m_sidebar->setItemEnabled( 2, true );
m_sidebar->setItemEnabled( 3, true );
m_sidebar->setItemEnabled( m_reviewsWidget, true );
m_sidebar->setItemEnabled( m_bookmarkList, true );
m_sidebar->setSidebarVisibility( Okular::Settings::showLeftPanel() );
// add back and next in history
......
......@@ -64,6 +64,7 @@ class MiniBarLogic;
class FileKeeper;
class Reviews;
class BookmarkList;
class Layers;
namespace Okular
{
......@@ -219,6 +220,7 @@ class OKULAR_PART_EXPORT Part : public KParts::ReadWritePart, public Okular::Doc
void updateBookmarksActions();
void enableTOC(bool enable);
void slotRebuildBookmarkMenu();
void enableLayers( bool enable );
public slots:
// connected to Shell action (and browserExtension), not local one
......@@ -278,6 +280,7 @@ class OKULAR_PART_EXPORT Part : public KParts::ReadWritePart, public Okular::Doc
QPointer<PageSizeLabel> m_pageSizeLabel;
QPointer<Reviews> m_reviewsWidget;
QPointer<BookmarkList> m_bookmarkList;
QPointer<Layers> m_layers;
// document watcher (and reloader) variables
KDirWatch *m_watcher;
......@@ -285,7 +288,7 @@ class OKULAR_PART_EXPORT Part : public KParts::ReadWritePart, public Okular::Doc
KUrl m_oldUrl;
Okular::DocumentViewport m_viewportDirty;
bool m_wasPresentationOpen;
int m_dirtyToolboxIndex;
QWidget *m_dirtyToolboxItem;
bool m_wasSidebarVisible;
bool m_wasSidebarCollapsed;
bool m_fileWasRemoved;
......
......@@ -267,9 +267,6 @@ void FormWidgetIface::moveTo( int x, int y )
bool FormWidgetIface::setVisibility( bool visible )
{
if ( !m_ff->isVisible() )
return false;
bool hadfocus = m_widget->hasFocus();
if ( hadfocus )
m_widget->clearFocus();
......
......@@ -43,34 +43,27 @@ class KTreeViewSearchLine::Private
public:
Private( KTreeViewSearchLine *_parent )
: parent( _parent ),
treeView( 0 ),
caseSensitive( Qt::CaseInsensitive ),
regularExpression( false ),
activeSearch( false ),
keepParentsVisible( true ),
canChooseColumns( true ),
queuedSearches( 0 )
{
}
KTreeViewSearchLine *parent;
QList<QTreeView *> treeViews;
QTreeView * treeView;
Qt::CaseSensitivity caseSensitive;
bool regularExpression;
bool activeSearch;
bool keepParentsVisible;
bool canChooseColumns;
QString search;
int queuedSearches;
QList<int> searchColumns;
void rowsInserted(const QModelIndex & parent, int start, int end) const;
void treeViewDeleted( QObject *treeView );
void slotColumnActivated(QAction* action);
void slotAllVisibleColumns();
void slotCaseSensitive();
void slotRegularExpression();
void checkColumns();
void checkItemParentsNotVisible(QTreeView *treeView);
bool checkItemParentsVisible(QTreeView *treeView, const QModelIndex &index);
};
......@@ -86,11 +79,9 @@ void KTreeViewSearchLine::Private::rowsInserted( const QModelIndex & parentIndex
return;
QTreeView* widget = 0L;
foreach ( QTreeView* tree, treeViews )
if ( tree->model() == model ) {
widget = tree;
break;
}
if ( treeView->model() == model ) {
widget = treeView;
}
if ( !widget )
return;
......@@ -102,57 +93,10 @@ void KTreeViewSearchLine::Private::rowsInserted( const QModelIndex & parentIndex
void KTreeViewSearchLine::Private::treeViewDeleted( QObject *object )
{
treeViews.removeAll( static_cast<QTreeView *>( object ) );
parent->setEnabled( treeViews.isEmpty() );
}
void KTreeViewSearchLine::Private::slotColumnActivated( QAction *action )
{
if ( !action )
return;
bool ok;
int column = action->data().toInt( &ok );
if ( !ok )
return;
if ( action->isChecked() ) {
if ( !searchColumns.isEmpty() ) {
if ( !searchColumns.contains( column ) )
searchColumns.append( column );
if ( searchColumns.count() == treeViews.first()->header()->count() - treeViews.first()->header()->hiddenSectionCount() )
searchColumns.clear();
} else {
searchColumns.append( column );
}
} else {
if ( searchColumns.isEmpty() ) {
QHeaderView* const header = treeViews.first()->header();
for ( int i = 0; i < header->count(); i++ ) {
if ( i != column && !header->isSectionHidden( i ) )
searchColumns.append( i );
}
} else if ( searchColumns.contains( column ) ) {
searchColumns.removeAll( column );
}
if ( object == treeView ) {
treeView = 0;
parent->setEnabled( false );
}
parent->updateSearch();
}
void KTreeViewSearchLine::Private::slotAllVisibleColumns()
{
if ( searchColumns.isEmpty() )
searchColumns.append( 0 );
else
searchColumns.clear();
parent->updateSearch();
}
void KTreeViewSearchLine::Private::slotCaseSensitive()
......@@ -180,24 +124,6 @@ void KTreeViewSearchLine::Private::slotRegularExpression()
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::Private::checkColumns()
{
canChooseColumns = parent->canChooseColumnsCheck();
}
void KTreeViewSearchLine::Private::checkItemParentsNotVisible( QTreeView *treeView )
{
// TODO: PORT ME
#if 0
QTreeWidgetItemIterator it( treeWidget );
for ( ; *it; ++it ) {
QTreeWidgetItem *item = *it;
item->treeWidget()->setItemHidden( item, !parent->itemMatches( item, search ) );
}
#endif
}
#include <kvbox.h>
/** Check whether \p item, its siblings and their descendents should be shown. Show or hide the items as necessary.
......@@ -245,17 +171,6 @@ KTreeViewSearchLine::KTreeViewSearchLine( QWidget *parent, QTreeView *treeView )
}
}
KTreeViewSearchLine::KTreeViewSearchLine( QWidget *parent,
const QList<QTreeView *> &treeViews )
: KLineEdit( parent ), d( new Private( this ) )
{
connect( this, SIGNAL(textChanged(QString)),
this, SLOT(queueSearch(QString)) );
setClearButtonShown( true );
setTreeViews( treeViews );
}
KTreeViewSearchLine::~KTreeViewSearchLine()
{
delete d;
......@@ -271,30 +186,9 @@ bool KTreeViewSearchLine::regularExpression() const
return d->regularExpression;
}
QList<int> KTreeViewSearchLine::searchColumns() const
{
if ( d->canChooseColumns )
return d->searchColumns;
else
return QList<int>();
}
bool KTreeViewSearchLine::keepParentsVisible() const
{
return d->keepParentsVisible;
}
QTreeView *KTreeViewSearchLine::treeView() const
{
if ( d->treeViews.count() == 1 )
return d->treeViews.first();
else
return 0;
}
QList<QTreeView *> KTreeViewSearchLine::treeViews() const
{
return d->treeViews;
return d->treeView;
}
......@@ -302,40 +196,11 @@ QList<QTreeView *> KTreeViewSearchLine::treeViews() const
// public slots
////////////////////////////////////////////////////////////////////////////////
void KTreeViewSearchLine::addTreeView( QTreeView *treeView )
{
if ( treeView ) {
connectTreeView( treeView );
d->treeViews.append( treeView );
setEnabled( !d->treeViews.isEmpty() );
d->checkColumns();
}
}
void KTreeViewSearchLine::removeTreeView( QTreeView *treeView )
{
if ( treeView ) {
int index = d->treeViews.indexOf( treeView );
if ( index != -1 ) {
d->treeViews.removeAt( index );
d->checkColumns();
disconnectTreeView( treeView );
setEnabled( !d->treeViews.isEmpty() );
}
}
}
void KTreeViewSearchLine::updateSearch( const QString &pattern )
{
d->search = pattern.isNull() ? text() : pattern;
foreach ( QTreeView* treeView, d->treeViews )
updateSearch( treeView );
updateSearch( d->treeView );
}
void KTreeViewSearchLine::updateSearch( QTreeView *treeView )
......@@ -351,11 +216,8 @@ void KTreeViewSearchLine::updateSearch( QTreeView *treeView )
bool wasUpdateEnabled = treeView->updatesEnabled();
treeView->setUpdatesEnabled( false );
if ( d->keepParentsVisible )
for ( int i = 0; i < treeView->model()->rowCount(); ++i )
d->checkItemParentsVisible( treeView, treeView->rootIndex() );
else
d->checkItemParentsNotVisible( treeView );
for ( int i = 0; i < treeView->model()->rowCount(); ++i )
d->checkItemParentsVisible( treeView, treeView->rootIndex() );
treeView->setUpdatesEnabled( wasUpdateEnabled );
if ( currentIndex.isValid() )
......@@ -380,51 +242,25 @@ void KTreeViewSearchLine::setRegularExpression( bool value )
}
}
void KTreeViewSearchLine::setKeepParentsVisible( bool visible )
{
if ( d->keepParentsVisible != visible ) {
d->keepParentsVisible = visible;
updateSearch();
}
}
void KTreeViewSearchLine::setSearchColumns( const QList<int> &columns )
{
if ( d->canChooseColumns )
d->searchColumns = columns;
}
void KTreeViewSearchLine::setTreeView( QTreeView *treeView )
{
setTreeViews( QList<QTreeView *>() );
addTreeView( treeView );
}
void KTreeViewSearchLine::setTreeViews( const QList<QTreeView *> &treeViews )
{
foreach ( QTreeView* treeView, d->treeViews )
disconnectTreeView( treeView );
d->treeViews = treeViews;
foreach ( QTreeView* treeView, d->treeViews )
connectTreeView( treeView );
d->checkColumns();
disconnectTreeView( d->treeView );
d->treeView = treeView;
connectTreeView( treeView );
setEnabled( !d->treeViews.isEmpty() );
setEnabled( treeView != NULL );
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////