/*************************************************************************** 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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(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(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, 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(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 << " <"< <" << nowExt<<">" < 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 - < * 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(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(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( 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(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 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 * 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(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(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(curr->firstChild()); while( child ) { kdDebug(28000) << "Unloading item " << child << endl; slotUnloadItem( child ); child = static_cast (child->nextSibling()); } } else { KFileItem *kfi = curr->fileItem(); KookaImage *image = static_cast(kfi->extraData( this )); /* If image is zero, ok, than there is nothing to unload :) */ if( image ) { if( image->subImagesCount() > 0 ) { KFileTreeViewItem *child = static_cast(curr->firstChild()); while( child ) { KFileTreeViewItem *nextChild = 0; kdDebug(28000) << "Unloading subimage item " << child << endl; slotUnloadItem( child ); nextChild = static_cast (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?").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; 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").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 (item)->isDir(); if( isDir ) { KFileTreeView::contentsDragMoveEvent( e ); // for the autoopen code return; } } e->acceptAction(); } #include "scanpackager.moc"