/*************************************************************************** * 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. * ***************************************************************************/ // qt/kde includes #include #include #include // local includes #include "toc.h" #include "core/link.h" #include "core/page.h" // uncomment following to enable a 2nd column showing the page referred // by each tree entry note: PDF uses often references to viewports and // they're slow when converted to page number. drop the 2nd column idea. //#define TOC_ENABLE_PAGE_COLUMN class TOCItem : public KListViewItem { public: TOCItem( KListView *parent, TOCItem *after, const TQDomElement & e ) : KListViewItem( parent, after, e.tagName() ), m_element( e ) { #ifdef TOC_ENABLE_PAGE_COLUMN if ( e.hasAttribute( "Page" ) ) setText( 1, e.attribute( "Page" ) ); #endif setMultiLinesEnabled(true); } TOCItem( KListViewItem *parent, TOCItem *after, const TQDomElement & e ) : KListViewItem( parent, after, e.tagName() ), m_element( e ) { #ifdef TOC_ENABLE_PAGE_COLUMN if ( e.hasAttribute( "Page" ) ) setText( 1, e.attribute( "Page" ) ); #endif setMultiLinesEnabled(true); } const TQDomElement & element() const { return m_element; } private: TQDomElement m_element; }; TOC::TOC(TQWidget *parent, KPDFDocument *document) : KListView(parent), m_document(document) { addColumn( i18n("Topic") ); #ifdef TOC_ENABLE_PAGE_COLUMN addColumn( i18n("Page") ); #else header() -> hide(); #endif setSorting(-1); setRootIsDecorated(true); // the next line causes bug:147233 // setResizeMode(AllColumns); setAllColumnsShowFocus(true); connect(this, TQT_SIGNAL(clicked(TQListViewItem *)), this, TQT_SLOT(slotExecuted(TQListViewItem *))); connect(this, TQT_SIGNAL(returnPressed(TQListViewItem *)), this, TQT_SLOT(slotExecuted(TQListViewItem *))); } TOC::~TOC() { m_document->removeObserver( this ); } uint TOC::observerId() const { return TOC_ID; } void TOC::notifySetup( const TQValueVector< KPDFPage * > & /*pages*/, bool documentChanged ) { if ( !documentChanged ) return; // clear contents clear(); // request synopsis description (is a dom tree) const DocumentSynopsis * syn = m_document->documentSynopsis(); // if not present, disable the contents tab if ( !syn ) { emit hasTOC( false ); return; } // else populate the listview and enable the tab addChildren( *syn ); emit hasTOC( true ); } void TOC::addChildren( const TQDomNode & parentNode, KListViewItem * parentItem ) { // keep track of the current listViewItem TOCItem * currentItem = 0; TQDomNode n = parentNode.firstChild(); while( !n.isNull() ) { // convert the node to an element (sure it is) TQDomElement e = n.toElement(); // insert the entry as top level (listview parented) or 2nd+ level if ( !parentItem ) currentItem = new TOCItem( this, currentItem, e ); else currentItem = new TOCItem( parentItem, currentItem, e ); // descend recursively and advance to the next node if ( e.hasChildNodes() ) addChildren( n, currentItem ); // open/keep close the item bool isOpen = false; if ( e.hasAttribute( "Open" ) ) isOpen = TQVariant( e.attribute( "Open" ) ).toBool(); currentItem->setOpen( isOpen ); n = n.nextSibling(); } } void TOC::slotExecuted( TQListViewItem *i ) { TOCItem* tocItem = dynamic_cast( i ); // that filters clicks on [+] that for a strange reason don't seem to be TOCItem* if (tocItem == NULL) return; const TQDomElement & e = tocItem->element(); TQString externalFileName = e.attribute( "ExternalFileName" ); if ( !externalFileName.isEmpty() ) { KPDFLinkGoto link( externalFileName, getViewport( e ) ); m_document->processLink( &link ); } else { m_document->setViewport( getViewport( e ), TOC_ID ); } } DocumentViewport TOC::getViewport( const TQDomElement &e ) const { if ( e.hasAttribute( "Viewport" ) ) { // if the node has a viewport, set it return DocumentViewport( e.attribute( "Viewport" ) ); } else if ( e.hasAttribute( "ViewportName" ) ) { // if the node references a viewport, get the reference and set it const TQString & page = e.attribute( "ViewportName" ); const TQString & viewport = m_document->getMetaData( "NamedViewport", page ); if ( !viewport.isNull() ) return DocumentViewport( viewport ); } return DocumentViewport(); } #include "toc.moc"