DigiKam – digital photo management application
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.
 
 
 
 
 
 

1677 lines
55 KiB

  1. /* ============================================================
  2. *
  3. * This file is a part of digiKam project
  4. * http://www.digikam.org
  5. *
  6. * Date : 2007-03-05
  7. * Description : digiKam light table GUI
  8. *
  9. * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
  10. *
  11. * This program is free software; you can redistribute it
  12. * and/or modify it under the terms of the GNU General
  13. * Public License as published by the Free Software Foundation;
  14. * either version 2, or (at your option)
  15. * any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * ============================================================ */
  23. // TQt includes.
  24. #include <tqdockarea.h>
  25. // KDE includes.
  26. #include <kkeydialog.h>
  27. #include <kedittoolbar.h>
  28. #include <tdeversion.h>
  29. #include <tdelocale.h>
  30. #include <twin.h>
  31. #include <tdemessagebox.h>
  32. #include <tdeapplication.h>
  33. #include <tdeconfig.h>
  34. #include <kstatusbar.h>
  35. #include <tdemenubar.h>
  36. // LibKDcraw includes.
  37. #include <libkdcraw/version.h>
  38. #include <libkdcraw/kdcraw.h>
  39. #if KDCRAW_VERSION < 0x000106
  40. #include <libkdcraw/dcrawbinary.h>
  41. #endif
  42. // Local includes.
  43. #include "ddebug.h"
  44. #include "dlogoaction.h"
  45. #include "themeengine.h"
  46. #include "dimg.h"
  47. #include "dmetadata.h"
  48. #include "albumsettings.h"
  49. #include "albummanager.h"
  50. #include "deletedialog.h"
  51. #include "imagewindow.h"
  52. #include "slideshow.h"
  53. #include "setup.h"
  54. #include "syncjob.h"
  55. #include "thumbnailsize.h"
  56. #include "rawcameradlg.h"
  57. #include "lighttablepreview.h"
  58. #include "lighttablewindowprivate.h"
  59. #include "lighttablewindow.h"
  60. #include "lighttablewindow.moc"
  61. namespace Digikam
  62. {
  63. LightTableWindow* LightTableWindow::m_instance = 0;
  64. LightTableWindow* LightTableWindow::lightTableWindow()
  65. {
  66. if (!m_instance)
  67. new LightTableWindow();
  68. return m_instance;
  69. }
  70. bool LightTableWindow::lightTableWindowCreated()
  71. {
  72. return m_instance;
  73. }
  74. LightTableWindow::LightTableWindow()
  75. : TDEMainWindow(0, "lighttable", WType_TopLevel)
  76. {
  77. d = new LightTableWindowPriv;
  78. m_instance = this;
  79. setCaption(i18n("Light Table"));
  80. // -- Build the GUI -------------------------------
  81. setupUserArea();
  82. setupStatusBar();
  83. setupActions();
  84. setupAccelerators();
  85. // Make signals/slots connections
  86. setupConnections();
  87. //-------------------------------------------------------------
  88. d->leftSidebar->loadViewState();
  89. d->rightSidebar->loadViewState();
  90. d->leftSidebar->populateTags();
  91. d->rightSidebar->populateTags();
  92. readSettings();
  93. applySettings();
  94. setAutoSaveSettings("LightTable Settings");
  95. }
  96. LightTableWindow::~LightTableWindow()
  97. {
  98. m_instance = 0;
  99. delete d->barView;
  100. delete d->rightSidebar;
  101. delete d->leftSidebar;
  102. delete d;
  103. }
  104. void LightTableWindow::readSettings()
  105. {
  106. TDEConfig* config = kapp->config();
  107. config->setGroup("LightTable Settings");
  108. if(config->hasKey("Vertical Splitter Sizes"))
  109. d->vSplitter->setSizes(config->readIntListEntry("Vertical Splitter Sizes"));
  110. if(config->hasKey("Horizontal Splitter Sizes"))
  111. d->hSplitter->setSizes(config->readIntListEntry("Horizontal Splitter Sizes"));
  112. d->navigateByPairAction->setChecked(config->readBoolEntry("Navigate By Pair", false));
  113. slotToggleNavigateByPair();
  114. }
  115. void LightTableWindow::writeSettings()
  116. {
  117. TDEConfig* config = kapp->config();
  118. config->setGroup("LightTable Settings");
  119. config->writeEntry("Vertical Splitter Sizes", d->vSplitter->sizes());
  120. config->writeEntry("Horizontal Splitter Sizes", d->hSplitter->sizes());
  121. config->writeEntry("Navigate By Pair", d->navigateByPairAction->isChecked());
  122. config->sync();
  123. }
  124. void LightTableWindow::applySettings()
  125. {
  126. TDEConfig* config = kapp->config();
  127. config->setGroup("LightTable Settings");
  128. d->autoLoadOnRightPanel = config->readBoolEntry("Auto Load Right Panel", true);
  129. d->autoSyncPreview = config->readBoolEntry("Auto Sync Preview", true);
  130. d->fullScreenHideToolBar = config->readBoolEntry("FullScreen Hide ToolBar", false);
  131. d->previewView->setLoadFullImageSize(config->readBoolEntry("Load Full Image size", false));
  132. refreshView();
  133. }
  134. void LightTableWindow::refreshView()
  135. {
  136. d->leftSidebar->refreshTagsView();
  137. d->rightSidebar->refreshTagsView();
  138. }
  139. void LightTableWindow::closeEvent(TQCloseEvent* e)
  140. {
  141. if (!e) return;
  142. writeSettings();
  143. e->accept();
  144. }
  145. void LightTableWindow::setupUserArea()
  146. {
  147. TQWidget* mainW = new TQWidget(this);
  148. d->hSplitter = new TQSplitter(Qt::Horizontal, mainW);
  149. TQHBoxLayout *hlay = new TQHBoxLayout(mainW);
  150. d->leftSidebar = new ImagePropertiesSideBarDB(mainW,
  151. "LightTable Left Sidebar", d->hSplitter,
  152. Sidebar::Left, true);
  153. TQWidget* centralW = new TQWidget(d->hSplitter);
  154. TQVBoxLayout *vlay = new TQVBoxLayout(centralW);
  155. d->vSplitter = new TQSplitter(Qt::Vertical, centralW);
  156. d->barView = new LightTableBar(d->vSplitter, ThumbBarView::Horizontal,
  157. AlbumSettings::instance()->getExifRotate());
  158. d->previewView = new LightTableView(d->vSplitter);
  159. vlay->addWidget(d->vSplitter);
  160. d->rightSidebar = new ImagePropertiesSideBarDB(mainW,
  161. "LightTable Right Sidebar", d->hSplitter,
  162. Sidebar::Right, true);
  163. hlay->addWidget(d->leftSidebar);
  164. hlay->addWidget(d->hSplitter);
  165. hlay->addWidget(d->rightSidebar);
  166. d->hSplitter->setFrameStyle( TQFrame::NoFrame );
  167. d->hSplitter->setFrameShadow( TQFrame::Plain );
  168. d->hSplitter->setFrameShape( TQFrame::NoFrame );
  169. d->hSplitter->setOpaqueResize(false);
  170. d->vSplitter->setFrameStyle( TQFrame::NoFrame );
  171. d->vSplitter->setFrameShadow( TQFrame::Plain );
  172. d->vSplitter->setFrameShape( TQFrame::NoFrame );
  173. d->vSplitter->setOpaqueResize(false);
  174. setCentralWidget(mainW);
  175. }
  176. void LightTableWindow::setupStatusBar()
  177. {
  178. d->leftZoomBar = new StatusZoomBar(statusBar());
  179. d->leftZoomBar->setMaximumHeight(fontMetrics().height()+2);
  180. statusBar()->addWidget(d->leftZoomBar, 1);
  181. d->leftZoomBar->setEnabled(false);
  182. d->statusProgressBar = new StatusProgressBar(statusBar());
  183. d->statusProgressBar->setAlignment(TQt::AlignCenter);
  184. d->statusProgressBar->setMaximumHeight(fontMetrics().height()+2);
  185. statusBar()->addWidget(d->statusProgressBar, 100);
  186. d->rightZoomBar = new StatusZoomBar(statusBar());
  187. d->rightZoomBar->setMaximumHeight(fontMetrics().height()+2);
  188. statusBar()->addWidget(d->rightZoomBar, 1);
  189. d->rightZoomBar->setEnabled(false);
  190. }
  191. void LightTableWindow::setupConnections()
  192. {
  193. connect(d->statusProgressBar, TQT_SIGNAL(signalCancelButtonPressed()),
  194. TQT_TQOBJECT(this), TQT_SLOT(slotProgressBarCancelButtonPressed()));
  195. connect(ThemeEngine::instance(), TQT_SIGNAL(signalThemeChanged()),
  196. TQT_TQOBJECT(this), TQT_SLOT(slotThemeChanged()));
  197. // Thumbs bar connections ---------------------------------------
  198. connect(d->barView, TQT_SIGNAL(signalSetItemOnLeftPanel(ImageInfo*)),
  199. TQT_TQOBJECT(this), TQT_SLOT(slotSetItemOnLeftPanel(ImageInfo*)));
  200. connect(d->barView, TQT_SIGNAL(signalSetItemOnRightPanel(ImageInfo*)),
  201. TQT_TQOBJECT(this), TQT_SLOT(slotSetItemOnRightPanel(ImageInfo*)));
  202. connect(d->barView, TQT_SIGNAL(signalRemoveItem(ImageInfo*)),
  203. TQT_TQOBJECT(this), TQT_SLOT(slotRemoveItem(ImageInfo*)));
  204. connect(d->barView, TQT_SIGNAL(signalEditItem(ImageInfo*)),
  205. TQT_TQOBJECT(this), TQT_SLOT(slotEditItem(ImageInfo*)));
  206. connect(d->barView, TQT_SIGNAL(signalClearAll()),
  207. TQT_TQOBJECT(this), TQT_SLOT(slotClearItemsList()));
  208. connect(d->barView, TQT_SIGNAL(signalLightTableBarItemSelected(ImageInfo*)),
  209. TQT_TQOBJECT(this), TQT_SLOT(slotItemSelected(ImageInfo*)));
  210. connect(d->barView, TQT_SIGNAL(signalDroppedItems(const ImageInfoList&)),
  211. TQT_TQOBJECT(this), TQT_SLOT(slotThumbbarDroppedItems(const ImageInfoList&)));
  212. // Zoom bars connections -----------------------------------------
  213. connect(d->leftZoomBar, TQT_SIGNAL(signalZoomMinusClicked()),
  214. d->previewView, TQT_SLOT(slotDecreaseLeftZoom()));
  215. connect(d->leftZoomBar, TQT_SIGNAL(signalZoomPlusClicked()),
  216. d->previewView, TQT_SLOT(slotIncreaseLeftZoom()));
  217. connect(d->leftZoomBar, TQT_SIGNAL(signalZoomSliderChanged(int)),
  218. d->previewView, TQT_SLOT(slotLeftZoomSliderChanged(int)));
  219. connect(d->rightZoomBar, TQT_SIGNAL(signalZoomMinusClicked()),
  220. d->previewView, TQT_SLOT(slotDecreaseRightZoom()));
  221. connect(d->rightZoomBar, TQT_SIGNAL(signalZoomPlusClicked()),
  222. d->previewView, TQT_SLOT(slotIncreaseRightZoom()));
  223. connect(d->rightZoomBar, TQT_SIGNAL(signalZoomSliderChanged(int)),
  224. d->previewView, TQT_SLOT(slotRightZoomSliderChanged(int)));
  225. // View connections ---------------------------------------------
  226. connect(d->previewView, TQT_SIGNAL(signalLeftZoomFactorChanged(double)),
  227. TQT_TQOBJECT(this), TQT_SLOT(slotLeftZoomFactorChanged(double)));
  228. connect(d->previewView, TQT_SIGNAL(signalRightZoomFactorChanged(double)),
  229. TQT_TQOBJECT(this), TQT_SLOT(slotRightZoomFactorChanged(double)));
  230. connect(d->previewView, TQT_SIGNAL(signalEditItem(ImageInfo*)),
  231. TQT_TQOBJECT(this), TQT_SLOT(slotEditItem(ImageInfo*)));
  232. connect(d->previewView, TQT_SIGNAL(signalDeleteItem(ImageInfo*)),
  233. TQT_TQOBJECT(this), TQT_SLOT(slotDeleteItem(ImageInfo*)));
  234. connect(d->previewView, TQT_SIGNAL(signalSlideShow()),
  235. TQT_TQOBJECT(this), TQT_SLOT(slotToggleSlideShow()));
  236. connect(d->previewView, TQT_SIGNAL(signalLeftDroppedItems(const ImageInfoList&)),
  237. TQT_TQOBJECT(this), TQT_SLOT(slotLeftDroppedItems(const ImageInfoList&)));
  238. connect(d->previewView, TQT_SIGNAL(signalRightDroppedItems(const ImageInfoList&)),
  239. TQT_TQOBJECT(this), TQT_SLOT(slotRightDroppedItems(const ImageInfoList&)));
  240. connect(d->previewView, TQT_SIGNAL(signalToggleOnSyncPreview(bool)),
  241. TQT_TQOBJECT(this), TQT_SLOT(slotToggleOnSyncPreview(bool)));
  242. connect(d->previewView, TQT_SIGNAL(signalLeftPreviewLoaded(bool)),
  243. TQT_TQOBJECT(this), TQT_SLOT(slotLeftPreviewLoaded(bool)));
  244. connect(d->previewView, TQT_SIGNAL(signalRightPreviewLoaded(bool)),
  245. TQT_TQOBJECT(this), TQT_SLOT(slotRightPreviewLoaded(bool)));
  246. connect(d->previewView, TQT_SIGNAL(signalLeftPanelLeftButtonClicked()),
  247. TQT_TQOBJECT(this), TQT_SLOT(slotLeftPanelLeftButtonClicked()));
  248. connect(d->previewView, TQT_SIGNAL(signalRightPanelLeftButtonClicked()),
  249. TQT_TQOBJECT(this), TQT_SLOT(slotRightPanelLeftButtonClicked()));
  250. }
  251. void LightTableWindow::setupActions()
  252. {
  253. // -- Standard 'File' menu actions ---------------------------------------------
  254. d->backwardAction = KStdAction::back(TQT_TQOBJECT(this), TQT_SLOT(slotBackward()),
  255. actionCollection(), "lighttable_backward");
  256. d->backwardAction->setEnabled(false);
  257. d->forwardAction = KStdAction::forward(TQT_TQOBJECT(this), TQT_SLOT(slotForward()),
  258. actionCollection(), "lighttable_forward");
  259. d->forwardAction->setEnabled(false);
  260. d->firstAction = new TDEAction(i18n("&First"), "go-first",
  261. TDEStdAccel::shortcut( TDEStdAccel::Home),
  262. TQT_TQOBJECT(this), TQT_SLOT(slotFirst()),
  263. actionCollection(), "lighttable_first");
  264. d->firstAction->setEnabled(false);
  265. d->lastAction = new TDEAction(i18n("&Last"), "go-last",
  266. TDEStdAccel::shortcut( TDEStdAccel::End),
  267. TQT_TQOBJECT(this), TQT_SLOT(slotLast()),
  268. actionCollection(), "lighttable_last");
  269. d->lastAction->setEnabled(false);
  270. d->setItemLeftAction = new TDEAction(i18n("On Left"), "go-previous",
  271. CTRL+Key_L, TQT_TQOBJECT(this), TQT_SLOT(slotSetItemLeft()),
  272. actionCollection(), "lighttable_setitemleft");
  273. d->setItemLeftAction->setEnabled(false);
  274. d->setItemLeftAction->setWhatsThis(i18n("Show item on left panel"));
  275. d->setItemRightAction = new TDEAction(i18n("On Right"), "go-next",
  276. CTRL+Key_R, TQT_TQOBJECT(this), TQT_SLOT(slotSetItemRight()),
  277. actionCollection(), "lighttable_setitemright");
  278. d->setItemRightAction->setEnabled(false);
  279. d->setItemRightAction->setWhatsThis(i18n("Show item on right panel"));
  280. d->editItemAction = new TDEAction(i18n("Edit"), "editimage",
  281. Key_F4, TQT_TQOBJECT(this), TQT_SLOT(slotEditItem()),
  282. actionCollection(), "lighttable_edititem");
  283. d->editItemAction->setEnabled(false);
  284. d->removeItemAction = new TDEAction(i18n("Remove item from LightTable"), "window-close",
  285. CTRL+Key_K, TQT_TQOBJECT(this), TQT_SLOT(slotRemoveItem()),
  286. actionCollection(), "lighttable_removeitem");
  287. d->removeItemAction->setEnabled(false);
  288. d->clearListAction = new TDEAction(i18n("Remove all items from LightTable"), "editshred",
  289. CTRL+SHIFT+Key_K, TQT_TQOBJECT(this), TQT_SLOT(slotClearItemsList()),
  290. actionCollection(), "lighttable_clearlist");
  291. d->clearListAction->setEnabled(false);
  292. d->fileDeleteAction = new TDEAction(i18n("Move to Trash"), "edittrash",
  293. Key_Delete,
  294. TQT_TQOBJECT(this), TQT_SLOT(slotDeleteItem()),
  295. actionCollection(), "lighttable_filedelete");
  296. d->fileDeleteAction->setEnabled(false);
  297. KStdAction::close(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection(), "lighttable_close");
  298. // -- Standard 'View' menu actions ---------------------------------------------
  299. d->syncPreviewAction = new TDEToggleAction(i18n("Synchronize"), "goto",
  300. CTRL+SHIFT+Key_Y, TQT_TQOBJECT(this),
  301. TQT_SLOT(slotToggleSyncPreview()),
  302. actionCollection(), "lighttable_syncpreview");
  303. d->syncPreviewAction->setEnabled(false);
  304. d->syncPreviewAction->setWhatsThis(i18n("Synchronize preview from left and right panels"));
  305. d->navigateByPairAction = new TDEToggleAction(i18n("By Pair"), "preferences-system",
  306. CTRL+SHIFT+Key_P, TQT_TQOBJECT(this),
  307. TQT_SLOT(slotToggleNavigateByPair()),
  308. actionCollection(), "lighttable_navigatebypair");
  309. d->navigateByPairAction->setEnabled(false);
  310. d->navigateByPairAction->setWhatsThis(i18n("Navigate by pair with all items"));
  311. d->zoomPlusAction = KStdAction::zoomIn(TQT_TQOBJECT(d->previewView), TQT_SLOT(slotIncreaseZoom()),
  312. actionCollection(), "lighttable_zoomplus");
  313. d->zoomPlusAction->setEnabled(false);
  314. d->zoomMinusAction = KStdAction::zoomOut(TQT_TQOBJECT(d->previewView), TQT_SLOT(slotDecreaseZoom()),
  315. actionCollection(), "lighttable_zoomminus");
  316. d->zoomMinusAction->setEnabled(false);
  317. d->zoomTo100percents = new TDEAction(i18n("Zoom to 100%"), "zoom-original",
  318. ALT+CTRL+Key_0, // NOTE: Photoshop 7 use ALT+CTRL+0.
  319. TQT_TQOBJECT(this), TQT_SLOT(slotZoomTo100Percents()),
  320. actionCollection(), "lighttable_zoomto100percents");
  321. d->zoomFitToWindowAction = new TDEAction(i18n("Fit to &Window"), "view_fit_window",
  322. CTRL+SHIFT+Key_E, TQT_TQOBJECT(this), TQT_SLOT(slotFitToWindow()),
  323. actionCollection(), "lighttable_zoomfit2window");
  324. // Do not use std KDE action for full screen because action text is too large for app. toolbar.
  325. d->fullScreenAction = new TDEToggleAction(i18n("Full Screen"), "view-fullscreen",
  326. CTRL+SHIFT+Key_F, TQT_TQOBJECT(this),
  327. TQT_SLOT(slotToggleFullScreen()),
  328. actionCollection(), "lighttable_fullscreen");
  329. d->fullScreenAction->setWhatsThis(i18n("Toggle the window to full screen mode"));
  330. d->slideShowAction = new TDEAction(i18n("Slideshow"), "slideshow", Key_F9,
  331. TQT_TQOBJECT(this), TQT_SLOT(slotToggleSlideShow()),
  332. actionCollection(),"lighttable_slideshow");
  333. // -- Standard 'Configure' menu actions ----------------------------------------
  334. d->showMenuBarAction = KStdAction::showMenubar(TQT_TQOBJECT(this), TQT_SLOT(slotShowMenuBar()), actionCollection());
  335. KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(slotEditKeys()), actionCollection());
  336. KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(slotConfToolbars()), actionCollection());
  337. KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotSetup()), actionCollection());
  338. // -----------------------------------------------------------------------------------------
  339. d->themeMenuAction = new TDESelectAction(i18n("&Themes"), 0, actionCollection(), "theme_menu");
  340. connect(d->themeMenuAction, TQT_SIGNAL(activated(const TQString&)),
  341. TQT_TQOBJECT(this), TQT_SLOT(slotChangeTheme(const TQString&)));
  342. d->themeMenuAction->setItems(ThemeEngine::instance()->themeNames());
  343. slotThemeChanged();
  344. // -- Standard 'Help' menu actions ---------------------------------------------
  345. d->donateMoneyAction = new TDEAction(i18n("Donate..."),
  346. 0, 0,
  347. TQT_TQOBJECT(this), TQT_SLOT(slotDonateMoney()),
  348. actionCollection(),
  349. "lighttable_donatemoney");
  350. d->contributeAction = new TDEAction(i18n("Contribute..."),
  351. 0, 0,
  352. TQT_TQOBJECT(this), TQT_SLOT(slotContribute()),
  353. actionCollection(),
  354. "lighttable_contribute");
  355. d->rawCameraListAction = new TDEAction(i18n("Supported RAW Cameras"),
  356. "kdcraw",
  357. 0,
  358. TQT_TQOBJECT(this),
  359. TQT_SLOT(slotRawCameraList()),
  360. actionCollection(),
  361. "lighttable_rawcameralist");
  362. // Provides a menu entry that allows showing/hiding the toolbar(s)
  363. setStandardToolBarMenuEnabled(true);
  364. // Provides a menu entry that allows showing/hiding the statusbar
  365. createStandardStatusBarAction();
  366. // -- Rating actions ---------------------------------------------------------------
  367. d->star0 = new TDEAction(i18n("Assign Rating \"No Stars\""), CTRL+Key_0,
  368. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingNoStar()),
  369. actionCollection(), "lighttable_ratenostar");
  370. d->star1 = new TDEAction(i18n("Assign Rating \"One Star\""), CTRL+Key_1,
  371. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingOneStar()),
  372. actionCollection(), "lighttable_rateonestar");
  373. d->star2 = new TDEAction(i18n("Assign Rating \"Two Stars\""), CTRL+Key_2,
  374. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingTwoStar()),
  375. actionCollection(), "lighttable_ratetwostar");
  376. d->star3 = new TDEAction(i18n("Assign Rating \"Three Stars\""), CTRL+Key_3,
  377. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingThreeStar()),
  378. actionCollection(), "lighttable_ratethreestar");
  379. d->star4 = new TDEAction(i18n("Assign Rating \"Four Stars\""), CTRL+Key_4,
  380. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingFourStar()),
  381. actionCollection(), "lighttable_ratefourstar");
  382. d->star5 = new TDEAction(i18n("Assign Rating \"Five Stars\""), CTRL+Key_5,
  383. TQT_TQOBJECT(d->barView), TQT_SLOT(slotAssignRatingFiveStar()),
  384. actionCollection(), "lighttable_ratefivestar");
  385. // ---------------------------------------------------------------------------------
  386. new DLogoAction(actionCollection(), "logo_action");
  387. createGUI("lighttablewindowui.rc", false);
  388. }
  389. void LightTableWindow::setupAccelerators()
  390. {
  391. d->accelerators = new TDEAccel(this);
  392. d->accelerators->insert("Exit fullscreen", i18n("Exit Fullscreen mode"),
  393. i18n("Exit fullscreen viewing mode"),
  394. Key_Escape, TQT_TQOBJECT(this), TQT_SLOT(slotEscapePressed()),
  395. false, true);
  396. d->accelerators->insert("Next Image Key_Space", i18n("Next Image"),
  397. i18n("Load Next Image"),
  398. Key_Space, TQT_TQOBJECT(this), TQT_SLOT(slotForward()),
  399. false, true);
  400. d->accelerators->insert("Previous Image SHIFT+Key_Space", i18n("Previous Image"),
  401. i18n("Load Previous Image"),
  402. SHIFT+Key_Space, TQT_TQOBJECT(this), TQT_SLOT(slotBackward()),
  403. false, true);
  404. d->accelerators->insert("Previous Image Key_Backspace", i18n("Previous Image"),
  405. i18n("Load Previous Image"),
  406. Key_Backspace, TQT_TQOBJECT(this), TQT_SLOT(slotBackward()),
  407. false, true);
  408. d->accelerators->insert("Next Image Key_Next", i18n("Next Image"),
  409. i18n("Load Next Image"),
  410. Key_Next, TQT_TQOBJECT(this), TQT_SLOT(slotForward()),
  411. false, true);
  412. d->accelerators->insert("Previous Image Key_Prior", i18n("Previous Image"),
  413. i18n("Load Previous Image"),
  414. Key_Prior, TQT_TQOBJECT(this), TQT_SLOT(slotBackward()),
  415. false, true);
  416. d->accelerators->insert("Zoom Plus Key_Plus", i18n("Zoom in"),
  417. i18n("Zoom in on image"),
  418. Key_Plus, TQT_TQOBJECT(d->previewView), TQT_SLOT(slotIncreaseZoom()),
  419. false, true);
  420. d->accelerators->insert("Zoom Plus Key_Minus", i18n("Zoom out"),
  421. i18n("Zoom out from image"),
  422. Key_Minus, TQT_TQOBJECT(d->previewView), TQT_SLOT(slotDecreaseZoom()),
  423. false, true);
  424. }
  425. // Deal with items dropped onto the thumbbar (e.g. from the Album view)
  426. void LightTableWindow::slotThumbbarDroppedItems(const ImageInfoList& list)
  427. {
  428. // Setting the third parameter of loadImageInfos to true
  429. // means that the images are added to the presently available images.
  430. loadImageInfos(list, 0, true);
  431. }
  432. // We get here either
  433. // - via CTRL+L (from the albumview)
  434. // a) digikamapp.cpp: CTRL+key_L leads to slotImageLightTable())
  435. // b) digikamview.cpp: void DigikamView::slotImageLightTable()
  436. // calls d->iconView->insertToLightTable(list, info);
  437. // c) albumiconview.cpp: AlbumIconView::insertToLightTable
  438. // calls ltview->loadImageInfos(list, current);
  439. // - via drag&drop, i.e. calls issued by the ...Dropped... routines
  440. void LightTableWindow::loadImageInfos(const ImageInfoList &list,
  441. ImageInfo *imageInfoCurrent,
  442. bool addTo)
  443. {
  444. // Clear all items before adding new images to the light table.
  445. if (!addTo)
  446. slotClearItemsList();
  447. ImageInfoList l = list;
  448. if (!imageInfoCurrent)
  449. imageInfoCurrent = l.first();
  450. AlbumSettings *settings = AlbumSettings::instance();
  451. if (!settings) return;
  452. TQString imagefilter = settings->getImageFileFilter().lower() +
  453. settings->getImageFileFilter().upper();
  454. #if KDCRAW_VERSION < 0x000106
  455. if (KDcrawIface::DcrawBinary::instance()->versionIsRight())
  456. {
  457. // add raw files only if dcraw is available
  458. imagefilter += settings->getRawFileFilter().lower() +
  459. settings->getRawFileFilter().upper();
  460. }
  461. #else
  462. imagefilter += settings->getRawFileFilter().lower() +
  463. settings->getRawFileFilter().upper();
  464. #endif
  465. d->barView->blockSignals(true);
  466. for (TQPtrList<ImageInfo>::const_iterator it = l.begin(); it != l.end(); ++it)
  467. {
  468. TQString fileExtension = (*it)->kurl().fileName().section( '.', -1 );
  469. if ( imagefilter.find(fileExtension) != -1 &&
  470. !d->barView->findItemByInfo(*it) )
  471. {
  472. new LightTableBarItem(d->barView, *it);
  473. }
  474. }
  475. d->barView->blockSignals(false);
  476. // if window is iconified, show it
  477. if (isMinimized())
  478. {
  479. KWin::deIconifyWindow(winId());
  480. }
  481. refreshStatusBar();
  482. }
  483. void LightTableWindow::refreshStatusBar()
  484. {
  485. switch (d->barView->countItems())
  486. {
  487. case 0:
  488. d->statusProgressBar->progressBarMode(StatusProgressBar::TextMode,
  489. i18n("No item on Light Table"));
  490. break;
  491. case 1:
  492. d->statusProgressBar->progressBarMode(StatusProgressBar::TextMode,
  493. i18n("1 item on Light Table"));
  494. break;
  495. default:
  496. d->statusProgressBar->progressBarMode(StatusProgressBar::TextMode,
  497. i18n("%1 items on Light Table")
  498. .arg(d->barView->countItems()));
  499. break;
  500. }
  501. }
  502. void LightTableWindow::slotItemsUpdated(const KURL::List& urls)
  503. {
  504. d->barView->refreshThumbs(urls);
  505. for (KURL::List::const_iterator it = urls.begin() ; it != urls.end() ; ++it)
  506. {
  507. if (d->previewView->leftImageInfo())
  508. {
  509. if (d->previewView->leftImageInfo()->kurl() == *it)
  510. {
  511. d->previewView->leftReload();
  512. d->leftSidebar->itemChanged(d->previewView->leftImageInfo());
  513. }
  514. }
  515. if (d->previewView->rightImageInfo())
  516. {
  517. if (d->previewView->rightImageInfo()->kurl() == *it)
  518. {
  519. d->previewView->rightReload();
  520. d->rightSidebar->itemChanged(d->previewView->rightImageInfo());
  521. }
  522. }
  523. }
  524. }
  525. void LightTableWindow::slotLeftPanelLeftButtonClicked()
  526. {
  527. if (d->navigateByPairAction->isChecked()) return;
  528. d->barView->setSelectedItem(d->barView->findItemByInfo(d->previewView->leftImageInfo()));
  529. }
  530. void LightTableWindow::slotRightPanelLeftButtonClicked()
  531. {
  532. // With navigate by pair option, only the left panel can be selected.
  533. if (d->navigateByPairAction->isChecked()) return;
  534. d->barView->setSelectedItem(d->barView->findItemByInfo(d->previewView->rightImageInfo()));
  535. }
  536. void LightTableWindow::slotLeftPreviewLoaded(bool b)
  537. {
  538. d->leftZoomBar->setEnabled(b);
  539. if (b)
  540. {
  541. d->previewView->checkForSelection(d->barView->currentItemImageInfo());
  542. d->barView->setOnLeftPanel(d->previewView->leftImageInfo());
  543. LightTableBarItem *item = d->barView->findItemByInfo(d->previewView->leftImageInfo());
  544. if (item) item->setOnLeftPanel(true);
  545. if (d->navigateByPairAction->isChecked() && item)
  546. {
  547. LightTableBarItem* next = dynamic_cast<LightTableBarItem*>(item->next());
  548. if (next)
  549. {
  550. d->barView->setOnRightPanel(next->info());
  551. slotSetItemOnRightPanel(next->info());
  552. }
  553. else
  554. {
  555. LightTableBarItem* first = dynamic_cast<LightTableBarItem*>(d->barView->firstItem());
  556. slotSetItemOnRightPanel(first ? first->info() : 0);
  557. }
  558. }
  559. }
  560. }
  561. void LightTableWindow::slotRightPreviewLoaded(bool b)
  562. {
  563. d->rightZoomBar->setEnabled(b);
  564. if (b)
  565. {
  566. d->previewView->checkForSelection(d->barView->currentItemImageInfo());
  567. d->barView->setOnRightPanel(d->previewView->rightImageInfo());
  568. LightTableBarItem *item = d->barView->findItemByInfo(d->previewView->rightImageInfo());
  569. if (item) item->setOnRightPanel(true);
  570. }
  571. }
  572. void LightTableWindow::slotItemSelected(ImageInfo* info)
  573. {
  574. if (info)
  575. {
  576. d->setItemLeftAction->setEnabled(true);
  577. d->setItemRightAction->setEnabled(true);
  578. d->editItemAction->setEnabled(true);
  579. d->removeItemAction->setEnabled(true);
  580. d->clearListAction->setEnabled(true);
  581. d->fileDeleteAction->setEnabled(true);
  582. d->backwardAction->setEnabled(true);
  583. d->forwardAction->setEnabled(true);
  584. d->firstAction->setEnabled(true);
  585. d->lastAction->setEnabled(true);
  586. d->syncPreviewAction->setEnabled(true);
  587. d->zoomPlusAction->setEnabled(true);
  588. d->zoomMinusAction->setEnabled(true);
  589. d->navigateByPairAction->setEnabled(true);
  590. d->slideShowAction->setEnabled(true);
  591. LightTableBarItem* curr = d->barView->findItemByInfo(info);
  592. if (curr)
  593. {
  594. if (!curr->prev())
  595. {
  596. // d->backwardAction->setEnabled(false);
  597. d->firstAction->setEnabled(false);
  598. }
  599. if (!curr->next())
  600. {
  601. // d->forwardAction->setEnabled(false);
  602. d->lastAction->setEnabled(false);
  603. }
  604. if (d->navigateByPairAction->isChecked())
  605. {
  606. d->setItemLeftAction->setEnabled(false);
  607. d->setItemRightAction->setEnabled(false);
  608. d->barView->setOnLeftPanel(info);
  609. slotSetItemOnLeftPanel(info);
  610. }
  611. else if (d->autoLoadOnRightPanel && !curr->isOnLeftPanel())
  612. {
  613. d->barView->setOnRightPanel(info);
  614. slotSetItemOnRightPanel(info);
  615. }
  616. }
  617. }
  618. else
  619. {
  620. d->setItemLeftAction->setEnabled(false);
  621. d->setItemRightAction->setEnabled(false);
  622. d->editItemAction->setEnabled(false);
  623. d->removeItemAction->setEnabled(false);
  624. d->clearListAction->setEnabled(false);
  625. d->fileDeleteAction->setEnabled(false);
  626. d->backwardAction->setEnabled(false);
  627. d->forwardAction->setEnabled(false);
  628. d->firstAction->setEnabled(false);
  629. d->lastAction->setEnabled(false);
  630. d->zoomPlusAction->setEnabled(false);
  631. d->zoomMinusAction->setEnabled(false);
  632. d->syncPreviewAction->setEnabled(false);
  633. d->navigateByPairAction->setEnabled(false);
  634. d->slideShowAction->setEnabled(false);
  635. }
  636. d->previewView->checkForSelection(info);
  637. }
  638. // Deal with one (or more) items dropped onto the left panel
  639. void LightTableWindow::slotLeftDroppedItems(const ImageInfoList& list)
  640. {
  641. ImageInfo *info = *(list.begin());
  642. // add the image to the existing images
  643. loadImageInfos(list, info, true);
  644. // We will check if first item from list is already stored in thumbbar
  645. // Note that the thumbbar stores all ImageInfo reference
  646. // in memory for preview object.
  647. LightTableBarItem *item = d->barView->findItemByInfo(info);
  648. if (item)
  649. {
  650. slotSetItemOnLeftPanel(item->info());
  651. // One approach is to make this item the current one, via
  652. // d->barView->setSelectedItem(item);
  653. // However, this is not good, because this also sets
  654. // the right thumb to the same image.
  655. // Therefore we use setLeftRightItems if there is more than
  656. // one item in the list of dropped images.
  657. }
  658. }
  659. // Deal with one (or more) items dropped onto the right panel
  660. void LightTableWindow::slotRightDroppedItems(const ImageInfoList& list)
  661. {
  662. ImageInfo *info = *(list.begin());
  663. // add the image to the existing images
  664. loadImageInfos(list, info, true);
  665. // We will check if first item from list is already stored in thumbbar
  666. // Note that the thumbbar stores all ImageInfo reference
  667. // in memory for preview object.
  668. LightTableBarItem *item = d->barView->findItemByInfo(info);
  669. if (item)
  670. {
  671. slotSetItemOnRightPanel(item->info());
  672. // Make this item the current one.
  673. d->barView->setSelectedItem(item);
  674. }
  675. }
  676. // Set the images for the left and right panel.
  677. void LightTableWindow::setLeftRightItems(const ImageInfoList &list, bool addTo)
  678. {
  679. ImageInfoList l = list;
  680. if (l.count() == 0)
  681. return;
  682. ImageInfo *info = l.first();
  683. LightTableBarItem *ltItem = d->barView->findItemByInfo(info);
  684. if (l.count() == 1 && !addTo)
  685. {
  686. // Just one item; this is used for the left panel.
  687. d->barView->setOnLeftPanel(info);
  688. slotSetItemOnLeftPanel(info);
  689. d->barView->setSelectedItem(ltItem);
  690. d->barView->ensureItemVisible(ltItem);
  691. return;
  692. }
  693. if (ltItem)
  694. {
  695. // The first item is used for the left panel.
  696. if (!addTo)
  697. {
  698. d->barView->setOnLeftPanel(info);
  699. slotSetItemOnLeftPanel(info);
  700. }
  701. // The subsequent item is used for the right panel.
  702. LightTableBarItem* next = dynamic_cast<LightTableBarItem*>(ltItem->next());
  703. if (next && !addTo)
  704. {
  705. d->barView->setOnRightPanel(next->info());
  706. slotSetItemOnRightPanel(next->info());
  707. if (!d->navigateByPairAction->isChecked())
  708. {
  709. d->barView->setSelectedItem(next);
  710. // ensure that the selected item is visible
  711. // FIXME: this does not work:
  712. d->barView->ensureItemVisible(next);
  713. }
  714. }
  715. // If navigate by pairs is active, the left panel item is selected.
  716. // (Fixes parts of bug #150296)
  717. if (d->navigateByPairAction->isChecked())
  718. {
  719. d->barView->setSelectedItem(ltItem);
  720. d->barView->ensureItemVisible(ltItem);
  721. }
  722. }
  723. }
  724. void LightTableWindow::slotSetItemLeft()
  725. {
  726. if (d->barView->currentItemImageInfo())
  727. {
  728. slotSetItemOnLeftPanel(d->barView->currentItemImageInfo());
  729. }
  730. }
  731. void LightTableWindow::slotSetItemRight()
  732. {
  733. if (d->barView->currentItemImageInfo())
  734. {
  735. slotSetItemOnRightPanel(d->barView->currentItemImageInfo());
  736. }
  737. }
  738. void LightTableWindow::slotSetItemOnLeftPanel(ImageInfo* info)
  739. {
  740. d->previewView->setLeftImageInfo(info);
  741. if (info)
  742. d->leftSidebar->itemChanged(info);
  743. else
  744. d->leftSidebar->slotNoCurrentItem();
  745. }
  746. void LightTableWindow::slotSetItemOnRightPanel(ImageInfo* info)
  747. {
  748. d->previewView->setRightImageInfo(info);
  749. if (info)
  750. d->rightSidebar->itemChanged(info);
  751. else
  752. d->rightSidebar->slotNoCurrentItem();
  753. }
  754. void LightTableWindow::slotClearItemsList()
  755. {
  756. if (d->previewView->leftImageInfo())
  757. {
  758. d->previewView->setLeftImageInfo();
  759. d->leftSidebar->slotNoCurrentItem();
  760. }
  761. if (d->previewView->rightImageInfo())
  762. {
  763. d->previewView->setRightImageInfo();
  764. d->rightSidebar->slotNoCurrentItem();
  765. }
  766. d->barView->clear();
  767. refreshStatusBar();
  768. }
  769. void LightTableWindow::slotDeleteItem()
  770. {
  771. if (d->barView->currentItemImageInfo())
  772. slotDeleteItem(d->barView->currentItemImageInfo());
  773. }
  774. void LightTableWindow::slotDeleteItem(ImageInfo* info)
  775. {
  776. bool ask = true;
  777. bool permanently = false;
  778. KURL u = info->kurl();
  779. PAlbum *palbum = AlbumManager::instance()->findPAlbum(u.directory());
  780. if (!palbum)
  781. return;
  782. // Provide a digikamalbums:// URL to TDEIO
  783. KURL kioURL = info->kurlForKIO();
  784. KURL fileURL = u;
  785. bool useTrash;
  786. if (ask)
  787. {
  788. bool preselectDeletePermanently = permanently;
  789. DeleteDialog dialog(this);
  790. KURL::List urlList;
  791. urlList.append(u);
  792. if (!dialog.confirmDeleteList(urlList,
  793. DeleteDialogMode::Files,
  794. preselectDeletePermanently ?
  795. DeleteDialogMode::NoChoiceDeletePermanently : DeleteDialogMode::NoChoiceTrash))
  796. return;
  797. useTrash = !dialog.shouldDelete();
  798. }
  799. else
  800. {
  801. useTrash = !permanently;
  802. }
  803. // trash does not like non-local URLs, put is not implemented
  804. if (useTrash)
  805. kioURL = fileURL;
  806. if (!SyncJob::del(kioURL, useTrash))
  807. {
  808. TQString errMsg(SyncJob::lastErrorMsg());
  809. KMessageBox::error(this, errMsg, errMsg);
  810. return;
  811. }
  812. emit signalFileDeleted(u);
  813. slotRemoveItem(info);
  814. }
  815. void LightTableWindow::slotRemoveItem()
  816. {
  817. if (d->barView->currentItemImageInfo())
  818. slotRemoveItem(d->barView->currentItemImageInfo());
  819. }
  820. void LightTableWindow::slotRemoveItem(ImageInfo* info)
  821. {
  822. // When either the image from the left or right panel is removed,
  823. // there are various situations to account for.
  824. // To describe them, 4 images A B C D are used
  825. // and the subscript _L and _ R mark the currently
  826. // active item on the left and right panel
  827. bool leftPanelActive = false;
  828. ImageInfo *curr_linfo = d->previewView->leftImageInfo();
  829. ImageInfo *curr_rinfo = d->previewView->rightImageInfo();
  830. ImageInfo *new_linfo = 0;
  831. ImageInfo *new_rinfo = 0;
  832. TQ_LLONG infoId = info->id();
  833. // First determine the next images to the current left and right image:
  834. ImageInfo *next_linfo = 0;
  835. ImageInfo *next_rinfo = 0;
  836. if (curr_linfo)
  837. {
  838. LightTableBarItem *ltItem = d->barView->findItemByInfo(curr_linfo);
  839. if (ltItem)
  840. {
  841. LightTableBarItem* next = dynamic_cast<LightTableBarItem*>(ltItem->next());
  842. if (next)
  843. {
  844. next_linfo = next->info();
  845. }
  846. }
  847. }
  848. if (curr_rinfo)
  849. {
  850. LightTableBarItem *ltItem = d->barView->findItemByInfo(curr_rinfo);
  851. if (ltItem)
  852. {
  853. LightTableBarItem* next = dynamic_cast<LightTableBarItem*>(ltItem->next());
  854. if (next)
  855. {
  856. next_rinfo = next->info();
  857. }
  858. }
  859. }
  860. d->barView->removeItem(info);
  861. // Make sure that next_linfo and next_rinfo are still available:
  862. if (!d->barView->findItemByInfo(next_linfo))
  863. {
  864. next_linfo = 0;
  865. }
  866. if (!d->barView->findItemByInfo(next_rinfo))
  867. {
  868. next_rinfo = 0;
  869. }
  870. // removal of the left panel item?
  871. if (curr_linfo)
  872. {
  873. if ( curr_linfo->id() == infoId )
  874. {
  875. leftPanelActive = true;
  876. // Delete the item A_L of the left panel:
  877. // 1) A_L B_R C D -> B_L C_R D
  878. // 2) A_L B C_R D -> B C_L D_R
  879. // 3) A_L B C D_R -> B_R C D_L
  880. // 4) A_L B_R -> A_L
  881. // some more corner cases:
  882. // 5) A B_L C_R D -> A C_L D_R
  883. // 6) A B_L C_R -> A_R C_L
  884. // 7) A_LR B C D -> B_L C_R D (does not yet work)
  885. // I.e. in 3) we wrap around circularly.
  886. // When removing the left panel image,
  887. // put the right panel image into the left panel.
  888. // Check if this one is not the same (i.e. also removed).
  889. if (curr_rinfo)
  890. {
  891. if (curr_rinfo->id() != infoId)
  892. {
  893. new_linfo = curr_rinfo;
  894. // Set the right panel to the next image:
  895. new_rinfo = next_rinfo;
  896. // set the right panel active
  897. leftPanelActive = false;
  898. }
  899. }
  900. }
  901. }
  902. // removal of the right panel item?
  903. if (curr_rinfo)
  904. {
  905. if (curr_rinfo->id() == infoId)
  906. {
  907. // Leave the left panel as the current one
  908. new_linfo = curr_linfo;
  909. // Set the right panel to the next image
  910. new_rinfo = next_rinfo;
  911. }
  912. }
  913. // Now we deal with the corner cases, where no left or right item exists.
  914. // If the right panel would be set, but not the left-one, then swap
  915. if (!new_linfo && new_rinfo)
  916. {
  917. new_linfo = new_rinfo;
  918. new_rinfo = 0;
  919. leftPanelActive = true;
  920. }
  921. if (!new_linfo)
  922. {
  923. if (d->barView->countItems() > 0)
  924. {
  925. LightTableBarItem* first = dynamic_cast<LightTableBarItem*>(d->barView->firstItem());
  926. new_linfo = first->info();
  927. }
  928. }
  929. // Make sure that new_linfo and new_rinfo exist.
  930. // This addresses a crash occuring if the last image is removed
  931. // in the navigate by pairs mode.
  932. if (!d->barView->findItemByInfo(new_linfo))
  933. {
  934. new_linfo = 0;
  935. }
  936. if (!d->barView->findItemByInfo(new_rinfo))
  937. {
  938. new_rinfo = 0;
  939. }
  940. // no right item defined?
  941. if (!new_rinfo)
  942. {
  943. // If there are at least two items, we can find reasonable right image.
  944. if (d->barView->countItems() > 1)
  945. {
  946. // See if there is an item next to the left one:
  947. LightTableBarItem *ltItem = d->barView->findItemByInfo(new_linfo);
  948. LightTableBarItem* next = 0;
  949. // re-check if ltItem is really set
  950. if (ltItem)
  951. {
  952. next = dynamic_cast<LightTableBarItem*>(ltItem->next());
  953. }
  954. if (next)
  955. {
  956. new_rinfo = next->info();
  957. }
  958. else
  959. {
  960. // If there is no item to the right of new_linfo
  961. // then we can choose the first item for new_rinfo
  962. // (as we made sure that there are at least two items)
  963. LightTableBarItem* first = dynamic_cast<LightTableBarItem*>(d->barView->firstItem());
  964. new_rinfo = first->info();
  965. }
  966. }
  967. }
  968. // Check if left and right are set to the same
  969. if (new_linfo && new_rinfo)
  970. {
  971. if (new_linfo->id() == new_rinfo->id())
  972. {
  973. // Only keep the left one
  974. new_rinfo = 0;
  975. }
  976. }
  977. // If the right panel would be set, but not the left-one, then swap
  978. // (note that this has to be done here again!)
  979. if (!new_linfo && new_rinfo)
  980. {
  981. new_linfo = new_rinfo;
  982. new_rinfo = 0;
  983. leftPanelActive = true;
  984. }
  985. // set the image for the left panel
  986. if (new_linfo)
  987. {
  988. d->barView->setOnLeftPanel(new_linfo);
  989. slotSetItemOnLeftPanel(new_linfo);
  990. // make this the selected item if the left was active before
  991. if ( leftPanelActive)
  992. {
  993. LightTableBarItem *ltItem = d->barView->findItemByInfo(new_linfo);
  994. d->barView->setSelectedItem(ltItem);
  995. }
  996. }
  997. else
  998. {
  999. d->previewView->setLeftImageInfo();
  1000. d->leftSidebar->slotNoCurrentItem();
  1001. }
  1002. // set the image for the right panel
  1003. if (new_rinfo)
  1004. {
  1005. d->barView->setOnRightPanel(new_rinfo);
  1006. slotSetItemOnRightPanel(new_rinfo);
  1007. // make this the selected item if the left was active before
  1008. if (!leftPanelActive)
  1009. {
  1010. LightTableBarItem *ltItem = d->barView->findItemByInfo(new_rinfo);
  1011. d->barView->setSelectedItem(ltItem);
  1012. }
  1013. }
  1014. else
  1015. {
  1016. d->previewView->setRightImageInfo();
  1017. d->rightSidebar->slotNoCurrentItem();
  1018. }
  1019. refreshStatusBar();
  1020. }
  1021. void LightTableWindow::slotEditItem()
  1022. {
  1023. if (d->barView->currentItemImageInfo())
  1024. slotEditItem(d->barView->currentItemImageInfo());
  1025. }
  1026. void LightTableWindow::slotEditItem(ImageInfo* info)
  1027. {
  1028. ImageWindow *im = ImageWindow::imagewindow();
  1029. ImageInfoList list = d->barView->itemsImageInfoList();
  1030. im->loadImageInfos(list, info, i18n("Light Table"), true);
  1031. if (im->isHidden())
  1032. im->show();
  1033. else
  1034. im->raise();
  1035. im->setFocus();
  1036. }
  1037. void LightTableWindow::slotZoomTo100Percents()
  1038. {
  1039. d->previewView->toggleFitToWindowOr100();
  1040. }
  1041. void LightTableWindow::slotFitToWindow()
  1042. {
  1043. d->previewView->fitToWindow();
  1044. }
  1045. void LightTableWindow::slotToggleSlideShow()
  1046. {
  1047. TDEConfig* config = kapp->config();
  1048. config->setGroup("ImageViewer Settings");
  1049. bool startWithCurrent = config->readBoolEntry("SlideShowStartCurrent", false);
  1050. SlideShowSettings settings;
  1051. settings.exifRotate = AlbumSettings::instance()->getExifRotate();
  1052. settings.delay = config->readNumEntry("SlideShowDelay", 5) * 1000;
  1053. settings.printName = config->readBoolEntry("SlideShowPrintName", true);
  1054. settings.printDate = config->readBoolEntry("SlideShowPrintDate", false);
  1055. settings.printApertureFocal = config->readBoolEntry("SlideShowPrintApertureFocal", false);
  1056. settings.printExpoSensitivity = config->readBoolEntry("SlideShowPrintExpoSensitivity", false);
  1057. settings.printMakeModel = config->readBoolEntry("SlideShowPrintMakeModel", false);
  1058. settings.printComment = config->readBoolEntry("SlideShowPrintComment", false);
  1059. settings.loop = config->readBoolEntry("SlideShowLoop", false);
  1060. slideShow(startWithCurrent, settings);
  1061. }
  1062. void LightTableWindow::slideShow(bool startWithCurrent, SlideShowSettings& settings)
  1063. {
  1064. if (!d->barView->countItems()) return;
  1065. DMetadata meta;
  1066. int i = 0;
  1067. d->cancelSlideShow = false;
  1068. d->statusProgressBar->progressBarMode(StatusProgressBar::CancelProgressBarMode,
  1069. i18n("Preparing slideshow. Please wait..."));
  1070. ImageInfoList list = d->barView->itemsImageInfoList();
  1071. for (ImageInfo *info = list.first() ; !d->cancelSlideShow && info ; info = list.next())
  1072. {
  1073. SlidePictureInfo pictInfo;
  1074. pictInfo.comment = info->caption();
  1075. // Perform optimizations: only read pictures metadata if necessary.
  1076. if (settings.printApertureFocal || settings.printExpoSensitivity || settings.printMakeModel)
  1077. {
  1078. meta.load(info->kurl().path());
  1079. pictInfo.photoInfo = meta.getPhotographInformations();
  1080. }
  1081. // In case of dateTime extraction from metadata failed
  1082. pictInfo.photoInfo.dateTime = info->dateTime();
  1083. settings.pictInfoMap.insert(info->kurl(), pictInfo);
  1084. settings.fileList.append(info->kurl());
  1085. d->statusProgressBar->setProgressValue((int)((i++/(float)list.count())*100.0));
  1086. kapp->processEvents();
  1087. }
  1088. d->statusProgressBar->progressBarMode(StatusProgressBar::TextMode, TQString());
  1089. refreshStatusBar();
  1090. if (!d->cancelSlideShow)
  1091. {
  1092. settings.exifRotate = AlbumSettings::instance()->getExifRotate();
  1093. SlideShow *slide = new SlideShow(settings);
  1094. if (startWithCurrent)
  1095. slide->setCurrent(d->barView->currentItemImageInfo()->kurl());
  1096. slide->show();
  1097. }
  1098. }
  1099. void LightTableWindow::slotProgressBarCancelButtonPressed()
  1100. {
  1101. d->cancelSlideShow = true;
  1102. }
  1103. void LightTableWindow::slotToggleFullScreen()
  1104. {
  1105. if (d->fullScreen) // out of fullscreen
  1106. {
  1107. setWindowState( windowState() & ~WindowFullScreen );
  1108. menuBar()->show();
  1109. statusBar()->show();
  1110. leftDock()->show();
  1111. rightDock()->show();
  1112. topDock()->show();
  1113. bottomDock()->show();
  1114. TQObject* obj = child("ToolBar","TDEToolBar");
  1115. if (obj)
  1116. {
  1117. TDEToolBar* toolBar = static_cast<TDEToolBar*>(TQT_TQWIDGET(obj));
  1118. if (d->fullScreenAction->isPlugged(toolBar) && d->removeFullScreenButton)
  1119. d->fullScreenAction->unplug(toolBar);
  1120. if (toolBar->isHidden())
  1121. showToolBars();
  1122. }
  1123. // -- remove the gui action accels ----
  1124. unplugActionAccel(d->zoomFitToWindowAction);
  1125. if (d->fullScreen)
  1126. {
  1127. d->leftSidebar->restore();
  1128. d->rightSidebar->restore();
  1129. }
  1130. else
  1131. {
  1132. d->leftSidebar->backup();
  1133. d->rightSidebar->backup();
  1134. }
  1135. d->fullScreen = false;
  1136. }
  1137. else // go to fullscreen
  1138. {
  1139. // hide the menubar and the statusbar
  1140. menuBar()->hide();
  1141. statusBar()->hide();
  1142. topDock()->hide();
  1143. leftDock()->hide();
  1144. rightDock()->hide();
  1145. bottomDock()->hide();
  1146. TQObject* obj = child("ToolBar","TDEToolBar");
  1147. if (obj)
  1148. {
  1149. TDEToolBar* toolBar = static_cast<TDEToolBar*>(TQT_TQWIDGET(obj));
  1150. if (d->fullScreenHideToolBar)
  1151. {
  1152. hideToolBars();
  1153. }
  1154. else
  1155. {
  1156. showToolBars();
  1157. if ( !d->fullScreenAction->isPlugged(toolBar) )
  1158. {
  1159. d->fullScreenAction->plug(toolBar);
  1160. d->removeFullScreenButton=true;
  1161. }
  1162. else
  1163. {
  1164. // If FullScreen button is enable in toolbar settings
  1165. // We don't remove it when we out of fullscreen mode.
  1166. d->removeFullScreenButton=false;
  1167. }
  1168. }
  1169. }
  1170. // -- Insert all the gui actions into the accel --
  1171. plugActionAccel(d->zoomFitToWindowAction);
  1172. if (d->fullScreen)
  1173. {
  1174. d->leftSidebar->restore();
  1175. d->rightSidebar->restore();
  1176. }
  1177. else
  1178. {
  1179. d->leftSidebar->backup();
  1180. d->rightSidebar->backup();
  1181. }
  1182. showFullScreen();
  1183. d->fullScreen = true;
  1184. }
  1185. }
  1186. void LightTableWindow::slotEscapePressed()
  1187. {
  1188. if (d->fullScreen)
  1189. d->fullScreenAction->activate();
  1190. }
  1191. void LightTableWindow::showToolBars()
  1192. {
  1193. TQPtrListIterator<TDEToolBar> it = toolBarIterator();
  1194. TDEToolBar* bar;
  1195. for( ; it.current()!=0L ; ++it)
  1196. {
  1197. bar=it.current();
  1198. if (bar->area())
  1199. bar->area()->show();
  1200. else
  1201. bar->show();
  1202. }
  1203. }
  1204. void LightTableWindow::hideToolBars()
  1205. {
  1206. TQPtrListIterator<TDEToolBar> it = toolBarIterator();
  1207. TDEToolBar* bar;
  1208. for( ; it.current()!=0L ; ++it)
  1209. {
  1210. bar=it.current();
  1211. if (bar->area())
  1212. bar->area()->hide();
  1213. else
  1214. bar->hide();
  1215. }
  1216. }
  1217. void LightTableWindow::plugActionAccel(TDEAction* action)
  1218. {
  1219. if (!action)
  1220. return;
  1221. d->accelerators->insert(action->text(),
  1222. action->text(),
  1223. action->whatsThis(),
  1224. action->shortcut(),
  1225. action,
  1226. TQT_SLOT(activate()));
  1227. }
  1228. void LightTableWindow::unplugActionAccel(TDEAction* action)
  1229. {
  1230. d->accelerators->remove(action->text());
  1231. }
  1232. void LightTableWindow::slotDonateMoney()
  1233. {
  1234. TDEApplication::kApplication()->invokeBrowser("http://www.digikam.org/?q=donation");
  1235. }
  1236. void LightTableWindow::slotContribute()
  1237. {
  1238. TDEApplication::kApplication()->invokeBrowser("http://www.digikam.org/?q=contrib");
  1239. }
  1240. void LightTableWindow::slotEditKeys()
  1241. {
  1242. KKeyDialog dialog(true, this);
  1243. dialog.insert( actionCollection(), i18n( "General" ) );
  1244. dialog.configure();
  1245. }
  1246. void LightTableWindow::slotConfToolbars()
  1247. {
  1248. saveMainWindowSettings(TDEGlobal::config(), "LightTable Settings");
  1249. KEditToolbar dlg(factory(), this);
  1250. connect(&dlg, TQT_SIGNAL(newToolbarConfig()),
  1251. TQT_TQOBJECT(this), TQT_SLOT(slotNewToolbarConfig()));
  1252. dlg.exec();
  1253. }
  1254. void LightTableWindow::slotNewToolbarConfig()
  1255. {
  1256. applyMainWindowSettings(TDEGlobal::config(), "LightTable Settings");
  1257. }
  1258. void LightTableWindow::slotSetup()
  1259. {
  1260. Setup setup(this, 0);
  1261. if (setup.exec() != TQDialog::Accepted)
  1262. return;
  1263. kapp->config()->sync();
  1264. applySettings();
  1265. }
  1266. void LightTableWindow::slotLeftZoomFactorChanged(double zoom)
  1267. {
  1268. double h = (double)ThumbnailSize::Huge;
  1269. double s = (double)ThumbnailSize::Small;
  1270. double zmin = d->previewView->leftZoomMin();
  1271. double zmax = d->previewView->leftZoomMax();
  1272. double b = (zmin-(zmax*s/h))/(1-s/h);
  1273. double a = (zmax-b)/h;
  1274. int size = (int)((zoom - b) /a);
  1275. d->leftZoomBar->setZoomSliderValue(size);
  1276. d->leftZoomBar->setZoomTrackerText(i18n("zoom: %1%").arg((int)(zoom*100.0)));
  1277. d->leftZoomBar->setEnableZoomPlus(true);
  1278. d->leftZoomBar->setEnableZoomMinus(true);
  1279. if (d->previewView->leftMaxZoom())
  1280. d->leftZoomBar->setEnableZoomPlus(false);
  1281. if (d->previewView->leftMinZoom())
  1282. d->leftZoomBar->setEnableZoomMinus(false);
  1283. }
  1284. void LightTableWindow::slotRightZoomFactorChanged(double zoom)
  1285. {
  1286. double h = (double)ThumbnailSize::Huge;
  1287. double s = (double)ThumbnailSize::Small;
  1288. double zmin = d->previewView->rightZoomMin();
  1289. double zmax = d->previewView->rightZoomMax();
  1290. double b = (zmin-(zmax*s/h))/(1-s/h);
  1291. double a = (zmax-b)/h;
  1292. int size = (int)((zoom - b) /a);
  1293. d->rightZoomBar->setZoomSliderValue(size);
  1294. d->rightZoomBar->setZoomTrackerText(i18n("zoom: %1%").arg((int)(zoom*100.0)));
  1295. d->rightZoomBar->setEnableZoomPlus(true);
  1296. d->rightZoomBar->setEnableZoomMinus(true);
  1297. if (d->previewView->rightMaxZoom())
  1298. d->rightZoomBar->setEnableZoomPlus(false);
  1299. if (d->previewView->rightMinZoom())
  1300. d->rightZoomBar->setEnableZoomMinus(false);
  1301. }
  1302. void LightTableWindow::slotToggleSyncPreview()
  1303. {
  1304. d->previewView->setSyncPreview(d->syncPreviewAction->isChecked());
  1305. }
  1306. void LightTableWindow::slotToggleOnSyncPreview(bool t)
  1307. {
  1308. d->syncPreviewAction->setEnabled(t);
  1309. if (!t)
  1310. {
  1311. d->syncPreviewAction->setChecked(false);
  1312. }
  1313. else
  1314. {
  1315. if (d->autoSyncPreview)
  1316. d->syncPreviewAction->setChecked(true);
  1317. }
  1318. }
  1319. void LightTableWindow::slotBackward()
  1320. {
  1321. ThumbBarItem* curr = d->barView->currentItem();
  1322. ThumbBarItem* last = d->barView->lastItem();
  1323. if (curr)
  1324. {
  1325. if (curr->prev())
  1326. d->barView->setSelected(curr->prev());
  1327. else
  1328. d->barView->setSelected(last);
  1329. }
  1330. }
  1331. void LightTableWindow::slotForward()
  1332. {
  1333. ThumbBarItem* curr = d->barView->currentItem();
  1334. ThumbBarItem* first = d->barView->firstItem();
  1335. if (curr)
  1336. {
  1337. if (curr->next())
  1338. d->barView->setSelected(curr->next());
  1339. else
  1340. d->barView->setSelected(first);
  1341. }
  1342. }
  1343. void LightTableWindow::slotFirst()
  1344. {
  1345. d->barView->setSelected( d->barView->firstItem() );
  1346. }
  1347. void LightTableWindow::slotLast()
  1348. {
  1349. d->barView->setSelected( d->barView->lastItem() );
  1350. }
  1351. void LightTableWindow::slotToggleNavigateByPair()
  1352. {
  1353. d->barView->setNavigateByPair(d->navigateByPairAction->isChecked());
  1354. d->previewView->setNavigateByPair(d->navigateByPairAction->isChecked());
  1355. slotItemSelected(d->barView->currentItemImageInfo());
  1356. }
  1357. void LightTableWindow::slotRawCameraList()
  1358. {
  1359. RawCameraDlg dlg(this);
  1360. dlg.exec();
  1361. }
  1362. void LightTableWindow::slotThemeChanged()
  1363. {
  1364. TQStringList themes(ThemeEngine::instance()->themeNames());
  1365. int index = themes.findIndex(AlbumSettings::instance()->getCurrentTheme());
  1366. if (index == -1)
  1367. index = themes.findIndex(i18n("Default"));
  1368. d->themeMenuAction->setCurrentItem(index);
  1369. }
  1370. void LightTableWindow::slotChangeTheme(const TQString& theme)
  1371. {
  1372. AlbumSettings::instance()->setCurrentTheme(theme);
  1373. ThemeEngine::instance()->slotChangeTheme(theme);
  1374. }
  1375. void LightTableWindow::slotShowMenuBar()
  1376. {
  1377. if (menuBar()->isVisible())
  1378. menuBar()->hide();
  1379. else
  1380. menuBar()->show();
  1381. }
  1382. } // namespace Digikam