/***************************************************************************
scanpackager . cpp - description
- - - - - - - - - - - - - - - - - - -
begin : Fri Dec 17 1999
copyright : ( C ) 1999 by Klaas Freitag
email : freitag @ suse . de
$ Id $
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* This file may be distributed and / or modified under the terms of the *
* GNU General Public License version 2 as published by the Free Software *
* Foundation and appearing in the file COPYING included in the *
* packaging of this file . *
*
* As a special exception , permission is given to link this program *
* with any version of the KADMOS ocr / icr engine of reRecognition GmbH , *
* Kreuzlingen and distribute the resulting executable without *
* including the source code for KADMOS in the source distribution . *
*
* As a special exception , permission is given to link this program *
* with any edition of TQt , and distribute the resulting executable , *
* without including the source code for TQt in the source distribution . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "scanpackager.h"
# include "resource.h"
# include "img_saver.h"
# include "kookaimage.h"
# include "kookaimagemeta.h"
# include "previewer.h"
# include "devselector.h"
# include <tqapplication.h>
# include <tqdir.h>
# include <tqfile.h>
# include <tqpopupmenu.h>
# include <tqdict.h>
# include <tqpixmap.h>
# include <kmessagebox.h>
# include <tqfiledialog.h>
# include <tqstringlist.h>
# include <tqheader.h>
# include <tdefiletreeview.h>
# include <tdefiletreeviewitem.h>
# include <tdefiletreebranch.h>
# include <kurldrag.h>
# include <tdepopupmenu.h>
# include <tdeaction.h>
# include <kinputdialog.h>
# include <kiconloader.h>
# include <tdefiledialog.h>
# include <kurl.h>
# include <kdebug.h>
# include <klocale.h>
# include <kglobal.h>
# include <tdeio/global.h>
# include <tdeio/progressbase.h>
# include <tdeio/netaccess.h>
# include <tdeio/jobclasses.h>
# include <tdeio/file.h>
# include <tdeio/job.h>
# define STARTUP_FIRST_START "firstStart"
/* ----------------------------------------------------------------------- */
/* Constructor Scan Packager */
ScanPackager : : ScanPackager ( TQWidget * parent ) : KFileTreeView ( parent )
{
// TODO:
setItemsRenameable ( true ) ;
setDefaultRenameAction ( TQListView : : Reject ) ;
addColumn ( i18n ( " Image Name " ) ) ;
setColumnAlignment ( 0 , AlignLeft ) ;
addColumn ( i18n ( " Size " ) ) ;
setColumnAlignment ( 1 , AlignRight ) ;
setColumnAlignment ( 2 , AlignRight ) ;
addColumn ( i18n ( " Format " ) ) ; setColumnAlignment ( 3 , AlignRight ) ;
/* Drag and Drop */
setDragEnabled ( true ) ;
setDropVisualizer ( true ) ;
setAcceptDrops ( true ) ;
connect ( this , TQT_SIGNAL ( dropped ( TQWidget * , TQDropEvent * , KURL : : List & , KURL & ) ) ,
this , TQT_SLOT ( slotUrlsDropped ( TQWidget * , TQDropEvent * , KURL : : List & , KURL & ) ) ) ;
kdDebug ( 28000 ) < < " connected Drop-Signal " < < endl ;
setRenameable ( 0 , true ) ;
setRenameable ( 1 , false ) ;
setRenameable ( 2 , false ) ;
setRenameable ( 3 , false ) ;
setRootIsDecorated ( false ) ;
connect ( this , TQT_SIGNAL ( clicked ( TQListViewItem * ) ) ,
TQT_SLOT ( slClicked ( TQListViewItem * ) ) ) ;
connect ( this , TQT_SIGNAL ( rightButtonPressed ( TQListViewItem * , const TQPoint & , int ) ) ,
TQT_SLOT ( slShowContextMenue ( TQListViewItem * , const TQPoint & , int ) ) ) ;
connect ( this , TQT_SIGNAL ( itemRenamed ( TQListViewItem * , const TQString & , int ) ) , this ,
TQT_SLOT ( slFileRename ( TQListViewItem * , const TQString & , int ) ) ) ;
img_counter = 1 ;
/* Set the current export dir to home */
m_currCopyDir = TQDir : : home ( ) . absPath ( ) ;
m_currImportDir = m_currCopyDir ;
/* Preload frequently used icons */
TDEIconLoader * loader = TDEGlobal : : iconLoader ( ) ;
m_floppyPixmap = loader - > loadIcon ( " 3floppy_unmount " , TDEIcon : : Small ) ;
m_grayPixmap = loader - > loadIcon ( " palette_gray " , TDEIcon : : Small ) ;
m_bwPixmap = loader - > loadIcon ( " palette_lineart " , TDEIcon : : Small ) ;
m_colorPixmap = loader - > loadIcon ( " palette_color " , TDEIcon : : Small ) ;
m_startup = true ;
/* create a context menu and set the title */
m_contextMenu = new TDEPopupMenu ( ) ;
static_cast < TDEPopupMenu * > ( m_contextMenu ) - > insertTitle ( i18n ( " Gallery " ) ) ;
}
void ScanPackager : : openRoots ( )
{
/* standard root always exists, ImgRoot creates it */
KURL rootUrl ( Previewer : : galleryRoot ( ) ) ;
kdDebug ( 28000 ) < < " Open standard root " < < rootUrl . url ( ) < < endl ;
openRoot ( rootUrl , true ) ;
m_defaultBranch - > setOpen ( true ) ;
/* open more configurable image repositories TODO */
}
KFileTreeBranch * ScanPackager : : openRoot ( const KURL & root , bool )
{
TDEIconLoader * loader = TDEGlobal : : iconLoader ( ) ;
/* working on the global branch. FIXME */
m_defaultBranch = addBranch ( root , i18n ( " Kooka Gallery " ) ,
loader - > loadIcon ( " folder_image " , TDEIcon : : Small ) ,
false /* do not showHidden */ ) ;
// TQ_CHECK_PTR( m_defaultBranch );
m_defaultBranch - > setOpenPixmap ( loader - > loadIcon ( " folder_blue_open " , TDEIcon : : Small ) ) ;
setDirOnlyMode ( m_defaultBranch , false ) ;
m_defaultBranch - > setShowExtensions ( true ) ; // false );
connect ( m_defaultBranch , TQT_SIGNAL ( newTreeViewItems ( KFileTreeBranch * , const KFileTreeViewItemList & ) ) ,
this , TQT_SLOT ( slotDecorate ( KFileTreeBranch * , const KFileTreeViewItemList & ) ) ) ;
connect ( m_defaultBranch , TQT_SIGNAL ( directoryChildCount ( KFileTreeViewItem * , int ) ) ,
this , TQT_SLOT ( slotDirCount ( KFileTreeViewItem * , int ) ) ) ;
connect ( m_defaultBranch , TQT_SIGNAL ( deleteItem ( KFileItem * ) ) ,
this , TQT_SLOT ( slotDeleteFromBranch ( KFileItem * ) ) ) ;
connect ( m_defaultBranch , TQT_SIGNAL ( populateFinished ( KFileTreeViewItem * ) ) ,
this , TQT_SLOT ( slotStartupFinished ( KFileTreeViewItem * ) ) ) ;
return ( m_defaultBranch ) ;
}
void ScanPackager : : slotStartupFinished ( KFileTreeViewItem * it )
{
if ( m_startup & & ( it = = m_defaultBranch - > root ( ) ) )
{
kdDebug ( 28000 ) < < " Slot population finished hit! " < < endl ;
/* If nothing is selected, select the root. */
if ( ! currentKFileTreeViewItem ( ) )
{
( m_defaultBranch - > root ( ) ) - > setSelected ( true ) ;
}
m_startup = false ;
}
}
void ScanPackager : : slotDirCount ( KFileTreeViewItem * item , int cnt )
{
if ( item & & item - > isDir ( ) )
{
TQString cc = i18n ( " one item " , " %n items " , cnt ) ;
item - > setText ( 1 , cc ) ;
}
else
{
kdDebug ( 28000 ) < < " Item is NOT directory - do not set child count! " < < endl ;
}
}
void ScanPackager : : slotDecorate ( KFileTreeViewItem * item )
{
if ( ! item ) return ;
if ( item - > isDir ( ) )
{
// done in extra slot.
kdDebug ( 28000 ) < < " Decorating directory! " < < endl ;
}
else
{
KFileItem * kfi = item - > fileItem ( ) ;
KookaImage * img = 0L ;
if ( kfi )
{
img = static_cast < KookaImage * > ( kfi - > extraData ( this ) ) ;
}
if ( img )
{
/* The image appears to be loaded to memory. */
if ( img - > depth ( ) = = 1 )
{
/* a bw-image */
item - > setPixmap ( 0 , m_bwPixmap ) ;
}
else
{
if ( img - > isGrayscale ( ) )
{
item - > setPixmap ( 0 , m_grayPixmap ) ;
}
else
{
item - > setPixmap ( 0 , m_colorPixmap ) ;
}
}
/* set image size in pixels */
TQString t = i18n ( " %1 x %2 " ) . arg ( img - > width ( ) ) . arg ( img - > height ( ) ) ;
item - > setText ( 1 , t ) ;
kdDebug ( 28000 ) < < " Image loaded and decorated! " < < endl ;
}
else
{
/* Item is not yet loaded. Display file information */
item - > setPixmap ( 0 , m_floppyPixmap ) ;
if ( kfi )
{
item - > setText ( 1 , TDEIO : : convertSize ( kfi - > size ( ) ) ) ;
}
}
/* Image format */
TQString format = getImgFormat ( item ) ;
item - > setText ( 2 , format ) ;
}
// This code is quite similar to m_nextUrlToSelect in KFileTreeView::slotNewTreeViewItems
// When scanning a new image, we wait for the KDirLister to notice the new file,
// and then we have the KFileTreeViewItem that we need to display the image.
if ( ! m_nextUrlToShow . isEmpty ( ) )
{
if ( m_nextUrlToShow . equals ( item - > url ( ) , true ) )
{
m_nextUrlToShow = KURL ( ) ; // do this first to prevent recursion
slClicked ( item ) ;
setCurrentItem ( item ) ; // neccessary in case of new file from D&D
}
}
}
void ScanPackager : : slotDecorate ( KFileTreeBranch * branch , const KFileTreeViewItemList & list )
{
( void ) branch ;
kdDebug ( 28000 ) < < " decorating slot for list ! " < < endl ;
KFileTreeViewItemListIterator it ( list ) ;
bool end = false ;
for ( ; ! end & & it . current ( ) ; + + it )
{
KFileTreeViewItem * kftvi = * it ;
slotDecorate ( kftvi ) ;
emit fileChanged ( kftvi - > fileItem ( ) ) ;
}
}
void ScanPackager : : slFileRename ( TQListViewItem * it , const TQString & newStr , int )
{
bool success = true ;
if ( ! it ) return ;
if ( newStr . isEmpty ( ) )
success = false ;
KFileTreeViewItem * item = static_cast < KFileTreeViewItem * > ( it ) ;
/* Free memory and imform everybody who is interested. */
KURL urlFrom = item - > url ( ) ;
KURL urlTo ( urlFrom ) ;
/* clean filename and apply new name */
urlTo . setFileName ( " " ) ;
urlTo . setFileName ( newStr ) ;
if ( success )
{
if ( urlFrom = = urlTo )
{
kdDebug ( 28000 ) < < " Renaming to same url does not make sense! " < < endl ;
success = false ;
}
else
{
/* clear selection, because the renamed image comes in through
* kdirlister again
*/
slotUnloadItem ( item ) ;
kdDebug ( 28000 ) < < " Renaming to " < < urlTo . prettyURL ( ) < <
" from " < < urlFrom . prettyURL ( ) < < endl ;
/* to urlTo the really used filename is written */
setSelected ( item , false ) ;
if ( ImgSaver : : renameImage ( urlFrom , urlTo , false , this ) )
{
kdDebug ( 28000 ) < < " renaming OK " < < endl ;
emit fileRenamed ( item - > fileItem ( ) , urlTo ) ;
success = true ;
}
else
{
success = false ;
}
}
}
if ( ! success )
{
kdDebug ( 28000 ) < < " renaming failed " < < endl ;
/* restore the name */
item - > setText ( 0 , urlFrom . fileName ( ) ) ;
setSelected ( item , true ) ;
}
}
/* ----------------------------------------------------------------------- */
/*
* Method that checks if the new filename a user enters while renaming an image is valid .
* It checks for a proper extension .
*/
TQString ScanPackager : : buildNewFilename ( TQString cmplFilename , TQString currFormat ) const
{
/* cmplFilename = new name the user wishes.
* currFormat = the current format of the image .
* if the new filename has a valid extension , which is the same as the
* format of the current , fine . A ' ' - String has to be returned .
*/
TQFileInfo fiNew ( cmplFilename ) ;
TQString base = fiNew . baseName ( ) ;
TQString newExt = fiNew . extension ( false ) . lower ( ) ;
TQString nowExt = currFormat . lower ( ) ;
TQString ext = " " ;
kdDebug ( 28000 ) < < " Filename wanted: " < < cmplFilename < < " < " < < newExt < < " > < " < < nowExt < < " > " < < endl ;
if ( newExt . isEmpty ( ) )
{
/* ok, fine -> return the currFormat-Extension */
ext = base + " . " + currFormat ;
}
else if ( newExt = = nowExt )
{
/* also good, no reason to put another extension */
ext = cmplFilename ;
}
else
{
/* new Ext. differs from the current extension. Later. */
KMessageBox : : sorry ( 0L , i18n ( " You entered a file extension that differs from the existing one. That is not yet possible. Converting 'on the fly' is planned for a future release. \n "
" Kooka corrects the extension. " ) ,
i18n ( " On the Fly Conversion " ) ) ;
ext = base + " . " + currFormat ;
}
return ( ext ) ;
}
/* ----------------------------------------------------------------------- */
/* This method returns the directory of an image or directory.
*/
TQString ScanPackager : : itemDirectory ( const KFileTreeViewItem * item , bool relativ ) const
{
if ( ! item )
{
kdDebug ( 28000 ) < < " ERR: itemDirectory without item " < < endl ;
return TQString ( ) ;
}
TQString relativUrl = ( item - > url ( ) ) . prettyURL ( ) ;
if ( ! item - > isDir ( ) )
{
// Cut off the filename in case it is not a dir
relativUrl . truncate ( relativUrl . findRev ( ' / ' ) + 1 ) ;
}
else
{
/* add a "/" to the directory if not there */
if ( ! relativUrl . endsWith ( " / " ) )
relativUrl . append ( " / " ) ;
}
if ( relativ )
{
KFileTreeBranch * branch = item - > branch ( ) ;
if ( branch )
{
kdDebug ( 28000 ) < < " Relativ URL of the file " < < relativUrl < < endl ;
TQString rootUrl = ( branch - > rootUrl ( ) ) . prettyURL ( ) ; // directory of branch root
if ( relativUrl . startsWith ( rootUrl ) )
{
relativUrl . remove ( 0 , rootUrl . length ( ) ) ;
if ( relativUrl . isEmpty ( ) ) relativUrl = " / " ; // The root
}
else
{
kdDebug ( 28000 ) < < " ERR: Item-URL does not start with root url " < < rootUrl < < endl ;
}
}
}
return ( relativUrl ) ;
}
/* ----------------------------------------------------------------------- */
/* This slot receives a string from the gallery-path combobox shown under the
* image gallery . The form of the string coming in here is < branch - name > - <
* relativ directory under the branch . Now it is to assemble a complete path
* from the data , find out which KFileTreeViewItem is associated with it and
* call slClicked with it .
*/
void ScanPackager : : slotSelectDirectory ( const TQString & dirString )
{
kdDebug ( 28000 ) < < " Trying to decode directory string " < < dirString < < endl ;
TQString searchFor = TQString : : fromLatin1 ( " - " ) ;
int pos = dirString . find ( searchFor ) ;
if ( pos > - 1 )
{
/* Splitting up the string coming in */
TQString branchName = dirString . left ( pos ) ;
TQString relPath ( dirString ) ;
relPath = relPath . remove ( 0 , pos + searchFor . length ( ) ) ;
kdDebug ( 28000 ) < < " Splitted up to branch < " < < branchName < < " > and < " < < relPath < < endl ;
KFileTreeViewItem * kfi = findItem ( branchName , relPath ) ;
if ( kfi )
{
kdDebug ( 28000 ) < < " got a new item to select ! " < < endl ;
ensureItemVisible ( kfi ) ;
setCurrentItem ( kfi ) ;
slClicked ( kfi ) ; // load thumbnails for this dir etc.
}
}
}
/* ----------------------------------------------------------------------- */
/* This slot is called when clicking on an item. */
void ScanPackager : : slClicked ( TQListViewItem * newItem )
{
KFileTreeViewItem * item = static_cast < KFileTreeViewItem * > ( newItem ) ;
if ( item ) // can be 0, when clicking where no item is present
{
kdDebug ( 28000 ) < < " Clicked - newItem ! " < < endl ;
/* Check if directory, hide image for now, later show a thumb view */
if ( item - > isDir ( ) )
{
kdDebug ( 28000 ) < < " clicked: Is a directory ! " < < endl ;
emit ( showImage ( 0L ) ) ;
kdDebug ( 28000 ) < < " emitting showThumbnails " < < endl ;
}
else
{
/* if not a dir, load the image if necessary. This is done by loadImageForItem,
* which is async ( TODO ) . The image finally arrives in slotImageArrived */
TQApplication : : setOverrideCursor ( waitCursor ) ;
emit ( aboutToShowImage ( item - > url ( ) ) ) ;
loadImageForItem ( item ) ;
TQApplication : : restoreOverrideCursor ( ) ;
}
/* emit a signal indicating the new directory if there is a new one */
TQString wholeDir = itemDirectory ( item , false ) ; /* not relativ to root */
if ( currSelectedDir ! = wholeDir )
{
currSelectedDir = wholeDir ;
TQString relativUrl = itemDirectory ( item , true ) ;
kdDebug ( 28000 ) < < " Emitting " < < relativUrl < < " as new relative Url " < < endl ;
/* Emit the signal with branch and the relative path */
emit ( galleryPathSelected ( item - > branch ( ) , relativUrl ) ) ;
if ( item - > isDir ( ) )
{
emit ( showThumbnails ( item ) ) ;
}
else
{
emit ( showThumbnails ( static_cast < KFileTreeViewItem * > ( item - > parent ( ) ) ) ) ;
}
}
else
{
// kdDebug(28000) << "directory is not new: " << currSelectedDir << endl;
}
}
}
void ScanPackager : : loadImageForItem ( KFileTreeViewItem * item )
{
if ( ! item ) return ;
bool result = true ;
KFileItem * kfi = item - > fileItem ( ) ;
if ( ! kfi ) return ;
KookaImage * img = static_cast < KookaImage * > ( kfi - > extraData ( this ) ) ;
if ( img )
{
kdDebug ( 28000 ) < < " Image already loaded. " < < endl ;
/* result is still true, image must be shown. */
}
else
{
/* The image needs to be loaded. Possibly it is a multi-page image.
* If it is , the kookaImage has a subImageCount larger than one . We
* create an subimage - item for every subimage , but do not yet load
* them .
*/
KURL url = item - > url ( ) ;
img = new KookaImage ( ) ;
if ( ! img | | ! img - > loadFromUrl ( url ) )
{
kdDebug ( 28000 ) < < " Loading KookaImage from File failed! " < < endl ;
result = false ;
}
else
{
/* store the fileitem */
img - > setFileItem ( kfi ) ;
/* care for subimages, create items for them */
kdDebug ( 28000 ) < < " subImage-count: " < < img - > subImagesCount ( ) < < endl ;
if ( img - > subImagesCount ( ) > 1 )
{
TDEIconLoader * loader = TDEGlobal : : iconLoader ( ) ;
kdDebug ( 28000 ) < < " SubImages existing! " < < endl ;
/* Start at the image with index 1, that makes one less than are actually in the
* image . But image 0 was already created above . */
KFileTreeViewItem * prevItem = 0 ;
for ( int i = 1 ; i < img - > subImagesCount ( ) ; i + + )
{
kdDebug ( 28000 ) < < " Creating subimage no " < < i < < endl ;
KFileItem * newKfi = new KFileItem ( * kfi ) ;
KFileTreeViewItem * subImgItem = new KFileTreeViewItem ( item , newKfi , item - > branch ( ) ) ;
if ( prevItem )
{
subImgItem - > moveItem ( prevItem ) ;
}
prevItem = subImgItem ;
subImgItem - > setPixmap ( 0 , loader - > loadIcon ( " editcopy " , TDEIcon : : Small ) ) ;
subImgItem - > setText ( 0 , i18n ( " Sub-image %1 " ) . arg ( i ) ) ;
KookaImage * subImgImg = new KookaImage ( i , img ) ;
subImgImg - > setFileItem ( newKfi ) ;
newKfi - > setExtraData ( ( void * ) this , ( void * ) subImgImg ) ;
}
}
}
}
if ( result & & img )
{
if ( img - > isSubImage ( ) )
{
kdDebug ( 28000 ) < < " it _is_ a subimage " < < endl ;
/* load if not loaded */
if ( img - > isNull ( ) )
{
kdDebug ( 28000 ) < < " extracting subimage " < < endl ;
img - > extractNow ( ) ;
}
else
{
kdDebug ( 28000 ) < < " Is not a null image " < < endl ;
}
}
slImageArrived ( item , img ) ;
}
}
/* Hit this slot with a file for a tdefiletreeviewitem. */
void ScanPackager : : slImageArrived ( KFileTreeViewItem * item , KookaImage * image )
{
if ( item & & image )
{
/* Associate the image for the Scanpackager-Object. */
KFileItem * kfi = item - > fileItem ( ) ;
if ( kfi )
{
kfi - > setExtraData ( ( void * ) this , ( void * ) image ) ;
}
slotDecorate ( item ) ;
emit ( showImage ( image ) ) ;
}
}
KookaImage * ScanPackager : : getCurrImage ( ) const
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
KookaImage * img = 0L ;
if ( curr )
{
KFileItem * kfi = curr - > fileItem ( ) ;
if ( kfi )
{
img = static_cast < KookaImage * > ( kfi - > extraData ( this ) ) ;
}
}
return ( img ) ;
}
TQString ScanPackager : : getCurrImageFileName ( bool withPath = true ) const
{
TQString result = " " ;
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
if ( ! curr )
{
kdDebug ( 28000 ) < < " getCurrImageFileName: nothing selected ! " < < endl ;
}
else
{
if ( withPath )
{
result = localFileName ( curr ) ;
}
else
{
KURL url ( localFileName ( curr ) ) ;
url = curr - > url ( ) ;
result = url . fileName ( ) ;
}
}
return ( result ) ;
}
/* ----------------------------------------------------------------------- */
TQCString ScanPackager : : getImgFormat ( KFileTreeViewItem * item ) const
{
TQCString cstr ;
if ( ! item ) return ( cstr ) ;
#if 0
KFileItem * kfi = item - > fileItem ( ) ;
TQString mime = kfi - > mimetype ( ) ;
# endif
// TODO find the real extension for use with the filename !
// temporarely:
TQString f = localFileName ( item ) ;
return ( TQImage : : imageFormat ( f ) ) ;
}
TQString ScanPackager : : localFileName ( KFileTreeViewItem * it ) const
{
if ( ! it ) return ( TQString ( ) ) ;
KURL url = it - > url ( ) ;
TQString res ;
if ( url . isLocalFile ( ) )
{
res = url . directory ( false , true ) + url . fileName ( ) ;
}
return ( res ) ;
}
/* Called if the image exists but was changed by image manipulation func */
void ScanPackager : : slotCurrentImageChanged ( TQImage * img )
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
if ( ! curr )
{
kdDebug ( 28000 ) < < " ImageChanged: nothing selected ! " < < endl ;
return ;
}
/* Do not save directories */
if ( curr - > isDir ( ) ) return ;
/* unload image and free memory */
slotUnloadItem ( curr ) ;
const TQString filename = localFileName ( curr ) ;
const TQCString format = getImgFormat ( curr ) ;
ImgSaver saver ( this ) ;
ImgSaveStat is_stat = ISS_OK ;
is_stat = saver . saveImage ( img , filename , format ) ;
if ( is_stat = = ISS_ERR_FORMAT_NO_WRITE )
{
KMessageBox : : error ( this , i18n ( " Cannot write this image format. \n Image will not be saved! " ) ,
i18n ( " Save Error " ) ) ;
}
else if ( is_stat = = ISS_ERR_PERM )
{
KMessageBox : : error ( this , i18n ( " Image file is write protected. \n Image will not be saved! " ) ,
i18n ( " Save Error " ) ) ;
}
else if ( is_stat = = ISS_ERR_PROTOCOL )
{
KMessageBox : : sorry ( this , i18n ( " Cannot save the image, because the file is local. \n "
" Kooka will support other protocols later. " ) ,
i18n ( " Save Error " ) ) ;
}
else if ( is_stat ! = ISS_OK )
{
kdDebug ( 28000 ) < < " Error while saving existing image ! " < < endl ;
}
if ( img & & ! img - > isNull ( ) )
{
emit ( imageChanged ( curr - > fileItem ( ) ) ) ;
KookaImage * newImage = new KookaImage ( * img ) ;
slImageArrived ( curr , newImage ) ;
}
}
/* ----------------------------------------------------------------------- */
/* This slot takes a new scanned Picture and saves it.
* It urgently needs to make a deep copy of the image !
*/
void ScanPackager : : slAddImage ( TQImage * img , KookaImageMeta * )
{
ImgSaveStat is_stat = ISS_OK ;
/* Save the image with the help of the ImgSaver */
if ( ! img ) return ;
/* currently selected item is the directory or a file item */
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
/* Use root if nothing is selected */
if ( ! curr )
{
KFileTreeBranch * b = branches ( ) . at ( 0 ) ; /* There should be at least one */
if ( b )
{
curr = findItem ( b , i18n ( " Incoming/ " ) ) ;
if ( ! curr ) curr = b - > root ( ) ;
}
/* If curr is still undefined, something very tough has happend. Go away here */
if ( ! curr ) return ;
setSelected ( curr , true ) ;
}
/* find the directory above the current one */
KURL dir ( itemDirectory ( curr ) ) ;
/* Path of curr sel item */
ImgSaver img_saver ( this , dir ) ;
is_stat = img_saver . saveImage ( img ) ;
if ( is_stat = = ISS_ERR_FORMAT_NO_WRITE )
{
KMessageBox : : error ( this , i18n ( " Cannot write this image format. \n Image will not be saved! " ) ,
i18n ( " Save Error " ) ) ;
}
else if ( is_stat = = ISS_ERR_PERM )
{
KMessageBox : : error ( this , i18n ( " Image file is write protected. \n Image will not be saved! " ) ,
i18n ( " Save Error " ) ) ;
}
else if ( is_stat ! = ISS_OK )
{
if ( is_stat = = ISS_SAVE_CANCELED )
{
return ;
}
kdDebug ( 28000 ) < < " ERROR: Saving failed: " < < img_saver . errorString ( is_stat ) < < endl ;
/* And now ?? */
}
/* Add the new image to the list of new images */
KURL lurl = img_saver . lastFileUrl ( ) ;
KFileTreeBranchList branchlist = branches ( ) ;
KFileTreeBranch * kookaBranch = branchlist . at ( 0 ) ;
TQString strdir = itemDirectory ( curr ) ;
if ( strdir . endsWith ( TQString ( " / " ) ) ) strdir . truncate ( strdir . length ( ) - 1 ) ;
kdDebug ( 28000 ) < < " Updating directory with " < < strdir < < endl ;
if ( kookaBranch ) kookaBranch - > updateDirectory ( KURL ( strdir ) ) ;
slotSetNextUrlToSelect ( lurl ) ;
m_nextUrlToShow = lurl ;
TQString s ;
/* Count amount of children of the father */
TQListViewItem * paps = curr - > parent ( ) ;
if ( curr - > isDir ( ) ) /* take only father if the is no directory */
paps = curr ;
if ( paps )
{
int childcount = paps - > childCount ( ) ;
s = i18n ( " %1 images " ) . arg ( childcount ) ;
paps - > setText ( 1 , s ) ;
setOpen ( paps , true ) ;
}
}
/* ----------------------------------------------------------------------- */
/* selects and opens the file with the given name. This is used to restore the
* last displayed image by its name .
*/
void ScanPackager : : slSelectImage ( const KURL & name )
{
KFileTreeViewItem * found = spFindItem ( UrlSearch , name . url ( ) ) ;
if ( found )
{
kdDebug ( 28000 ) < < " slSelectImage: Found an item ! " < < endl ;
ensureItemVisible ( found ) ;
setCurrentItem ( found ) ;
slClicked ( found ) ;
}
}
KFileTreeViewItem * ScanPackager : : spFindItem ( SearchType type , const TQString name , const KFileTreeBranch * branch )
{
/* Prepare a list of branches to go through. If the parameter branch is set, search
* only in the parameter branch . If it is zero , search all branches returned by
* tdefiletreeview . branches ( )
*/
KFileTreeBranchList branchList ;
if ( branch )
{
branchList . append ( branch ) ;
}
else
{
branchList = branches ( ) ;
}
KFileTreeBranchIterator it ( branchList ) ;
KFileItem * kfi = 0L ;
KFileTreeViewItem * foundItem = 0L ;
/* Leave the loop in case kfi is defined */
KFileTreeBranch * branchloop = 0L ;
for ( ; ! kfi & & it . current ( ) ; + + it )
{
branchloop = * it ;
KURL url ( name ) ;
switch ( type )
{
case Dummy :
kdDebug ( 28000 ) < < " Dummy search skipped ! " < < endl ;
break ;
case NameSearch :
kdDebug ( 28000 ) < < " ScanPackager: searching for " < < name < < endl ;
kfi = branchloop - > findByName ( name ) ;
break ;
case UrlSearch :
kdDebug ( 28000 ) < < " ScanPackager: URL search for " < < name < < endl ;
kfi = branchloop - > find ( url ) ;
break ;
default :
kdDebug ( 28000 ) < < " Scanpackager: Wrong search type ! " < < endl ;
break ;
}
}
if ( kfi )
{
foundItem = static_cast < KFileTreeViewItem * > ( kfi - > extraData ( branchloop ) ) ;
kdDebug ( 28000 ) < < " spFindItem: Success ! " < < foundItem < < endl ;
}
return ( foundItem ) ;
}
/* ----------------------------------------------------------------------- */
void ScanPackager : : slShowContextMenue ( TQListViewItem * lvi , const TQPoint & p , int col )
{
kdDebug ( 28000 ) < < " Showing Context Menue " < < endl ;
( void ) col ;
KFileTreeViewItem * curr = 0 ;
if ( lvi )
{
curr = currentKFileTreeViewItem ( ) ;
if ( curr - > isDir ( ) )
setSelected ( curr , true ) ;
}
if ( m_contextMenu )
{
m_contextMenu - > exec ( p ) ;
}
}
/* ----------------------------------------------------------------------- */
void ScanPackager : : slotExportFile ( )
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
if ( ! curr ) return ;
if ( curr - > isDir ( ) )
{
kdDebug ( 28000 ) < < " Not yet implemented! " < < endl ;
}
else
{
KURL fromUrl ( curr - > url ( ) ) ;
TQString filter = " *. " + getImgFormat ( curr ) . lower ( ) ;
filter + = " \n *| " + i18n ( " All Files " ) ;
// initial += fromUrl.filename(false);
TQString initial = m_currCopyDir + " / " ;
initial + = fromUrl . filename ( false ) ;
KURL fileName = KFileDialog : : getSaveURL ( initial ,
filter , this ) ;
if ( fileName . isValid ( ) ) // got a file name
{
if ( fromUrl = = fileName ) return ;
/* Since it is asynchron, we will never get if it succeeded. */
ImgSaver : : copyImage ( fromUrl , fileName ) ;
/* remember the filename for the next export */
fileName . setFileName ( TQString ( ) ) ;
m_currCopyDir = fileName . url ( ) ;
}
}
}
void ScanPackager : : slotImportFile ( )
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
if ( ! curr ) return ;
KURL impTarget = curr - > url ( ) ;
if ( ! curr - > isDir ( ) )
{
KFileTreeViewItem * pa = static_cast < KFileTreeViewItem * > ( curr - > parent ( ) ) ;
impTarget = pa - > url ( ) ;
}
kdDebug ( 28000 ) < < " Importing to " < < impTarget . url ( ) < < endl ;
KURL impUrl = KFileDialog : : getImageOpenURL ( m_currImportDir , this , i18n ( " Import Image File to Gallery " ) ) ;
if ( ! impUrl . isEmpty ( ) )
{
m_currImportDir = impUrl . url ( ) ;
impTarget . addPath ( impUrl . fileName ( ) ) ; // append the name of the sourcefile to the path
m_nextUrlToShow = impTarget ;
ImgSaver : : copyImage ( impUrl , impTarget ) ;
}
}
void ScanPackager : : slotUrlsDropped ( TQWidget * , TQDropEvent * ev , KURL : : List & urls , KURL & copyTo )
{
if ( ! urls . isEmpty ( ) )
{
kdDebug ( 28000 ) < < " Kooka drop event! " < < endl ;
// kdDebug(28000) << "Kooka drop event. First src url=" << urls.first() << " copyTo=" << copyTo
// << " move=" << ( ev->action() == TQDropEvent::Move ) << endl;
/* first make the last url to copy to the one to select next */
if ( ! urls . empty ( ) )
{
KURL nextSel = copyTo ;
nextSel . addPath ( urls . back ( ) . fileName ( false ) ) ;
kdDebug ( 28000 ) < < " Selecting next url: " < < nextSel . url ( ) < < endl ;
m_nextUrlToShow = nextSel ;
// slotSetNextUrlToSelect( nextSel );
}
if ( ev - > action ( ) = = TQDropEvent : : Move )
copyjob = TDEIO : : move ( urls , copyTo , true ) ;
else
copyjob = TDEIO : : copy ( urls , copyTo , true ) ;
}
}
void ScanPackager : : slotCanceled ( TDEIO : : Job * )
{
kdDebug ( 28000 ) < < i18n ( " Canceled by user " ) < < endl ;
}
/* ----------------------------------------------------------------------- */
void ScanPackager : : slotUnloadItems ( )
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
emit ( showImage ( 0L ) ) ;
slotUnloadItem ( curr ) ;
}
void ScanPackager : : slotUnloadItem ( KFileTreeViewItem * curr )
{
if ( ! curr ) return ;
if ( curr - > isDir ( ) )
{
KFileTreeViewItem * child = static_cast < KFileTreeViewItem * > ( curr - > firstChild ( ) ) ;
while ( child )
{
kdDebug ( 28000 ) < < " Unloading item " < < child < < endl ;
slotUnloadItem ( child ) ;
child = static_cast < KFileTreeViewItem * > ( child - > nextSibling ( ) ) ;
}
}
else
{
KFileItem * kfi = curr - > fileItem ( ) ;
KookaImage * image = static_cast < KookaImage * > ( kfi - > extraData ( this ) ) ;
/* If image is zero, ok, than there is nothing to unload :) */
if ( image )
{
if ( image - > subImagesCount ( ) > 0 )
{
KFileTreeViewItem * child = static_cast < KFileTreeViewItem * > ( curr - > firstChild ( ) ) ;
while ( child )
{
KFileTreeViewItem * nextChild = 0 ;
kdDebug ( 28000 ) < < " Unloading subimage item " < < child < < endl ;
slotUnloadItem ( child ) ;
nextChild = static_cast < KFileTreeViewItem * > ( child - > nextSibling ( ) ) ;
delete child ;
child = nextChild ;
}
}
emit ( unloadImage ( image ) ) ;
delete image ;
kfi - > removeExtraData ( this ) ;
slotDecorate ( curr ) ;
}
}
}
/* ----------------------------------------------------------------------- */
void ScanPackager : : slotDeleteItems ( )
{
KFileTreeViewItem * curr = currentKFileTreeViewItem ( ) ;
if ( ! curr ) return ;
KURL urlToDel = curr - > url ( ) ;
TQListViewItem * nextToSelect = curr - > nextSibling ( ) ;
kdDebug ( 28000 ) < < " Deleting: " < < urlToDel . prettyURL ( ) < < endl ;
bool ask = true ; /* for later use */
int result = KMessageBox : : Yes ;
KFileItem * item = curr - > fileItem ( ) ;
if ( ask )
{
TQString s ;
s = i18n ( " Do you really want to delete this image? \n It cannot be restored! " ) ;
if ( item - > isDir ( ) )
{
s = i18n ( " Do you really want to delete the folder %1 \n and all the images inside? " ) . arg ( " " ) ;
}
result = KMessageBox : : warningContinueCancel ( this , s , i18n ( " Delete Collection Item " ) ,
KStdGuiItem : : del ( ) , " AskForDeleteFiles " ) ;
}
/* Since we are currently talking about local files here, NetAccess is OK */
if ( result = = KMessageBox : : Continue )
{
if ( TDEIO : : NetAccess : : del ( urlToDel , 0 ) )
{
if ( nextToSelect )
setSelected ( nextToSelect , true ) ;
/* TODO: remove the directory from the imageNameCombobox */
if ( curr & & item - > isDir ( ) )
{
/* The directory needs to be removed from the name combo */
emit ( directoryToRemove ( curr - > branch ( ) , itemDirectory ( curr , true ) ) ) ;
}
}
else
kdDebug ( 28000 ) < < " Deleting files failed " < < endl ;
}
}
/* ----------------------------------------------------------------------- */
void ScanPackager : : slotCreateFolder ( )
{
bool ok ;
TQString folder = KInputDialog : : getText ( i18n ( " New Folder " ) ,
i18n ( " Please enter a name for the new folder: " ) , TQString ( ) ,
& ok , this ) ;
if ( ok )
{
/* KIO create folder goes here */
KFileTreeViewItem * it = currentKFileTreeViewItem ( ) ;
if ( it )
{
KURL url = it - > url ( ) ;
/* If a directory is selected, the filename needs not to be deleted */
if ( ! it - > isDir ( ) )
url . setFileName ( " " ) ;
/* add the folder name from user input */
url . addPath ( folder ) ;
kdDebug ( 28000 ) < < " Creating folder " < < url . prettyURL ( ) < < endl ;
/* Since the new directory arrives in the packager in the newItems-slot, we set a
* variable urlToSelectOnArrive here . The newItems - slot will honor it and select
* the treeviewitem with that url .
*/
slotSetNextUrlToSelect ( url ) ;
if ( ! TDEIO : : NetAccess : : mkdir ( url , 0 , - 1 ) )
{
kdDebug ( 28000 ) < < " ERR: creation of " < < url . prettyURL ( ) < < " failed ! " < < endl ;
}
else
{
/* created successfully */
/* open the branch if necessary and select the new folder */
}
}
}
}
/* ----------------------------------------------------------------------- */
TQString ScanPackager : : getImgName ( TQString name_on_disk )
{
TQString s ;
( void ) name_on_disk ;
s = i18n ( " image %1 " ) . arg ( img_counter + + ) ;
return ( s ) ;
}
/* ----------------------------------------------------------------------- */
ScanPackager : : ~ ScanPackager ( ) {
kdDebug ( 29000 ) < < " Destructor of ScanPackager " < < endl ;
}
/* called whenever one branch detects a deleted file */
void ScanPackager : : slotDeleteFromBranch ( KFileItem * kfi )
{
emit fileDeleted ( kfi ) ;
}
void ScanPackager : : contentsDragMoveEvent ( TQDragMoveEvent * e )
{
if ( ! acceptDrag ( e ) )
{
e - > ignore ( ) ;
return ;
}
TQListViewItem * afterme = 0 ;
TQListViewItem * parent = 0 ;
findDrop ( e - > pos ( ) , parent , afterme ) ;
// "afterme" is 0 when aiming at a directory itself
TQListViewItem * item = afterme ? afterme : parent ;
if ( item )
{
bool isDir = static_cast < KFileTreeViewItem * > ( item ) - > isDir ( ) ;
if ( isDir ) {
KFileTreeView : : contentsDragMoveEvent ( e ) ; // for the autoopen code
return ;
}
}
e - > acceptAction ( ) ;
}
# include "scanpackager.moc"