Commit 75db44d8 authored by Piotr Szymanski's avatar Piotr Szymanski

- sync with hdd, refactored text page, ported backends to textpage,

- fixed crash in fax, chm builds and ghostview nearly ported to libqgs

svn path=/trunk/playground/graphics/oKular/kpdf/; revision=481340
parent de78c91f
......@@ -4,7 +4,7 @@ INCLUDES = -I$(srcdir)/.. -I$(top_builddir)/kpdf $(all_includes)
METASOURCES = AUTO
liboKularcore_la_SOURCES = chooseenginedialog.ui area.cpp textpage.cpp page.cpp document.cpp link.cpp annotations.cpp \
liboKularcore_la_SOURCES = chooseenginedialog.ui generator.cpp area.cpp textpage.cpp page.cpp document.cpp link.cpp annotations.cpp \
pagetransition.cpp
liboKularcore_la_LIBADD = -lkio
......
......@@ -1298,7 +1298,7 @@ void KPDFDocument::sendGeneratorRequest()
generator->generatePixmap ( request );
}
else
QTimer::singleShot( 20, this, SLOT(sendGeneratorRequest()) );
QTimer::singleShot( 10, this, SLOT(sendGeneratorRequest()) );
}
void KPDFDocument::cleanupPixmapMemory( int /*sure? bytesOffset*/ )
......
/***************************************************************************
* Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2004-5 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2005 by Piotr Szymañski <niedakh@gmail.com> *
* *
* 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 *
......@@ -19,6 +20,7 @@
#include <qobject.h>
#include <qvaluevector.h>
#include <qstring.h>
#include <ostream>
#include "core/document.h"
#include "core/textpage.h"
class KPrinter;
......@@ -157,6 +159,9 @@ struct PixmapRequest
// this field is set by the Docuemnt prior passing the
// request to the generator
KPDFPage * page;
};
std::ostream& operator<< (std::ostream& str, const PixmapRequest *req);
#endif
......@@ -108,7 +108,7 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
// queryLeft is the length of the query we have left
QString str;
int j=0, len=0, queryLeft=query.length();
bool haveMatch=false,wasEol=false;
bool haveMatch=false;
bool dontIncrement=false;
QValueList<KPDFTextEntity*>::Iterator it;
// we dont support backward search yet
......@@ -116,10 +116,12 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
{
// a static cast would be faster?
str=(*it)->txt;
if (query.mid(j,1)==" " && wasEol )
if (query.mid(j,1)==" " && query.mid(j,1)=="\n")
{
// lets match newline as a space
kdDebug(1223) << "Matched, space after eol " << endl;
#ifdef DEBUG_TEXTPAGE
kdDebug(1223) << "newline or space" << endl;
#endif
j++;
queryLeft--;
// since we dont really need to increment this after this
......@@ -148,7 +150,9 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
haveMatch=false;
delete ret;
ret=new RegularAreaRect;
kdDebug(1223) << "\tNotmatched" << endl;
#ifdef DEBUG_TEXTPAGE
kdDebug(1223) << "\tnot matched" << endl;
#endif
j=0;
queryLeft=query.length();
}
......@@ -160,16 +164,15 @@ RegularAreaRect* KPDFTextPage::findTextInternal(const QString &query, bool forwa
// we matched
// substract the length of the current entity from
// the left length of the query
kdDebug(1223) << "\tMatched" << endl;
#ifdef DEBUG_TEXTPAGE
kdDebug(1223) << "\tmatched" << endl;
#endif
haveMatch=true;
ret->append( (*it)->area );
j+=min;
queryLeft-=min;
}
}
wasEol=(*it)->eol;
if (wasEol)
kdDebug(1223) << "\t\tENDOFLINE" << endl;
if (haveMatch && queryLeft==0 && j==query.length())
{
// RegularAreaRect::ConstIterator i=ret->begin(), end=ret->end;
......@@ -218,27 +221,6 @@ QString * KPDFTextPage::getText(const RegularAreaRect *area)
if (area->intersects((*it)->area))
{
*ret += ((*it)->txt);
if (last)
{
if ( (last -> baseline != (*it)-> baseline )
&& ((*it)->rotation % 2 == 0)
&& ((*it)->rotation == last->rotation)
)
{
// on different baseline, on a vertical rotation (0 or 180)
*ret+='\n';
}
// what if horizontal? how do i determine end of line?
/*if (((*it)->rotation == (*last)->rotation)
&& ((*it)->rotation % 2 == 1)
&& ((*
{
// 90 or 270 degrees rotation
// maybe add a tabulation?
}
}*/
}
last=*it;
}
}
......
......@@ -52,12 +52,8 @@ struct KPDFTextEntity
//
QString txt;
NormalizedRect* area;
double baseline;
int rotation;
// after this entity we have an end of line
bool eol;
KPDFTextEntity(QString text, NormalizedRect* ar, double base,
int rot,bool eoline) : txt(text),baseline(base),rotation(rot),eol(eoline)
KPDFTextEntity(QString text, NormalizedRect* ar, int rot) : txt(text), rotation(rot)
{ area=ar; };
~KPDFTextEntity() { delete area; };
};
......@@ -69,9 +65,8 @@ class KPDFTextPage {
QString * getText(const RegularAreaRect *rect);
KPDFTextPage(QValueList<KPDFTextEntity*> words) : m_words(words) {};
KPDFTextPage() : m_words() {};
void append(QString txt, NormalizedRect* area,
double bline, int rot, bool eoline)
{ m_words.append(new KPDFTextEntity(txt,area,bline,rot,eoline) ); };
void append(QString txt, NormalizedRect* area, int rot)
{ m_words.append(new KPDFTextEntity(txt,area,rot) ); };
~KPDFTextPage();
private:
RegularAreaRect * findTextInternal(const QString &query, bool forward,
......
......@@ -221,7 +221,7 @@ void TGenerator::recursiveExploreNodes(DOM::Node node,KPDFTextPage *tp)
}
#else
nodeNormRect=new NormalizedRect (r,vWidth,vHeight);
tp->append(nodeText,nodeNormRect,nodeNormRect->bottom,0,false);
tp->append(nodeText,nodeNormRect,0);
#endif
}
DOM::Node child = node.firstChild();
......
if test -z "$LIB_GS"; then
if test -z "$LIB_QGS"; then
echo ""
echo "The Ghostscript library was not found in your system. ."
echo "The Ghostscript backend will not be available."
......@@ -10,7 +10,7 @@ echo "or contact your package provider."
echo ""
fi
if test "$HAVE_CHM_LIB != yes"; then
if test "$HAVE_CHMLIB != yes"; then
echo ""
echo "The chm library was not found in your system."
echo "The chm backend will not be available."
......
AC_ARG_WITH(libgs,
[AC_HELP_STRING(--with-libgs, [Where the Ghostscript library is installed])],
AC_ARG_WITH(libqgs,
[AC_HELP_STRING(--with-libqgs, [Where the Qt Ghostscript library is installed])],
[],
with_libgs=check)
LIB_GS=
if test "x$with_libgs" != xno; then
with_libqgs=check)
LIB_QGS=
if test "x$with_libqgs" != xno; then
AUX="$LDFLAGS"
LDFLAGS="-L$withval $LDFLAGS"
KDE_CHECK_LIB(gs, gsapi_new_instance,
LIB_GS=-lgs
if test "x$with_libgs" != "xcheck"; then
LIB_GS_PATH="$withval"
KDE_CHECK_LIB(qgs, main,
LIB_QGS=-lqgs
if test "x$with_libqgs" != "xcheck"; then
LIB_QGS_PATH="$withval"
fi)
LDFLAGS="$AUX"
fi
AC_SUBST(LIB_GS)
AC_SUBST(LIB_GS_PATH)
AC_SUBST(LIB_QGS)
AC_SUBST(LIB_QGS_PATH)
AM_CONDITIONAL(include_ghostscript, test -n "$LIB_GS")
AM_CONDITIONAL(include_ghostscript, test -n "$LIB_QGS")
HAVE_CHMLIB=no
KDE_CHECK_HEADER(chm_lib.h, HAVE_CHMLIB=yes)
......
......@@ -50,8 +50,9 @@ void FaxRenderer::generatePixmap( PixmapRequest * request )
// Wait for all access to this documentRenderer to finish
QPixmap* pix = new QPixmap();
QPainter p(pix);
QImage img = fax.page(request->pageNumber-1);
pix->drawPixmap( 0,0, img, 0,0,img.width(),img.height());
p.drawImage( 0,0, img, 0,0,img.width(),img.height());
/*
SimplePageSize psize = pageSizes[page->getPageNumber() - 1];
if (psize.isValid()) {
......
......@@ -11,7 +11,7 @@ kpdflibgsasyncgenerator_LDFLAGS = $(LIB_QT) -lkgs
kde_module_LTLIBRARIES = libokularGenerator_ghostview.la
ibokularGenerator_ghostview_la_LIBADD = $(top_builddir)/kpdf/core/liboKularcore.la $(top_builddir)/kpdf/conf/liboKularconf.la -lkgs -lkdeui -lkdeprint
libokularGenerator_ghostview_la_LIBADD = $(top_builddir)/kpdf/core/liboKularcore.la $(top_builddir)/kpdf/conf/liboKularconf.la -lkgs -lkdeui -lkdeprint
libokularGenerator_ghostview_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -L$(LIB_GS_PATH)
libokularGenerator_ghostview_la_SOURCES = interpreter_cmd.cpp internaldocument.cpp generator_ghostview.cpp gvlogwindow.cpp dscparse_adapter.cpp ps.c dscparse.cpp
#libokularGenerator_ghostview_la_METASOURCES = AUTO
......
......@@ -10,6 +10,7 @@
#include <math.h>
#include <qfile.h>
#include <qpainter.h>
#include <qsize.h>
#include <qtoolbox.h>
......@@ -29,7 +30,6 @@
#include "gvlogwindow.h"
#include "interpreter_cmd.h"
#include "interpreter_lib.h"
#include "internaldocument.h"
#include "interpreter.h"
#include "generator_ghostview.h"
......@@ -167,7 +167,7 @@ bool GSGenerator::loadDocument( const QString & fileName, QValueVector< KPDFPage
<< "-c quit";
GSInterpreterLib * m_convert=new GSInterpreterLib();
m_convert->setGhostscriptArguments(arg);
m_convert->startInterpreter();
m_convert->start();
delete m_convert;
m_convert=0;
arg.clear();
......@@ -176,37 +176,59 @@ bool GSGenerator::loadDocument( const QString & fileName, QValueVector< KPDFPage
if (! asyncGenerator )
{
asyncGenerator= new GSInterpreterCMD ( fileName );
connect (asyncGenerator, SIGNAL (newPageImage(PixmapRequest *)),
this, SLOT(slotAsyncPixmapGenerated (PixmapRequest *)));
connect (asyncGenerator, SIGNAL (Finished(QPixmap *)),
this, SLOT(slotAsyncPixmapGenerated (QPixmap *));
}
if( !pixGenerator )
{
pixGenerator = new GSInterpreterLib ();
connect (pixGenerator, SIGNAL (newPageImage(PixmapRequest *)),
this, SLOT(slotPixmapGenerated (PixmapRequest *)));
connect (pixGenerator, SIGNAL (Finished(const QImage* img)),
this, SLOT(slotPixmapGenerated (const QImage* img)));
if ( GSSettings::messages() )
{
pixGenerator->setBuffered(true);
connect (pixGenerator, SIGNAL (io( MessageType , const char*, int )),
m_logWindow, SLOT (append(MessageType , const char*,int)));
}
}
m_pages=pagesVector;
if ( GSSettings::platformFonts() )
{
pixGenerator->setPlatformFonts(false);
asyncGenerator->setPlatformFonts(false);
}
if ( GSSettings::antialiasing())
{
pixGenerator->setAABits(4,2);
asyncGenerator->setAABits(4,2);
}
else
{
pixGenerator->setAABits(1,1);
asyncGenerator->setAABits(1,1);
}
pixGenerator->setProgressive(false);
// m_pages=pagesVector;
return loadDocumentWithDSC(name,pagesVector,ps);
}
void GSGenerator::slotPixmapGenerated(PixmapRequest * request )
void GSGenerator::slotPixmapGenerated(const QImage* img)
{
request->page->setPixmap( request->id, pixGenerator->takePixmap() );
signalRequestDone( request );
QPixmap *pix=new QPixmap(m_sRequest->width, m_asRequest->height);
QPainter p(pix);
p.drawImage(0,0,*img,0,0,img->width(),img->height());
docLock.unlock();
m_sRequest->page->setPixmap( m_sRequest->id, pix );
signalRequestDone( m_sRequest );
}
void GSGenerator::slotAsyncPixmapGenerated(PixmapRequest * request )
void GSGenerator::slotAsyncPixmapGenerated(QPixmap * pix)
{
QPixmap *pix=asyncGenerator->takePixmap();
docLock.unlock();
request->page->setPixmap( request->id, pix );
signalRequestDone( request );
m_asRequest->page->setPixmap( m_asRequest->id, pix );
signalRequestDone( m_asRequest );
}
void GSGenerator::setOrientation(QValueVector<KPDFPage*>& pages, int rot)
......@@ -220,7 +242,8 @@ void GSGenerator::setOrientation(QValueVector<KPDFPage*>& pages, int rot)
void GSGenerator::slotPaperSize (const QString & p)
{
internalDoc->setMedia(p);
loadPages(m_pages);
// TODO: global papersize
// loadPages(m_pages);
NotifyRequest r(DocumentObserver::Setup, false);
m_document->notifyObservers( &r );
}
......@@ -299,12 +322,12 @@ bool GSGenerator::initInterpreter()
{
if (! pixGenerator->running())
{
if( pixGenerator->startInterpreter() && internalDoc->dsc()->isStructured() )
if( pixGenerator->start() && internalDoc->dsc()->isStructured() )
{
// this 0 is ok here, we will not be getting a PAGE anwser from those
pixGenerator->run ( internalDoc->file() , internalDoc->prolog(), static_cast<PixmapRequest*>(0x0),false);
pixGenerator->run ( internalDoc->file() , internalDoc->prolog(), false);
pixGenerator->unlock();
pixGenerator->run ( internalDoc->file() , internalDoc->setup(), static_cast<PixmapRequest*>(0x0),false );
pixGenerator->run ( internalDoc->file() , internalDoc->setup(), false );
pixGenerator->unlock();
}
}
......@@ -321,27 +344,21 @@ bool GSGenerator::loadDocumentWithDSC( QString & name, QValueVector< KPDFPage *
void GSGenerator::generatePixmap( PixmapRequest * req )
{
QString a="S";
if (req->async) a="As";
kdDebug() << a << "ync PixmapRequest of " << req->width << "x"
<< req->height << " size, pageNo " << req->pageNumber
<< ", priority: " << req->priority << " pageaddress " << (unsigned long long int) req->page
<< endl;
int i=req->pageNumber;
kdDebug() << req << endl;
int pgNo=req->pageNumber;
if ( req->async )
{
docLock.lock();
asyncGenerator->setOrientation(rotation (internalDoc->orientation(i)));
m_asRequest=req;
asyncGenerator->setOrientation(rotation (internalDoc->orientation(pgNo)));
// asyncGenerator->setBoundingBox( internalDoc->boundingBox(i));
asyncGenerator->setSize(req->width ,req->height);
asyncGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( i )) );
asyncGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( pgNo )) );
asyncGenerator->setMagnify(QMAX(static_cast<double>(req->width)/req->page->width() ,
static_cast<double>(req->height)/req->page->height()));
PagePosition* u=internalDoc->pagePos(i);
kdDebug() << "Page pos is " << i << ":"<< u->first << "/" << u->second << endl;
GSInterpreterLib::Position u=internalDoc->pagePos(pgNo);
kdDebug() << "Page pos is " << pgNo << ":"<< u.first << "/" << u.second << endl;
if (!asyncGenerator->running())
{
if ( internalDoc->dsc()->isStructured() )
......@@ -349,22 +366,22 @@ void GSGenerator::generatePixmap( PixmapRequest * req )
asyncGenerator->setStructure( internalDoc->prolog() , internalDoc->setup() );
kdDebug () << "sending init" << endl;
}
asyncGenerator->startInterpreter();
asyncGenerator->start();
}
asyncGenerator->run ( internalDoc->pagePos(i) , req);
asyncGenerator->run (internalDoc->pagePos(pgNo));
return;
}
pixGenerator->setOrientation(rotation (internalDoc->orientation(i)));
m_sRequest=req;
pixGenerator->setOrientation(rotation (internalDoc->orientation(pgNo)));
// pixGenerator->setBoundingBox( internalDoc->boundingBox(i));
pixGenerator->setSize(req->width ,req->height);
pixGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( i )) );
pixGenerator->setMedia( internalDoc -> getPaperSize ( internalDoc -> pageMedia( pgNo )) );
pixGenerator->setMagnify(QMAX(static_cast<double>(req->width)/req->page->width() ,
static_cast<double>(req->height)/req->page->height()));
if (!pixGenerator->running())
initInterpreter();
pixGenerator->run ( internalDoc->file() , internalDoc->pagePos(i) , req, true);
pixGenerator->run ( internalDoc->file() , internalDoc->pagePos(pgNo));
}
......
......@@ -70,8 +70,8 @@ class GSGenerator : public Generator
~GSGenerator();
public slots:
void slotPixmapGenerated(PixmapRequest * request);
void slotAsyncPixmapGenerated(PixmapRequest * request );
void slotPixmapGenerated(const QImage* img);
void slotAsyncPixmapGenerated(QPixmap * img);
void slotPaperSize (const QString & );
signals:
......@@ -85,7 +85,7 @@ class GSGenerator : public Generator
KTempFile * dscForPDF;
QMutex convertLock;
GSInterpreterLib* m_convert;
QValueVector<KPDFPage*> m_pages;
// QValueVector<KPDFPage*> m_pages;
bool loadDocumentWithDSC( QString & name, QValueVector< KPDFPage * > & pagesVector , bool ps );
bool loadPages( QValueVector< KPDFPage * > & pagesVector );
......@@ -96,6 +96,10 @@ class GSGenerator : public Generator
QMutex docLock;
bool m_asyncBusy;
// pixmap requests
PixmapRequest* m_asRequest;
PixmapRequest* m_sRequest;
// backendish stuff
GSInterpreterLib* pixGenerator;
GSInterpreterCMD* asyncGenerator;
......
......@@ -54,7 +54,7 @@ bool GSLogWindow::event( QEvent * event )
return true;
}
void GSLogWindow::append( MessageType t, const QString &text)
void GSLogWindow::append( GSInterpreterLib::MessageType t, const QString &text)
{
//kdDebug() << "Appending: " << text <<endl;
kdDebug() << "last int: " << m_lastInt << endl;
......@@ -83,7 +83,7 @@ void GSLogWindow::append( MessageType t, const QString &text)
}
}
void GSLogWindow::append( MessageType t, const char* buf, int num )
void GSLogWindow::append( GSInterpreterLib::MessageType t, const char* buf, int num )
{
// ghostscript splits messages longer then 128 to chunks, handle this properly
if (m_lastInt == 128)
......
......@@ -27,16 +27,16 @@ public:
QWidget* parent = 0, const char* name = 0 );
public slots:
void append( MessageType t, const char* buf, int num );
void append( GSInterpreterLib::MessageType t, const char* buf, int num );
void appendBuffered() { m_lastInt=0; m_clearTimer.stop(); append(m_buffer.first,m_buffer.second); };
void append( MessageType t, const QString &text);
void append( GSInterpreterLib::MessageType t, const QString &text);
void clear();
bool event( QEvent * event );
private:
KListView* m_msgList;
KListViewSearchLine* m_searchLine;
QPair <MessageType, QString> m_buffer;
QPair <GSInterpreterLib::MessageType, QString> m_buffer;
int m_tCol;
int m_lastInt;
QTimer m_clearTimer;
......
......@@ -47,10 +47,10 @@ class GSInternalDocument
CDSC_ORIENTATION_ENUM orientation( int pagenumber ) const;
void setOrientation(CDSC_ORIENTATION_ENUM ori) { m_overrideOrientation=ori; };
void insertPageData (int n, PagePosition p) { pagesInternalData.insert(n,p); };
void insertPageData (int n, GSInterpreterLib::Position p) { pagesInternalData.insert(n,p); };
FILE * file () { return m_internalFile; };
PagePosition * pagePos (int i) { return &pagesInternalData[i]; };
GSInterpreterLib::Position pagePos (int i) { return pagesInternalData[i]; };
const QString & fileName () { return m_fileName ; };
const KDSC* dsc () { return m_dsc; };
......@@ -59,10 +59,10 @@ class GSInternalDocument
KDSCBBOX boundingBox( int pageNo ) const;
KDSCBBOX boundingBox() const;
void setProlog( PagePosition p ) { m_prolog=p; };
PagePosition * prolog() { return &m_prolog ; }
void setSetup( PagePosition p) { m_setup=p; };
PagePosition * setup() { return &m_setup; }
void setProlog( GSInterpreterLib::Position p ) { m_prolog=p; };
GSInterpreterLib::Position prolog() { return m_prolog ; }
void setSetup( GSInterpreterLib::Position p) { m_setup=p; };
GSInterpreterLib::Position setup() { return m_setup; }
Format format() { return m_format; };
const DocumentInfo * generateDocumentInfo();
......@@ -85,8 +85,8 @@ class GSInternalDocument
FILE* m_internalFile;
KDSC* m_dsc;
Format m_format;
PagePosition m_prolog;
PagePosition m_setup;
QMap<int, PagePosition > pagesInternalData;
GSInterpreterLib::Position m_prolog;
GSInterpreterLib::Position m_setup;
QMap<int, GSInterpreterLib::Position > pagesInternalData;
};
#endif
#ifndef _KPDF_INTERPETER_H_
#define _KPDF_INTERPETER_H_
#include <qpaintdevice.h>
#include <qgs.h>
namespace DPIMod
{
......
......@@ -82,7 +82,7 @@ GSInterpreterCMD::~GSInterpreterCMD()
if (!m_pixmap)
delete m_pixmap;
if ( running() )
stopInterpreter(false);
stop(false);
// remove (crashes kpdf somehow, probably because
// the destuction thread does the same a line higher
/* this should not be needed!
......@@ -138,7 +138,7 @@ bool GSInterpreterCMD::running ()
}
}
void GSInterpreterCMD::setStructure(PagePosition *prolog, PagePosition *setup)
void GSInterpreterCMD::setStructure(GSInterpreterLib::Position prolog, GSInterpreterLib::Position setup)
{
kdDebug(4655) << "setStructure()" << endl;
m_structurePending=true;
......@@ -146,9 +146,9 @@ void GSInterpreterCMD::setStructure(PagePosition *prolog, PagePosition *setup)
m_data[1]=setup;
}
bool GSInterpreterCMD::stopInterpreter(bool async)
bool GSInterpreterCMD::stop(bool async)
{
kdDebug(4655) << "stopInterpreter()" << endl;
kdDebug(4655) << "stop()" << endl;
// if( !_interpreterBusy ) return;
if ( running() )
......@@ -181,9 +181,9 @@ bool GSInterpreterCMD::stopInterpreter(bool async)
return true;
}
bool GSInterpreterCMD::startInterpreter()
bool GSInterpreterCMD::start()
{
kdDebug(4655) << "startInterpreter()" << endl;
kdDebug(4655) << "start()" << endl;
if ( m_process && m_process->isRunning() )
{
kdDebug(4655) << "ERROR: starting an interpreter while one is running" << endl;
......@@ -241,7 +241,7 @@ void GSInterpreterCMD::setOrientation( int orientation )
if( m_orientation != orientation )
{
m_orientation = orientation;
stopInterpreter();
stop();
}
unlock();
}
......@@ -252,7 +252,7 @@ void GSInterpreterCMD::setMagnify( double magnify )
if( m_magnify != magnify )
{
m_magnify = magnify;
stopInterpreter();
stop();
}
unlock();
}
......@@ -263,7 +263,7 @@ void GSInterpreterCMD::setMedia( QString media )
if( m_media != media )
{
m_media = media;
stopInterpreter();
stop();
}
unlock();