/* This file is part of the KDE project
Copyright ( C ) 1999 Simon Hausmann < hausmann @ kde . org >
2001 - 2003 Matthias Kretz < kretz @ kde . org >
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 .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
# include "kviewviewer.h"
# include "kimageviewer/canvas.h"
# include "version.h"
# include <ksettings/dispatcher.h>
# include <unistd.h>
# include <assert.h>
# include <tqbuffer.h>
# include <tqlayout.h>
# include <tqvbox.h>
# include <tqlabel.h>
# include <tqregexp.h>
# include <kpushbutton.h>
# include <kpassivepopup.h>
# include <kdebug.h>
# include <kio/job.h>
# include <kxmlguifactory.h>
# include <kfiledialog.h>
# include <kparts/genericfactory.h>
# include <kparts/componentfactory.h>
# include <kparts/plugin.h>
# include <kmessagebox.h>
# include <ktempfile.h>
# include <kapplication.h>
# include <kimageio.h>
# include <kstdaccel.h>
# include <kdirwatch.h>
# include <kurldrag.h>
# include <krecentdocument.h>
typedef KParts : : GenericFactory < KViewViewer > KViewViewerFactory ;
K_EXPORT_COMPONENT_FACTORY ( libkviewviewer , KViewViewerFactory )
KViewViewer : : KViewViewer ( TQWidget * parentWidget , const char * /*widgetName*/ ,
TQObject * parent , const char * name , const TQStringList & )
: KImageViewer : : Viewer ( parent , name )
, m_pParentWidget ( parentWidget )
, m_pJob ( 0 )
, m_pExtension ( 0 )
, m_pCanvas ( 0 )
, m_pTempFile ( 0 )
, m_pBuffer ( 0 )
, m_pFileWatch ( new KDirWatch ( this ) )
{
KImageIO : : registerFormats ( ) ;
TQWidget * widget = KParts : : ComponentFactory : : createInstanceFromQuery < TQWidget > (
" KImageViewer/Canvas " , TQString ( ) , TQT_TQOBJECT ( m_pParentWidget ) ) ;
m_pCanvas = static_cast < KImageViewer : : Canvas * > ( widget - > qt_cast ( " KImageViewer::Canvas " ) ) ;
kdDebug ( 4610 ) < < " KImageViewer::Canvas at " < < m_pCanvas < < endl ;
if ( ! ( widget & & m_pCanvas ) )
{
if ( ! widget )
KMessageBox : : error ( m_pParentWidget , i18n ( " Unable to find a suitable Image Canvas. This probably means that KView was not installed properly. " ) ) ;
else
KMessageBox : : error ( m_pParentWidget , i18n ( " Accessing the KImageViewer interface of the Image Canvas failed. Something in your setup is broken (a component claims to be a KImageViewer::Canvas but it is not). " ) ) ;
}
else
{
// create the extension before the plugins are loaded, because plugins might want to use it
m_pExtension = new KViewKonqExtension ( m_pCanvas , this ) ;
setPluginLoadingMode ( LoadPluginsIfEnabled ) ;
setInstance ( KViewViewerFactory : : instance ( ) ) ;
// m_url isn't set from ReadOnlyPart so we set it here to the CWD
m_url = TQDir : : currentDirPath ( ) + " / " ;
m_sCaption = i18n ( " Title caption when no image loaded " , " no image loaded " ) ;
setWidget ( widget ) ;
// Drag and Drop for the Canvas
widget - > setAcceptDrops ( true ) ;
widget - > installEventFilter ( this ) ;
setupActions ( ) ;
if ( isReadWrite ( ) )
setXMLFile ( " kviewviewer.rc " ) ;
else
setXMLFile ( " kviewviewer_ro.rc " ) ;
connect ( widget , TQT_SIGNAL ( contextPress ( const TQPoint & ) ) ,
this , TQT_SLOT ( slotPopupMenu ( const TQPoint & ) ) ) ;
connect ( widget , TQT_SIGNAL ( zoomChanged ( double ) ) ,
this , TQT_SLOT ( zoomChanged ( double ) ) ) ;
connect ( widget , TQT_SIGNAL ( showingImageDone ( ) ) ,
this , TQT_SLOT ( switchBlendEffect ( ) ) ) ;
connect ( widget , TQT_SIGNAL ( hasImage ( bool ) ) ,
this , TQT_SLOT ( hasImage ( bool ) ) ) ;
connect ( widget , TQT_SIGNAL ( imageChanged ( ) ) ,
this , TQT_SLOT ( setModified ( ) ) ) ;
connect ( m_pFileWatch , TQT_SIGNAL ( dirty ( const TQString & ) ) ,
this , TQT_SLOT ( slotFileDirty ( const TQString & ) ) ) ;
KSettings : : Dispatcher : : self ( ) - > registerInstance ( instance ( ) , this , TQT_SLOT ( readSettings ( ) ) ) ;
// by default disable progress info (so it won't open the dialog in Konqueror)
setProgressInfoEnabled ( false ) ;
m_popupDoc = KXMLGUIFactory : : readConfigFile ( " kviewpopup.rc " , true , instance ( ) ) ;
KConfigGroup cfgGroup ( instance ( ) - > config ( ) , " Settings " ) ;
bool hideBars = cfgGroup . readBoolEntry ( " hideScrollbars " , false ) ;
m_pCanvas - > hideScrollbars ( hideBars ) ;
m_paShowScrollbars - > setChecked ( ! hideBars ) ;
m_vEffects . resize ( m_pCanvas - > numOfBlendEffects ( ) ) ;
readSettings ( ) ;
}
}
KViewViewer : : ~ KViewViewer ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
writeSettings ( ) ;
instance ( ) - > config ( ) - > sync ( ) ;
/*abortLoad(); //just in case
if ( isModified ( ) & & isReadWrite ( ) )
{
int res = m_url . isEmpty ( ) ?
KMessageBox : : warningYesNo ( widget ( ) ,
i18n ( " This is a new document. \n Do you want to save it ? " ) ,
TQString ( ) , KStdGuiItem : : saveAs ( ) , KStdGuiItem : : discard ( ) ) :
KMessageBox : : warningYesNo ( widget ( ) ,
i18n ( " The document has been modified. \n Do you want to save it ? " ) ,
TQString ( ) , KStdGuiItem : : saveAs ( ) , KStdGuiItem : : dontSave ( ) ) ;
if ( res = = KMessageBox : : Yes )
{
KURL url = KFileDialog : : getSaveURL ( ) ;
if ( ! url . isEmpty ( ) )
saveAs ( url ) ;
}
}
ReadOnlyPart : : closeURL ( ) ; */
abortLoad ( ) ;
delete m_pTempFile ;
delete m_pBuffer ;
}
KAboutData * KViewViewer : : createAboutData ( )
{
KAboutData * aboutData = new KAboutData ( " kviewviewer " , I18N_NOOP ( " KView " ) ,
KVIEW_VERSION , I18N_NOOP ( " KDE Image Viewer Part " ) ,
KAboutData : : License_GPL ,
I18N_NOOP ( " (c) 1997-2002, The KView Developers " ) ) ;
aboutData - > addAuthor ( " Matthias Kretz " , I18N_NOOP ( " Maintainer " ) , " kretz@kde.org " ) ;
aboutData - > addAuthor ( " Sirtaj Singh Kang " , I18N_NOOP ( " started it all " ) , " taj@kde.org " ) ;
aboutData - > addAuthor ( " Simon Hausmann " , 0 , " hausmann@kde.org " ) ;
return aboutData ;
}
void KViewViewer : : setReadWrite ( bool readwrite )
{
KImageViewer : : Viewer : : setReadWrite ( readwrite ) ;
if ( readwrite )
setXMLFile ( " kviewviewer.rc " ) ;
else
setXMLFile ( " kviewviewer_ro.rc " ) ;
}
bool KViewViewer : : saveAs ( const KURL & kurl )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
if ( ! kurl . isValid ( ) )
return KParts : : ReadWritePart : : saveAs ( kurl ) ; // sets m_bClosing = false
// if the image wasn't modified and should be saved in the same format we just copy the file - no need
// to lose some quality or information by calling TQImage::save()
if ( ! ( isModified ( ) & & isReadWrite ( ) ) & & m_mimeType = = m_newMimeType )
{
kdDebug ( 4610 ) < < " copy image from " < < m_file < < " to " < < kurl . prettyURL ( ) < < endl ;
KIO : : Job * job = KIO : : copy ( KURL ( m_file ) , kurl , isProgressInfoEnabled ( ) ) ;
emit started ( job ) ;
connect ( job , TQT_SIGNAL ( result ( KIO : : Job * ) ) ,
this , TQT_SLOT ( slotResultSaveAs ( KIO : : Job * ) ) ) ;
return true ;
}
kdDebug ( 4610 ) < < " call KParts::ReadWritePart::saveAs( " < < kurl . prettyURL ( ) < < " ) " < < endl ;
bool ret = KParts : : ReadWritePart : : saveAs ( kurl ) ;
if ( ret = = false )
KMessageBox : : error ( m_pParentWidget , i18n ( " The image could not be saved to disk. A possible causes is that you don't have permission to write to that file. " ) ) ;
return ret ;
}
void KViewViewer : : setModified ( bool modified )
{
m_paSave - > setEnabled ( modified ) ;
KImageViewer : : Viewer : : setModified ( modified ) ;
}
bool KViewViewer : : openURL ( const KURL & url )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
if ( ! url . isValid ( ) )
{
kdWarning ( 4610 ) < < " malformed URL " < < url . prettyURL ( ) < < endl ;
return false ;
}
if ( ! closeURL ( ) )
{
kdDebug ( 4610 ) < < " closeURL didn't work out " < < endl ;
return false ;
}
setModified ( false ) ;
m_url = url ;
m_mimeType = m_pExtension - > urlArgs ( ) . serviceType ; // if this fails to
// find the right mime type it'll be determined in openFile()
if ( m_url . isLocalFile ( ) )
{
emit started ( 0 ) ;
m_file = m_url . path ( ) ;
kdDebug ( 4610 ) < < " open local file " < < m_file < < endl ;
bool ret = openFile ( ) ;
if ( ret )
{
m_sCaption = m_url . prettyURL ( ) ;
emit setWindowCaption ( m_sCaption ) ;
emit completed ( ) ;
}
return ret ;
}
else
{
m_sCaption = m_url . prettyURL ( ) ;
emit setWindowCaption ( m_sCaption ) ;
m_bTemp = true ;
// Use same extension as remote file. This is important for mimetype-determination (e.g. koffice)
TQString extension ;
TQString fileName = url . fileName ( ) ;
int extensionPos = fileName . findRev ( ' . ' ) ;
if ( extensionPos ! = - 1 )
extension = fileName . mid ( extensionPos ) ; // keep the '.'
delete m_pTempFile ;
m_pTempFile = new KTempFile ( TQString ( ) , extension ) ;
m_file = m_pTempFile - > name ( ) ;
m_pJob = KIO : : get ( m_url , m_pExtension - > urlArgs ( ) . reload , isProgressInfoEnabled ( ) ) ;
emit started ( m_pJob ) ;
connect ( m_pJob , TQT_SIGNAL ( result ( KIO : : Job * ) ) , TQT_SLOT ( slotJobFinished ( KIO : : Job * ) ) ) ;
connect ( m_pJob , TQT_SIGNAL ( data ( KIO : : Job * , const TQByteArray & ) ) , TQT_SLOT ( slotData ( KIO : : Job * , const TQByteArray & ) ) ) ;
return true ;
}
}
bool KViewViewer : : closeURL ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
abortLoad ( ) ;
TQString file = m_file ;
bool ret = KParts : : ReadWritePart : : closeURL ( ) ;
if ( ret )
if ( ! file . isEmpty ( ) )
{
kdDebug ( 4610 ) < < " remove " < < file < < " from KDirWatch \n " ;
m_pFileWatch - > removeFile ( file ) ;
}
return ret ;
}
void KViewViewer : : newImage ( const TQImage & newimg )
{
if ( closeURL ( ) )
{
m_url = " " ;
m_file = TQString ( ) ;
m_sCaption = i18n ( " Title caption when new image selected " , " new image " ) ;
m_pCanvas - > setImage ( newimg ) ;
if ( isReadWrite ( ) )
setModified ( true ) ;
}
}
void KViewViewer : : reload ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
if ( isReadWrite ( ) & & isModified ( ) )
if ( ! queryClose ( ) )
return ;
//load from file
TQImage image ( m_file ) ;
m_pCanvas - > setImage ( image ) ;
setModified ( false ) ;
}
bool KViewViewer : : eventFilter ( TQObject * o , TQEvent * e )
{
KImageViewer : : Canvas * canvas = static_cast < KImageViewer : : Canvas * > ( o - > qt_cast ( " KImageViewer::Canvas " ) ) ;
if ( canvas )
{
// intercept drops onto the Canvas
switch ( e - > type ( ) )
{
case TQEvent : : DragEnter :
{
TQDragEnterEvent * ev = static_cast < TQDragEnterEvent * > ( e ) ;
kdDebug ( 4610 ) < < " DragEnter Event in the Canvas: " < < endl ;
for ( int i = 0 ; ev - > format ( i ) ; + + i )
kdDebug ( 4610 ) < < " - " < < ev - > format ( i ) < < endl ;
ev - > accept ( KURLDrag : : canDecode ( ev ) | | TQImageDrag : : canDecode ( ev ) ) ;
return true ;
}
case TQEvent : : Drop :
{
TQDropEvent * ev = static_cast < TQDropEvent * > ( e ) ;
kdDebug ( 4610 ) < < " Drop Event in the Canvas " < < endl ;
TQStringList l ;
TQImage image ;
if ( KURLDrag : : decodeToUnicodeUris ( ev , l ) )
openURL ( KURL ( l . first ( ) ) ) ;
else if ( TQImageDrag : : decode ( ev , image ) )
newImage ( image ) ;
return true ;
}
default :
break ;
}
}
return KImageViewer : : Viewer : : eventFilter ( o , e ) ;
}
void KViewViewer : : abortLoad ( )
{
if ( m_pJob )
{
m_pJob - > kill ( ) ;
m_pJob = 0 ;
}
}
bool KViewViewer : : openFile ( )
{
//m_pCanvas->setMaximumImageSize( TQSize( widget()->width(), widget()->height() ) );
if ( m_pBuffer )
{
kdDebug ( 4610 ) < < k_funcinfo < < " load from buffer \n " ;
//load from buffer
m_pBuffer - > close ( ) ;
if ( m_pTempFile )
{
m_pTempFile - > dataStream ( ) - > writeRawBytes ( m_pBuffer - > buffer ( ) . data ( ) , m_pBuffer - > buffer ( ) . size ( ) ) ;
m_pTempFile - > close ( ) ;
}
// determine Mime Type
if ( m_mimeType . isNull ( ) )
{
m_mimeType = KImageIO : : mimeType ( m_url . fileName ( ) ) ;
kdDebug ( 4610 ) < < " MimeType: " < < m_mimeType < < endl ;
if ( m_mimeType . isNull ( ) )
{
m_mimeType = KMimeType : : findByContent ( m_pBuffer - > buffer ( ) ) - > name ( ) ;
kdDebug ( 4610 ) < < " MimeType: " < < m_mimeType < < endl ;
}
}
TQImage image ( m_pBuffer - > buffer ( ) ) ;
delete m_pBuffer ;
m_pBuffer = 0 ;
if ( ! image . isNull ( ) )
{
TQSize size = image . size ( ) ;
m_pCanvas - > setImage ( image , size ) ;
}
else
{
emit setStatusBarText ( i18n ( " Unknown image format: %1 " ) . arg ( m_url . prettyURL ( ) ) ) ;
return false ;
}
}
else
{ //load from local file
kdDebug ( 4610 ) < < k_funcinfo < < " load from file: " < < m_file < < endl ;
if ( ! TQFile : : exists ( m_file ) )
{
emit setStatusBarText ( i18n ( " No such file: %1 " ) . arg ( m_file ) ) ;
return false ;
}
if ( TQImage : : imageFormat ( m_file ) = = 0 )
{
emit setStatusBarText ( i18n ( " Unknown image format: %1 " ) . arg ( m_file ) ) ;
return false ;
}
// determine Mime Type
if ( m_mimeType . isNull ( ) )
{
m_mimeType = KImageIO : : mimeType ( m_file ) ;
kdDebug ( 4610 ) < < " MimeType: " < < m_mimeType < < endl ;
}
//load from file
TQImage image ( m_file ) ;
TQSize size = image . size ( ) ;
m_pCanvas - > setImage ( image , size ) ;
}
m_pFileWatch - > addFile ( m_file ) ;
emit imageOpened ( m_url ) ;
return true ;
}
bool KViewViewer : : saveFile ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
// two possibilities:
//
// 1. The image should be saved as an exact copy of the loaded one (this
// is useful if you downloaded an image from the net and want to save it
// locally) - this can happen only in saveAs() so only 2. applies here:
//
// 2. The image should be saved in a different format or was modified, so
// that copying isn't possible anymore.
const TQImage * image = m_pCanvas - > image ( ) ;
if ( ! image )
return false ;
if ( ! m_newMimeType . isNull ( ) )
{
m_mimeType = m_newMimeType ;
m_newMimeType = TQString ( ) ;
}
TQString type = KImageIO : : typeForMime ( m_mimeType ) ;
kdDebug ( 4610 ) < < " save m_pCanvas->image() to " < < m_file < < " as " < < type < < endl ;
int quality = 100 ; // TODO: ask user for quality. Keep it at 100 so that our
// users don't lose quality when working with KView.
m_pFileWatch - > removeFile ( m_file ) ;
bool ret = image - > save ( m_file , type . latin1 ( ) , quality ) ;
m_pFileWatch - > addFile ( m_file ) ;
return ret ;
}
void KViewViewer : : setupActions ( )
{
m_paZoomIn = new KAction ( i18n ( " Zoom In " ) , " viewmag+ " , KStdAccel : : shortcut ( KStdAccel : : ZoomIn ) , this ,
TQT_SLOT ( slotZoomIn ( ) ) , actionCollection ( ) , " zoomin " ) ;
m_paZoomOut = new KAction ( i18n ( " Zoom Out " ) , " viewmag- " , KStdAccel : : shortcut ( KStdAccel : : ZoomOut ) , this ,
TQT_SLOT ( slotZoomOut ( ) ) , actionCollection ( ) , " zoomout " ) ;
m_paZoom = new KSelectAction ( i18n ( " Zoom " ) , " viewmag " , 0 , actionCollection ( ) , " view_zoom " ) ;
connect ( m_paZoom , TQT_SIGNAL ( activated ( const TQString & ) ) , this , TQT_SLOT ( setZoom ( const TQString & ) ) ) ;
m_paZoom - > setEditable ( true ) ;
m_paZoom - > clear ( ) ;
m_paZoom - > setItems ( TQStringList : : split ( ' | ' , " 20%|25%|33%|50%|75%|100%|125%|150%|200%|250%|300%|350%|400%|450%|500% " ) ) ;
m_paZoom - > setCurrentItem ( 5 ) ;
m_paFlipMenu = new KActionMenu ( i18n ( " &Flip " ) , actionCollection ( ) , " flip " ) ;
m_paFlipV = new KAction ( i18n ( " &Vertical " ) , Key_V , this , TQT_SLOT ( slotFlipV ( ) ) , actionCollection ( ) , " flip_vertical " ) ;
m_paFlipH = new KAction ( i18n ( " &Horizontal " ) , Key_H , this , TQT_SLOT ( slotFlipH ( ) ) , actionCollection ( ) , " flip_horizontal " ) ;
m_paFlipMenu - > insert ( m_paFlipV ) ;
m_paFlipMenu - > insert ( m_paFlipH ) ;
m_paRotateCCW = new KAction ( i18n ( " Ro&tate Counter-Clockwise " ) , " rotate_ccw " , 0 , this ,
TQT_SLOT ( slotRotateCCW ( ) ) , actionCollection ( ) , " rotateCCW " ) ;
m_paRotateCW = new KAction ( i18n ( " Rotate Clockwise " ) , " rotate_cw " , 0 , this ,
TQT_SLOT ( slotRotateCW ( ) ) , actionCollection ( ) , " rotateCW " ) ;
m_paSave = KStdAction : : save ( this , TQT_SLOT ( slotSave ( ) ) , actionCollection ( ) ) ;
m_paSave - > setEnabled ( false ) ;
m_paSaveAs = KStdAction : : saveAs ( this , TQT_SLOT ( slotSaveAs ( ) ) , actionCollection ( ) ) ;
m_paFitToWin = new KAction ( i18n ( " Fit Image to Window " ) , 0 , 0 , this ,
TQT_SLOT ( slotFitToWin ( ) ) , actionCollection ( ) , " fittowin " ) ;
m_paZoomIn - > setEnabled ( false ) ;
m_paZoomOut - > setEnabled ( false ) ;
m_paZoom - > setEnabled ( false ) ;
m_paRotateCCW - > setEnabled ( false ) ;
m_paRotateCW - > setEnabled ( false ) ;
m_paSaveAs - > setEnabled ( false ) ;
m_paFitToWin - > setEnabled ( false ) ;
m_paFlipMenu - > setEnabled ( false ) ;
m_paFlipV - > setEnabled ( false ) ;
m_paFlipH - > setEnabled ( false ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paZoomIn , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paZoomOut , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paZoom , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paRotateCCW , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paRotateCW , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paSaveAs , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paFitToWin , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paFlipMenu , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paFlipV , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( widget ( ) , TQT_SIGNAL ( hasImage ( bool ) ) , m_paFlipH , TQT_SLOT ( setEnabled ( bool ) ) ) ;
m_paShowScrollbars = new KToggleAction ( i18n ( " Show Scrollbars " ) , 0 , this , TQT_SLOT ( slotToggleScrollbars ( ) ) ,
actionCollection ( ) , " show_scrollbars " ) ;
m_paShowScrollbars - > setCheckedState ( i18n ( " Hide Scrollbars " ) ) ;
}
void KViewViewer : : guiActivateEvent ( KParts : : GUIActivateEvent * event )
{
ReadWritePart : : guiActivateEvent ( event ) ;
bool enabled = m_pCanvas - > image ( ) ? true : false ;
emit m_pExtension - > enableAction ( " del " , enabled ) ;
emit m_pExtension - > enableAction ( " print " , enabled ) ;
if ( ! enabled )
{
m_sCaption = i18n ( " Title caption when no image loaded " , " no image loaded " ) ;
emit setWindowCaption ( m_sCaption ) ;
}
}
void KViewViewer : : readSettings ( )
{
KConfigGroup cfgGroup ( instance ( ) - > config ( ) , " Settings " ) ;
m_pCanvas - > setFastScale ( ! cfgGroup . readBoolEntry ( " Smooth Scaling " , ! m_pCanvas - > fastScale ( ) ) ) ;
m_pCanvas - > setKeepAspectRatio ( cfgGroup . readBoolEntry ( " Keep Aspect Ratio " , m_pCanvas - > keepAspectRatio ( ) ) ) ;
m_pCanvas - > setCentered ( cfgGroup . readBoolEntry ( " Center Image " , m_pCanvas - > centered ( ) ) ) ;
m_pCanvas - > setBgColor ( cfgGroup . readColorEntry ( " Background Color " , & m_pCanvas - > bgColor ( ) ) ) ;
m_pCanvas - > setMinimumImageSize ( TQSize ( cfgGroup . readNumEntry ( " Minimum Width " , m_pCanvas - > minimumImageSize ( ) . width ( ) ) ,
cfgGroup . readNumEntry ( " Minimum Height " , m_pCanvas - > minimumImageSize ( ) . height ( ) ) ) ) ;
m_pCanvas - > setMaximumImageSize ( TQSize ( cfgGroup . readNumEntry ( " Maximum Width " , m_pCanvas - > maximumImageSize ( ) . width ( ) ) ,
cfgGroup . readNumEntry ( " Maximum Height " , m_pCanvas - > maximumImageSize ( ) . height ( ) ) ) ) ;
KConfigGroup blendConfig ( instance ( ) - > config ( ) , " Blend Effects " ) ;
m_vEffects . clear ( ) ;
for ( unsigned int i = 1 ; i < = m_pCanvas - > numOfBlendEffects ( ) ; + + i )
{
if ( blendConfig . readBoolEntry ( TQString : : number ( i ) , false ) )
m_vEffects . push_back ( i ) ;
}
// and now tell the canvas what blend effect to use
switchBlendEffect ( ) ;
loadPlugins ( ) ;
}
void KViewViewer : : writeSettings ( )
{
KConfigGroup cfgGroup ( instance ( ) - > config ( ) , " Settings " ) ;
cfgGroup . writeEntry ( " hideScrollbars " , ! m_paShowScrollbars - > isChecked ( ) ) ;
}
void KViewViewer : : zoomChanged ( double zoom )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
emit setWindowCaption ( m_sCaption + TQString ( " (%1%) " ).arg( zoom * 100, 0, 'f', 0 ) ) ;
updateZoomMenu ( zoom ) ;
}
void KViewViewer : : slotJobFinished ( KIO : : Job * job )
{
assert ( job = = m_pJob ) ;
m_pJob = 0 ;
if ( job - > error ( ) )
emit canceled ( job - > errorString ( ) ) ;
else
{
openFile ( ) ;
emit completed ( ) ;
}
}
void KViewViewer : : slotData ( KIO : : Job * , const TQByteArray & data )
{
if ( ! m_pBuffer )
{
m_pBuffer = new TQBuffer ( ) ;
m_pBuffer - > open ( IO_ReadWrite ) ;
}
m_pBuffer - > writeBlock ( data . data ( ) , data . size ( ) ) ;
//show partial image XXX: is this really the way to do it?
//No. :) It takes forever like this.
//OK. So I really have to look at khtml...
//later...
//m_pCanvas->setImage( TQImage( m_pBuffer->buffer() ) );
}
void KViewViewer : : slotSave ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
if ( ! save ( ) )
KMessageBox : : error ( m_pParentWidget , i18n ( " The image could not be saved to disk. A possible causes is that you don't have permission to write to that file. " ) ) ;
}
void KViewViewer : : slotSaveAs ( )
{
kdDebug ( 4610 ) < < k_funcinfo < < endl ;
KFileDialog dlg ( TQString ( ) , TQString ( ) , widget ( ) , " filedialog " , true ) ;
dlg . setMimeFilter ( KImageIO : : mimeTypes ( KImageIO : : Writing ) ) ;
dlg . setSelection ( m_url . fileName ( ) ) ;
dlg . setCaption ( i18n ( " Save As " ) ) ;
dlg . setOperationMode ( KFileDialog : : Saving ) ;
dlg . exec ( ) ;
KURL url = dlg . selectedURL ( ) ;
m_newMimeType = dlg . currentMimeFilter ( ) ;
if ( m_newMimeType . isEmpty ( ) )
m_newMimeType = KImageIO : : mimeType ( url . path ( ) ) ;
kdDebug ( 4610 ) < < k_funcinfo < < " m_newMimeType = " < < m_newMimeType < < endl ;
if ( url . isValid ( ) )
KRecentDocument : : add ( url ) ;
saveAs ( url ) ;
}
void KViewViewer : : slotZoomIn ( )
{
double zoom = m_pCanvas - > zoom ( ) * 1.1 ;
if ( zoom < 0.01 ) zoom = 0.01 ;
m_pCanvas - > setZoom ( zoom ) ;
}
void KViewViewer : : slotZoomOut ( )
{
double zoom = m_pCanvas - > zoom ( ) / 1.1 ;
if ( zoom < 0.01 ) zoom = 0.01 ;
m_pCanvas - > setZoom ( zoom ) ;
}
void KViewViewer : : setZoom ( const TQString & newZoom )
{
kdDebug ( 4610 ) < < k_funcinfo < < newZoom < < endl ;
double zoom ;
TQString z = newZoom ;
z . remove ( z . find ( ' % ' ) , 1 ) ;
if ( newZoom = = " 33% " )
zoom = 1.0 / 3.0 ;
else
zoom = KGlobal : : locale ( ) - > readNumber ( z ) / 100 ;
m_pCanvas - > setZoom ( zoom ) ;
}
void KViewViewer : : updateZoomMenu ( double zoom )
{
TQStringList lst ;
if ( zoom > 0.0 )
{
//lst << i18n( "Maxpect" );
TQValueList < int > list ;
TQString z ;
int val ;
bool ok ;
TQStringList itemsList = m_paZoom - > items ( ) ;
for ( TQStringList : : Iterator it = itemsList . begin ( ) ; it ! = itemsList . end ( ) ; + + it )
{
z = ( * it ) . replace ( TQRegExp ( " % " ) , " " ) ;
z = z . simplifyWhiteSpace ( ) ;
val = z . toInt ( & ok ) ;
if ( ok & & val > 0 & & list . contains ( val ) = = 0 )
list < < val ;
}
val = TQString : : number ( zoom * 100 , ' f ' , 0 ) . toInt ( ) ; // round/lround from math.h doesn't work - dunno
if ( list . contains ( val ) = = 0 )
list . append ( val ) ;
qHeapSort ( list ) ;
for ( TQValueList < int > : : Iterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
lst < < TQString : : number ( * it ) + ' % ' ;
m_paZoom - > setItems ( lst ) ;
}
// first look if it's a new value (not in the list yet)
TQString z = TQString ( " %1% " ) . arg ( zoom * 100 , 0 , ' f ' , 0 ) ;
TQStringList items = m_paZoom - > items ( ) ;
int idx = items . findIndex ( z ) ;
if ( - 1 = = idx )
{
// not found XXX: remove when done
kdDebug ( 4610 ) < < " zoom value not in the list: " < < z < < endl ;
kdDebug ( 4610 ) < < " here's the list: \n - " < < items . join ( " \n - " ) < < endl ;
}
else
{
// already in the list
kdDebug ( 4610 ) < < " zoom value already in the list: " < < z < < endl ;
// make that one selected
m_paZoom - > setCurrentItem ( idx ) ;
}
}
void KViewViewer : : slotFlipH ( )
{
m_pCanvas - > flipVertical ( isReadWrite ( ) ) ;
}
void KViewViewer : : slotFlipV ( )
{
m_pCanvas - > flipHorizontal ( isReadWrite ( ) ) ;
}
void KViewViewer : : slotRotateCCW ( )
{
m_pCanvas - > rotate ( - 90.0 , isReadWrite ( ) ) ;
}
void KViewViewer : : slotRotateCW ( )
{
m_pCanvas - > rotate ( 90.0 , isReadWrite ( ) ) ;
}
void KViewViewer : : slotFitToWin ( )
{
m_pCanvas - > boundImageTo ( widget ( ) - > size ( ) ) ;
}
void KViewViewer : : slotDel ( )
{
//just in case m_url get's modified while closing
KURL urltodel = m_url ;
if ( closeURL ( ) )
{
setModified ( false ) ;
KIO : : file_delete ( urltodel ) ;
m_pCanvas - > clear ( ) ;
}
}
class PopupGUIClient : public KXMLGUIClient
{
public :
PopupGUIClient ( KInstance * inst , const TQString & doc )
{
setInstance ( inst ) ;
setXML ( doc ) ;
}
} ;
void KViewViewer : : slotPopupMenu ( const TQPoint & pos )
{
KXMLGUIClient * popupGUIClient = new PopupGUIClient ( instance ( ) , m_popupDoc ) ;
( void ) new KAction ( i18n ( " Save Image As... " ) , 0 , this , TQT_SLOT ( slotSaveAs ( ) ) ,
popupGUIClient - > actionCollection ( ) , " saveimageas " ) ;
// ### HACK treat the image as dir to get the back/fwd/reload buttons (Simon)
emit m_pExtension - > popupMenu ( popupGUIClient , pos , m_url , m_mimeType , S_IFDIR ) ;
delete popupGUIClient ;
}
void KViewViewer : : slotResultSaveAs ( KIO : : Job * job )
{
if ( job - > error ( ) )
{
emit canceled ( job - > errorString ( ) ) ;
//job->showErrorDialog( widget() );
}
else
{
emit completed ( ) ;
KIO : : CopyJob * cjob = : : tqqt_cast < KIO : : CopyJob * > ( job ) ;
if ( cjob )
{
m_url = cjob - > destURL ( ) ;
m_sCaption = m_url . prettyURL ( ) ;
}
else
m_sCaption = " " ;
emit setWindowCaption ( m_sCaption ) ;
}
// Now we have to delete the tempfile if it exists and if the current
// image position is on the local HD. If it's somewhere else we keep the
// tempfile in case the user calls saveAs() again.
if ( m_url . isLocalFile ( ) )
{
if ( m_bTemp )
{
unlink ( TQFile : : encodeName ( m_file ) ) ;
m_bTemp = false ;
}
m_file = m_url . path ( ) ;
}
}
void KViewViewer : : slotFileDirty ( const TQString & )
{
if ( isModified ( ) & & isReadWrite ( ) )
{
KPassivePopup * pop = new KPassivePopup ( m_pParentWidget ) ;
TQVBox * vb = pop - > standardView ( i18n ( " Load changed image? - %1 " ) . arg ( kapp - > aboutData ( ) - > programName ( ) ) ,
TQString ( ) , kapp - > miniIcon ( ) ) ;
( void ) new TQLabel ( i18n ( " The image %1 which you have modified has changed on disk. \n "
" Do you want to reload the file and lose your changes? \n "
" If you don't and subsequently save the image, you will lose the \n "
" changes that have already been saved. " ) . arg ( url ( ) . fileName ( ) ) , vb ) ;
TQWidget * hb = new TQWidget ( vb ) ;
TQHBoxLayout * tqlayout = new TQHBoxLayout ( hb ) ;
tqlayout - > addItem ( new TQSpacerItem ( 0 , 0 , TQSizePolicy : : Minimum , TQSizePolicy : : Minimum ) ) ;
KPushButton * yes = new KPushButton ( i18n ( " Reload " ) , hb ) ;
tqlayout - > addWidget ( yes ) ;
tqlayout - > addItem ( new TQSpacerItem ( 0 , 0 , TQSizePolicy : : Minimum , TQSizePolicy : : Minimum ) ) ;
KPushButton * no = new KPushButton ( i18n ( " Do Not Reload " ) , hb ) ;
tqlayout - > addWidget ( no ) ;
tqlayout - > addItem ( new TQSpacerItem ( 0 , 0 , TQSizePolicy : : Minimum , TQSizePolicy : : Minimum ) ) ;
connect ( yes , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( slotReloadUnmodified ( ) ) ) ;
connect ( yes , TQT_SIGNAL ( clicked ( ) ) , pop , TQT_SLOT ( hide ( ) ) ) ;
connect ( no , TQT_SIGNAL ( clicked ( ) ) , pop , TQT_SLOT ( hide ( ) ) ) ;
pop - > setView ( vb ) ;
pop - > setTimeout ( 0 ) ;
pop - > setAutoDelete ( true ) ;
pop - > show ( ) ;
kdDebug ( 4610 ) < < " popup returned \n " ;
}
else
reload ( ) ;
}
void KViewViewer : : slotReloadUnmodified ( )
{
setModified ( false ) ;
reload ( ) ;
kdDebug ( 4610 ) < < " reload done \n " ;
}
void KViewViewer : : slotToggleScrollbars ( )
{
m_pCanvas - > hideScrollbars ( ! m_paShowScrollbars - > isChecked ( ) ) ;
}
void KViewViewer : : loadPlugins ( )
{
KImageViewer : : Viewer : : loadPlugins ( this , this , instance ( ) ) ;
if ( factory ( ) )
{
TQPtrList < KParts : : Plugin > plugins = KParts : : Plugin : : pluginObjects ( this ) ;
KParts : : Plugin * plugin ;
for ( plugin = plugins . first ( ) ; plugin ; plugin = plugins . next ( ) )
factory ( ) - > addClient ( plugin ) ;
}
}
void KViewViewer : : switchBlendEffect ( )
{
if ( m_vEffects . empty ( ) )
m_pCanvas - > setBlendEffect ( 0 ) ;
else
{
unsigned int num = KApplication : : random ( ) % m_vEffects . size ( ) ;
m_pCanvas - > setBlendEffect ( m_vEffects [ num ] ) ;
}
}
void KViewViewer : : hasImage ( bool b )
{
emit m_pExtension - > enableAction ( " del " , b ) ;
emit m_pExtension - > enableAction ( " print " , b ) ;
if ( ! b )
{
m_sCaption = i18n ( " Title caption when no image loaded " , " No Image Loaded " ) ;
emit setWindowCaption ( m_sCaption ) ;
}
}
// vim:sw=4:ts=4
# include "kviewviewer.moc"