toc.cpp 4.96 KB
Newer Older
1
/***************************************************************************
Albert Astals Cid's avatar
Albert Astals Cid committed
2
 *   Copyright (C) 2004-2006 by Albert Astals Cid <tsdgeos@terra.es>       *
3 4 5 6 7 8 9
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

10 11
// qt/kde includes
#include <klocale.h>
12

13
// local includes
14
#include "toc.h"
15
#include "core/document.h"
16
#include "core/page.h"
17
#include "conf/settings.h"
18
#include "core/link.h"
19

20 21 22
// 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.
23
// to enable set TocPageColumn=true in [Nav Panel]
24

Pino Toscano's avatar
porting  
Pino Toscano committed
25
class TOCItem : public K3ListViewItem
26
{
27
    public:
Pino Toscano's avatar
porting  
Pino Toscano committed
28 29
        TOCItem( K3ListView *parent, TOCItem *after, const QDomElement & e )
            : K3ListViewItem( parent, after, e.tagName() ), m_element( e )
30
        {
Piotr Szymanski's avatar
Piotr Szymanski committed
31
            if ( KpdfSettings::tocPageColumn() && e.hasAttribute( "Page" ) )
32
                setText( 1, e.attribute( "Page" ) );
Albert Astals Cid's avatar
Albert Astals Cid committed
33
            setMultiLinesEnabled( true );
34 35
        }

Pino Toscano's avatar
porting  
Pino Toscano committed
36 37
        TOCItem( K3ListViewItem *parent, TOCItem *after, const QDomElement & e )
            : K3ListViewItem( parent, after, e.tagName() ), m_element( e )
38
        {
Piotr Szymanski's avatar
Piotr Szymanski committed
39
            if ( KpdfSettings::tocPageColumn() && e.hasAttribute( "Page" ) )
40
                setText( 1, e.attribute( "Page" ) );
Albert Astals Cid's avatar
Albert Astals Cid committed
41
            setMultiLinesEnabled( true );
42 43 44 45 46 47 48 49 50
        }

        const QDomElement & element() const
        {
            return m_element;
        }

    private:
        QDomElement m_element;
51 52
};

Pino Toscano's avatar
porting  
Pino Toscano committed
53
TOC::TOC(QWidget *parent, KPDFDocument *document) : K3ListView(parent), m_document(document)
54
{
55
    addColumn( i18n("Topic") );
Piotr Szymanski's avatar
Piotr Szymanski committed
56
    if (KpdfSettings::tocPageColumn())
57
    	addColumn( i18n("Page") );
58 59 60
    setSorting(-1);
    setRootIsDecorated(true);
    setResizeMode(AllColumns);
Enrico Ros's avatar
Enrico Ros committed
61
    setAllColumnsShowFocus(true);
Enrico Ros's avatar
Enrico Ros committed
62 63
    connect(this, SIGNAL(clicked(QListViewItem *)), this, SLOT(slotExecuted(QListViewItem *)));
    connect(this, SIGNAL(returnPressed(QListViewItem *)), this, SLOT(slotExecuted(QListViewItem *)));
64 65
}

Albert Astals Cid's avatar
Albert Astals Cid committed
66 67 68 69 70
TOC::~TOC()
{
    m_document->removeObserver( this );
}

Laurent Montel's avatar
Laurent Montel committed
71
uint TOC::observerId() const
72
{
73
    return TOC_ID;
Albert Astals Cid's avatar
Albert Astals Cid committed
74
}
75

Albert Astals Cid's avatar
Albert Astals Cid committed
76
void TOC::notifySetup( const QVector< KPDFPage * > & /*pages*/, bool documentChanged )
Albert Astals Cid's avatar
Albert Astals Cid committed
77
{
Piotr Szymanski's avatar
Piotr Szymanski committed
78
    if ( !documentChanged )
79
        return;
Albert Astals Cid's avatar
Albert Astals Cid committed
80

81
    // clear contents
82
    clear();
83 84

    // request synopsis description (is a dom tree)
85
    const DocumentSynopsis * syn = m_document->documentSynopsis();
86 87 88

    // if not present, disable the contents tab
    if ( !syn )
89
    {
90 91
        emit hasTOC( false );
        return;
92
    }
93

94 95 96 97 98
    // else populate the listview and enable the tab
    addChildren( *syn );
    emit hasTOC( true );
}

Pino Toscano's avatar
porting  
Pino Toscano committed
99
void TOC::addChildren( const QDomNode & parentNode, K3ListViewItem * parentItem )
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
{
    // keep track of the current listViewItem
    TOCItem * currentItem = 0;
    QDomNode n = parentNode.firstChild();
    while( !n.isNull() )
    {
        // convert the node to an element (sure it is)
        QDomElement 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 );
        n = n.nextSibling();
    }
120 121
}

Albert Astals Cid's avatar
Albert Astals Cid committed
122
void TOC::slotExecuted( Q3ListViewItem *i )
123
{
Enrico Ros's avatar
Enrico Ros committed
124 125 126 127 128
    TOCItem* tocItem = dynamic_cast<TOCItem*>( i );
    // that filters clicks on [+] that for a strange reason don't seem to be TOCItem*
    if (tocItem == NULL)
        return;
    const QDomElement & e = tocItem->element();
129 130 131

    QString externalFileName = e.attribute( "ExternalFileName" );
    if ( !externalFileName.isEmpty() )
132
    {
Piotr Szymanski's avatar
Piotr Szymanski committed
133
        KPDFLinkGoto link( externalFileName, getViewport( e ) );
134
        m_document->processLink( &link );
135
    }
136
    else
137
    {
Piotr Szymanski's avatar
Piotr Szymanski committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
        m_document->setViewport( getViewport( e ), TOC_ID );
    }
}

DocumentViewport TOC::getViewport( const QDomElement &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 QString & page = e.attribute( "ViewportName" );
        const QString & viewport = m_document->getMetaData( "NamedViewport", page );
        if ( !viewport.isNull() )
            return DocumentViewport( viewport );
156
    }
Piotr Szymanski's avatar
Piotr Szymanski committed
157
    return DocumentViewport();
158 159 160
}

#include "toc.moc"