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.
digikam/digikam/digikam/album.cpp

544 lines
9.8 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2004-06-15
* Description : digiKam album types
*
* Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
* either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
// KDE includes.
#include <tdelocale.h>
// Local includes.
#include "ddebug.h"
#include "albummanager.h"
#include "albumdb.h"
#include "album.h"
namespace Digikam
{
Album::Album(Album::Type type, int id, bool root)
{
m_parent = 0;
m_next = 0;
m_prev = 0;
m_firstChild = 0;
m_lastChild = 0;
m_clearing = false;
m_type = type;
m_id = id;
m_root = root;
}
Album::~Album()
{
if (m_parent)
m_parent->removeChild(this);
clear();
}
void Album::setParent(Album* parent)
{
if (parent)
{
m_parent = parent;
parent->insertChild(this);
}
}
Album* Album::parent() const
{
return m_parent;
}
Album* Album::firstChild() const
{
return m_firstChild;
}
Album* Album::lastChild() const
{
return m_lastChild;
}
Album* Album::next() const
{
return m_next;
}
Album* Album::prev() const
{
return m_prev;
}
void Album::insertChild(Album* child)
{
if (!child)
return;
if (!m_firstChild)
{
m_firstChild = child;
m_lastChild = child;
child->m_next = 0;
child->m_prev = 0;
}
else
{
m_lastChild->m_next = child;
child->m_prev = m_lastChild;
child->m_next = 0;
m_lastChild = child;
}
}
void Album::removeChild(Album* child)
{
if (!child || m_clearing)
return;
if (child == m_firstChild)
{
m_firstChild = m_firstChild->m_next;
if (m_firstChild)
m_firstChild->m_prev = 0;
else
m_firstChild = m_lastChild = 0;
}
else if (child == m_lastChild)
{
m_lastChild = m_lastChild->m_prev;
if (m_lastChild)
m_lastChild->m_next = 0;
else
m_firstChild = m_lastChild = 0;
}
else
{
Album* c = child;
if (c->m_prev)
c->m_prev->m_next = c->m_next;
if (c->m_next)
c->m_next->m_prev = c->m_prev;
}
}
void Album::clear()
{
m_clearing = true;
Album* child = m_firstChild;
Album* nextChild;
while (child)
{
nextChild = child->m_next;
delete child;
child = nextChild;
}
m_firstChild = 0;
m_lastChild = 0;
m_clearing = false;
}
int Album::globalID() const
{
switch (m_type)
{
case (PHYSICAL):
return 10000 + m_id;
case(TAG):
return 20000 + m_id;
case(DATE):
return 30000 + m_id;
case(SEARCH):
return 40000 + m_id;
default:
DError() << "Unknown album type" << endl;
return -1;
}
}
int Album::id() const
{
return m_id;
}
void Album::setTitle(const TQString& title)
{
m_title = title;
}
TQString Album::title() const
{
return m_title;
}
Album::Type Album::type() const
{
return m_type;
}
void Album::setExtraData(const void* key, void* value)
{
m_extraMap.replace(key, value);
}
void Album::removeExtraData(const void* key)
{
m_extraMap.remove(key);
}
void* Album::extraData(const void* key) const
{
typedef TQMap<const void*, void*> Map;
Map::const_iterator it = m_extraMap.find(key);
if (it == m_extraMap.end())
return 0;
return it.data();
}
bool Album::isRoot() const
{
return m_root;
}
bool Album::isAncestorOf(Album* album) const
{
bool val = false;
Album* a = album;
while (a && !a->isRoot())
{
if (a == this)
{
val = true;
break;
}
a = a->parent();
}
return val;
}
// ------------------------------------------------------------------------------
PAlbum::PAlbum(const TQString& title, int id, bool root)
: Album(Album::PHYSICAL, id, root)
{
setTitle(title);
m_caption = "";
m_collection = "";
m_date = TQDate::currentDate();
}
PAlbum::~PAlbum()
{
}
void PAlbum::setCaption(const TQString& caption)
{
m_caption = caption;
AlbumDB* db = AlbumManager::instance()->albumDB();
db->setAlbumCaption(id(), m_caption);
}
void PAlbum::setCollection(const TQString& collection)
{
m_collection = collection;
AlbumDB* db = AlbumManager::instance()->albumDB();
db->setAlbumCollection(id(), m_collection);
}
void PAlbum::setDate(const TQDate& date)
{
m_date = date;
AlbumDB* db = AlbumManager::instance()->albumDB();
db->setAlbumDate(id(), m_date);
}
TQString PAlbum::caption() const
{
return m_caption;
}
TQString PAlbum::collection() const
{
return m_collection;
}
TQDate PAlbum::date() const
{
return m_date;
}
TQString PAlbum::url() const
{
TQString u("");
if (isRoot())
{
return "/";
}
else if (parent())
{
u = ((PAlbum*)parent())->url();
if (!u.endsWith("/"))
u += '/';
}
u += title();
return u;
}
KURL PAlbum::kurl() const
{
KURL u;
u.setProtocol("digikamalbums");
u.setUser(AlbumManager::instance()->getLibraryPath());
// add an empty host. KURLDrag will eat away the user
// attribute if a host is not present. probably a URL
// specification
u.setHost(" ");
u.setPath(url());
return u;
}
TQString PAlbum::prettyURL() const
{
TQString u = i18n("My Albums") + url();
return u;
}
TQString PAlbum::icon() const
{
return m_icon;
}
KURL PAlbum::iconKURL() const
{
KURL u;
u.setPath( m_icon );
return u;
}
TQString PAlbum::folderPath() const
{
KURL u(AlbumManager::instance()->getLibraryPath());
u.addPath(url());
return u.path();
}
// --------------------------------------------------------------------------
TAlbum::TAlbum(const TQString& title, int id, bool root)
: Album(Album::TAG, id, root)
{
setTitle(title);
}
TAlbum::~TAlbum()
{
}
TQString TAlbum::tagPath(bool leadingSlash) const
{
if (isRoot())
return leadingSlash ? "/" : "";
TQString u;
if (parent())
{
u = ((TAlbum*)parent())->tagPath(leadingSlash);
if (!parent()->isRoot())
u += '/';
}
u += title();
return u;
}
TQString TAlbum::prettyURL() const
{
TQString u = i18n("My Tags") + tagPath(true);
return u;
}
KURL TAlbum::kurl() const
{
KURL url;
url.setProtocol("digikamtags");
if (isRoot())
{
url.setPath("/");
}
else if (parent())
{
TAlbum *p = static_cast<TAlbum*>(parent());
url.setPath(p->kurl().path(1));
url.addPath(TQString::number(id()));
}
else
{
url = KURL();
}
return url;
}
TQString TAlbum::icon() const
{
return m_icon;
}
// --------------------------------------------------------------------------
int DAlbum::m_uniqueID = 0;
DAlbum::DAlbum(const TQDate& date, bool root, Range range)
: Album(Album::DATE, root ? 0 : ++m_uniqueID, root)
{
m_date = date;
m_range = range;
// Set the name of the date album
TQString dateTitle;
if (m_range == Month)
dateTitle = m_date.toString("MMMM yyyy");
else
dateTitle = m_date.toString("yyyy");
setTitle(dateTitle);
}
DAlbum::~DAlbum()
{
}
TQDate DAlbum::date() const
{
return m_date;
}
DAlbum::Range DAlbum::range() const
{
return m_range;
}
KURL DAlbum::kurl() const
{
TQDate endDate;
if (m_range == Month)
endDate = m_date.addMonths(1);
else
endDate = m_date.addYears(1);
KURL u;
u.setProtocol("digikamdates");
u.setPath(TQString("/%1/%2/%3/%4")
.arg(m_date.year())
.arg(m_date.month())
.arg(endDate.year())
.arg(endDate.month()));
return u;
}
// --------------------------------------------------------------------------
SAlbum::SAlbum(int id, const KURL& url, bool simple, bool root)
: Album(Album::SEARCH, id, root),
m_kurl(url), m_simple(simple)
{
setTitle(url.queryItem("name"));
}
SAlbum::~SAlbum()
{
}
KURL SAlbum::kurl() const
{
return m_kurl;
}
bool SAlbum::isSimple() const
{
return m_simple;
}
// --------------------------------------------------------------------------
AlbumIterator::AlbumIterator(Album *album)
{
m_root = album;
m_current = album ? album->firstChild() : 0;
}
AlbumIterator::~AlbumIterator()
{
}
AlbumIterator& AlbumIterator::operator++()
{
if (!m_current)
return *this;
Album *album = m_current->firstChild();
if ( !album )
{
while ( (album = m_current->next()) == 0 )
{
m_current = m_current->parent();
if ( m_current == m_root )
{
// we have reached the root.
// that means no more children
m_current = 0;
break;
}
if ( m_current == 0 )
break;
}
}
m_current = album;
return *this;
}
Album* AlbumIterator::operator*()
{
return m_current;
}
Album* AlbumIterator::current() const
{
return m_current;
}
} // namespace Digikam