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.

544 lines
9.8KB

  1. /* ============================================================
  2. *
  3. * This file is a part of digiKam project
  4. * http://www.digikam.org
  5. *
  6. * Date : 2004-06-15
  7. * Description : digiKam album types
  8. *
  9. * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
  10. * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
  11. *
  12. * This program is free software; you can redistribute it
  13. * and/or modify it under the terms of the GNU General
  14. * Public License as published by the Free Software Foundation;
  15. * either version 2, or (at your option)
  16. * any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * ============================================================ */
  24. // KDE includes.
  25. #include <tdelocale.h>
  26. // Local includes.
  27. #include "ddebug.h"
  28. #include "albummanager.h"
  29. #include "albumdb.h"
  30. #include "album.h"
  31. namespace Digikam
  32. {
  33. Album::Album(Album::Type type, int id, bool root)
  34. {
  35. m_parent = 0;
  36. m_next = 0;
  37. m_prev = 0;
  38. m_firstChild = 0;
  39. m_lastChild = 0;
  40. m_clearing = false;
  41. m_type = type;
  42. m_id = id;
  43. m_root = root;
  44. }
  45. Album::~Album()
  46. {
  47. if (m_parent)
  48. m_parent->removeChild(this);
  49. clear();
  50. }
  51. void Album::setParent(Album* parent)
  52. {
  53. if (parent)
  54. {
  55. m_parent = parent;
  56. parent->insertChild(this);
  57. }
  58. }
  59. Album* Album::parent() const
  60. {
  61. return m_parent;
  62. }
  63. Album* Album::firstChild() const
  64. {
  65. return m_firstChild;
  66. }
  67. Album* Album::lastChild() const
  68. {
  69. return m_lastChild;
  70. }
  71. Album* Album::next() const
  72. {
  73. return m_next;
  74. }
  75. Album* Album::prev() const
  76. {
  77. return m_prev;
  78. }
  79. void Album::insertChild(Album* child)
  80. {
  81. if (!child)
  82. return;
  83. if (!m_firstChild)
  84. {
  85. m_firstChild = child;
  86. m_lastChild = child;
  87. child->m_next = 0;
  88. child->m_prev = 0;
  89. }
  90. else
  91. {
  92. m_lastChild->m_next = child;
  93. child->m_prev = m_lastChild;
  94. child->m_next = 0;
  95. m_lastChild = child;
  96. }
  97. }
  98. void Album::removeChild(Album* child)
  99. {
  100. if (!child || m_clearing)
  101. return;
  102. if (child == m_firstChild)
  103. {
  104. m_firstChild = m_firstChild->m_next;
  105. if (m_firstChild)
  106. m_firstChild->m_prev = 0;
  107. else
  108. m_firstChild = m_lastChild = 0;
  109. }
  110. else if (child == m_lastChild)
  111. {
  112. m_lastChild = m_lastChild->m_prev;
  113. if (m_lastChild)
  114. m_lastChild->m_next = 0;
  115. else
  116. m_firstChild = m_lastChild = 0;
  117. }
  118. else
  119. {
  120. Album* c = child;
  121. if (c->m_prev)
  122. c->m_prev->m_next = c->m_next;
  123. if (c->m_next)
  124. c->m_next->m_prev = c->m_prev;
  125. }
  126. }
  127. void Album::clear()
  128. {
  129. m_clearing = true;
  130. Album* child = m_firstChild;
  131. Album* nextChild;
  132. while (child)
  133. {
  134. nextChild = child->m_next;
  135. delete child;
  136. child = nextChild;
  137. }
  138. m_firstChild = 0;
  139. m_lastChild = 0;
  140. m_clearing = false;
  141. }
  142. int Album::globalID() const
  143. {
  144. switch (m_type)
  145. {
  146. case (PHYSICAL):
  147. return 10000 + m_id;
  148. case(TAG):
  149. return 20000 + m_id;
  150. case(DATE):
  151. return 30000 + m_id;
  152. case(SEARCH):
  153. return 40000 + m_id;
  154. default:
  155. DError() << "Unknown album type" << endl;
  156. return -1;
  157. }
  158. }
  159. int Album::id() const
  160. {
  161. return m_id;
  162. }
  163. void Album::setTitle(const TQString& title)
  164. {
  165. m_title = title;
  166. }
  167. TQString Album::title() const
  168. {
  169. return m_title;
  170. }
  171. Album::Type Album::type() const
  172. {
  173. return m_type;
  174. }
  175. void Album::setExtraData(const void* key, void* value)
  176. {
  177. m_extraMap.replace(key, value);
  178. }
  179. void Album::removeExtraData(const void* key)
  180. {
  181. m_extraMap.remove(key);
  182. }
  183. void* Album::extraData(const void* key) const
  184. {
  185. typedef TQMap<const void*, void*> Map;
  186. Map::const_iterator it = m_extraMap.find(key);
  187. if (it == m_extraMap.end())
  188. return 0;
  189. return it.data();
  190. }
  191. bool Album::isRoot() const
  192. {
  193. return m_root;
  194. }
  195. bool Album::isAncestorOf(Album* album) const
  196. {
  197. bool val = false;
  198. Album* a = album;
  199. while (a && !a->isRoot())
  200. {
  201. if (a == this)
  202. {
  203. val = true;
  204. break;
  205. }
  206. a = a->parent();
  207. }
  208. return val;
  209. }
  210. // ------------------------------------------------------------------------------
  211. PAlbum::PAlbum(const TQString& title, int id, bool root)
  212. : Album(Album::PHYSICAL, id, root)
  213. {
  214. setTitle(title);
  215. m_caption = "";
  216. m_collection = "";
  217. m_date = TQDate::currentDate();
  218. }
  219. PAlbum::~PAlbum()
  220. {
  221. }
  222. void PAlbum::setCaption(const TQString& caption)
  223. {
  224. m_caption = caption;
  225. AlbumDB* db = AlbumManager::instance()->albumDB();
  226. db->setAlbumCaption(id(), m_caption);
  227. }
  228. void PAlbum::setCollection(const TQString& collection)
  229. {
  230. m_collection = collection;
  231. AlbumDB* db = AlbumManager::instance()->albumDB();
  232. db->setAlbumCollection(id(), m_collection);
  233. }
  234. void PAlbum::setDate(const TQDate& date)
  235. {
  236. m_date = date;
  237. AlbumDB* db = AlbumManager::instance()->albumDB();
  238. db->setAlbumDate(id(), m_date);
  239. }
  240. TQString PAlbum::caption() const
  241. {
  242. return m_caption;
  243. }
  244. TQString PAlbum::collection() const
  245. {
  246. return m_collection;
  247. }
  248. TQDate PAlbum::date() const
  249. {
  250. return m_date;
  251. }
  252. TQString PAlbum::url() const
  253. {
  254. TQString u("");
  255. if (isRoot())
  256. {
  257. return "/";
  258. }
  259. else if (parent())
  260. {
  261. u = ((PAlbum*)parent())->url();
  262. if (!u.endsWith("/"))
  263. u += '/';
  264. }
  265. u += title();
  266. return u;
  267. }
  268. KURL PAlbum::kurl() const
  269. {
  270. KURL u;
  271. u.setProtocol("digikamalbums");
  272. u.setUser(AlbumManager::instance()->getLibraryPath());
  273. // add an empty host. KURLDrag will eat away the user
  274. // attribute if a host is not present. probably a URL
  275. // specification
  276. u.setHost(" ");
  277. u.setPath(url());
  278. return u;
  279. }
  280. TQString PAlbum::prettyURL() const
  281. {
  282. TQString u = i18n("My Albums") + url();
  283. return u;
  284. }
  285. TQString PAlbum::icon() const
  286. {
  287. return m_icon;
  288. }
  289. KURL PAlbum::iconKURL() const
  290. {
  291. KURL u;
  292. u.setPath( m_icon );
  293. return u;
  294. }
  295. TQString PAlbum::folderPath() const
  296. {
  297. KURL u(AlbumManager::instance()->getLibraryPath());
  298. u.addPath(url());
  299. return u.path();
  300. }
  301. // --------------------------------------------------------------------------
  302. TAlbum::TAlbum(const TQString& title, int id, bool root)
  303. : Album(Album::TAG, id, root)
  304. {
  305. setTitle(title);
  306. }
  307. TAlbum::~TAlbum()
  308. {
  309. }
  310. TQString TAlbum::tagPath(bool leadingSlash) const
  311. {
  312. if (isRoot())
  313. return leadingSlash ? "/" : "";
  314. TQString u;
  315. if (parent())
  316. {
  317. u = ((TAlbum*)parent())->tagPath(leadingSlash);
  318. if (!parent()->isRoot())
  319. u += '/';
  320. }
  321. u += title();
  322. return u;
  323. }
  324. TQString TAlbum::prettyURL() const
  325. {
  326. TQString u = i18n("My Tags") + tagPath(true);
  327. return u;
  328. }
  329. KURL TAlbum::kurl() const
  330. {
  331. KURL url;
  332. url.setProtocol("digikamtags");
  333. if (isRoot())
  334. {
  335. url.setPath("/");
  336. }
  337. else if (parent())
  338. {
  339. TAlbum *p = static_cast<TAlbum*>(parent());
  340. url.setPath(p->kurl().path(1));
  341. url.addPath(TQString::number(id()));
  342. }
  343. else
  344. {
  345. url = KURL();
  346. }
  347. return url;
  348. }
  349. TQString TAlbum::icon() const
  350. {
  351. return m_icon;
  352. }
  353. // --------------------------------------------------------------------------
  354. int DAlbum::m_uniqueID = 0;
  355. DAlbum::DAlbum(const TQDate& date, bool root, Range range)
  356. : Album(Album::DATE, root ? 0 : ++m_uniqueID, root)
  357. {
  358. m_date = date;
  359. m_range = range;
  360. // Set the name of the date album
  361. TQString dateTitle;
  362. if (m_range == Month)
  363. dateTitle = m_date.toString("MMMM yyyy");
  364. else
  365. dateTitle = m_date.toString("yyyy");
  366. setTitle(dateTitle);
  367. }
  368. DAlbum::~DAlbum()
  369. {
  370. }
  371. TQDate DAlbum::date() const
  372. {
  373. return m_date;
  374. }
  375. DAlbum::Range DAlbum::range() const
  376. {
  377. return m_range;
  378. }
  379. KURL DAlbum::kurl() const
  380. {
  381. TQDate endDate;
  382. if (m_range == Month)
  383. endDate = m_date.addMonths(1);
  384. else
  385. endDate = m_date.addYears(1);
  386. KURL u;
  387. u.setProtocol("digikamdates");
  388. u.setPath(TQString("/%1/%2/%3/%4")
  389. .arg(m_date.year())
  390. .arg(m_date.month())
  391. .arg(endDate.year())
  392. .arg(endDate.month()));
  393. return u;
  394. }
  395. // --------------------------------------------------------------------------
  396. SAlbum::SAlbum(int id, const KURL& url, bool simple, bool root)
  397. : Album(Album::SEARCH, id, root),
  398. m_kurl(url), m_simple(simple)
  399. {
  400. setTitle(url.queryItem("name"));
  401. }
  402. SAlbum::~SAlbum()
  403. {
  404. }
  405. KURL SAlbum::kurl() const
  406. {
  407. return m_kurl;
  408. }
  409. bool SAlbum::isSimple() const
  410. {
  411. return m_simple;
  412. }
  413. // --------------------------------------------------------------------------
  414. AlbumIterator::AlbumIterator(Album *album)
  415. {
  416. m_root = album;
  417. m_current = album ? album->firstChild() : 0;
  418. }
  419. AlbumIterator::~AlbumIterator()
  420. {
  421. }
  422. AlbumIterator& AlbumIterator::operator++()
  423. {
  424. if (!m_current)
  425. return *this;
  426. Album *album = m_current->firstChild();
  427. if ( !album )
  428. {
  429. while ( (album = m_current->next()) == 0 )
  430. {
  431. m_current = m_current->parent();
  432. if ( m_current == m_root )
  433. {
  434. // we have reached the root.
  435. // that means no more children
  436. m_current = 0;
  437. break;
  438. }
  439. if ( m_current == 0 )
  440. break;
  441. }
  442. }
  443. m_current = album;
  444. return *this;
  445. }
  446. Album* AlbumIterator::operator*()
  447. {
  448. return m_current;
  449. }
  450. Album* AlbumIterator::current() const
  451. {
  452. return m_current;
  453. }
  454. } // namespace Digikam