/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-11-22 * Description : stand alone digiKam image editor GUI * * Copyright (C) 2004-2005 by Renchi Raju * Copyright (C) 2005-2006 by Tom Albers * Copyright (C) 2004-2008 by Gilles Caulier * Copyright (C) 2006-2008 by Marcel Wiesweg * Copyright (C) 2008 by Arnd Baecker * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ // C Ansi includes. extern "C" { #include } // C++ includes. #include // TQt includes. #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // LibKDcraw includes. #include #include #if KDCRAW_VERSION < 0x000106 #include #endif // Local includes. #include "ddebug.h" #include "dpopupmenu.h" #include "dmetadata.h" #include "canvas.h" #include "thumbbar.h" #include "imagepropertiessidebar.h" #include "imageplugin.h" #include "imagepluginloader.h" #include "imagedialog.h" #include "dimginterface.h" #include "splashscreen.h" #include "slideshow.h" #include "setup.h" #include "setupicc.h" #include "statusprogressbar.h" #include "iccsettingscontainer.h" #include "iofilesettingscontainer.h" #include "loadingcacheinterface.h" #include "savingcontextcontainer.h" #include "themeengine.h" #include "editorstackview.h" #include "showfoto.h" #include "showfoto.moc" namespace ShowFoto { class ShowFotoPriv { public: ShowFotoPriv() { currentItem = 0; itemsNb = 0; splash = 0; BCGAction = 0; showBarAction = 0; openFilesInFolderAction = 0; fileOpenAction = 0; thumbBar = 0; rightSidebar = 0; splash = 0; itemsNb = 0; vSplitter = 0; deleteItem2Trash = true; fullScreenHideThumbBar = true; validIccPath = true; } bool fullScreenHideThumbBar; bool deleteItem2Trash; bool validIccPath; int itemsNb; TQSplitter *vSplitter; KURL lastOpenedDirectory; KToggleAction *showBarAction; KAction *openFilesInFolderAction; KAction *fileOpenAction; KActionMenu *BCGAction; Digikam::ThumbBarView *thumbBar; Digikam::ThumbBarItem *currentItem; Digikam::ImagePropertiesSideBar *rightSidebar; Digikam::SplashScreen *splash; }; ShowFoto::ShowFoto(const KURL::List& urlList) : Digikam::EditorWindow( "Showfoto" ) { d = new ShowFotoPriv(); // -- Show splash at start ---------------------------- KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); KGlobal::dirs()->addResourceType("data", KGlobal::dirs()->kde_default("data") + "digikam"); KGlobal::iconLoader()->addAppDir("digikam"); if(config->readBoolEntry("ShowSplash", true) && !kapp->isRestored()) { d->splash = new Digikam::SplashScreen("showfoto-splash.png"); d->splash->show(); } // Check ICC profiles repository availability if(d->splash) d->splash->message(i18n("Checking ICC repository")); d->validIccPath = Digikam::SetupICC::iccRepositoryIsValid(); #if KDCRAW_VERSION < 0x000106 // Check witch dcraw version available if(d->splash) d->splash->message(i18n("Checking dcraw version")); KDcrawIface::DcrawBinary::instance()->checkSystem(); #endif // Populate Themes if(d->splash) d->splash->message(i18n("Loading themes")); Digikam::ThemeEngine::instance()->scanThemes(); // -- Build the GUI ----------------------------------- setupUserArea(); setupStatusBar(); setupActions(); // Load image plugins to GUI m_imagePluginLoader = new Digikam::ImagePluginLoader(TQT_TQOBJECT(this), d->splash); loadImagePlugins(); // If plugin core is not available, plug BCG actions to collection instead. if ( !m_imagePluginLoader->pluginLibraryIsLoaded("digikamimageplugin_core") ) { d->BCGAction = new KActionMenu(i18n("Brightness/Contrast/Gamma"), 0, 0, "showfoto_bcg"); d->BCGAction->setDelayed(false); KAction *incGammaAction = new KAction(i18n("Increase Gamma"), 0, ALT+Key_G, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "gamma_plus"); KAction *decGammaAction = new KAction(i18n("Decrease Gamma"), 0, ALT+SHIFT+Key_G, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "gamma_minus"); KAction *incBrightAction = new KAction(i18n("Increase Brightness"), 0, ALT+Key_B, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "brightness_plus"); KAction *decBrightAction = new KAction(i18n("Decrease Brightness"), 0, ALT+SHIFT+Key_B, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "brightness_minus"); KAction *incContrastAction = new KAction(i18n("Increase Contrast"), 0, ALT+Key_C, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "contrast_plus"); KAction *decContrastAction = new KAction(i18n("Decrease Contrast"), 0, ALT+SHIFT+Key_C, TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()), actionCollection(), "contrast_minus"); d->BCGAction->insert(incBrightAction); d->BCGAction->insert(decBrightAction); d->BCGAction->insert(incContrastAction); d->BCGAction->insert(decContrastAction); d->BCGAction->insert(incGammaAction); d->BCGAction->insert(decGammaAction); TQPtrList bcg_actions; bcg_actions.append( d->BCGAction ); unplugActionList( "showfoto_bcg" ); plugActionList( "showfoto_bcg", bcg_actions ); } // Create context menu. setupContextMenu(); // Make signals/slots connections setupConnections(); // -- Read settings -------------------------------- readSettings(); applySettings(); setAutoSaveSettings("ImageViewer Settings"); // -- Load current items --------------------------- for (KURL::List::const_iterator it = urlList.begin(); it != urlList.end(); ++it) { KURL url = *it; if (url.isLocalFile()) { TQFileInfo fi(url.path()); if (fi.isDir()) { // Local Dir openFolder(url); } else { // Local file new Digikam::ThumbBarItem(d->thumbBar, url); d->lastOpenedDirectory=(*it); } } else { // Remote file. new Digikam::ThumbBarItem(d->thumbBar, url); d->lastOpenedDirectory=(*it); } } if ( urlList.isEmpty() ) { emit signalNoCurrentItem(); toggleActions(false); toggleNavigation(0); } else { toggleNavigation(1); toggleActions(true); } } ShowFoto::~ShowFoto() { unLoadImagePlugins(); delete m_imagePluginLoader; delete d->thumbBar; delete d->rightSidebar; delete d; } Digikam::Sidebar* ShowFoto::rightSideBar() const { return dynamic_cast(d->rightSidebar); } bool ShowFoto::queryClose() { // wait if a save operation is currently running if (!waitForSavingToComplete()) return false; if (d->currentItem && !promptUserSave(d->currentItem->url())) return false; // put right side bar in a defined state emit signalNoCurrentItem(); m_canvas->resetImage(); return true; } bool ShowFoto::queryExit() { saveSettings(); return true; } void ShowFoto::show() { // Remove Splashscreen. if(d->splash) { d->splash->finish(this); delete d->splash; d->splash = 0; } // Display application window. KMainWindow::show(); // Report errors from ICC repository path. KConfig* config = kapp->config(); if(!d->validIccPath) { TQString message = i18n("

The ICC profile path seems to be invalid.

" "

If you want to set it now, select \"Yes\", otherwise " "select \"No\". In this case, \"Color Management\" feature " "will be disabled until you solve this issue

"); if (KMessageBox::warningYesNo(this, message) == KMessageBox::Yes) { if (!setup(true)) { config->setGroup("Color Management"); config->writeEntry("EnableCM", false); config->sync(); } } else { config->setGroup("Color Management"); config->writeEntry("EnableCM", false); config->sync(); } } #if KDCRAW_VERSION < 0x000106 // Report errors from dcraw detection. KDcrawIface::DcrawBinary::instance()->checkReport(); #endif } void ShowFoto::setupConnections() { setupStandardConnections(); connect(d->thumbBar, TQT_SIGNAL(signalURLSelected(const KURL&)), TQT_TQOBJECT(this), TQT_SLOT(slotOpenURL(const KURL&))); connect(d->thumbBar, TQT_SIGNAL(signalItemAdded()), TQT_TQOBJECT(this), TQT_SLOT(slotUpdateItemInfo())); connect(this, TQT_SIGNAL(signalSelectionChanged(const TQRect &)), d->rightSidebar, TQT_SLOT(slotImageSelectionChanged(const TQRect &))); connect(this, TQT_SIGNAL(signalNoCurrentItem()), d->rightSidebar, TQT_SLOT(slotNoCurrentItem())); } void ShowFoto::setupUserArea() { KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); TQWidget* widget = new TQWidget(this); TQSizePolicy rightSzPolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding, 2, 1); if(!config->readBoolEntry("HorizontalThumbbar", false)) //Qt::Vertical thumbbar tqlayout { TQHBoxLayout *hlay = new TQHBoxLayout(widget); m_splitter = new TQSplitter(widget); d->thumbBar = new Digikam::ThumbBarView(m_splitter, Digikam::ThumbBarView::Vertical); m_stackView = new Digikam::EditorStackView(m_splitter); m_canvas = new Digikam::Canvas(m_stackView); m_canvas->setSizePolicy(rightSzPolicy); d->rightSidebar = new Digikam::ImagePropertiesSideBar(widget, "ShowFoto Sidebar Right", m_splitter, Digikam::Sidebar::Right); hlay->addWidget(m_splitter); hlay->addWidget(d->rightSidebar); } else //Qt::Horizontal thumbbar tqlayout { m_splitter = new TQSplitter(Qt::Horizontal, widget); TQWidget* widget2 = new TQWidget(m_splitter); TQVBoxLayout *vlay = new TQVBoxLayout(widget2); d->vSplitter = new TQSplitter(Qt::Vertical, widget2); m_stackView = new Digikam::EditorStackView(d->vSplitter); m_canvas = new Digikam::Canvas(m_stackView); d->thumbBar = new Digikam::ThumbBarView(d->vSplitter, Digikam::ThumbBarView::Horizontal); m_canvas->setSizePolicy(rightSzPolicy); d->vSplitter->setFrameStyle( TQFrame::NoFrame ); d->vSplitter->setFrameShadow( TQFrame::Plain ); d->vSplitter->setFrameShape( TQFrame::NoFrame ); d->vSplitter->setOpaqueResize(false); vlay->addWidget(d->vSplitter); TQHBoxLayout *hlay = new TQHBoxLayout(widget); d->rightSidebar = new Digikam::ImagePropertiesSideBar(widget, "ShowFoto Sidebar Right", m_splitter, Digikam::Sidebar::Right); hlay->addWidget(m_splitter); hlay->addWidget(d->rightSidebar); } m_canvas->makeDefaultEditingCanvas(); m_stackView->setCanvas(m_canvas); m_stackView->setViewMode(Digikam::EditorStackView::CanvasMode); m_splitter->setFrameStyle( TQFrame::NoFrame ); m_splitter->setFrameShadow( TQFrame::Plain ); m_splitter->setFrameShape( TQFrame::NoFrame ); m_splitter->setOpaqueResize(false); setCentralWidget(widget); d->rightSidebar->loadViewState(); } void ShowFoto::setupActions() { setupStandardActions(); // Provides a menu entry that allows showing/hiding the toolbar(s) setStandardToolBarMenuEnabled(true); // Provides a menu entry that allows showing/hiding the statusbar createStandardStatusBarAction(); // Extra 'File' menu actions --------------------------------------------- d->fileOpenAction = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(slotOpenFile()), actionCollection(), "showfoto_open_file"); d->openFilesInFolderAction = new KAction(i18n("Open folder"), "folder_image", CTRL+SHIFT+Key_O, TQT_TQOBJECT(this), TQT_SLOT(slotOpenFilesInFolder()), actionCollection(), "showfoto_open_folder"); KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection(), "showfoto_quit"); // Extra 'View' menu actions --------------------------------------------- d->showBarAction = new KToggleAction(i18n("Show Thumbnails"), 0, CTRL+Key_T, TQT_TQOBJECT(this), TQT_SLOT(slotToggleShowBar()), actionCollection(), "shofoto_showthumbs"); // --- Create the gui -------------------------------------------------------------- createGUI("showfotoui.rc", false); setupStandardAccelerators(); } void ShowFoto::readSettings() { readStandardSettings(); KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); d->showBarAction->setChecked(config->readBoolEntry("Show Thumbnails", true)); slotToggleShowBar(); d->lastOpenedDirectory.setPath( config->readEntry("Last Opened Directory", KGlobalSettings::documentPath()) ); TQSizePolicy szPolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding, 2, 1); if(config->hasKey("Vertical Splitter Sizes") && d->vSplitter) d->vSplitter->setSizes(config->readIntListEntry("Vertical Splitter Sizes")); else m_canvas->setSizePolicy(szPolicy); Digikam::ThemeEngine::instance()->setCurrentTheme(config->readEntry("Theme", i18n("Default"))); } void ShowFoto::saveSettings() { saveStandardSettings(); KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); config->writeEntry("Last Opened Directory", d->lastOpenedDirectory.path() ); config->writeEntry("Show Thumbnails", d->showBarAction->isChecked()); if (d->vSplitter) config->writeEntry("Vertical Splitter Sizes", d->vSplitter->sizes()); config->writeEntry("Theme", Digikam::ThemeEngine::instance()->getCurrentThemeName()); config->sync(); } void ShowFoto::applySettings() { applyStandardSettings(); KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); // Current image deleted go to trash ? d->deleteItem2Trash = config->readBoolEntry("DeleteItem2Trash", true); if (d->deleteItem2Trash) { m_fileDeleteAction->setIcon("edittrash"); m_fileDeleteAction->setText(i18n("Move to Trash")); } else { m_fileDeleteAction->setIcon("editdelete"); m_fileDeleteAction->setText(i18n("Delete File")); } bool exifRotate = config->readBoolEntry("EXIF Rotate", true); m_canvas->setExifOrient(exifRotate); d->thumbBar->setExifRotate(exifRotate); m_setExifOrientationTag = config->readBoolEntry("EXIF Set Orientation", true); d->fullScreenHideThumbBar = config->readBoolEntry("FullScreenHideThumbBar", true); Digikam::ThumbBarToolTipSettings settings; settings.showToolTips = config->readBoolEntry("Show ToolTips", true); settings.showFileName = config->readBoolEntry("ToolTips Show File Name", true); settings.showFileDate = config->readBoolEntry("ToolTips Show File Date", false); settings.showFileSize = config->readBoolEntry("ToolTips Show File Size", false); settings.showImageType = config->readBoolEntry("ToolTips Show Image Type", false); settings.showImageDim = config->readBoolEntry("ToolTips Show Image Dim", true); settings.showPhotoMake = config->readBoolEntry("ToolTips Show Photo Make", true); settings.showPhotoDate = config->readBoolEntry("ToolTips Show Photo Date", true); settings.showPhotoFocal = config->readBoolEntry("ToolTips Show Photo Focal", true); settings.showPhotoExpo = config->readBoolEntry("ToolTips Show Photo Expo", true); settings.showPhotoMode = config->readBoolEntry("ToolTips Show Photo Mode", true); settings.showPhotoFlash = config->readBoolEntry("ToolTips Show Photo Flash", false); settings.showPhotoWB = config->readBoolEntry("ToolTips Show Photo WB", false); d->thumbBar->setToolTipSettings(settings); } void ShowFoto::slotOpenFile() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; KURL::List urls = Digikam::ImageDialog::getImageURLs(this, d->lastOpenedDirectory); if (!urls.isEmpty()) { d->currentItem = 0; d->thumbBar->clear(); for (KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it) { new Digikam::ThumbBarItem(d->thumbBar, *it); d->lastOpenedDirectory=(*it); } toggleActions(true); } } void ShowFoto::slotOpenURL(const KURL& url) { if(d->currentItem && !promptUserSave(d->currentItem->url())) { d->thumbBar->blockSignals(true); d->thumbBar->setSelected(d->currentItem); d->thumbBar->blockSignals(false); return; } d->currentItem = d->thumbBar->currentItem(); if(!d->currentItem) return; TQString localFile; #if KDE_IS_VERSION(3,2,0) KIO::NetAccess::download(url, localFile, this); #else KIO::NetAccess::download(url, localFile); #endif m_canvas->load(localFile, m_IOFileSettings); // TODO : add preload here like in ImageWindow::slotLoadCurrent() ??? } void ShowFoto::toggleGUI2FullScreen() { if (m_fullScreen) { d->rightSidebar->restore(); // If show Thumbbar option is checked, restore it. if (d->showBarAction->isChecked()) d->thumbBar->show(); } else { d->rightSidebar->backup(); // If Hide Thumbbar option is checked, catch it if necessary. if (d->showBarAction->isChecked()) { if (d->fullScreenHideThumbBar) d->thumbBar->hide(); } } } void ShowFoto::slotToggleShowBar() { if (d->showBarAction->isChecked()) d->thumbBar->show(); else d->thumbBar->hide(); } void ShowFoto::slotChangeBCG() { TQString name; if (sender()) name = TQT_TQOBJECT(const_cast(sender()))->name(); if (name == "gamma_plus") { m_canvas->increaseGamma(); } else if (name == "gamma_minus") { m_canvas->decreaseGamma(); } else if (name == "brightness_plus") { m_canvas->increaseBrightness(); } else if (name == "brightness_minus") { m_canvas->decreaseBrightness(); } else if (name == "contrast_plus") { m_canvas->increaseContrast(); } else if (name == "contrast_minus") { m_canvas->decreaseContrast(); } } void ShowFoto::slotChanged() { TQString mpixels; TQSize dims(m_canvas->imageWidth(), m_canvas->imageHeight()); mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2); TQString str = (!dims.isValid()) ? i18n("Unknown") : i18n("%1x%2 (%3Mpx)") .arg(dims.width()).arg(dims.height()).arg(mpixels); m_resLabel->setText(str); if (d->currentItem) { if (d->currentItem->url().isValid()) { TQRect sel = m_canvas->getSelectedArea(); Digikam::DImg* img = m_canvas->interface()->getImg(); d->rightSidebar->itemChanged(d->currentItem->url(), sel, img); } } } void ShowFoto::slotUndoStateChanged(bool moreUndo, bool moreRedo, bool canSave) { m_revertAction->setEnabled(canSave); m_undoAction->setEnabled(moreUndo); m_redoAction->setEnabled(moreRedo); m_saveAction->setEnabled(canSave); if (!moreUndo) m_rotatedOrFlipped = false; } void ShowFoto::toggleActions(bool val) { toggleStandardActions(val); // if BCG actions exists then toggle it. if (d->BCGAction) d->BCGAction->setEnabled(val); } void ShowFoto::slotFilePrint() { printImage(d->currentItem->url()); } bool ShowFoto::setup(bool iccSetupPage) { Setup setup(this, 0, iccSetupPage ? Setup::ICCPage : Setup::LastPageUsed); if (setup.exec() != TQDialog::Accepted) return false; kapp->config()->sync(); applySettings(); if ( d->itemsNb == 0 ) { slotUpdateItemInfo(); toggleActions(false); } return true; } void ShowFoto::slotUpdateItemInfo(void) { d->itemsNb = d->thumbBar->countItems(); m_rotatedOrFlipped = false; int index = 0; TQString text; if (d->itemsNb > 0) { index = 1; for (Digikam::ThumbBarItem *item = d->thumbBar->firstItem(); item; item = item->next()) { if (item->url().equals(d->currentItem->url())) { break; } index++; } text = d->currentItem->url().filename() + i18n(" (%2 of %3)") .arg(TQString::number(index)) .arg(TQString::number(d->itemsNb)); setCaption(d->currentItem->url().directory()); } else { text = ""; setCaption(""); } m_nameLabel->setText(text); toggleNavigation( index ); } void ShowFoto::slotOpenFolder(const KURL& url) { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; m_canvas->load(TQString(), m_IOFileSettings); d->thumbBar->clear(true); emit signalNoCurrentItem(); d->currentItem = 0; openFolder(url); toggleActions(true); toggleNavigation(1); } void ShowFoto::openFolder(const KURL& url) { if (!url.isValid() || !url.isLocalFile()) return; // Parse KDE image IO mime types registration to get files filter pattern. TQStringList mimeTypes = KImageIO::mimeTypes(KImageIO::Reading); TQString filter; for (TQStringList::ConstIterator it = mimeTypes.begin() ; it != mimeTypes.end() ; ++it) { TQString format = KImageIO::typeForMime(*it); filter.append ("*."); filter.append (format); filter.append (" "); } // Because KImageIO return only *.JPEG and *.TIFF mime types. if ( filter.contains("*.TIFF") ) filter.append (" *.TIF"); if ( filter.contains("*.JPEG") ) { filter.append (" *.JPG"); filter.append (" *.JPE"); } // Added RAW files estentions supported by dcraw program and // defines to digikam/libs/dcraw/rawfiles.h filter.append (" "); #if KDCRAW_VERSION < 0x000106 filter.append ( TQString(KDcrawIface::DcrawBinary::instance()->rawFiles()) ); #else filter.append ( TQString(KDcrawIface::KDcraw::rawFiles()) ); #endif filter.append (" "); TQString patterns = filter.lower(); patterns.append (" "); patterns.append (filter.upper()); DDebug() << "patterns=" << patterns << endl; // Get all image files from directory. TQDir dir(url.path(), patterns); dir.setFilter ( TQDir::Files | TQDir::NoSymLinks ); if (!dir.exists()) return; // Determine sort ordering for the entries from configuration setting: KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); int flag; switch(config->readNumEntry("SortOrder", 0)) { case 1: flag = TQDir::Name; // Ordering by file name. break; case 2: flag = TQDir::Size; // Ordering by file size. break; default: flag = TQDir::Time; // Ordering by file date. break; } // Disabled reverse in the settings leads e.g. to increasing dates // Note, that this is just the opposite to the sort order for TQDir. if (!config->readBoolEntry("ReverseSort", false)) flag = flag | TQDir::Reversed; dir.setSorting(flag); const TQFileInfoList* fileinfolist = dir.entryInfoList(); if (!fileinfolist || fileinfolist->isEmpty()) { KMessageBox::sorry(this, i18n("There are no images in this folder.")); return; } TQFileInfoListIterator it(*fileinfolist); TQFileInfo* fi; // And open all items in image editor. while( (fi = it.current() ) ) { new Digikam::ThumbBarItem( d->thumbBar, KURL(fi->filePath()) ); ++it; } } void ShowFoto::slotOpenFilesInFolder() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; KURL url(KFileDialog::getExistingDirectory(d->lastOpenedDirectory.directory(), this, i18n("Open Images From Folder"))); if (!url.isEmpty()) { d->lastOpenedDirectory = url; slotOpenFolder(url); } } void ShowFoto::slotFirst() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; d->thumbBar->setSelected( d->thumbBar->firstItem() ); d->currentItem = d->thumbBar->firstItem(); } void ShowFoto::slotLast() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; d->thumbBar->setSelected( d->thumbBar->lastItem() ); d->currentItem = d->thumbBar->lastItem(); } void ShowFoto::slotForward() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; Digikam::ThumbBarItem* curr = d->thumbBar->currentItem(); if (curr && curr->next()) { d->thumbBar->setSelected(curr->next()); d->currentItem = d->thumbBar->currentItem(); } } void ShowFoto::slotBackward() { if (d->currentItem && !promptUserSave(d->currentItem->url())) return; Digikam::ThumbBarItem* curr = d->thumbBar->currentItem(); if (curr && curr->prev()) { d->thumbBar->setSelected(curr->prev()); d->currentItem = d->thumbBar->currentItem(); } } void ShowFoto::toggleNavigation(int index) { if ( d->itemsNb == 0 || d->itemsNb == 1 ) { m_backwardAction->setEnabled(false); m_forwardAction->setEnabled(false); m_firstAction->setEnabled(false); m_lastAction->setEnabled(false); } else { m_backwardAction->setEnabled(true); m_forwardAction->setEnabled(true); m_firstAction->setEnabled(true); m_lastAction->setEnabled(true); } if (index == 1) { m_backwardAction->setEnabled(false); m_firstAction->setEnabled(false); } if (index == d->itemsNb) { m_forwardAction->setEnabled(false); m_lastAction->setEnabled(false); } } void ShowFoto::slotLoadingStarted(const TQString& filename) { Digikam::EditorWindow::slotLoadingStarted(filename); // Here we disable specific actions on showfoto. d->openFilesInFolderAction->setEnabled(false); d->fileOpenAction->setEnabled(false); } void ShowFoto::slotLoadingFinished(const TQString& filename, bool success) { Digikam::EditorWindow::slotLoadingFinished(filename, success); // Here we re-enable specific actions on showfoto. d->openFilesInFolderAction->setEnabled(true); d->fileOpenAction->setEnabled(true); } void ShowFoto::slotSavingStarted(const TQString& filename) { Digikam::EditorWindow::slotSavingStarted(filename); // Here we disable specific actions on showfoto. d->openFilesInFolderAction->setEnabled(false); d->fileOpenAction->setEnabled(false); } void ShowFoto::finishSaving(bool success) { Digikam::EditorWindow::finishSaving(success); // Here we re-enable specific actions on showfoto. d->openFilesInFolderAction->setEnabled(true); d->fileOpenAction->setEnabled(true); } void ShowFoto::saveIsComplete() { Digikam::LoadingCacheInterface::putImage(m_savingContext->destinationURL.path(), m_canvas->currentImage()); d->thumbBar->invalidateThumb(d->currentItem); } void ShowFoto::saveAsIsComplete() { m_canvas->switchToLastSaved(m_savingContext->destinationURL.path()); Digikam::LoadingCacheInterface::putImage(m_savingContext->destinationURL.path(), m_canvas->currentImage()); // Add the file to the list of thumbbar images if it's not there already Digikam::ThumbBarItem* foundItem = d->thumbBar->findItemByURL(m_savingContext->destinationURL); d->thumbBar->invalidateThumb(foundItem); if (!foundItem) foundItem = new Digikam::ThumbBarItem(d->thumbBar, m_savingContext->destinationURL); // shortcut slotOpenURL d->thumbBar->blockSignals(true); d->thumbBar->setSelected(foundItem); d->thumbBar->blockSignals(false); d->currentItem = foundItem; } bool ShowFoto::save() { if (!d->currentItem) { DWarning() << k_funcinfo << "This should not happen" << endl; return true; } if (!d->currentItem->url().isLocalFile()) { return false; } startingSave(d->currentItem->url()); return true; } bool ShowFoto::saveAs() { if (!d->currentItem) { DWarning() << k_funcinfo << "This should not happen" << endl; return false; } return ( startingSaveAs(d->currentItem->url()) ); } void ShowFoto::slotDeleteCurrentItem() { KURL urlCurrent(d->currentItem->url()); if (!d->deleteItem2Trash) { TQString warnMsg(i18n("About to delete file \"%1\"\nAre you sure?") .arg(urlCurrent.filename())); if (KMessageBox::warningContinueCancel(this, warnMsg, i18n("Warning"), i18n("Delete")) != KMessageBox::Continue) { return; } else { KIO::Job* job = KIO::del( urlCurrent ); connect( job, TQT_SIGNAL(result( KIO::Job* )), TQT_TQOBJECT(this), TQT_SLOT(slotDeleteCurrentItemResult( KIO::Job*)) ); } } else { KURL dest("trash:/"); if (!KProtocolInfo::isKnownProtocol(dest)) { dest = KGlobalSettings::trashPath(); } KIO::Job* job = KIO::move( urlCurrent, dest ); connect( job, TQT_SIGNAL(result( KIO::Job* )), TQT_TQOBJECT(this), TQT_SLOT(slotDeleteCurrentItemResult( KIO::Job*)) ); } } void ShowFoto::slotDeleteCurrentItemResult( KIO::Job * job ) { if (job->error() != 0) { TQString errMsg(job->errorString()); KMessageBox::error(this, errMsg); return; } // No error, remove item in thumbbar. Digikam::ThumbBarItem *item2remove = d->currentItem; Digikam::ThumbBarItem *nextItem = 0; for (Digikam::ThumbBarItem *item = d->thumbBar->firstItem(); item; item = item->next()) { if (item->url().equals(item2remove->url())) { // Find item next to the current item nextItem = item->next(); d->thumbBar->removeItem(item); d->currentItem = 0; break; } } d->itemsNb = d->thumbBar->countItems(); // Disable menu actions and SideBar if no current image. if ( d->itemsNb == 0 ) { emit signalNoCurrentItem(); slotUpdateItemInfo(); toggleActions(false); m_canvas->load(TQString(), m_IOFileSettings); } else { // If there is an image after the deleted one, make that selected. if (nextItem) d->thumbBar->setSelected(nextItem); d->currentItem = d->thumbBar->currentItem(); slotOpenURL(d->currentItem->url()); } } void ShowFoto::slotContextMenu() { m_contextMenu->exec(TQCursor::pos()); } void ShowFoto::slideShow(bool startWithCurrent, Digikam::SlideShowSettings& settings) { if (!d->thumbBar->countItems()) return; KConfig* config = kapp->config(); config->setGroup("ImageViewer Settings"); settings.exifRotate = config->readBoolEntry("EXIF Rotate", true); settings.fileList = d->thumbBar->itemsURLs(); int i = 0; float cnt = settings.fileList.count(); Digikam::DMetadata meta; m_cancelSlideShow = false; m_nameLabel->progressBarMode(Digikam::StatusProgressBar::CancelProgressBarMode, i18n("Preparing slideshow. Please wait...")); for (KURL::List::Iterator it = settings.fileList.begin() ; !m_cancelSlideShow && (it != settings.fileList.end()) ; ++it) { Digikam::SlidePictureInfo pictInfo; meta.load((*it).path()); pictInfo.comment = meta.getImageComment(); pictInfo.photoInfo = meta.getPhotographInformations(); settings.pictInfoMap.insert(*it, pictInfo); m_nameLabel->setProgressValue((int)((i++/cnt)*100.0)); kapp->processEvents(); } m_nameLabel->progressBarMode(Digikam::StatusProgressBar::TextMode, TQString()); if (!m_cancelSlideShow) { Digikam::SlideShow *slide = new Digikam::SlideShow(settings); if (startWithCurrent) slide->setCurrent(d->currentItem->url()); slide->show(); } } void ShowFoto::slotRevert() { if(!promptUserSave(d->currentItem->url())) return; m_canvas->slotRestore(); } } // namespace ShowFoto