/*
Copyright ( C ) 2001 - 2003 KSVG Team
This file is part of the KDE project
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Library General Public License for more details .
You should have received a copy of the GNU Library General Public License
along with this library ; see the file COPYING . LIB . If not , write to
the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
Boston , MA 02110 - 1301 , USA .
*/
# include <krun.h>
# include <kdebug.h>
# include <tdeaction.h>
# include <tdefiledialog.h>
# include <tdelocale.h>
# include <tdetempfile.h>
# include <ksimpleconfig.h>
# include <tdeaboutapplication.h>
# include "ksvg_widget.h"
# include "ksvg_factory.h"
# include "ksvg_plugin.moc"
# include "KSVGCanvas.h"
# include "KSVGLoader.h"
# include "CanvasFactory.h"
# include "DocumentFactory.h"
# include "SVGDocument.h"
# include "SVGWindowImpl.h"
# include "SVGZoomAndPan.h"
# include "SVGDocumentImpl.h"
# include "SVGSVGElementImpl.h"
# include <tqimage.h>
using namespace KSVG ;
# define DEFAULT_WIDTH 400
# define DEFAULT_HEIGHT 400
# define ZOOM_FACTOR 1.2
struct KSVGPlugin : : Private
{
KSVGWidget * window ;
KSVGPluginBrowserExtension * extension ;
TDEAction * zoomInAction ;
TDEAction * zoomOutAction ;
TDEAction * zoomResetAction ;
TDEAction * stopAnimationsAction ;
TDEAction * viewSourceAction ;
TDEAction * viewMemoryAction ;
TDEAction * aboutApp ;
TDEAction * saveToPNG ;
TDEToggleAction * fontKerningAction ;
TDEToggleAction * progressiveAction ;
TDESelectAction * renderingBackendAction ;
TQString description ;
TQPoint panPoint ;
float zoomFactor ;
SVGDocumentImpl * doc ;
KSVGCanvas * canvas ;
TQPixmap * backgroundPixmap ;
TDEAboutApplication * aboutKSVG ;
unsigned int width ;
unsigned int height ;
} ;
KSVGPlugin : : KSVGPlugin ( TQWidget * wparent , const char * , TQObject * parent , const char * name , unsigned int width , unsigned int height ) : KParts : : ReadOnlyPart ( parent , name )
{
kdDebug ( 26003 ) < < " KSVGPlugin::KSVGPlugin " < < endl ;
setInstance ( KSVGPluginFactory : : instance ( ) ) ;
ksvgd = new KSVGPlugin : : Private ( ) ;
ksvgd - > width = width ;
ksvgd - > height = height ;
ksvgd - > zoomFactor = 1.0 ;
ksvgd - > doc = 0 ;
ksvgd - > window = new KSVGWidget ( this , wparent , " Rendering Widget " ) ;
connect ( ksvgd - > window , TQ_SIGNAL ( browseURL ( const TQString & ) ) , this , TQ_SLOT ( browseURL ( const TQString & ) ) ) ;
ksvgd - > window - > show ( ) ;
KParts : : Part : : setWidget ( ksvgd - > window ) ;
ksvgd - > extension = new KSVGPluginBrowserExtension ( this ) ;
ksvgd - > backgroundPixmap = new TQPixmap ( width > 0 ? width : DEFAULT_WIDTH , height > 0 ? height : DEFAULT_HEIGHT ) ;
ksvgd - > backgroundPixmap - > fill ( ) ;
ksvgd - > canvas = KSVG : : CanvasFactory : : self ( ) - > loadCanvas ( width > 0 ? width : DEFAULT_WIDTH , height > 0 ? height : DEFAULT_HEIGHT ) ;
if ( ! ksvgd - > canvas )
return ;
ksvgd - > canvas - > setup ( ksvgd - > backgroundPixmap , ksvgd - > window ) ;
ksvgd - > zoomInAction = KStdAction : : zoomIn ( this , TQ_SLOT ( slotZoomIn ( ) ) , actionCollection ( ) ) ;
ksvgd - > zoomOutAction = KStdAction : : zoomOut ( this , TQ_SLOT ( slotZoomOut ( ) ) , actionCollection ( ) ) ;
ksvgd - > zoomResetAction = new TDEAction ( i18n ( " Zoom &Reset " ) , " viewmag " , this , TQ_SLOT ( slotZoomReset ( ) ) , actionCollection ( ) , " zoom_reset " ) ;
ksvgd - > stopAnimationsAction = new TDEAction ( i18n ( " &Stop Animations " ) , " process-stop " , Key_Escape , this , TQ_SLOT ( slotStop ( ) ) , actionCollection ( ) , " stop_anims " ) ;
ksvgd - > viewSourceAction = new TDEAction ( i18n ( " View &Source " ) , " text-x-generic-template " , Key_F6 , this , TQ_SLOT ( slotViewSource ( ) ) , actionCollection ( ) , " view_source " ) ;
ksvgd - > viewMemoryAction = new TDEAction ( i18n ( " View &Memory " ) , " text-x-generic-template " , Key_F7 , this , TQ_SLOT ( slotViewMemory ( ) ) , actionCollection ( ) , " view_memory " ) ;
ksvgd - > saveToPNG = new TDEAction ( i18n ( " Save to PNG... " ) , " save " , 0 , this , TQ_SLOT ( slotSaveToPNG ( ) ) , actionCollection ( ) , " save_to_png " ) ;
// ksvgd->aboutApp = KStdAction::aboutApp(this, TQ_SLOT(slotAboutKSVG()), actionCollection());//, "KSVG");
ksvgd - > aboutApp = new TDEAction ( i18n ( " About KSVG " ) , " image-svg+xml " , 0 , this , TQ_SLOT ( slotAboutKSVG ( ) ) , actionCollection ( ) , " help_about_app " ) ;
ksvgd - > fontKerningAction = new TDEToggleAction ( i18n ( " Use Font &Kerning " ) , " zoom-fit-best " , Key_F8 , this , TQ_SLOT ( slotFontKerning ( ) ) , actionCollection ( ) , " font_kerning " ) ;
ksvgd - > progressiveAction = new TDEToggleAction ( i18n ( " Use &Progressive Rendering " ) , " " , Key_F9 , this , TQ_SLOT ( slotProgressiveRendering ( ) ) , actionCollection ( ) , " progressive " ) ;
KSimpleConfig config ( " ksvgpluginrc " , true ) ;
config . setGroup ( " Rendering " ) ;
ksvgd - > fontKerningAction - > setChecked ( config . readBoolEntry ( " FontKerning " , true ) ) ;
ksvgd - > progressiveAction - > setChecked ( config . readBoolEntry ( " ProgressiveRendering " , true ) ) ;
ksvgd - > renderingBackendAction = new TDESelectAction ( i18n ( " Rendering &Backend " ) , 0 , this , TQ_SLOT ( slotRenderingBackend ( ) ) , actionCollection ( ) , " rendering_backend " ) ;
TQStringList items ;
TQPtrList < KSVG : : CanvasInfo > canvasList = KSVG : : CanvasFactory : : self ( ) - > canvasList ( ) ;
TQPtrListIterator < KSVG : : CanvasInfo > it ( canvasList ) ;
KSVG : : CanvasInfo * canvasInfo = 0 ;
while ( ( canvasInfo = it . current ( ) ) ! = 0 )
{
items < < canvasInfo - > name ;
+ + it ;
}
ksvgd - > renderingBackendAction - > setItems ( items ) ;
ksvgd - > renderingBackendAction - > setCurrentItem ( KSVG : : CanvasFactory : : self ( ) - > itemInList ( ksvgd - > canvas ) ) ;
ksvgd - > aboutKSVG = new TDEAboutApplication ( KSVGPluginFactory : : instance ( ) - > aboutData ( ) , wparent ) ;
setXMLFile ( " ksvgplugin.rc " ) ;
}
KSVGPlugin : : ~ KSVGPlugin ( )
{
kdDebug ( 26003 ) < < " KSVGPlugin::~KSVGPlugin " < < endl ;
if ( ksvgd - > doc & & ksvgd - > doc - > rootElement ( ) )
ksvgd - > doc - > rootElement ( ) - > pauseAnimations ( ) ;
KSVG : : CanvasFactory : : self ( ) - > cleanup ( ) ;
delete ksvgd - > extension ;
if ( ksvgd - > doc )
ksvgd - > doc - > detach ( ) ;
delete ksvgd - > canvas ;
delete ksvgd - > backgroundPixmap ;
delete ksvgd ;
}
SVGDocumentImpl * KSVGPlugin : : docImpl ( )
{
return ksvgd - > doc ;
}
SVGDocument KSVGPlugin : : document ( )
{
return SVGDocument ( ksvgd - > doc ) ;
}
void KSVGPlugin : : reset ( )
{
if ( ksvgd - > canvas )
ksvgd - > canvas - > reset ( ) ;
ksvgd - > zoomFactor = 1 ;
ksvgd - > window - > reset ( ) ;
ksvgd - > panPoint = TQPoint ( 0 , 0 ) ;
}
bool KSVGPlugin : : openURL ( const KURL & url )
{
m_url = url ;
if ( ! url . prettyURL ( ) . isEmpty ( ) )
{
reset ( ) ;
DocumentFactory * docFactory = DocumentFactory : : self ( ) ;
// when embedded, stick to passed width and height
ksvgd - > doc = docFactory - > requestDocumentImpl ( ( ksvgd - > width > 0 & & ksvgd - > height > 0 ) ) ;
ksvgd - > doc - > attach ( ksvgd - > canvas ) ;
ksvgd - > doc - > addToDocumentDict ( ksvgd - > doc - > handle ( ) , ksvgd - > doc ) ;
ksvgd - > doc - > setReferrer ( ksvgd - > extension - > urlArgs ( ) . metaData ( ) [ " referrer " ] ) ;
connect ( ksvgd - > doc , TQ_SIGNAL ( finishedParsing ( bool , const TQString & ) ) , this , TQ_SLOT ( slotParsingFinished ( bool , const TQString & ) ) ) ;
connect ( ksvgd - > doc , TQ_SIGNAL ( finishedRendering ( ) ) , this , TQ_SLOT ( slotRenderingFinished ( ) ) ) ;
connect ( ksvgd - > doc , TQ_SIGNAL ( gotDescription ( const TQString & ) ) , this , TQ_SLOT ( slotSetDescription ( const TQString & ) ) ) ;
connect ( ksvgd - > doc , TQ_SIGNAL ( gotTitle ( const TQString & ) ) , this , TQ_SLOT ( slotSetTitle ( const TQString & ) ) ) ;
connect ( ksvgd - > doc , TQ_SIGNAL ( gotURL ( const TQString & ) ) , this , TQ_SLOT ( slotGotURL ( const TQString & ) ) ) ;
connect ( ksvgd - > window , TQ_SIGNAL ( redraw ( const TQRect & ) ) , this , TQ_SLOT ( slotRedraw ( const TQRect & ) ) ) ;
ksvgd - > backgroundPixmap - > fill ( ) ;
bitBlt ( ksvgd - > window , 0 , 0 , ksvgd - > backgroundPixmap , 0 , 0 , ksvgd - > backgroundPixmap - > width ( ) , ksvgd - > backgroundPixmap - > height ( ) ) ;
ksvgd - > zoomFactor = 1 ;
emit started ( 0 ) ;
ksvgd - > doc - > open ( url ) ;
emit completed ( ) ;
}
else
return false ;
return true ;
}
void KSVGPlugin : : browseURL ( const TQString & url )
{
ksvgd - > doc - > rootElement ( ) - > pauseAnimations ( ) ;
KParts : : URLArgs args ;
args . frameName = " _self " ;
emit ksvgd - > extension - > openURLRequest ( KURL ( m_url , url ) , args ) ;
}
void KSVGPlugin : : slotRedraw ( const TQRect & r )
{
if ( ksvgd - > window - > width ( ) ! = ksvgd - > backgroundPixmap - > width ( ) | |
ksvgd - > window - > height ( ) ! = ksvgd - > backgroundPixmap - > height ( ) )
{
ksvgd - > backgroundPixmap - > resize ( ksvgd - > window - > width ( ) , ksvgd - > window - > height ( ) ) ;
if ( ksvgd - > doc & & ksvgd - > doc - > canvas ( ) )
{
ksvgd - > doc - > canvas ( ) - > resize ( ksvgd - > window - > width ( ) , ksvgd - > window - > height ( ) ) ;
ksvgd - > doc - > canvas ( ) - > blit ( ) ;
}
}
bitBlt ( ksvgd - > window , r . x ( ) , r . y ( ) , ksvgd - > backgroundPixmap , r . x ( ) , r . y ( ) , r . width ( ) , r . height ( ) ) ;
}
void KSVGPlugin : : slotViewSource ( )
{
KTempFile temp ;
* temp . textStream ( ) < < KSVGLoader : : getUrl ( m_url , true ) < < endl ;
KRun : : runURL ( KURL ( temp . name ( ) ) , " text/plain " , true ) ;
}
void KSVGPlugin : : slotViewMemory ( )
{
KTempFile temp ;
* temp . textStream ( ) < < ksvgd - > doc - > window ( ) - > printNode ( * ksvgd - > doc ) . string ( ) < < endl ;
KRun : : runURL ( KURL ( temp . name ( ) ) , " text/plain " , true ) ;
}
void KSVGPlugin : : slotFontKerning ( )
{
KSimpleConfig config ( " ksvgpluginrc " , false ) ;
config . setGroup ( " Rendering " ) ;
config . writeEntry ( " FontKerning " , ksvgd - > fontKerningAction - > isChecked ( ) ) ;
if ( ksvgd - > doc )
{
SVGSVGElementImpl * root = ksvgd - > doc - > rootElement ( ) ;
if ( ! root )
return ;
ksvgd - > doc - > canvas ( ) - > fontContext ( ) - > setKerning ( ksvgd - > fontKerningAction - > isChecked ( ) ) ;
update ( ) ;
}
}
void KSVGPlugin : : slotProgressiveRendering ( )
{
KSimpleConfig config ( " ksvgpluginrc " , false ) ;
config . setGroup ( " Rendering " ) ;
config . writeEntry ( " ProgressiveRendering " , ksvgd - > progressiveAction - > isChecked ( ) ) ;
}
void KSVGPlugin : : slotRenderingBackend ( )
{
KSimpleConfig config ( " ksvgpluginrc " , false ) ;
config . setGroup ( " Canvas " ) ;
config . writeEntry ( " ActiveCanvas " , KSVG : : CanvasFactory : : self ( ) - > internalNameFor ( ksvgd - > renderingBackendAction - > currentText ( ) ) ) ;
config . sync ( ) ;
KSVG : : CanvasFactory : : self ( ) - > deleteCanvas ( ksvgd - > canvas ) ;
ksvgd - > canvas = KSVG : : CanvasFactory : : self ( ) - > loadCanvas ( ksvgd - > width > 0 ? ksvgd - > width : DEFAULT_WIDTH , ksvgd - > height > 0 ? ksvgd - > height : DEFAULT_HEIGHT ) ;
if ( ! ksvgd - > canvas )
return ;
ksvgd - > canvas - > setup ( ksvgd - > backgroundPixmap , ksvgd - > window ) ;
openURL ( m_url ) ;
}
void KSVGPlugin : : slotAboutKSVG ( )
{
ksvgd - > aboutKSVG - > show ( ) ;
}
void KSVGPlugin : : slotStop ( )
{
if ( ksvgd - > doc - > rootElement ( ) - > animationsPaused ( ) )
ksvgd - > doc - > rootElement ( ) - > unpauseAnimations ( ) ;
else
ksvgd - > doc - > rootElement ( ) - > pauseAnimations ( ) ;
}
void KSVGPlugin : : slotParsingFinished ( bool error , const TQString & errorDesc )
{
emit completed ( ) ;
if ( error )
{
kdDebug ( 26003 ) < < " Finished with error : " < < errorDesc < < endl ;
emit setStatusBarText ( errorDesc ) ;
}
else
kdDebug ( 26003 ) < < " Finished without errors! " < < endl ;
}
void KSVGPlugin : : slotRenderingFinished ( )
{
bitBlt ( ksvgd - > window , 0 , 0 , ksvgd - > backgroundPixmap , 0 , 0 , ksvgd - > canvas - > width ( ) , ksvgd - > canvas - > height ( ) ) ;
}
void KSVGPlugin : : slotZoomIn ( )
{
ksvgd - > zoomFactor * = ZOOM_FACTOR ;
update ( ) ;
}
void KSVGPlugin : : slotZoomOut ( )
{
ksvgd - > zoomFactor * = ( 1.0 / ZOOM_FACTOR ) ;
update ( ) ;
}
void KSVGPlugin : : slotZoomReset ( )
{
ksvgd - > zoomFactor = 1.0 ;
update ( ) ;
}
void KSVGPlugin : : slotSaveToPNG ( )
{
if ( ksvgd & & ksvgd - > backgroundPixmap )
{
TQImage img = ksvgd - > backgroundPixmap - > convertToImage ( ) ;
TQString filename = KFileDialog : : getSaveFileName ( ) ;
if ( ! filename . isEmpty ( ) )
img . save ( filename , " PNG " ) ;
}
}
void KSVGPlugin : : setPanPoint ( const TQPoint & translate )
{
ksvgd - > panPoint = translate ;
update ( ) ;
}
void KSVGPlugin : : update ( )
{
if ( ksvgd - > doc )
{
SVGSVGElementImpl * root = ksvgd - > doc - > rootElement ( ) ;
if ( ! root | | root - > zoomAndPan ( ) ! = SVG_ZOOMANDPAN_MAGNIFY )
return ;
ksvgd - > backgroundPixmap - > fill ( ) ;
bool zoomChanged = ksvgd - > zoomFactor ! = root - > currentScale ( ) ;
root - > setCurrentScale ( ksvgd - > zoomFactor ) ;
root - > setCurrentTranslate ( ksvgd - > panPoint ) ;
ksvgd - > doc - > syncCachedMatrices ( ) ;
if ( zoomChanged )
ksvgd - > doc - > canvas ( ) - > update ( ksvgd - > zoomFactor ) ;
else
ksvgd - > doc - > canvas ( ) - > update ( ksvgd - > panPoint ) ;
// Fixes drawing glitches
slotRedraw ( TQRect ( 0 , 0 , ksvgd - > backgroundPixmap - > width ( ) , ksvgd - > backgroundPixmap - > height ( ) ) ) ;
}
}
void KSVGPlugin : : slotSetDescription ( const TQString & desc )
{
ksvgd - > description = desc ;
emit setStatusBarText ( i18n ( " Description: %1 " ) . arg ( desc ) ) ;
}
void KSVGPlugin : : slotSetTitle ( const TQString & title )
{
emit setWindowCaption ( title ) ;
}
void KSVGPlugin : : slotGotURL ( const TQString & text )
{
if ( text . isNull ( ) & & ! ksvgd - > description . isEmpty ( ) )
emit setStatusBarText ( i18n ( " Description: %1 " ) . arg ( ksvgd - > description ) ) ;
else
emit setStatusBarText ( text ) ;
}