[Okular-devel] [PATCH] Re: how to invoke okular with inverse search with pdf?

Jochen Trumpf Jochen.Trumpf at anu.edu.au
Fri Dec 25 02:08:46 CET 2009


On Thursday 24 December 2009 09:08:52 Albert Astals Cid wrote:
> A Dimecres 26 Agost 2009 09:14:37, Oliver Heins va escriure:
> > Hello Jochen,
> >
> > thank you very much for the help.  Forward Search now works with okular,
> > within the limitations of the two bugs.
> 
> Hi dudes, how did this issue end up, is it solved or still needs some work?

Well, the patch I proposed works for me and also seems to work for Oliver. 
Maybe someone with karma (Albert?) could commit it so it gets wider exposure? 
I just tried a couple of minutes ago and the patch still applies to current 
trunk. I copy it below for your convenience. It introduces a new method, so 
maybe you want to check if the naming scheme is okay etc.

Cheers,
Jochen

--- generators/poppler/generator_pdf.h.old	2009-08-24 11:05:46.000000000 +1000
+++ generators/poppler/generator_pdf.h	2009-08-24 12:14:23.000000000 +1000
@@ -129,6 +129,8 @@
         void loadPdfSync( const QString & fileName, QVector<Okular::Page*> & 
pagesVector );
         // init the synctex parser if a synctex file exists
         void initSynctexParser( const QString& filePath );
+	// search document for source reference
+	void fillViewportFromSourceReference( Okular::DocumentViewport &viewport, 
const QString &reference ) const;
 
         Okular::TextPage * abstractTextPage(const QList<Poppler::TextBox*> 
&text, double height, double width, int rot);
 
--- generators/poppler/generator_pdf.cpp.old	2009-08-24 10:12:49.000000000 
+1000
+++ generators/poppler/generator_pdf.cpp	2009-08-24 17:19:37.000000000 +1000
@@ -958,17 +958,27 @@
     }
     else if ( key == "NamedViewport" && !option.toString().isEmpty() )
     {
-        // asking for the page related to a 'named link destination'. the
-        // option is the link name. @see addSynopsisChildren.
         Okular::DocumentViewport viewport;
-        userMutex()->lock();
-        Poppler::LinkDestination *ld = pdfdoc->linkDestination( 
option.toString() );
-        userMutex()->unlock();
-        if ( ld )
-        {
-            fillViewportFromLinkDestination( viewport, *ld );
-        }
-        delete ld;
+
+	// if option starts with "src:" assume that we are handling a 
+	// source reference
+	if (option.toString().indexOf("src:", 0, Qt::CaseInsensitive) == 0)
+	{
+	    fillViewportFromSourceReference( viewport, option.toString() );
+	} 
+	else
+	{
+	    // asking for the page related to a 'named link destination'. the
+	    // option is the link name. @see addSynopsisChildren.
+	    userMutex()->lock();
+	    Poppler::LinkDestination *ld = pdfdoc->linkDestination( 
option.toString() );
+	    userMutex()->unlock();
+	    if ( ld )
+	    {
+	        fillViewportFromLinkDestination( viewport, *ld );
+	    }
+	    delete ld;
+	}
         if ( viewport.pageNumber >= 0 )
             return viewport.toString();
     }
@@ -1484,6 +1494,57 @@
     return 0;
 }
 
+void PDFGenerator::fillViewportFromSourceReference( Okular::DocumentViewport 
&viewport, const QString &reference ) const
+{
+    if  ( !synctex_scanner )
+        return;
+
+    // The reference is of form "src:1111Filename", where "1111"
+    // points to line number 1111 in the file "Filename".
+    // Extract the file name and the numeral part from the reference string.
+    // This will fail if Filename starts with a digit.
+    QString name, line;
+    // Remove "src:". Presence of substring has been checked before this 
+    // function is called.
+    name = reference.mid(4);
+    // split
+    quint32 max = name.length();
+    quint32 i = 0;
+    for(i=0; i<max; ++i) if ( !name[i].isDigit()) break;
+    line = name.left(i);
+    name = name.mid(i);
+    // Remove spaces.
+    name = name.trimmed();
+    line = line.trimmed();
+    // Convert line to integer. 
+    bool ok;
+    int m_line = line.toInt(&ok);
+    if (!ok) m_line = -1;
+    
+    // Use column == -1 for now.
+    if( synctex_display_query( synctex_scanner, name.toLatin1(), m_line, -1 ) 
> 0 )
+    {
+        synctex_node_t node;
+	// For now use the first hit. Could possibly be made smarter
+	// in case there are multiple hits.
+        while( (node = synctex_next_result(synctex_scanner)) ) 
+	{
+	    // TeX pages start at 1.
+	    viewport.pageNumber = synctex_node_page( node ) - 1;
+
+	    if (!viewport.isValid()) return;
+
+	    // TeX small points ...
+	    viewport.rePos.normalizedX = (synctex_node_h( node ) * dpiX) / (72.27 * 
65536.0 * document()->page(viewport.pageNumber)->width());
+	    viewport.rePos.normalizedY = (synctex_node_v( node ) * dpiY) / (72.27 * 
65536.0 * document()->page(viewport.pageNumber)->height());
+	    viewport.rePos.enabled = true;
+	    viewport.rePos.pos = Okular::DocumentViewport::TopLeft;
+	    
+	    return;
+        }
+    }
+}
+
 QWidget* PDFGenerator::printConfigurationWidget() const
 {
     if ( !pdfOptionsPage )


More information about the Okular-devel mailing list