Commit 34b8e283 authored by Piotr Szymanski's avatar Piotr Szymanski

- Page/Link: tooltips for links backported

- Page: rotation does not switch height and width
- Document/Part/Generator:
  1. Add API for attaching stuff to the interface: ActionCollection and the Navigation Panel
     also add possibility to merge an XML .rc file with menu layout. Relevant functions are:

     QString Generator::getXMLFile(), returns a QString with your .rc file name.
     void  Generator::setupGUI (KActionCollection* , QToolbox* ), add your components to the user interface

  2. Supporting backend settings:
     If during startup, backends which provide a configuration ([X-KDE-oKularHasInternalSettings]
     set to true) are found, a menu item: configure backends is created, clicking on it results in
     loading all the generators that have settings, but not those that dont. the Generator::addPages(KConfigDialog *dlg)
     function should be overloaded by a generator and dlg->addPage should be used to add pages.

     If a user opens a file that needs an already loaded generator, the already loaded one is used instead of loading another.

  3. Error/Warning/Notice sending support, to send a notice/error/warning, add a relevant notice/error/warning(QString& txt ,int duration)
     to the generator class, and sending a message to the user is as simple as emitting a signal!

  4. Intercepting of events generated by the PageView is done by Generator::handleEvent(QEvent*), subclass it, do a switch on QEvent::type(), handle your
     event and return true if pageview is to proceed with its handling or false if not.

  5. Support configuring the KPrinter on the generator side, use Generator::canConfigurePrinter(), return true there, and you get a nonconfigured KPrinter in your
     Generator::print()

  6. PixmapRequest handling update:
     a.) Generator::canGeneratePixmap is now Generator::canGeneratePixmap(bool async)
     b.) Document::sendGeneratorRequests is a slot now
     c.) Old way of sending pixmaps (Document::requestPixmaps(QValueList<PixmapRequest*> checking if we can generate pixmap if not, waiting for receiving)
         is replaced with: requestPixmaps only queues the pixmap all checking if w can generate is done in sendGeneratorReqest, the sendGeneratorRequest is
         run in three places:
         1.  in requestPixmaps when we receive a request
         2.  in requestDone if pixmapStack is not empty
         3.  sendGeneratorRequest, apart from removing invalid requests, takes the current request and if generator canGeratePixmap(request->async)
        it removes the pixmap from stack and sends to generator if not, QTimer::singleshots to itself after 20ms, it ends when stack has no valid pixmap request

  7. Added a commented out zoom field to PixmapGenerator, mightcome in handy sometime

- TextPage: add instructions that handle simplyfing the RegularAreaRect, no more double painted borders in selection rectangles, this rocks.


svn path=/trunk/playground/graphics/oKular/kpdf/; revision=445196
parent bb7a9f73
SUBDIRS = conf core ui shell generators
INCLUDES = -I$(srcdir)/xpdf -I$(srcdir)/xpdf/goo -I$(top_builddir)/kpdf $(all_includes) $(FREETYPE_CFLAGS)
INCLUDES = -I$(top_builddir)/kpdf $(all_includes) $(FREETYPE_CFLAGS)
METASOURCES = AUTO
......@@ -17,7 +17,7 @@ kde_module_LTLIBRARIES = libkpdfpart.la
libkpdfpart_la_SOURCES = dcop.skel part.cpp
libkpdfpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
libkpdfpart_la_LIBADD = xpdf/xpdf/libxpdf.la conf/libkpdfconf.la core/libkpdfcore.la \
libkpdfpart_la_LIBADD = conf/libkpdfconf.la core/libkpdfcore.la \
ui/libkpdfui.la ui/painter_agg2/libagg2.la $(LIB_KPARTS) \
$(LIB_KFILE) $(LIB_KDEPRINT) $(LIB_KUTILS) $(LIB_KNEWSTUFF) \
$(LIB_KHTML) -lm
......
......@@ -4,7 +4,7 @@ INCLUDES = -I$(srcdir)/.. -I$(top_builddir)/kpdf $(all_includes)
METASOURCES = AUTO
libkpdfcore_la_SOURCES = area.cpp textpage.cpp page.cpp document.cpp link.cpp annotations.cpp \
libkpdfcore_la_SOURCES = chooseenginedialog.ui area.cpp textpage.cpp page.cpp document.cpp link.cpp annotations.cpp \
pagetransition.cpp
libkpdfcore_la_LIBADD = -lkio
......
......@@ -69,8 +69,6 @@ QRect NormalizedRect::geometry( int xScale, int yScale ) const
return QRect( l, t, r - l + 1, b - t + 1 );
}
HighlightAreaRect::HighlightAreaRect(RegularAreaRect *area)
{
RegularAreaRect::Iterator i;
......
......@@ -38,7 +38,6 @@ class NormalizedRect
NormalizedRect();
NormalizedRect( double l, double t, double r, double b );
NormalizedRect( const QRect &r, double xScale, double yScale );
bool isNull() const;
bool contains( double x, double y ) const;
bool intersects( const NormalizedRect & normRect ) const;
......@@ -101,7 +100,8 @@ struct HighlightRect : public NormalizedRect
*/
template <class NormalizedShape, class Shape> class RegularArea :
public QValueList<NormalizedShape*> {
public QValueList<NormalizedShape*>
{
public:
typedef QValueListIterator<NormalizedShape*> Iterator;
typedef QValueListConstIterator<NormalizedShape*> ConstIterator;
......
......@@ -17,6 +17,7 @@
#include <qvaluevector.h>
#include <qtimer.h>
#include <qmap.h>
#include <kconfigdialog.h>
#include <kdebug.h>
#include <kimageio.h>
#include <klocale.h>
......@@ -29,6 +30,8 @@
#include <kstandarddirs.h>
#include <klibloader.h>
#include <ktrader.h>
#include <qcombobox.h>
#include <qlabel.h>
// local includes
#include "document.h"
......@@ -36,6 +39,7 @@
#include "observer.h"
#include "page.h"
#include "link.h"
#include "chooseenginedialog.h"
#include "conf/settings.h"
......@@ -109,8 +113,8 @@ struct RunningSearch
/** KPDFDocument **/
KPDFDocument::KPDFDocument()
: generator( 0 ), d( new KPDFDocumentPrivate )
KPDFDocument::KPDFDocument( QDict<Generator> * genList )
: m_loadedGenerators ( genList ), generator( 0 ), d( new KPDFDocumentPrivate )
{
d->allocatedPixmapsTotalMemory = 0;
d->memCheckTimer = 0;
......@@ -153,49 +157,94 @@ bool KPDFDocument::openDocument( const QString & docFile, const KURL & url )
// 0. load Generator
// request only valid non-disabled plugins suitable for the mimetype
QString constraint("([X-KDE-Priority] > 0) and (exist Library)") ;
KTrader::OfferList offers=KTrader::self()->query(mime->name(),"oKular/Generator",constraint, QString::null);
KTrader::OfferList offers=KTrader::self()->query(mime->name(),"oKular/Generator",constraint, "[X-KDE-Priority]");
if (offers.isEmpty())
{
kdWarning() << "No plugin for '" << mime->name() << "' mimetype." << endl;
return false;
return false;
}
// best ranked offer search
int hRank=0;
for (short i=0;i<offers.count();i++)
if (offers[hRank]->property("[X-KDE-Priority]").toInt() < offers[i]->property("[X-KDE-Priority])").toInt())
hRank=i;
KLibLoader *loader = KLibLoader::self();
if (!loader)
// best ranked offer search
if (offers.count() > 1 && Settings::chooseGenerators() )
{
kdWarning() << "Could not start library loader: '" << loader->lastErrorMessage() << "'." << endl;
return false;
ChooseEngineDialog * choose = new ChooseEngineDialog (0,0);
int count=offers.count();
int i;
for (i=0;i<count;i++)
{
choose->engineList->insertItem( offers[i]->property("Name").toString() , i );
}
choose -> description-> setText(
QString("More then one generator found for %1 mimetype, please select which one to use:").arg(mime->name())
);
switch( choose->exec() )
{
case QDialog::Accepted:
hRank=choose->engineList->currentItem();
break;
case QDialog::Rejected:
return false;
break;
}
}
KLibrary *lib = loader->globalLibrary( QFile::encodeName( offers[hRank]->library() ) );
if (!lib)
QString propName=offers[hRank]->property("Name").toString();
bool cached=false;
generator=m_loadedGenerators->take(propName);
if (!generator)
{
kdWarning() << "Could not load '" << lib->fileName() << "' library." << endl;
return false;
KLibLoader *loader = KLibLoader::self();
if (!loader)
{
kdWarning() << "Could not start library loader: '" << loader->lastErrorMessage() << "'." << endl;
return false;
}
KLibrary *lib = loader->globalLibrary( QFile::encodeName( offers[hRank]->library() ) );
if (!lib)
{
kdWarning() << "Could not load '" << lib->fileName() << "' library." << endl;
return false;
}
Generator* (*create_plugin)(KPDFDocument* doc) = ( Generator* (*)(KPDFDocument* doc) ) lib->symbol( "create_plugin" );
generator=create_plugin(this);
if ( !generator )
{
kdWarning() << "Sth broke." << endl;
return false;
}
if ( offers[hRank]->property("[X-KDE-oKularHasInternalSettings]").toBool() )
{
m_loadedGenerators->insert(propName,generator);
cached=true;
}
// end
}
Generator* (*create_plugin)(KPDFDocument* doc) = ( Generator* (*)(KPDFDocument* doc) ) lib->symbol( "create_plugin" );
generator=create_plugin(this);
if ( !generator )
else
{
kdWarning() << "Sth broke." << endl;
return false;
generator -> setDocument( this );
cached=true;
}
// end
// connect error reporting signals
connect (generator,SIGNAL(error(QString&,int )),this,SIGNAL(error(QString&,int )));
connect (generator,SIGNAL(warning(QString&,int )),this,SIGNAL(warning(QString&,int )));
connect (generator,SIGNAL(notice(QString&,int )),this,SIGNAL(notice(QString&,int )));
// 1. load Document (and set busy cursor while loading)
QApplication::setOverrideCursor( waitCursor );
bool openOk = generator->loadDocument( docFile, pages_vector );
QApplication::restoreOverrideCursor();
if ( !openOk || pages_vector.size() <= 0 )
{
delete generator;
if (!cached)
{
delete generator;
}
generator = 0;
return openOk;
}
......@@ -243,6 +292,21 @@ bool KPDFDocument::openDocument( const QString & docFile, const KURL & url )
return true;
}
QString KPDFDocument::getXMLFile()
{
if (generator)
return generator->getXMLFile();
return QString::null;
}
void KPDFDocument::setupGUI(KActionCollection* ac, QToolBox* tBox )
{
if (generator)
generator->setupGUI(ac,tBox);
}
void KPDFDocument::closeDocument()
{
// save document info if a document is still opened
......@@ -387,6 +451,16 @@ bool KPDFDocument::isOpened() const
return generator;
}
bool KPDFDocument::handleEvent( QEvent * event )
{
return generator ? generator->handleEvent( event ) : true;
}
bool KPDFDocument::canConfigurePrinter( ) const
{
return generator ? generator->canConfigurePrinter() : false;
}
const DocumentInfo * KPDFDocument::documentInfo() const
{
return generator ? generator->generateDocumentInfo() : NULL;
......@@ -519,10 +593,11 @@ void KPDFDocument::requestPixmaps( const QValueList< PixmapRequest * > & request
}
}
// 3. [START FIRST GENERATION] if generator is ready, start a new generation,
// 3. [START FIRST GENERATION] if <NO>generator is ready, start a new generation,
// or else (if gen is running) it will be started when the new contents will
//come from generator (in requestDone())
if ( generator->canGeneratePixmap() )
//come from generator (in requestDone())</NO>
// all handling of requests put into sendGeneratorRequest
// if ( generator->canGeneratePixmap() )
sendGeneratorRequest();
}
......@@ -1126,7 +1201,7 @@ bool KPDFDocument::print( KPrinter &printer )
void KPDFDocument::requestDone( PixmapRequest * req )
{
#ifndef NDEBUG
if ( !generator->canGeneratePixmap() )
if ( !generator->canGeneratePixmap( req->async ) )
kdDebug() << "requestDone with generator not in READY state." << endl;
#endif
......@@ -1168,12 +1243,15 @@ void KPDFDocument::sendGeneratorRequest()
while ( !d->pixmapRequestsStack.isEmpty() && !request )
{
PixmapRequest * r = d->pixmapRequestsStack.last();
d->pixmapRequestsStack.pop_back();
// request only if page isn't already present
if ( r->page->hasPixmap( r->id, r->width, r->height ) )
{
d->pixmapRequestsStack.pop_back();
delete r;
}
else if ( (long)r->width * (long)r->height > 20000000L )
{
d->pixmapRequestsStack.pop_back();
delete r;
if ( !d->warnedOutOfMemory )
{
......@@ -1183,6 +1261,10 @@ void KPDFDocument::sendGeneratorRequest()
d->warnedOutOfMemory = true;
}
}
else if (!r)
{
d->pixmapRequestsStack.pop_back();
}
else
request = r;
}
......@@ -1197,7 +1279,13 @@ void KPDFDocument::sendGeneratorRequest()
cleanupPixmapMemory( pixmapBytes );
// submit the request to the generator
generator->generatePixmap( request );
if ( generator->canGeneratePixmap( request->async ) )
{
d->pixmapRequestsStack.remove ( request );
generator->generatePixmap ( request );
}
else
QTimer::singleShot( 20, this, SLOT(sendGeneratorRequest()) );
}
void KPDFDocument::cleanupPixmapMemory( int /*sure? bytesOffset*/ )
......
......@@ -15,6 +15,7 @@
#include <qvaluevector.h>
#include <qstring.h>
#include <qdom.h>
#include <qdict.h>
class KPDFPage;
class KPDFLink;
......@@ -28,6 +29,9 @@ class PixmapRequest;
class Annotation;
class KPrinter;
class KURL;
class KActionCollection;
class QToolBox;
/**
* @short The Document. Heart of everything. Actions take place here.
......@@ -50,7 +54,7 @@ class KPDFDocument : public QObject
{
Q_OBJECT
public:
KPDFDocument();
KPDFDocument( QDict<Generator> * genList );
~KPDFDocument();
// document handling
......@@ -85,9 +89,8 @@ class KPDFDocument : public QObject
QString getMetaData( const QString & key, const QString & option = QString() ) const;
// gui altering stuff
bool altersGUI ();
QString& getXMLFile();
void setupActions(KActionCollection *ac);
QString getXMLFile();
void setupGUI(KActionCollection * ac , QToolBox * tBox );
// perform actions on document / pages
void setViewportPage( int page, int excludeId = -1, bool smoothMove = false );
......@@ -106,8 +109,9 @@ class KPDFDocument : public QObject
void toggleBookmark( int page );
void processLink( const KPDFLink * link );
bool canConfigurePrinter() const;
bool print( KPrinter &printer );
bool handleEvent (QEvent * event);
// notifications sent by generator
void requestDone( PixmapRequest * request );
......@@ -120,9 +124,11 @@ class KPDFDocument : public QObject
void linkPresentation();
void linkEndPresentation();
void openURL(const KURL &url);
void error(QString & string, int duration);
void warning(QString & string, int duration);
void notice(QString & string, int duration);
private:
void sendGeneratorRequest();
// memory management related functions
void cleanupPixmapMemory( int bytesOffset = 0 );
int getTotalMemory();
......@@ -131,7 +137,7 @@ class KPDFDocument : public QObject
void loadDocumentInfo();
QString giveAbsolutePath( const QString & fileName );
bool openRelativeFile( const QString & fileName );
QDict<Generator>* m_loadedGenerators ;
Generator * generator;
QValueVector< KPDFPage * > pages_vector;
class KPDFDocumentPrivate * d;
......@@ -139,6 +145,7 @@ class KPDFDocument : public QObject
private slots:
void saveDocumentInfo() const;
void slotTimedMemoryCheck();
void sendGeneratorRequest();
};
......
......@@ -25,6 +25,7 @@ class KPrinter;
class KPDFPage;
class KPDFLink;
class PixmapRequest;
class KConfigDialog;
/* Note: on contents generation and asyncronous queries.
* Many observers may want to request data syncronously or asyncronously.
......@@ -62,29 +63,42 @@ class Generator : public QObject
virtual bool isAllowed( int /*Document::Permisison(s)*/ ) { return true; }
// page contents generation
virtual bool canGeneratePixmap() = 0;
virtual bool canGeneratePixmap( bool async ) = 0;
virtual void generatePixmap( PixmapRequest * request ) = 0;
// can generate a KPDFText Page
virtual bool canGenerateTextPage() = 0;
virtual void generateSyncTextPage( KPDFPage * page ) = 0;
// gui stuff
virtual QString getXMLFile() = 0;
virtual void setupGUI(KActionCollection * ac , QToolBox * tBox ) = 0;
// capability querying
// provides internal search
virtual bool supportsSearching() = 0;
virtual bool prefersInternalSearching() = 0;
virtual bool supportsRotation() = 0;
// internal search and gettext
virtual RegularAreaRect * findText( const QString & text, SearchDir dir, const bool strictCase,
const RegularAreaRect * lastRect, KPDFPage * page) = 0;
virtual QString* getText( const RegularAreaRect * area, KPDFPage * page ) = 0;
// may come useful later
virtual void setOrientation(QValueVector<KPDFPage*> & pagesVector, int orientation) = 0;
// may come useful later
//virtual bool hasFonts() const = 0;
// print document using already configured kprinter
// return true if wanting to configure the printer yourself in backend
virtual bool canConfigurePrinter( ) { return false; }
// print the document (using a printer configured or not depending on the above function)
// note, if we are only asking for a preview this will be preconfigured
virtual bool print( KPrinter& /*printer*/ ) { return false; }
// access meta data of the generator
virtual QString getMetaData( const QString &/*key*/, const QString &/*option*/ ) { return QString(); }
// tell generator to re-parse configuration and return true if something changed
virtual bool reparseConfig() { return false; }
void setDocument( KPDFDocument * doc ) { m_document=doc; };
/** 'signals' to send events the KPDFDocument **/
// tell the document that the job has been completed
void signalRequestDone( PixmapRequest * request ) { m_document->requestDone( request ); }
......@@ -92,6 +106,28 @@ class Generator : public QObject
/** constructor: takes the Document as a parameter **/
Generator( KPDFDocument * doc ) : m_document( doc ) {};
// add support for settings
virtual void addPages( KConfigDialog* /*dlg*/) { ; } ;
// capture events
// return false if you don't wish kpdf to use its event handlers
// in the pageview after your handling (use with caution)
virtual bool handleEvent (QEvent * /*event*/ ) { return true; } ;
// podner if not making separate handlers for every event type (clutters the api though)
/*virtual bool mouseEvent ( QMouseEvent* event ) { return false; };
virtual bool wheelEvent ( QWheelEvent* event ) { return false; };
virtual bool keyEvent ( QKeyEvent* event ) { return false; };
virtual bool resizeEvent ( QResizeEvent* event ) { return false; };
virtual bool dragEnterEvent ( QDragEnterEvent* event ) { return false; };
virtual bool dropEvent ( QDropEvent* event ) { return false; };
virtual bool paintEvent ( QKeyEvent* event ) { return false; };*/
signals:
void error(QString & string, int duration);
void warning(QString & string, int duration);
void notice(QString & string, int duration);
private:
Generator();
KPDFDocument * m_document;
......@@ -102,16 +138,19 @@ class Generator : public QObject
*/
struct PixmapRequest
{
PixmapRequest( int rId, int n, int w, int h, int p, bool a = false )
: id( rId ), pageNumber( n ), width( w ), height( h ),
priority( p ), async( a ), page( 0 ) {};
PixmapRequest( int rId, int n, int w, int h, /*double z,*/ int r, int p, bool a = false )
: id( rId ), pageNumber( n ), width( w ), height( h ), /*zoom(z),*/
rotation(r) , priority( p ), async( a ), page( 0 ) {};
PixmapRequest() {;};
// observer id
int id;
// page number and size
int pageNumber;
int width;
int height;
// double zoom;
int rotation;
// asyncronous request priority (less is better, 0 is max)
int priority;
// generate the pixmap in a thread and notify observer when done
......
/***************************************************************************
* Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2004-2005 by Enrico Ros <eros.kde@email.it> *
* *
* 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 *
......@@ -7,9 +7,63 @@
* (at your option) any later version. *
***************************************************************************/
// kde includes
#include <klocale.h>
// local includes
#include "link.h"
KPDFLink::~KPDFLink()
{
}
QString KPDFLink::linkTip() const
{
return "";
}
// Link Tips
QString KPDFLinkGoto::linkTip() const
{
return m_extFileName.isEmpty() ? "" : i18n("Open external file");
}
QString KPDFLinkExecute::linkTip() const
{
return i18n( "Execute '%1'..." ).arg( m_fileName );
}
QString KPDFLinkBrowse::linkTip() const
{
return m_url;
}
QString KPDFLinkAction::linkTip() const
{
switch ( m_type )
{
case PageFirst:
return i18n( "First Page" );
case PagePrev:
return i18n( "Previous Page" );
case PageNext:
return i18n( "Next Page" );
case PageLast:
return i18n( "Last Page" );
case HistoryBack:
return i18n( "Back" );
case HistoryForward:
return i18n( "Forward" );
case Quit:
return i18n( "Quit" );
case Presentation:
return i18n( "Start Presentation" );
case EndPresentation:
return i18n( "End Presentation" );
case Find:
return i18n( "Find..." );
case GoToPage:
return i18n( "Go To Page..." );
}
return "";
}
......@@ -27,6 +27,7 @@ class KPDFLink
// get link type (inherited classes mustreturn an unique identifier)
enum LinkType { Goto, Execute, Browse, Action, Movie };
virtual LinkType linkType() const = 0;
virtual QString linkTip() const;
// virtual destructor (remove warnings)
virtual ~KPDFLink();
......@@ -45,6 +46,7 @@ class KPDFLinkGoto : public KPDFLink
// create a KPDFLink_Goto
KPDFLinkGoto( QString extFileName, const DocumentViewport & vp ) { m_extFileName = extFileName; m_vp = vp; }
LinkType linkType() const { return Goto; }
QString linkTip() const;
private:
QString m_extFileName;
......@@ -62,6 +64,7 @@ class KPDFLinkExecute : public KPDFLink
// create a KPDFLink_Execute
KPDFLinkExecute( const QString & file, const QString & params ) { m_fileName = file; m_parameters = params; }
LinkType linkType() const { return Execute; }
QString linkTip() const;
private:
QString m_fileName;
......@@ -78,6 +81,7 @@ class KPDFLinkBrowse : public KPDFLink
// create a KPDFLink_Browse
KPDFLinkBrowse( const QString &url ) { m_url = url; }
LinkType linkType() const { return Browse; }
QString linkTip() const;
private:
QString m_url;
......@@ -97,6 +101,7 @@ class KPDFLinkAction : public KPDFLink
// create a KPDFLink_Action
KPDFLinkAction( enum ActionType actionType ) { m_type = actionType; }
LinkType linkType() const { return Action; }
QString linkTip() const;
private:
ActionType m_type;
......
......@@ -8,4 +8,9 @@ Type=int
# Version of the API.
[PropertyDef::X-KDE-oKularAPIVersion]
Type=int
\ No newline at end of file
Type=int
# Has configuration option
[PropertyDef::X-KDE-oKularHasInternalSettings]
Type=bool
......@@ -33,11 +33,11 @@ KPDFPage::KPDFPage( uint page, double w, double h, int r )
m_bookmarked( false ), m_text( 0 ), m_transition( 0 )
{
// if landscape swap width <-> height (rotate 90deg CCW)
if ( r == 90 || r == 270 )
/* if ( r == 90 || r == 270 )
{
m_width = h;
m_height = w;
}
}*/
// avoid Division-By-Zero problems in the program
if ( m_width <= 0 )
m_width = 1;
......
......@@ -19,6 +19,8 @@ KPDFTextPage::~KPDFTextPage()
}
}
RegularAreaRect* KPDFTextPage::findText(const QString &query, SearchDir & direct,
const bool &strictCase, const RegularAreaRect *area)
{
......@@ -99,8 +101,8 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
const QValueList<KPDFTextEntity*>::Iterator &end)
{
RegularAreaRect* ret=new RegularAreaRect;
RegularAreaRect* ret=new RegularAreaRect;
// j is the current position in our query
// len is the length of the string in kpdftextentity
// queryLeft is the length of the query we have left
......@@ -133,7 +135,7 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
//kdDebug(1223) << str.left(min) << " : " << query.mid(j,min) << endl;
// we have equal (or less then) area of the query left as the lengt of the current
// entity