/*************************************************************************** * Copyright (C) 2004-2006 by Albert Astals Cid * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "toc.h" // qt/kde includes #include #include #include #include #include #include // local includes #include "ktreeviewsearchline.h" #include "pageitemdelegate.h" #include "tocmodel.h" #include "core/action.h" #include "core/document.h" #include "settings.h" TOC::TOC(QWidget *parent, Okular::Document *document) : QWidget(parent), m_document(document) { QVBoxLayout *mainlay = new QVBoxLayout( this ); mainlay->setMargin( 0 ); mainlay->setSpacing( 6 ); m_searchLine = new KTreeViewSearchLine( this ); mainlay->addWidget( m_searchLine ); m_searchLine->setCaseSensitivity( Okular::Settings::self()->contentsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive ); m_searchLine->setRegularExpression( Okular::Settings::self()->contentsSearchRegularExpression() ); connect(m_searchLine, &KTreeViewSearchLine::searchOptionsChanged, this, &TOC::saveSearchOptions); m_treeView = new QTreeView( this ); mainlay->addWidget( m_treeView ); m_model = new TOCModel( document, m_treeView ); m_treeView->setModel( m_model ); m_treeView->setSortingEnabled( false ); m_treeView->setRootIsDecorated( true ); m_treeView->setAlternatingRowColors( true ); m_treeView->setItemDelegate( new PageItemDelegate( m_treeView ) ); m_treeView->header()->hide(); m_treeView->setSelectionBehavior( QAbstractItemView::SelectRows ); connect(m_treeView, &QTreeView::clicked, this, &TOC::slotExecuted); connect(m_treeView, &QTreeView::activated, this, &TOC::slotExecuted); m_searchLine->setTreeView( m_treeView ); } TOC::~TOC() { m_document->removeObserver( this ); } void TOC::notifySetup( const QVector< Okular::Page * > & /*pages*/, int setupFlags ) { if ( !( setupFlags & Okular::DocumentObserver::DocumentChanged ) ) return; // clear contents m_model->clear(); // request synopsis description (is a dom tree) const Okular::DocumentSynopsis * syn = m_document->documentSynopsis(); if ( !syn ) { if ( m_document->isOpened() ) { // Make sure we clear the reload old model data m_model->setOldModelData( nullptr, QVector() ); } emit hasTOC( false ); return; } m_model->fill( syn ); emit hasTOC( !m_model->isEmpty() ); } void TOC::notifyCurrentPageChanged( int, int ) { m_model->setCurrentViewport( m_document->viewport() ); } void TOC::prepareForReload() { if( m_model->isEmpty() ) return; const QVector list = expandedNodes(); TOCModel *m = m_model; m_model = new TOCModel( m_document, m_treeView ); m_model->setOldModelData( m, list ); m->setParent( nullptr ); } void TOC::rollbackReload() { if( !m_model->hasOldModelData() ) return; TOCModel *m = m_model; m_model = m->clearOldModelData(); m_model->setParent( m_treeView ); delete m; } void TOC::finishReload() { m_treeView->setModel( m_model ); m_model->setParent( m_treeView ); } QVector TOC::expandedNodes( const QModelIndex &parent ) const { QVector list; for ( int i = 0; i < m_model->rowCount( parent ); i++ ) { const QModelIndex index = m_model->index( i, 0, parent ); if ( m_treeView->isExpanded( index ) ) { list << index; } if ( m_model->hasChildren( index ) ) { list << expandedNodes( index ); } } return list; } void TOC::reparseConfig() { m_searchLine->setCaseSensitivity( Okular::Settings::contentsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive ); m_searchLine->setRegularExpression( Okular::Settings::contentsSearchRegularExpression() ); m_treeView->update(); } void TOC::slotExecuted( const QModelIndex &index ) { if ( !index.isValid() ) return; QString url = m_model->urlForIndex( index ); if ( !url.isEmpty() ) { Okular::BrowseAction action( QUrl::fromLocalFile( url ) ); m_document->processAction( &action ); return; } QString externalFileName = m_model->externalFileNameForIndex( index ); Okular::DocumentViewport viewport = m_model->viewportForIndex( index ); if ( !externalFileName.isEmpty() ) { Okular::GotoAction action( externalFileName, viewport ); m_document->processAction( &action ); } else if ( viewport.isValid() ) { m_document->setViewport( viewport ); } } void TOC::saveSearchOptions() { Okular::Settings::setContentsSearchRegularExpression( m_searchLine->regularExpression() ); Okular::Settings::setContentsSearchCaseSensitive( m_searchLine->caseSensitivity() == Qt::CaseSensitive ? true : false ); Okular::Settings::self()->save(); } void TOC::contextMenuEvent(QContextMenuEvent* e) { QModelIndex index = m_treeView->currentIndex(); if (!index.isValid()) return; Okular::DocumentViewport viewport = m_model->viewportForIndex(index); emit rightClick(viewport, e->globalPos(), m_model->data(index).toString()); } void TOC::expandRecursively() { QList worklist = { m_treeView->currentIndex() }; if ( !worklist[0].isValid() ) { return; } while ( !worklist.isEmpty() ) { QModelIndex index = worklist.takeLast(); m_treeView->expand( index ); for ( int i = 0; i < m_model->rowCount(index); i++ ) { worklist += m_model->index( i, 0, index ); } } } void TOC::collapseRecursively() { QList worklist = { m_treeView->currentIndex() }; if ( !worklist[0].isValid() ) { return; } while ( !worklist.isEmpty() ) { QModelIndex index = worklist.takeLast(); m_treeView->collapse( index ); for ( int i = 0; i < m_model->rowCount(index); i++ ) { worklist += m_model->index( i, 0, index ); } } } void TOC::expandAll() { m_treeView->expandAll(); } void TOC::collapseAll() { m_treeView->collapseAll(); } #include "moc_toc.cpp"