You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1241 lines
36 KiB
1241 lines
36 KiB
/* ============================================================
|
|
*
|
|
* 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 <renchi@pooh.tam.uiuc.edu>
|
|
* Copyright (C) 2005-2006 by Tom Albers <tomalbers@kde.nl>
|
|
* Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
* Copyright (C) 2006-2008 by Marcel Wiesweg <marcel.wiesweg@gmx.de>
|
|
* Copyright (C) 2008 by Arnd Baecker <arnd dot baecker at web dot de>
|
|
*
|
|
* 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 <unistd.h>
|
|
}
|
|
|
|
// C++ includes.
|
|
|
|
#include <cstdio>
|
|
|
|
// TQt includes.
|
|
|
|
#include <tqlabel.h>
|
|
#include <tqlayout.h>
|
|
#include <tqsplitter.h>
|
|
#include <tqdir.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqfile.h>
|
|
#include <tqcursor.h>
|
|
|
|
// KDE includes.
|
|
|
|
#include <kcursor.h>
|
|
#include <tdeaction.h>
|
|
#include <kstdaction.h>
|
|
#include <tdeapplication.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdelocale.h>
|
|
#include <tdefiledialog.h>
|
|
#include <tdemenubar.h>
|
|
#include <kimageio.h>
|
|
#include <tdeaccel.h>
|
|
#include <tdeversion.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdeglobal.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kiconloader.h>
|
|
#include <tdeio/netaccess.h>
|
|
#include <tdeio/job.h>
|
|
#include <kprotocolinfo.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <tdetoolbar.h>
|
|
#include <kstatusbar.h>
|
|
#include <kprogress.h>
|
|
|
|
// LibKDcraw includes.
|
|
|
|
#include <libkdcraw/version.h>
|
|
#include <libkdcraw/kdcraw.h>
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
#include <libkdcraw/dcrawbinary.h>
|
|
#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;
|
|
|
|
TDEToggleAction *showBarAction;
|
|
|
|
TDEAction *openFilesInFolderAction;
|
|
TDEAction *fileOpenAction;
|
|
|
|
TDEActionMenu *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 ----------------------------
|
|
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup("ImageViewer Settings");
|
|
TDEGlobal::dirs()->addResourceType("data", TDEGlobal::dirs()->kde_default("data") + "digikam");
|
|
TDEGlobal::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 TDEActionMenu(i18n("Brightness/Contrast/Gamma"), 0, 0, "showfoto_bcg");
|
|
d->BCGAction->setDelayed(false);
|
|
|
|
TDEAction *incGammaAction = new TDEAction(i18n("Increase Gamma"), 0, ALT+Key_G,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()),
|
|
actionCollection(), "gamma_plus");
|
|
TDEAction *decGammaAction = new TDEAction(i18n("Decrease Gamma"), 0, ALT+SHIFT+Key_G,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()),
|
|
actionCollection(), "gamma_minus");
|
|
TDEAction *incBrightAction = new TDEAction(i18n("Increase Brightness"), 0, ALT+Key_B,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()),
|
|
actionCollection(), "brightness_plus");
|
|
TDEAction *decBrightAction = new TDEAction(i18n("Decrease Brightness"), 0, ALT+SHIFT+Key_B,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()),
|
|
actionCollection(), "brightness_minus");
|
|
TDEAction *incContrastAction = new TDEAction(i18n("Increase Contrast"), 0, ALT+Key_C,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotChangeBCG()),
|
|
actionCollection(), "contrast_plus");
|
|
TDEAction *decContrastAction = new TDEAction(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<TDEAction> 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<Digikam::Sidebar*>(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.
|
|
|
|
TDEMainWindow::show();
|
|
|
|
// Report errors from ICC repository path.
|
|
|
|
TDEConfig* config = kapp->config();
|
|
if(!d->validIccPath)
|
|
{
|
|
TQString message = i18n("<qt><p>The ICC profile path seems to be invalid.</p>"
|
|
"<p>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</p></qt>");
|
|
|
|
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()
|
|
{
|
|
TDEConfig* 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)) // Vertical thumbbar layout
|
|
{
|
|
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 // Horizontal thumbbar layout
|
|
{
|
|
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 TDEAction(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 TDEToggleAction(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();
|
|
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup("ImageViewer Settings");
|
|
|
|
d->showBarAction->setChecked(config->readBoolEntry("Show Thumbnails", true));
|
|
slotToggleShowBar();
|
|
|
|
d->lastOpenedDirectory.setPath( config->readEntry("Last Opened Directory",
|
|
TDEGlobalSettings::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();
|
|
|
|
TDEConfig* 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();
|
|
|
|
TDEConfig* 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("edit-delete");
|
|
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)
|
|
TDEIO::NetAccess::download(url, localFile, this);
|
|
#else
|
|
TDEIO::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<TQT_BASE_OBJECT_NAME*>(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:
|
|
|
|
TDEConfig* 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
|
|
{
|
|
TDEIO::Job* job = TDEIO::del( urlCurrent );
|
|
connect( job, TQT_SIGNAL(result( TDEIO::Job* )),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotDeleteCurrentItemResult( TDEIO::Job*)) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
KURL dest("trash:/");
|
|
|
|
if (!KProtocolInfo::isKnownProtocol(dest))
|
|
{
|
|
dest = TDEGlobalSettings::trashPath();
|
|
}
|
|
|
|
TDEIO::Job* job = TDEIO::move( urlCurrent, dest );
|
|
connect( job, TQT_SIGNAL(result( TDEIO::Job* )),
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotDeleteCurrentItemResult( TDEIO::Job*)) );
|
|
}
|
|
}
|
|
|
|
void ShowFoto::slotDeleteCurrentItemResult( TDEIO::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;
|
|
|
|
TDEConfig* 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
|