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.

1637 lines
44KB

  1. /* ============================================================
  2. *
  3. * This file is a part of digiKam project
  4. * http://www.digikam.org
  5. *
  6. * Date : 2005-05-06
  7. * Description : Albums folder view.
  8. *
  9. * Copyright (C) 2005-2006 by Joern Ahrens <joern.ahrens@kdemail.net>
  10. * Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
  11. * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
  12. *
  13. * This program is free software; you can redistribute it
  14. * and/or modify it under the terms of the GNU General
  15. * Public License as published by the Free Software Foundation;
  16. * either version 2, or (at your option)
  17. * any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * ============================================================ */
  25. // TQt includes.
  26. #include <tqpixmap.h>
  27. #include <tqguardedptr.h>
  28. #include <tqdir.h>
  29. #include <tdepopupmenu.h>
  30. #include <tqcursor.h>
  31. #include <tqdatastream.h>
  32. #include <tqvaluelist.h>
  33. #include <tqdatetime.h>
  34. // KDE includes.
  35. #include <tdelocale.h>
  36. #include <tdeglobal.h>
  37. #include <kcalendarsystem.h>
  38. #include <kiconloader.h>
  39. #include <tdeapplication.h>
  40. #include <tdemessagebox.h>
  41. #include <tdeaction.h>
  42. #include <tdefiledialog.h>
  43. #include <tdeversion.h>
  44. #if KDE_IS_VERSION(3,2,0)
  45. #include <kinputdialog.h>
  46. #else
  47. #include <klineeditdlg.h>
  48. #endif
  49. // Local includes.
  50. #include "ddebug.h"
  51. #include "digikamapp.h"
  52. #include "albumlister.h"
  53. #include "album.h"
  54. #include "albumdb.h"
  55. #include "albumpropsedit.h"
  56. #include "albummanager.h"
  57. #include "albumsettings.h"
  58. #include "thumbnailjob.h"
  59. #include "thumbnailsize.h"
  60. #include "folderitem.h"
  61. #include "cameraui.h"
  62. #include "dio.h"
  63. #include "dragobjects.h"
  64. #include "albumthumbnailloader.h"
  65. #include "deletedialog.h"
  66. #include "albumfolderview.h"
  67. #include "albumfolderview.moc"
  68. // X11 C Ansi includes.
  69. extern "C"
  70. {
  71. #include <X11/Xlib.h>
  72. }
  73. namespace Digikam
  74. {
  75. class AlbumFolderViewItem : public FolderItem
  76. {
  77. public:
  78. AlbumFolderViewItem(TQListView *parent, PAlbum *album);
  79. AlbumFolderViewItem(TQListViewItem *parent, PAlbum *album);
  80. // special group item (collection/dates)
  81. AlbumFolderViewItem(TQListViewItem* parent, const TQString& name,
  82. int year, int month);
  83. PAlbum* album() const;
  84. int id() const;
  85. bool isGroupItem() const;
  86. int compare(TQListViewItem *i, int col, bool ascending) const;
  87. void refresh();
  88. void setOpen(bool o);
  89. void setCount(int count);
  90. int count();
  91. private:
  92. bool m_groupItem;
  93. int m_count;
  94. int m_year;
  95. int m_month;
  96. PAlbum *m_album;
  97. };
  98. AlbumFolderViewItem::AlbumFolderViewItem(TQListView *parent, PAlbum *album)
  99. : FolderItem(parent, album->title())
  100. {
  101. setDragEnabled(true);
  102. m_album = album;
  103. m_groupItem = false;
  104. m_count = 0;
  105. }
  106. AlbumFolderViewItem::AlbumFolderViewItem(TQListViewItem *parent, PAlbum *album)
  107. : FolderItem(parent, album->title())
  108. {
  109. setDragEnabled(true);
  110. m_album = album;
  111. m_groupItem = false;
  112. m_count = 0;
  113. }
  114. // special group item (collection/dates)
  115. AlbumFolderViewItem::AlbumFolderViewItem(TQListViewItem* parent, const TQString& name,
  116. int year, int month)
  117. : FolderItem(parent, name, true)
  118. {
  119. m_album = 0;
  120. m_year = year;
  121. m_month = month;
  122. m_groupItem = true;
  123. m_count = 0;
  124. }
  125. void AlbumFolderViewItem::refresh()
  126. {
  127. if (!m_album) return;
  128. if (AlbumSettings::instance()->getShowFolderTreeViewItemsCount() &&
  129. dynamic_cast<AlbumFolderViewItem*>(parent()))
  130. {
  131. if (isOpen())
  132. setText(0, TQString("%1 (%2)").arg(m_album->title()).arg(m_count));
  133. else
  134. {
  135. int countRecursive = m_count;
  136. AlbumIterator it(m_album);
  137. while ( it.current() )
  138. {
  139. AlbumFolderViewItem *item = (AlbumFolderViewItem*)it.current()->extraData(listView());
  140. if (item)
  141. countRecursive += item->count();
  142. ++it;
  143. }
  144. setText(0, TQString("%1 (%2)").arg(m_album->title()).arg(countRecursive));
  145. }
  146. }
  147. else
  148. {
  149. setText(0, m_album->title());
  150. }
  151. }
  152. void AlbumFolderViewItem::setOpen(bool o)
  153. {
  154. TQListViewItem::setOpen(o);
  155. refresh();
  156. }
  157. PAlbum* AlbumFolderViewItem::album() const
  158. {
  159. return m_album;
  160. }
  161. int AlbumFolderViewItem::id() const
  162. {
  163. if (m_groupItem)
  164. {
  165. if (m_year != 0 && m_month != 0)
  166. {
  167. return (m_year*(-100) + m_month*(-1));
  168. }
  169. else
  170. {
  171. return ( - (AlbumSettings::instance()->getAlbumCollectionNames()
  172. .findIndex(text(0)) ) );
  173. }
  174. }
  175. else
  176. {
  177. return m_album ? m_album->id() : 0;
  178. }
  179. }
  180. bool AlbumFolderViewItem::isGroupItem() const
  181. {
  182. return m_groupItem;
  183. }
  184. int AlbumFolderViewItem::compare(TQListViewItem *i, int col, bool ascending) const
  185. {
  186. if (!m_groupItem || m_year == 0 || m_month == 0)
  187. return TQListViewItem::compare(i, col, ascending);
  188. AlbumFolderViewItem* thatItem = dynamic_cast<AlbumFolderViewItem*>(i);
  189. if (!thatItem)
  190. return 0;
  191. int myWeight = m_year*100 + m_month;
  192. int hisWeight = thatItem->m_year*100 + thatItem->m_month;
  193. if (myWeight == hisWeight)
  194. return 0;
  195. else if (myWeight > hisWeight)
  196. return 1;
  197. else
  198. return -1;
  199. }
  200. void AlbumFolderViewItem::setCount(int count)
  201. {
  202. m_count = count;
  203. refresh();
  204. }
  205. int AlbumFolderViewItem::count()
  206. {
  207. return m_count;
  208. }
  209. // -----------------------------------------------------------------------------
  210. class AlbumFolderViewPriv
  211. {
  212. public:
  213. AlbumFolderViewPriv()
  214. {
  215. albumMan = 0;
  216. iconThumbJob = 0;
  217. }
  218. AlbumManager *albumMan;
  219. ThumbnailJob *iconThumbJob;
  220. TQValueList<AlbumFolderViewItem*> groupItems;
  221. };
  222. AlbumFolderView::AlbumFolderView(TQWidget *parent)
  223. : FolderView(parent, "AlbumFolderView")
  224. {
  225. d = new AlbumFolderViewPriv();
  226. d->albumMan = AlbumManager::instance();
  227. d->iconThumbJob = 0;
  228. addColumn(i18n("My Albums"));
  229. setResizeMode(TQListView::LastColumn);
  230. setRootIsDecorated(false);
  231. setAllColumnsShowFocus(true);
  232. setAcceptDrops(true);
  233. viewport()->setAcceptDrops(true);
  234. connect(d->albumMan, TQT_SIGNAL(signalAlbumAdded(Album*)),
  235. this, TQT_SLOT(slotAlbumAdded(Album*)));
  236. connect(d->albumMan, TQT_SIGNAL(signalAlbumDeleted(Album*)),
  237. this, TQT_SLOT(slotAlbumDeleted(Album*)));
  238. connect(d->albumMan, TQT_SIGNAL(signalAlbumsCleared()),
  239. this, TQT_SLOT(slotAlbumsCleared()));
  240. connect(d->albumMan, TQT_SIGNAL(signalAlbumIconChanged(Album*)),
  241. this, TQT_SLOT(slotAlbumIconChanged(Album*)));
  242. connect(d->albumMan, TQT_SIGNAL(signalAlbumRenamed(Album*)),
  243. this, TQT_SLOT(slotAlbumRenamed(Album*)));
  244. connect(d->albumMan, TQT_SIGNAL(signalPAlbumsDirty(const TQMap<int, int>&)),
  245. this, TQT_SLOT(slotRefresh(const TQMap<int, int>&)));
  246. AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
  247. connect(loader, TQT_SIGNAL(signalThumbnail(Album *, const TQPixmap&)),
  248. this, TQT_SLOT(slotGotThumbnailFromIcon(Album *, const TQPixmap&)));
  249. connect(loader, TQT_SIGNAL(signalFailed(Album *)),
  250. this, TQT_SLOT(slotThumbnailLost(Album *)));
  251. connect(loader, TQT_SIGNAL(signalReloadThumbnails()),
  252. this, TQT_SLOT(slotReloadThumbnails()));
  253. connect(this, TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)),
  254. this, TQT_SLOT(slotContextMenu(TQListViewItem*, const TQPoint&, int)));
  255. connect(this, TQT_SIGNAL(selectionChanged()),
  256. this, TQT_SLOT(slotSelectionChanged()));
  257. }
  258. AlbumFolderView::~AlbumFolderView()
  259. {
  260. if (d->iconThumbJob)
  261. d->iconThumbJob->kill();
  262. saveViewState();
  263. delete d;
  264. }
  265. void AlbumFolderView::slotTextFolderFilterChanged(const TQString& filter)
  266. {
  267. if (filter.isEmpty())
  268. {
  269. collapseView();
  270. return;
  271. }
  272. TQString search = filter.lower();
  273. bool atleastOneMatch = false;
  274. AlbumList pList = d->albumMan->allPAlbums();
  275. for (AlbumList::iterator it = pList.begin(); it != pList.end(); ++it)
  276. {
  277. PAlbum* palbum = (PAlbum*)(*it);
  278. // don't touch the root Album
  279. if (palbum->isRoot())
  280. continue;
  281. bool match = palbum->title().lower().contains(search);
  282. bool doesExpand = false;
  283. if (!match)
  284. {
  285. // check if any of the parents match the search
  286. Album* parent = palbum->parent();
  287. while (parent && !parent->isRoot())
  288. {
  289. if (parent->title().lower().contains(search))
  290. {
  291. match = true;
  292. break;
  293. }
  294. parent = parent->parent();
  295. }
  296. }
  297. if (!match)
  298. {
  299. // check if any of the children match the search
  300. AlbumIterator it(palbum);
  301. while (it.current())
  302. {
  303. if ((*it)->title().lower().contains(search))
  304. {
  305. match = true;
  306. doesExpand = true;
  307. break;
  308. }
  309. ++it;
  310. }
  311. }
  312. AlbumFolderViewItem* viewItem = (AlbumFolderViewItem*) palbum->extraData(this);
  313. if (match)
  314. {
  315. atleastOneMatch = true;
  316. if (viewItem)
  317. {
  318. viewItem->setVisible(true);
  319. viewItem->setOpen(doesExpand);
  320. }
  321. }
  322. else
  323. {
  324. if (viewItem)
  325. {
  326. viewItem->setVisible(false);
  327. viewItem->setOpen(false);
  328. }
  329. }
  330. }
  331. emit signalTextFolderFilterMatch(atleastOneMatch);
  332. }
  333. void AlbumFolderView::slotAlbumAdded(Album *album)
  334. {
  335. if(!album)
  336. return;
  337. PAlbum *palbum = dynamic_cast<PAlbum*>(album);
  338. if(!palbum)
  339. return;
  340. bool failed;
  341. AlbumFolderViewItem* parent = findParent(palbum, failed);
  342. if (failed)
  343. {
  344. DWarning() << k_funcinfo << " Failed to find Album parent "
  345. << palbum->url() << endl;
  346. return;
  347. }
  348. AlbumFolderViewItem *item;
  349. if (!parent)
  350. {
  351. // root album
  352. item = new AlbumFolderViewItem(this, palbum);
  353. palbum->setExtraData(this, item);
  354. item->setOpen(true);
  355. }
  356. else
  357. {
  358. item = new AlbumFolderViewItem(parent, palbum);
  359. palbum->setExtraData(this, item);
  360. }
  361. setAlbumThumbnail(palbum);
  362. }
  363. void AlbumFolderView::slotAlbumDeleted(Album *album)
  364. {
  365. if(!album)
  366. return;
  367. PAlbum* palbum = dynamic_cast<PAlbum*>(album);
  368. if(!palbum)
  369. return;
  370. if(!palbum->icon().isEmpty() && d->iconThumbJob)
  371. d->iconThumbJob->removeItem(palbum->icon());
  372. AlbumFolderViewItem* item = (AlbumFolderViewItem*) palbum->extraData(this);
  373. if(item)
  374. {
  375. AlbumFolderViewItem *itemParent = dynamic_cast<AlbumFolderViewItem*>(item->parent());
  376. if(itemParent)
  377. itemParent->takeItem(item);
  378. else
  379. takeItem(item);
  380. delete item;
  381. clearEmptyGroupItems();
  382. }
  383. }
  384. void AlbumFolderView::slotAlbumRenamed(Album *album)
  385. {
  386. PAlbum* palbum = dynamic_cast<PAlbum*>(album);
  387. if(!palbum)
  388. return;
  389. AlbumFolderViewItem* item = (AlbumFolderViewItem*) palbum->extraData(this);
  390. if(item)
  391. item->refresh();
  392. if (item->parent())
  393. item->parent()->sort();
  394. }
  395. void AlbumFolderView::slotAlbumsCleared()
  396. {
  397. d->groupItems.clear();
  398. clear();
  399. }
  400. void AlbumFolderView::setAlbumThumbnail(PAlbum *album)
  401. {
  402. if(!album)
  403. return;
  404. AlbumFolderViewItem* item = (AlbumFolderViewItem*) album->extraData(this);
  405. if(!item)
  406. return;
  407. // Either, getThumbnail returns true and loads an icon asynchronously.
  408. // Then, for the time being, we set the standard icon.
  409. // Or, no icon is associated with the album, then we set the standard icon anyway.
  410. AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
  411. item->setPixmap(0, loader->getStandardAlbumIcon(album));
  412. loader->getAlbumThumbnail(album);
  413. }
  414. void AlbumFolderView::setCurrentAlbum(Album *album)
  415. {
  416. if(!album) return;
  417. AlbumFolderViewItem* item = (AlbumFolderViewItem*) album->extraData(this);
  418. if(!item) return;
  419. setCurrentItem(item);
  420. ensureItemVisible(item);
  421. }
  422. void AlbumFolderView::slotGotThumbnailFromIcon(Album *album,
  423. const TQPixmap& thumbnail)
  424. {
  425. if(!album || album->type() != Album::PHYSICAL)
  426. return;
  427. AlbumFolderViewItem* item = (AlbumFolderViewItem*)album->extraData(this);
  428. if(!item)
  429. return;
  430. item->setPixmap(0, thumbnail);
  431. }
  432. void AlbumFolderView::slotThumbnailLost(Album *)
  433. {
  434. // we already set the standard icon before loading
  435. }
  436. void AlbumFolderView::slotReloadThumbnails()
  437. {
  438. AlbumList tList = d->albumMan->allPAlbums();
  439. for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
  440. {
  441. PAlbum* album = (PAlbum*)(*it);
  442. setAlbumThumbnail(album);
  443. }
  444. }
  445. void AlbumFolderView::slotAlbumIconChanged(Album* album)
  446. {
  447. if(!album || album->type() != Album::PHYSICAL)
  448. return;
  449. setAlbumThumbnail((PAlbum*)album);
  450. }
  451. void AlbumFolderView::slotSelectionChanged()
  452. {
  453. if (!active())
  454. return;
  455. TQListViewItem* selItem = 0;
  456. TQListViewItemIterator it(this);
  457. while(it.current())
  458. {
  459. if(it.current()->isSelected())
  460. {
  461. selItem = it.current();
  462. break;
  463. }
  464. ++it;
  465. }
  466. if(!selItem)
  467. {
  468. d->albumMan->setCurrentAlbum(0);
  469. return;
  470. }
  471. AlbumFolderViewItem *albumitem = dynamic_cast<AlbumFolderViewItem*>(selItem);
  472. if(!albumitem)
  473. {
  474. d->albumMan->setCurrentAlbum(0);
  475. return;
  476. }
  477. d->albumMan->setCurrentAlbum(albumitem->album());
  478. }
  479. void AlbumFolderView::slotContextMenu(TQListViewItem *listitem, const TQPoint &, int)
  480. {
  481. TDEActionMenu menuImport(i18n("Import"));
  482. TDEActionMenu menuExport(i18n("Export"));
  483. TDEActionMenu menuKIPIBatch(i18n("Batch Process"));
  484. TDEPopupMenu popmenu(this);
  485. popmenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  486. popmenu.insertItem(SmallIcon("albumfolder-new"), i18n("New Album..."), 10);
  487. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(listitem);
  488. if (item && !item->album())
  489. {
  490. // if collection/date return
  491. return;
  492. }
  493. // Root folder only shows "New Album..."
  494. if(item && item->parent())
  495. {
  496. popmenu.insertItem(SmallIcon("pencil"), i18n("Rename..."), 14);
  497. popmenu.insertItem(SmallIcon("albumfolder-properties"), i18n("Album Properties..."), 11);
  498. popmenu.insertItem(SmallIcon("reload_page"), i18n("Reset Album Icon"), 13);
  499. popmenu.insertSeparator();
  500. // Add KIPI Albums plugins Actions
  501. TDEAction *action;
  502. const TQPtrList<TDEAction>& albumActions = DigikamApp::getinstance()->menuAlbumActions();
  503. if(!albumActions.isEmpty())
  504. {
  505. TQPtrListIterator<TDEAction> it(albumActions);
  506. while((action = it.current()))
  507. {
  508. action->plug(&popmenu);
  509. ++it;
  510. }
  511. }
  512. // Add All Import Actions
  513. const TQPtrList<TDEAction> importActions = DigikamApp::getinstance()->menuImportActions();
  514. if(!importActions.isEmpty())
  515. {
  516. TQPtrListIterator<TDEAction> it3(importActions);
  517. while((action = it3.current()))
  518. {
  519. menuImport.insert(action);
  520. ++it3;
  521. }
  522. menuImport.plug(&popmenu);
  523. }
  524. // Add All Export Actions
  525. const TQPtrList<TDEAction> exportActions = DigikamApp::getinstance()->menuExportActions();
  526. if(!exportActions.isEmpty())
  527. {
  528. TQPtrListIterator<TDEAction> it4(exportActions);
  529. while((action = it4.current()))
  530. {
  531. menuExport.insert(action);
  532. ++it4;
  533. }
  534. menuExport.plug(&popmenu);
  535. }
  536. // Add KIPI Batch processes plugins Actions
  537. const TQPtrList<TDEAction>& batchActions = DigikamApp::getinstance()->menuBatchActions();
  538. if(!batchActions.isEmpty())
  539. {
  540. TQPtrListIterator<TDEAction> it2(batchActions);
  541. while((action = it2.current()))
  542. {
  543. menuKIPIBatch.insert(action);
  544. ++it2;
  545. }
  546. menuKIPIBatch.plug(&popmenu);
  547. }
  548. if(!albumActions.isEmpty() || !batchActions.isEmpty() ||
  549. !importActions.isEmpty())
  550. {
  551. popmenu.insertSeparator(-1);
  552. }
  553. if(AlbumSettings::instance()->getUseTrash())
  554. {
  555. popmenu.insertItem(SmallIcon("edittrash"),
  556. i18n("Move Album to Trash"), 12);
  557. }
  558. else
  559. {
  560. popmenu.insertItem(SmallIcon("edit-delete"),
  561. i18n("Delete Album"), 12);
  562. }
  563. }
  564. switch(popmenu.exec((TQCursor::pos())))
  565. {
  566. case 10:
  567. {
  568. albumNew(item);
  569. break;
  570. }
  571. case 11:
  572. {
  573. albumEdit(item);
  574. break;
  575. }
  576. case 12:
  577. {
  578. albumDelete(item);
  579. break;
  580. }
  581. case 13:
  582. {
  583. TQString err;
  584. d->albumMan->updatePAlbumIcon(item->album(), 0, err);
  585. break;
  586. }
  587. case 14:
  588. {
  589. albumRename(item);
  590. break;
  591. }
  592. default:
  593. break;
  594. }
  595. }
  596. void AlbumFolderView::albumNew()
  597. {
  598. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  599. if (!item)
  600. {
  601. item = dynamic_cast<AlbumFolderViewItem*>(firstChild());
  602. }
  603. if (!item)
  604. return;
  605. albumNew(item);
  606. }
  607. void AlbumFolderView::albumNew(AlbumFolderViewItem *item)
  608. {
  609. AlbumSettings* settings = AlbumSettings::instance();
  610. if(!settings)
  611. {
  612. DWarning() << "AlbumFolderView: Couldn't get Album Settings" << endl;
  613. return;
  614. }
  615. TQDir libraryDir(settings->getAlbumLibraryPath());
  616. if(!libraryDir.exists())
  617. {
  618. KMessageBox::error(0,
  619. i18n("The album library has not been set correctly.\n"
  620. "Select \"Configure Digikam\" from the Settings "
  621. "menu and choose a folder to use for the album "
  622. "library."));
  623. return;
  624. }
  625. PAlbum *parent;
  626. if(!item)
  627. parent = d->albumMan->findPAlbum(0);
  628. else
  629. parent = item->album();
  630. if (!parent)
  631. return;
  632. TQString title;
  633. TQString comments;
  634. TQString collection;
  635. TQDate date;
  636. TQStringList albumCollections;
  637. if(!AlbumPropsEdit::createNew(parent, title, comments, date, collection,
  638. albumCollections))
  639. return;
  640. TQStringList oldAlbumCollections(AlbumSettings::instance()->getAlbumCollectionNames());
  641. if(albumCollections != oldAlbumCollections)
  642. {
  643. AlbumSettings::instance()->setAlbumCollectionNames(albumCollections);
  644. resort();
  645. }
  646. TQString errMsg;
  647. PAlbum* album = d->albumMan->createPAlbum(parent, title, comments,
  648. date, collection, errMsg);
  649. if (!album)
  650. {
  651. KMessageBox::error(0, errMsg);
  652. return;
  653. }
  654. // by this time the signalAlbumAdded has been fired and the appropriate
  655. // AlbumFolderViewItem has been created. Now make this folderviewitem visible
  656. AlbumFolderViewItem* newItem = (AlbumFolderViewItem*)album->extraData(this);
  657. if (newItem)
  658. {
  659. if(item)
  660. item->setOpen(true);
  661. ensureItemVisible(newItem);
  662. }
  663. }
  664. void AlbumFolderView::albumDelete()
  665. {
  666. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  667. if(!item)
  668. return;
  669. albumDelete(item);
  670. }
  671. void AlbumFolderView::albumDelete(AlbumFolderViewItem *item)
  672. {
  673. PAlbum *album = item->album();
  674. if(!album || album->isRoot())
  675. return;
  676. // find subalbums
  677. KURL::List childrenList;
  678. addAlbumChildrenToList(childrenList, album);
  679. DeleteDialog dialog(this);
  680. // All subalbums will be presented in the list as well
  681. if (!dialog.confirmDeleteList(childrenList,
  682. childrenList.size() == 1 ?
  683. DeleteDialogMode::Albums : DeleteDialogMode::Subalbums,
  684. DeleteDialogMode::UserPreference))
  685. return;
  686. bool useTrash = !dialog.shouldDelete();
  687. // Currently trash tdeioslave can handle only full paths.
  688. // pass full folder path to the trashing job
  689. KURL u;
  690. u.setProtocol("file");
  691. u.setPath(album->folderPath());
  692. TDEIO::Job* job = DIO::del(u, useTrash);
  693. connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
  694. this, TQT_SLOT(slotDIOResult(TDEIO::Job *)));
  695. }
  696. void AlbumFolderView::addAlbumChildrenToList(KURL::List &list, Album *album)
  697. {
  698. // simple recursive helper function
  699. if (album)
  700. {
  701. list.append(album->kurl());
  702. AlbumIterator it(album);
  703. while(it.current())
  704. {
  705. addAlbumChildrenToList(list, *it);
  706. ++it;
  707. }
  708. }
  709. }
  710. void AlbumFolderView::slotDIOResult(TDEIO::Job* job)
  711. {
  712. if (job->error())
  713. job->showErrorDialog(this);
  714. }
  715. void AlbumFolderView::albumRename()
  716. {
  717. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  718. if(!item)
  719. return;
  720. albumRename(item);
  721. }
  722. void AlbumFolderView::albumRename(AlbumFolderViewItem* item)
  723. {
  724. PAlbum *album = item->album();
  725. if (!album)
  726. return;
  727. TQString oldTitle(album->title());
  728. bool ok;
  729. #if KDE_IS_VERSION(3,2,0)
  730. TQString title = KInputDialog::getText(i18n("Rename Album (%1)").arg(oldTitle),
  731. i18n("Enter new album name:"),
  732. oldTitle, &ok, this);
  733. #else
  734. TQString title = KLineEditDlg::getText(i18n("Rename Item (%1)").arg(oldTitle),
  735. i18n("Enter new album name:"),
  736. oldTitle, &ok, this);
  737. #endif
  738. if (!ok)
  739. return;
  740. if(title != oldTitle)
  741. {
  742. TQString errMsg;
  743. if (!d->albumMan->renamePAlbum(album, title, errMsg))
  744. KMessageBox::error(0, errMsg);
  745. }
  746. emit signalAlbumModified();
  747. }
  748. void AlbumFolderView::albumEdit()
  749. {
  750. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  751. if(!item)
  752. return;
  753. albumEdit(item);
  754. }
  755. void AlbumFolderView::albumEdit(AlbumFolderViewItem* item)
  756. {
  757. PAlbum *album = item->album();
  758. if (!album)
  759. return;
  760. TQString oldTitle(album->title());
  761. TQString oldComments(album->caption());
  762. TQString oldCollection(album->collection());
  763. TQDate oldDate(album->date());
  764. TQStringList oldAlbumCollections(AlbumSettings::instance()->getAlbumCollectionNames());
  765. TQString title, comments, collection;
  766. TQDate date;
  767. TQStringList albumCollections;
  768. if(AlbumPropsEdit::editProps(album, title, comments, date,
  769. collection, albumCollections))
  770. {
  771. if(comments != oldComments)
  772. album->setCaption(comments);
  773. if(date != oldDate && date.isValid())
  774. album->setDate(date);
  775. if(collection != oldCollection)
  776. album->setCollection(collection);
  777. AlbumSettings::instance()->setAlbumCollectionNames(albumCollections);
  778. resort();
  779. // Do this last : so that if anything else changed we can
  780. // successfuly save to the db with the old name
  781. if(title != oldTitle)
  782. {
  783. TQString errMsg;
  784. if (!d->albumMan->renamePAlbum(album, title, errMsg))
  785. KMessageBox::error(0, errMsg);
  786. }
  787. emit signalAlbumModified();
  788. }
  789. }
  790. TQDragObject* AlbumFolderView::dragObject()
  791. {
  792. AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(dragItem());
  793. if(!item)
  794. return 0;
  795. PAlbum *album = item->album();
  796. if(album->isRoot())
  797. return 0;
  798. AlbumDrag *a = new AlbumDrag(album->kurl(), album->id(), this);
  799. if(!a)
  800. return 0;
  801. a->setPixmap(*item->pixmap(0));
  802. return a;
  803. }
  804. bool AlbumFolderView::acceptDrop(const TQDropEvent *e) const
  805. {
  806. TQPoint vp = contentsToViewport(e->pos());
  807. AlbumFolderViewItem *itemDrop = dynamic_cast<AlbumFolderViewItem*>(itemAt(vp));
  808. AlbumFolderViewItem *itemDrag = dynamic_cast<AlbumFolderViewItem*>(dragItem());
  809. if(AlbumDrag::canDecode(e))
  810. {
  811. switch(AlbumSettings::instance()->getAlbumSortOrder())
  812. {
  813. case(AlbumSettings::ByFolder):
  814. {
  815. // Allow dragging at the root, to move the album at the root
  816. if(!itemDrop)
  817. return true;
  818. // Dragging an item on itself makes no sense
  819. if(itemDrag == itemDrop)
  820. return false;
  821. // Dragging a parent on its child makes no sense
  822. if(itemDrag && itemDrag->album()->isAncestorOf(itemDrop->album()))
  823. return false;
  824. return true;
  825. }
  826. case (AlbumSettings::ByCollection):
  827. {
  828. if (!itemDrop)
  829. return false;
  830. // Only allow dragging onto Collection
  831. if (itemDrop->isGroupItem())
  832. return true;
  833. return false;
  834. }
  835. default:
  836. {
  837. return false;
  838. }
  839. }
  840. }
  841. if(itemDrop && !itemDrop->parent())
  842. {
  843. // Do not allow drop images on album root
  844. return false;
  845. }
  846. if (itemDrop && itemDrop->isGroupItem())
  847. {
  848. // do not allow drop on a group item
  849. return false;
  850. }
  851. if(ItemDrag::canDecode(e))
  852. {
  853. return true;
  854. }
  855. if (CameraItemListDrag::canDecode(e))
  856. {
  857. return true;
  858. }
  859. if(TQUriDrag::canDecode(e))
  860. {
  861. return true;
  862. }
  863. return false;
  864. }
  865. void AlbumFolderView::contentsDropEvent(TQDropEvent *e)
  866. {
  867. FolderView::contentsDropEvent(e);
  868. if(!acceptDrop(e))
  869. return;
  870. TQPoint vp = contentsToViewport(e->pos());
  871. AlbumFolderViewItem *itemDrop = dynamic_cast<AlbumFolderViewItem*>(itemAt(vp));
  872. if(AlbumDrag::canDecode(e))
  873. {
  874. AlbumFolderViewItem *itemDrag = dynamic_cast<AlbumFolderViewItem*>(dragItem());
  875. if(!itemDrag)
  876. return;
  877. if (AlbumSettings::instance()->getAlbumSortOrder()
  878. == AlbumSettings::ByFolder)
  879. {
  880. // TODO: Copy?
  881. TDEPopupMenu popMenu(this);
  882. popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  883. popMenu.insertItem(SmallIcon("goto"), i18n("&Move Here"), 10);
  884. popMenu.insertSeparator(-1);
  885. popMenu.insertItem(SmallIcon("cancel"), i18n("C&ancel"), 20);
  886. popMenu.setMouseTracking(true);
  887. int id = popMenu.exec(TQCursor::pos());
  888. if(id == 10)
  889. {
  890. PAlbum *album = itemDrag->album();
  891. PAlbum *destAlbum;
  892. if(!itemDrop)
  893. {
  894. // move dragItem to the root
  895. destAlbum = d->albumMan->findPAlbum(0);
  896. }
  897. else
  898. {
  899. // move dragItem below dropItem
  900. destAlbum = itemDrop->album();
  901. }
  902. TDEIO::Job* job = DIO::move(album->kurl(), destAlbum->kurl());
  903. connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
  904. this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
  905. }
  906. }
  907. else if (AlbumSettings::instance()->getAlbumSortOrder()
  908. == AlbumSettings::ByCollection)
  909. {
  910. if (!itemDrop)
  911. return;
  912. if (itemDrop->isGroupItem())
  913. {
  914. PAlbum *album = itemDrag->album();
  915. if (!album)
  916. return;
  917. album->setCollection(itemDrop->text(0));
  918. resort();
  919. }
  920. }
  921. return;
  922. }
  923. if (ItemDrag::canDecode(e))
  924. {
  925. if (!itemDrop)
  926. return;
  927. PAlbum *destAlbum = itemDrop->album();
  928. KURL::List urls;
  929. KURL::List kioURLs;
  930. TQValueList<int> albumIDs;
  931. TQValueList<int> imageIDs;
  932. if (!ItemDrag::decode(e, urls, kioURLs, albumIDs, imageIDs))
  933. return;
  934. if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
  935. return;
  936. // Check if items dropped come from outside current album.
  937. // This can be the case with reccursive content album mode.
  938. KURL::List extUrls;
  939. ImageInfoList extImgInfList;
  940. for (TQValueList<int>::iterator it = imageIDs.begin(); it != imageIDs.end(); ++it)
  941. {
  942. ImageInfo *info = new ImageInfo(*it);
  943. if (info->albumID() != destAlbum->id())
  944. {
  945. extUrls.append(info->kurlForKIO());
  946. extImgInfList.append(info);
  947. }
  948. }
  949. int id = 0;
  950. char keys_return[32];
  951. XQueryKeymap(x11Display(), keys_return);
  952. int key_1 = XKeysymToKeycode(x11Display(), 0xFFE3);
  953. int key_2 = XKeysymToKeycode(x11Display(), 0xFFE4);
  954. int key_3 = XKeysymToKeycode(x11Display(), 0xFFE1);
  955. int key_4 = XKeysymToKeycode(x11Display(), 0xFFE2);
  956. if(extUrls.isEmpty())
  957. {
  958. // Setting the dropped image as the album thumbnail
  959. // If the ctrl key is pressed, when dropping the image, the
  960. // thumbnail is set without a popup menu
  961. if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
  962. ((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
  963. {
  964. id = 12;
  965. }
  966. else
  967. {
  968. TDEPopupMenu popMenu(this);
  969. popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  970. popMenu.insertItem(i18n("Set as Album Thumbnail"), 12);
  971. popMenu.insertSeparator(-1);
  972. popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
  973. popMenu.setMouseTracking(true);
  974. id = popMenu.exec(TQCursor::pos());
  975. }
  976. if(id == 12)
  977. {
  978. TQString errMsg;
  979. d->albumMan->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
  980. }
  981. return;
  982. }
  983. // If shift key is pressed while dragging, move the drag object without
  984. // displaying popup menu -> move
  985. if (((keys_return[key_3 / 8]) && (1 << (key_3 % 8))) ||
  986. ((keys_return[key_4 / 8]) && (1 << (key_4 % 8))))
  987. {
  988. id = 10;
  989. }
  990. // If ctrl key is pressed while dragging, copy the drag object without
  991. // displaying popup menu -> copy
  992. else if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
  993. ((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
  994. {
  995. id = 11;
  996. }
  997. else
  998. {
  999. TDEPopupMenu popMenu(this);
  1000. popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  1001. popMenu.insertItem( SmallIcon("goto"), i18n("&Move Here"), 10 );
  1002. popMenu.insertItem( SmallIcon("edit-copy"), i18n("&Copy Here"), 11 );
  1003. if (imageIDs.count() == 1)
  1004. popMenu.insertItem(i18n("Set as Album Thumbnail"), 12);
  1005. popMenu.insertSeparator(-1);
  1006. popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
  1007. popMenu.setMouseTracking(true);
  1008. id = popMenu.exec(TQCursor::pos());
  1009. }
  1010. switch(id)
  1011. {
  1012. case 10:
  1013. {
  1014. TDEIO::Job* job = DIO::move(extUrls, destAlbum->kurl());
  1015. connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
  1016. this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
  1017. // In recurssive album contents mode, we need to force AlbumLister to take a care about
  1018. // moved items. This will have no incidence in normal mode.
  1019. ImageInfo* item;
  1020. for (ImageInfoListIterator it(extImgInfList); (item = it.current()) ; ++it)
  1021. {
  1022. AlbumLister::instance()->invalidateItem(item);
  1023. }
  1024. break;
  1025. }
  1026. case 11:
  1027. {
  1028. TDEIO::Job* job = DIO::copy(extUrls, destAlbum->kurl());
  1029. connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
  1030. this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
  1031. break;
  1032. }
  1033. case 12:
  1034. {
  1035. TQString errMsg;
  1036. d->albumMan->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
  1037. }
  1038. default:
  1039. break;
  1040. }
  1041. return;
  1042. }
  1043. // -- DnD from Camera GUI ------------------------------------------------
  1044. if(CameraItemListDrag::canDecode(e))
  1045. {
  1046. Album *album = dynamic_cast<Album*>(itemDrop->album());
  1047. if (!album) return;
  1048. CameraUI *ui = dynamic_cast<CameraUI*>(e->source());
  1049. if (ui)
  1050. {
  1051. TDEPopupMenu popMenu(this);
  1052. popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  1053. popMenu.insertItem(SmallIcon("go-down"), i18n("Download from camera"), 10);
  1054. popMenu.insertItem(SmallIcon("go-down"), i18n("Download && Delete from camera"), 11);
  1055. popMenu.insertSeparator(-1);
  1056. popMenu.insertItem(SmallIcon("cancel"), i18n("&Cancel"));
  1057. popMenu.setMouseTracking(true);
  1058. int id = popMenu.exec(TQCursor::pos());
  1059. switch(id)
  1060. {
  1061. case 10: // Download from camera
  1062. {
  1063. ui->slotDownload(true, false, album);
  1064. break;
  1065. }
  1066. case 11: // Download and Delete from camera
  1067. {
  1068. ui->slotDownload(true, true, album);
  1069. break;
  1070. }
  1071. default:
  1072. break;
  1073. }
  1074. }
  1075. }
  1076. // -- DnD from an external source ----------------------------------------
  1077. if(TQUriDrag::canDecode(e))
  1078. {
  1079. PAlbum* destAlbum = 0;
  1080. if (itemDrop)
  1081. destAlbum = itemDrop->album();
  1082. else
  1083. destAlbum = d->albumMan->findPAlbum(0);
  1084. // B.K.O #119205: do not handle root album.
  1085. if (destAlbum->isRoot())
  1086. return;
  1087. KURL destURL(destAlbum->kurl());
  1088. KURL::List srcURLs;
  1089. KURLDrag::decode(e, srcURLs);
  1090. char keys_return[32];
  1091. XQueryKeymap(x11Display(), keys_return);
  1092. int id = 0;
  1093. int key_1 = XKeysymToKeycode(x11Display(), 0xFFE3);
  1094. int key_2 = XKeysymToKeycode(x11Display(), 0xFFE4);
  1095. int key_3 = XKeysymToKeycode(x11Display(), 0xFFE1);
  1096. int key_4 = XKeysymToKeycode(x11Display(), 0xFFE2);
  1097. // If shift key is pressed while dropping, move the drag object without
  1098. // displaying popup menu -> move
  1099. if(((keys_return[key_3 / 8]) && (1 << (key_3 % 8))) ||
  1100. ((keys_return[key_4 / 8]) && (1 << (key_4 % 8))))
  1101. {
  1102. id = 10;
  1103. }
  1104. // If ctrl key is pressed while dropping, copy the drag object without
  1105. // displaying popup menu -> copy
  1106. else if(((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
  1107. ((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
  1108. {
  1109. id = 11;
  1110. }
  1111. else
  1112. {
  1113. TDEPopupMenu popMenu(this);
  1114. popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
  1115. popMenu.insertItem( SmallIcon("goto"), i18n("&Move Here"), 10 );
  1116. popMenu.insertItem( SmallIcon("edit-copy"), i18n("&Copy Here"), 11 );
  1117. popMenu.insertSeparator(-1);
  1118. popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
  1119. popMenu.setMouseTracking(true);
  1120. id = popMenu.exec(TQCursor::pos());
  1121. }
  1122. switch(id)
  1123. {
  1124. case 10:
  1125. {
  1126. TDEIO::Job* job = DIO::move(srcURLs, destAlbum->kurl());
  1127. connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
  1128. this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
  1129. break;
  1130. }
  1131. case 11:
  1132. {
  1133. TDEIO::Job* job = DIO::copy(srcURLs, destAlbum->kurl());
  1134. connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
  1135. this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
  1136. break;
  1137. }
  1138. default:
  1139. break;
  1140. }
  1141. return;
  1142. }
  1143. }
  1144. void AlbumFolderView::albumImportFolder()
  1145. {
  1146. AlbumSettings* settings = AlbumSettings::instance();
  1147. TQDir libraryDir(settings->getAlbumLibraryPath());
  1148. if(!libraryDir.exists())
  1149. {
  1150. KMessageBox::error(0,
  1151. i18n("The album library has not been set correctly.\n"
  1152. "Select \"Configure digiKam\" from the Settings "
  1153. "menu and choose a folder to use for the album "
  1154. "library."));
  1155. return;
  1156. }
  1157. PAlbum* parent = 0;
  1158. if(selectedItem())
  1159. {
  1160. AlbumFolderViewItem *folderItem = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  1161. Album *album = folderItem->album();
  1162. if (album && album->type() == Album::PHYSICAL)
  1163. {
  1164. parent = dynamic_cast<PAlbum*>(album);
  1165. }
  1166. }
  1167. if(!parent)
  1168. parent = dynamic_cast<PAlbum*>(d->albumMan->findPAlbum(0));
  1169. TQString libraryPath = parent->folderPath();
  1170. KFileDialog dlg(TQString(), "inode/directory", this, "importFolder", true);
  1171. dlg.setCaption(i18n("Select folders to import"));
  1172. dlg.setMode(KFile::Directory | KFile::Files);
  1173. if(dlg.exec() != TQDialog::Accepted)
  1174. return;
  1175. KURL::List urls = dlg.selectedURLs();
  1176. if(urls.empty())
  1177. return;
  1178. TDEIO::Job* job = DIO::copy(urls, parent->kurl());
  1179. connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
  1180. this, TQT_SLOT(slotDIOResult(TDEIO::Job *)));
  1181. }
  1182. void AlbumFolderView::selectItem(int id)
  1183. {
  1184. PAlbum* album = d->albumMan->findPAlbum(id);
  1185. if(!album)
  1186. return;
  1187. AlbumFolderViewItem *item = (AlbumFolderViewItem*)album->extraData(this);
  1188. if(item)
  1189. {
  1190. setSelected(item, true);
  1191. ensureItemVisible(item);
  1192. }
  1193. }
  1194. AlbumFolderViewItem* AlbumFolderView::findParent(PAlbum* album, bool& failed)
  1195. {
  1196. if (album->isRoot())
  1197. {
  1198. failed = false;
  1199. return 0;
  1200. }
  1201. switch(AlbumSettings::instance()->getAlbumSortOrder())
  1202. {
  1203. case(AlbumSettings::ByFolder):
  1204. {
  1205. return findParentByFolder(album, failed);
  1206. }
  1207. case(AlbumSettings::ByCollection):
  1208. {
  1209. return findParentByCollection(album, failed);
  1210. }
  1211. case(AlbumSettings::ByDate):
  1212. {
  1213. return findParentByDate(album, failed);
  1214. }
  1215. }
  1216. failed = true;
  1217. return 0;
  1218. }
  1219. AlbumFolderViewItem* AlbumFolderView::findParentByFolder(PAlbum* album, bool& failed)
  1220. {
  1221. AlbumFolderViewItem* parent =
  1222. (AlbumFolderViewItem*) album->parent()->extraData(this);
  1223. if (!parent)
  1224. {
  1225. failed = true;
  1226. return 0;
  1227. }
  1228. failed = false;
  1229. return parent;
  1230. }
  1231. AlbumFolderViewItem* AlbumFolderView::findParentByCollection(PAlbum* album, bool& failed)
  1232. {
  1233. TQStringList collectionList = AlbumSettings::instance()->getAlbumCollectionNames();
  1234. TQString collection = album->collection();
  1235. if (collection.isEmpty() || !collectionList.contains(collection))
  1236. collection = i18n("Uncategorized Albums");
  1237. AlbumFolderViewItem* parent = 0;
  1238. for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
  1239. it != d->groupItems.end(); ++it)
  1240. {
  1241. AlbumFolderViewItem* groupItem = *it;
  1242. if (groupItem->text(0) == collection)
  1243. {
  1244. parent = groupItem;
  1245. break;
  1246. }
  1247. }
  1248. // Need to create a new parent item
  1249. if (!parent)
  1250. {
  1251. parent = new AlbumFolderViewItem(firstChild(), collection, 0, 0);
  1252. d->groupItems.append(parent);
  1253. }
  1254. failed = false;
  1255. return parent;
  1256. }
  1257. AlbumFolderViewItem* AlbumFolderView::findParentByDate(PAlbum* album, bool& failed)
  1258. {
  1259. TQDate date = album->date();
  1260. TQString timeString = TQString::number(date.year()) + ", " +
  1261. TDEGlobal::locale()->calendar()->monthName(date, false);
  1262. AlbumFolderViewItem* parent = 0;
  1263. for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
  1264. it != d->groupItems.end(); ++it)
  1265. {
  1266. AlbumFolderViewItem* groupItem = *it;
  1267. if (groupItem->text(0) == timeString)
  1268. {
  1269. parent = groupItem;
  1270. break;
  1271. }
  1272. }
  1273. // Need to create a new parent item
  1274. if (!parent)
  1275. {
  1276. parent = new AlbumFolderViewItem(firstChild(), timeString,
  1277. date.year(), date.month());
  1278. d->groupItems.append(parent);
  1279. }
  1280. failed = false;
  1281. return parent;
  1282. }
  1283. void AlbumFolderView::resort()
  1284. {
  1285. AlbumFolderViewItem* prevSelectedItem = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
  1286. if (prevSelectedItem && prevSelectedItem->isGroupItem())
  1287. prevSelectedItem = 0;
  1288. AlbumList pList(d->albumMan->allPAlbums());
  1289. for (AlbumList::iterator it = pList.begin(); it != pList.end(); ++it)
  1290. {
  1291. PAlbum *album = (PAlbum*)(*it);
  1292. if (!album->isRoot() && album->extraData(this))
  1293. {
  1294. reparentItem(static_cast<AlbumFolderViewItem*>(album->extraData(this)));
  1295. }
  1296. }
  1297. // Clear any groupitems which have been left empty
  1298. clearEmptyGroupItems();
  1299. if (prevSelectedItem)
  1300. {
  1301. ensureItemVisible(prevSelectedItem);
  1302. setSelected(prevSelectedItem, true);
  1303. }
  1304. }
  1305. void AlbumFolderView::reparentItem(AlbumFolderViewItem* folderItem)
  1306. {
  1307. if (!folderItem)
  1308. return;
  1309. PAlbum* album = folderItem->album();
  1310. if (!album || album->isRoot())
  1311. return;
  1312. AlbumFolderViewItem* oldParent = dynamic_cast<AlbumFolderViewItem*>(folderItem->parent());
  1313. bool failed;
  1314. AlbumFolderViewItem* newParent = findParent(album, failed);
  1315. if (failed)
  1316. return;
  1317. if (oldParent == newParent)
  1318. return;
  1319. if (oldParent)
  1320. oldParent->removeItem(folderItem);
  1321. else
  1322. removeItem(folderItem);
  1323. // insert into new parent
  1324. if (newParent)
  1325. newParent->insertItem(folderItem);
  1326. else
  1327. insertItem(folderItem);
  1328. }
  1329. void AlbumFolderView::clearEmptyGroupItems()
  1330. {
  1331. TQValueList<AlbumFolderViewItem*> deleteItems;
  1332. for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
  1333. it != d->groupItems.end(); ++it)
  1334. {
  1335. AlbumFolderViewItem* groupItem = *it;
  1336. if (!groupItem->firstChild())
  1337. {
  1338. deleteItems.append(groupItem);
  1339. }
  1340. }
  1341. for (TQValueList<AlbumFolderViewItem*>::iterator it=deleteItems.begin();
  1342. it != deleteItems.end(); ++it)
  1343. {
  1344. d->groupItems.remove(*it);
  1345. delete *it;
  1346. }
  1347. }
  1348. void AlbumFolderView::refresh()
  1349. {
  1350. TQListViewItemIterator it(this);
  1351. while (it.current())
  1352. {
  1353. AlbumFolderViewItem* item = dynamic_cast<AlbumFolderViewItem*>(*it);
  1354. if (item)
  1355. item->refresh();
  1356. ++it;
  1357. }
  1358. }
  1359. void AlbumFolderView::slotRefresh(const TQMap<int, int>& albumsStatMap)
  1360. {
  1361. TQListViewItemIterator it(this);
  1362. while (it.current())
  1363. {
  1364. AlbumFolderViewItem* item = dynamic_cast<AlbumFolderViewItem*>(*it);
  1365. if (item)
  1366. {
  1367. if (item->album())
  1368. {
  1369. int id = item->id();
  1370. TQMap<int, int>::const_iterator it2 = albumsStatMap.find(id);
  1371. if ( it2 != albumsStatMap.end() )
  1372. item->setCount(it2.data());
  1373. }
  1374. }
  1375. ++it;
  1376. }
  1377. refresh();
  1378. }
  1379. } // namespace Digikam