You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/kooka/scanpackager.cpp

1262 lines
35 KiB

/***************************************************************************
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 <kfiletreeview.h>
#include <kfiletreeviewitem.h>
#include <kfiletreebranch.h>
#include <kurldrag.h>
#include <kpopupmenu.h>
#include <kaction.h>
#include <kinputdialog.h>
#include <kiconloader.h>
#include <kfiledialog.h>
#include <kurl.h>
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <kio/global.h>
#include <kio/progressbase.h>
#include <kio/netaccess.h>
#include <kio/jobclasses.h>
#include <kio/file.h>
#include <kio/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 */
KIconLoader *loader = KGlobal::iconLoader();
m_floppyPixmap = loader->loadIcon( "3floppy_unmount", KIcon::Small );
m_grayPixmap = loader->loadIcon( "palette_gray", KIcon::Small );
m_bwPixmap = loader->loadIcon( "palette_lineart", KIcon::Small );
m_colorPixmap = loader->loadIcon( "palette_color", KIcon::Small );
m_startup = true;
/* create a context menu and set the title */
m_contextMenu = new KPopupMenu();
static_cast<KPopupMenu*>(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 )
{
KIconLoader *loader = KGlobal::iconLoader();
/* working on the global branch. FIXME */
m_defaultBranch = addBranch( root, i18n("Kooka Gallery"),
loader->loadIcon( "folder_image", KIcon::Small ),
false /* do not showHidden */ );
// Q_CHECK_PTR( m_defaultBranch );
m_defaultBranch->setOpenPixmap( loader->loadIcon( "folder_blue_open", KIcon::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" ).tqarg( img->width()).tqarg(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, KIO::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::tqfromLatin1(" - ");
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 )
{
KIconLoader *loader = KGlobal::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", KIcon::Small ));
subImgItem->setText( 0, i18n("Sub-image %1").tqarg( 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 kfiletreeviewitem. */
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.\nImage will not be saved!"),
i18n("Save Error") );
}
else if( is_stat == ISS_ERR_PERM )
{
KMessageBox::error( this, i18n( "Image file is write protected.\nImage 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.\nImage will not be saved!"),
i18n("Save Error") );
}
else if( is_stat == ISS_ERR_PERM )
{
KMessageBox::error( this, i18n( "Image file is write protected.\nImage 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 tqchildren 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").tqarg(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
* kfiletreeview.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 = KIO::move( urls, copyTo, true );
else
copyjob = KIO::copy( urls, copyTo, true );
}
}
void ScanPackager::slotCanceled( KIO::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?\nIt cannot be restored!" );
if( item->isDir() )
{
s = i18n("Do you really want to delete the folder %1\nand all the images inside?").tqarg("");
}
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( KIO::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( ! KIO::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").tqarg(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"