diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 47d455dd55be855e4cc691c32f687f723d9247ee (patch) | |
tree | 52e236aaa2576bdb3840ebede26619692fed6d7d /kooka/scanpackager.cpp | |
download | tdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.tar.gz tdegraphics-47d455dd55be855e4cc691c32f687f723d9247ee.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegraphics@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kooka/scanpackager.cpp')
-rw-r--r-- | kooka/scanpackager.cpp | 1261 |
1 files changed, 1261 insertions, 0 deletions
diff --git a/kooka/scanpackager.cpp b/kooka/scanpackager.cpp new file mode 100644 index 00000000..7af7f151 --- /dev/null +++ b/kooka/scanpackager.cpp @@ -0,0 +1,1261 @@ +/*************************************************************************** + 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 Qt, and distribute the resulting executable, * + * without including the source code for Qt 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 <qapplication.h> +#include <qdir.h> +#include <qfile.h> +#include <qpopupmenu.h> +#include <qdict.h> +#include <qpixmap.h> +#include <kmessagebox.h> +#include <qfiledialog.h> +#include <qstringlist.h> +#include <qheader.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( QWidget *parent ) : KFileTreeView( parent ) +{ + // TODO: + setItemsRenameable (true ); + setDefaultRenameAction( QListView::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, SIGNAL(dropped( QWidget*, QDropEvent*, KURL::List&, KURL& )), + this, SLOT( slotUrlsDropped( QWidget*, QDropEvent*, 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, SIGNAL( clicked( QListViewItem*)), + SLOT( slClicked(QListViewItem*))); + + connect( this, SIGNAL( rightButtonPressed( QListViewItem *, const QPoint &, int )), + SLOT( slShowContextMenue(QListViewItem *, const QPoint &, int ))); + + connect( this, SIGNAL(itemRenamed (QListViewItem*, const QString &, int ) ), this, + SLOT(slFileRename( QListViewItem*, const QString&, int))); + + + img_counter = 1; + /* Set the current export dir to home */ + m_currCopyDir = QDir::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, SIGNAL( newTreeViewItems( KFileTreeBranch*, const KFileTreeViewItemList& )), + this, SLOT( slotDecorate(KFileTreeBranch*, const KFileTreeViewItemList& ))); + + connect( m_defaultBranch, SIGNAL( directoryChildCount( KFileTreeViewItem* , int )), + this, SLOT( slotDirCount( KFileTreeViewItem *, int ))); + + connect( m_defaultBranch, SIGNAL( deleteItem( KFileItem* )), + this, SLOT( slotDeleteFromBranch(KFileItem*))); + + connect( m_defaultBranch, SIGNAL( populateFinished( KFileTreeViewItem * )), + this, 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() ) + { + QString 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 */ + QString 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, KIO::convertSize( kfi->size() )); + } + } + + /* Image format */ + QString 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( QListViewItem* it, const QString& 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. + */ +QString ScanPackager::buildNewFilename( QString cmplFilename, QString 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. + */ + QFileInfo fiNew( cmplFilename ); + QString base = fiNew.baseName(); + QString newExt = fiNew.extension( false ).lower(); + QString nowExt = currFormat.lower(); + QString 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. + */ +QString ScanPackager::itemDirectory( const KFileTreeViewItem* item, bool relativ ) const +{ + if( ! item ) + { + kdDebug(28000) << "ERR: itemDirectory without item" << endl; + return QString::null; + } + + QString 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; + QString 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 QString & dirString ) +{ + kdDebug(28000) << "Trying to decode directory string " << dirString << endl; + + QString searchFor = QString::fromLatin1(" - "); + int pos = dirString.find( searchFor ); + + if( pos > -1 ) + { + /* Splitting up the string coming in */ + QString branchName = dirString.left( pos ); + QString 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( QListViewItem *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 */ + QApplication::setOverrideCursor(waitCursor); + emit( aboutToShowImage( item->url())); + loadImageForItem( item ); + QApplication::restoreOverrideCursor(); + } + + /* emit a signal indicating the new directory if there is a new one */ + QString wholeDir = itemDirectory( item, false ); /* not relativ to root */ + + if( currSelectedDir != wholeDir ) + { + currSelectedDir = wholeDir; + QString 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").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 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); +} + + +QString ScanPackager::getCurrImageFileName( bool withPath = true ) const +{ + QString 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 ); +} + +/* ----------------------------------------------------------------------- */ +QCString ScanPackager::getImgFormat( KFileTreeViewItem* item ) const +{ + + QCString cstr; + + if( !item ) return( cstr ); +#if 0 + KFileItem *kfi = item->fileItem(); + + QString mime = kfi->mimetype(); +#endif + + // TODO find the real extension for use with the filename ! + // temporarely: + QString f = localFileName( item ); + + return( QImage::imageFormat( f )); + +} + +QString ScanPackager::localFileName( KFileTreeViewItem *it ) const +{ + if( ! it ) return( QString::null ); + + KURL url = it->url(); + + QString 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( QImage *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 QString filename = localFileName( curr ); + const QCString 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( QImage *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); + + QString strdir = itemDirectory(curr); + if(strdir.endsWith(QString("/"))) strdir.truncate( strdir.length() - 1 ); + kdDebug(28000) << "Updating directory with " << strdir << endl; + + if( kookaBranch ) kookaBranch->updateDirectory( KURL(strdir) ); + slotSetNextUrlToSelect( lurl ); + m_nextUrlToShow = lurl; + + QString s; + /* Count amount of children of the father */ + QListViewItem *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 QString 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(QListViewItem *lvi, const QPoint &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()); + QString filter = "*." + getImgFormat(curr).lower(); + filter += "\n*|" + i18n( "All Files" ); + + // initial += fromUrl.filename(false); + QString 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( QString()); + 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( QWidget*, QDropEvent* 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() == QDropEvent::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() == QDropEvent::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(); + QListViewItem *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 ) + { + QString 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?").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( 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; + QString folder = KInputDialog::getText( i18n( "New Folder" ), + i18n( "Please enter a name for the new folder:" ), QString::null, + &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 */ + + } + } + } +} + + +/* ----------------------------------------------------------------------- */ +QString ScanPackager::getImgName( QString name_on_disk ) +{ + QString 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( QDragMoveEvent *e ) +{ + if( ! acceptDrag( e ) ) + { + e->ignore(); + return; + } + + QListViewItem *afterme = 0; + QListViewItem *parent = 0; + + findDrop( e->pos(), parent, afterme ); + + // "afterme" is 0 when aiming at a directory itself + QListViewItem *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" |