|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* This file is a part of digiKam project
|
|
|
|
* http://www.digikam.org
|
|
|
|
*
|
|
|
|
* Date : 2005-05-06
|
|
|
|
* Description : Albums folder view.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005-2006 by Joern Ahrens <joern.ahrens@kdemail.net>
|
|
|
|
* Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
|
|
* Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* ============================================================ */
|
|
|
|
|
|
|
|
// TQt includes.
|
|
|
|
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqguardedptr.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <kpopupmenu.h>
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqdatastream.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
#include <tqdatetime.h>
|
|
|
|
|
|
|
|
// KDE includes.
|
|
|
|
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kcalendarsystem.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <tdefiledialog.h>
|
|
|
|
|
|
|
|
#include <tdeversion.h>
|
|
|
|
#if KDE_IS_VERSION(3,2,0)
|
|
|
|
#include <kinputdialog.h>
|
|
|
|
#else
|
|
|
|
#include <klineeditdlg.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Local includes.
|
|
|
|
|
|
|
|
#include "ddebug.h"
|
|
|
|
#include "digikamapp.h"
|
|
|
|
#include "albumlister.h"
|
|
|
|
#include "album.h"
|
|
|
|
#include "albumdb.h"
|
|
|
|
#include "albumpropsedit.h"
|
|
|
|
#include "albummanager.h"
|
|
|
|
#include "albumsettings.h"
|
|
|
|
#include "thumbnailjob.h"
|
|
|
|
#include "thumbnailsize.h"
|
|
|
|
#include "folderitem.h"
|
|
|
|
#include "cameraui.h"
|
|
|
|
#include "dio.h"
|
|
|
|
#include "dragobjects.h"
|
|
|
|
#include "albumthumbnailloader.h"
|
|
|
|
#include "deletedialog.h"
|
|
|
|
#include "albumfolderview.h"
|
|
|
|
#include "albumfolderview.moc"
|
|
|
|
|
|
|
|
// X11 C Ansi includes.
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Digikam
|
|
|
|
{
|
|
|
|
|
|
|
|
class AlbumFolderViewItem : public FolderItem
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
AlbumFolderViewItem(TQListView *parent, PAlbum *album);
|
|
|
|
AlbumFolderViewItem(TQListViewItem *parent, PAlbum *album);
|
|
|
|
|
|
|
|
// special group item (collection/dates)
|
|
|
|
AlbumFolderViewItem(TQListViewItem* parent, const TQString& name,
|
|
|
|
int year, int month);
|
|
|
|
|
|
|
|
PAlbum* album() const;
|
|
|
|
int id() const;
|
|
|
|
bool isGroupItem() const;
|
|
|
|
int compare(TQListViewItem *i, int col, bool ascending) const;
|
|
|
|
void refresh();
|
|
|
|
void setOpen(bool o);
|
|
|
|
void setCount(int count);
|
|
|
|
int count();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
bool m_groupItem;
|
|
|
|
|
|
|
|
int m_count;
|
|
|
|
int m_year;
|
|
|
|
int m_month;
|
|
|
|
|
|
|
|
PAlbum *m_album;
|
|
|
|
};
|
|
|
|
|
|
|
|
AlbumFolderViewItem::AlbumFolderViewItem(TQListView *parent, PAlbum *album)
|
|
|
|
: FolderItem(parent, album->title())
|
|
|
|
{
|
|
|
|
setDragEnabled(true);
|
|
|
|
m_album = album;
|
|
|
|
m_groupItem = false;
|
|
|
|
m_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem::AlbumFolderViewItem(TQListViewItem *parent, PAlbum *album)
|
|
|
|
: FolderItem(parent, album->title())
|
|
|
|
{
|
|
|
|
setDragEnabled(true);
|
|
|
|
m_album = album;
|
|
|
|
m_groupItem = false;
|
|
|
|
m_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// special group item (collection/dates)
|
|
|
|
AlbumFolderViewItem::AlbumFolderViewItem(TQListViewItem* parent, const TQString& name,
|
|
|
|
int year, int month)
|
|
|
|
: FolderItem(parent, name, true)
|
|
|
|
{
|
|
|
|
m_album = 0;
|
|
|
|
m_year = year;
|
|
|
|
m_month = month;
|
|
|
|
m_groupItem = true;
|
|
|
|
m_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderViewItem::refresh()
|
|
|
|
{
|
|
|
|
if (!m_album) return;
|
|
|
|
|
|
|
|
if (AlbumSettings::instance()->getShowFolderTreeViewItemsCount() &&
|
|
|
|
dynamic_cast<AlbumFolderViewItem*>(parent()))
|
|
|
|
{
|
|
|
|
if (isOpen())
|
|
|
|
setText(0, TQString("%1 (%2)").arg(m_album->title()).arg(m_count));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int countRecursive = m_count;
|
|
|
|
AlbumIterator it(m_album);
|
|
|
|
while ( it.current() )
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = (AlbumFolderViewItem*)it.current()->extraData(listView());
|
|
|
|
if (item)
|
|
|
|
countRecursive += item->count();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
setText(0, TQString("%1 (%2)").arg(m_album->title()).arg(countRecursive));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setText(0, m_album->title());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderViewItem::setOpen(bool o)
|
|
|
|
{
|
|
|
|
TQListViewItem::setOpen(o);
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
PAlbum* AlbumFolderViewItem::album() const
|
|
|
|
{
|
|
|
|
return m_album;
|
|
|
|
}
|
|
|
|
|
|
|
|
int AlbumFolderViewItem::id() const
|
|
|
|
{
|
|
|
|
if (m_groupItem)
|
|
|
|
{
|
|
|
|
if (m_year != 0 && m_month != 0)
|
|
|
|
{
|
|
|
|
return (m_year*(-100) + m_month*(-1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ( - (AlbumSettings::instance()->getAlbumCollectionNames()
|
|
|
|
.findIndex(text(0)) ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return m_album ? m_album->id() : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AlbumFolderViewItem::isGroupItem() const
|
|
|
|
{
|
|
|
|
return m_groupItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
int AlbumFolderViewItem::compare(TQListViewItem *i, int col, bool ascending) const
|
|
|
|
{
|
|
|
|
if (!m_groupItem || m_year == 0 || m_month == 0)
|
|
|
|
return TQListViewItem::compare(i, col, ascending);
|
|
|
|
|
|
|
|
AlbumFolderViewItem* thatItem = dynamic_cast<AlbumFolderViewItem*>(i);
|
|
|
|
if (!thatItem)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int myWeight = m_year*100 + m_month;
|
|
|
|
int hisWeight = thatItem->m_year*100 + thatItem->m_month;
|
|
|
|
|
|
|
|
if (myWeight == hisWeight)
|
|
|
|
return 0;
|
|
|
|
else if (myWeight > hisWeight)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderViewItem::setCount(int count)
|
|
|
|
{
|
|
|
|
m_count = count;
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
int AlbumFolderViewItem::count()
|
|
|
|
{
|
|
|
|
return m_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class AlbumFolderViewPriv
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
AlbumFolderViewPriv()
|
|
|
|
{
|
|
|
|
albumMan = 0;
|
|
|
|
iconThumbJob = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumManager *albumMan;
|
|
|
|
ThumbnailJob *iconThumbJob;
|
|
|
|
TQValueList<AlbumFolderViewItem*> groupItems;
|
|
|
|
};
|
|
|
|
|
|
|
|
AlbumFolderView::AlbumFolderView(TQWidget *parent)
|
|
|
|
: FolderView(parent, "AlbumFolderView")
|
|
|
|
{
|
|
|
|
d = new AlbumFolderViewPriv();
|
|
|
|
d->albumMan = AlbumManager::instance();
|
|
|
|
d->iconThumbJob = 0;
|
|
|
|
|
|
|
|
addColumn(i18n("My Albums"));
|
|
|
|
setResizeMode(TQListView::LastColumn);
|
|
|
|
setRootIsDecorated(false);
|
|
|
|
setAllColumnsShowFocus(true);
|
|
|
|
|
|
|
|
setAcceptDrops(true);
|
|
|
|
viewport()->setAcceptDrops(true);
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalAlbumAdded(Album*)),
|
|
|
|
this, TQT_SLOT(slotAlbumAdded(Album*)));
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalAlbumDeleted(Album*)),
|
|
|
|
this, TQT_SLOT(slotAlbumDeleted(Album*)));
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalAlbumsCleared()),
|
|
|
|
this, TQT_SLOT(slotAlbumsCleared()));
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalAlbumIconChanged(Album*)),
|
|
|
|
this, TQT_SLOT(slotAlbumIconChanged(Album*)));
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalAlbumRenamed(Album*)),
|
|
|
|
this, TQT_SLOT(slotAlbumRenamed(Album*)));
|
|
|
|
|
|
|
|
connect(d->albumMan, TQT_SIGNAL(signalPAlbumsDirty(const TQMap<int, int>&)),
|
|
|
|
this, TQT_SLOT(slotRefresh(const TQMap<int, int>&)));
|
|
|
|
|
|
|
|
AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
|
|
|
|
|
|
|
|
connect(loader, TQT_SIGNAL(signalThumbnail(Album *, const TQPixmap&)),
|
|
|
|
this, TQT_SLOT(slotGotThumbnailFromIcon(Album *, const TQPixmap&)));
|
|
|
|
|
|
|
|
connect(loader, TQT_SIGNAL(signalFailed(Album *)),
|
|
|
|
this, TQT_SLOT(slotThumbnailLost(Album *)));
|
|
|
|
|
|
|
|
connect(loader, TQT_SIGNAL(signalReloadThumbnails()),
|
|
|
|
this, TQT_SLOT(slotReloadThumbnails()));
|
|
|
|
|
|
|
|
connect(this, TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)),
|
|
|
|
this, TQT_SLOT(slotContextMenu(TQListViewItem*, const TQPoint&, int)));
|
|
|
|
|
|
|
|
connect(this, TQT_SIGNAL(selectionChanged()),
|
|
|
|
this, TQT_SLOT(slotSelectionChanged()));
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderView::~AlbumFolderView()
|
|
|
|
{
|
|
|
|
if (d->iconThumbJob)
|
|
|
|
d->iconThumbJob->kill();
|
|
|
|
|
|
|
|
saveViewState();
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotTextFolderFilterChanged(const TQString& filter)
|
|
|
|
{
|
|
|
|
if (filter.isEmpty())
|
|
|
|
{
|
|
|
|
collapseView();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString search = filter.lower();
|
|
|
|
|
|
|
|
bool atleastOneMatch = false;
|
|
|
|
|
|
|
|
AlbumList pList = d->albumMan->allPAlbums();
|
|
|
|
for (AlbumList::iterator it = pList.begin(); it != pList.end(); ++it)
|
|
|
|
{
|
|
|
|
PAlbum* palbum = (PAlbum*)(*it);
|
|
|
|
|
|
|
|
// don't touch the root Album
|
|
|
|
if (palbum->isRoot())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
bool match = palbum->title().lower().contains(search);
|
|
|
|
bool doesExpand = false;
|
|
|
|
if (!match)
|
|
|
|
{
|
|
|
|
// check if any of the parents match the search
|
|
|
|
Album* parent = palbum->parent();
|
|
|
|
while (parent && !parent->isRoot())
|
|
|
|
{
|
|
|
|
if (parent->title().lower().contains(search))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
parent = parent->parent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
{
|
|
|
|
// check if any of the children match the search
|
|
|
|
AlbumIterator it(palbum);
|
|
|
|
while (it.current())
|
|
|
|
{
|
|
|
|
if ((*it)->title().lower().contains(search))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
doesExpand = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem* viewItem = (AlbumFolderViewItem*) palbum->extraData(this);
|
|
|
|
|
|
|
|
if (match)
|
|
|
|
{
|
|
|
|
atleastOneMatch = true;
|
|
|
|
|
|
|
|
if (viewItem)
|
|
|
|
{
|
|
|
|
viewItem->setVisible(true);
|
|
|
|
viewItem->setOpen(doesExpand);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (viewItem)
|
|
|
|
{
|
|
|
|
viewItem->setVisible(false);
|
|
|
|
viewItem->setOpen(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
emit signalTextFolderFilterMatch(atleastOneMatch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotAlbumAdded(Album *album)
|
|
|
|
{
|
|
|
|
if(!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PAlbum *palbum = dynamic_cast<PAlbum*>(album);
|
|
|
|
if(!palbum)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool failed;
|
|
|
|
AlbumFolderViewItem* parent = findParent(palbum, failed);
|
|
|
|
if (failed)
|
|
|
|
{
|
|
|
|
DWarning() << k_funcinfo << " Failed to find Album parent "
|
|
|
|
<< palbum->url() << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem *item;
|
|
|
|
if (!parent)
|
|
|
|
{
|
|
|
|
// root album
|
|
|
|
item = new AlbumFolderViewItem(this, palbum);
|
|
|
|
palbum->setExtraData(this, item);
|
|
|
|
item->setOpen(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item = new AlbumFolderViewItem(parent, palbum);
|
|
|
|
palbum->setExtraData(this, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
setAlbumThumbnail(palbum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotAlbumDeleted(Album *album)
|
|
|
|
{
|
|
|
|
if(!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PAlbum* palbum = dynamic_cast<PAlbum*>(album);
|
|
|
|
if(!palbum)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(!palbum->icon().isEmpty() && d->iconThumbJob)
|
|
|
|
d->iconThumbJob->removeItem(palbum->icon());
|
|
|
|
|
|
|
|
AlbumFolderViewItem* item = (AlbumFolderViewItem*) palbum->extraData(this);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *itemParent = dynamic_cast<AlbumFolderViewItem*>(item->parent());
|
|
|
|
|
|
|
|
if(itemParent)
|
|
|
|
itemParent->takeItem(item);
|
|
|
|
else
|
|
|
|
takeItem(item);
|
|
|
|
|
|
|
|
delete item;
|
|
|
|
clearEmptyGroupItems();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotAlbumRenamed(Album *album)
|
|
|
|
{
|
|
|
|
PAlbum* palbum = dynamic_cast<PAlbum*>(album);
|
|
|
|
if(!palbum)
|
|
|
|
return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem* item = (AlbumFolderViewItem*) palbum->extraData(this);
|
|
|
|
if(item)
|
|
|
|
item->refresh();
|
|
|
|
if (item->parent())
|
|
|
|
item->parent()->sort();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotAlbumsCleared()
|
|
|
|
{
|
|
|
|
d->groupItems.clear();
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::setAlbumThumbnail(PAlbum *album)
|
|
|
|
{
|
|
|
|
if(!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem* item = (AlbumFolderViewItem*) album->extraData(this);
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Either, getThumbnail returns true and loads an icon asynchronously.
|
|
|
|
// Then, for the time being, we set the standard icon.
|
|
|
|
// Or, no icon is associated with the album, then we set the standard icon anyway.
|
|
|
|
AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();
|
|
|
|
item->setPixmap(0, loader->getStandardAlbumIcon(album));
|
|
|
|
loader->getAlbumThumbnail(album);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::setCurrentAlbum(Album *album)
|
|
|
|
{
|
|
|
|
if(!album) return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem* item = (AlbumFolderViewItem*) album->extraData(this);
|
|
|
|
if(!item) return;
|
|
|
|
|
|
|
|
setCurrentItem(item);
|
|
|
|
ensureItemVisible(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotGotThumbnailFromIcon(Album *album,
|
|
|
|
const TQPixmap& thumbnail)
|
|
|
|
{
|
|
|
|
if(!album || album->type() != Album::PHYSICAL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem* item = (AlbumFolderViewItem*)album->extraData(this);
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
item->setPixmap(0, thumbnail);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotThumbnailLost(Album *)
|
|
|
|
{
|
|
|
|
// we already set the standard icon before loading
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotReloadThumbnails()
|
|
|
|
{
|
|
|
|
AlbumList tList = d->albumMan->allPAlbums();
|
|
|
|
for (AlbumList::iterator it = tList.begin(); it != tList.end(); ++it)
|
|
|
|
{
|
|
|
|
PAlbum* album = (PAlbum*)(*it);
|
|
|
|
setAlbumThumbnail(album);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotAlbumIconChanged(Album* album)
|
|
|
|
{
|
|
|
|
if(!album || album->type() != Album::PHYSICAL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
setAlbumThumbnail((PAlbum*)album);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotSelectionChanged()
|
|
|
|
{
|
|
|
|
if (!active())
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQListViewItem* selItem = 0;
|
|
|
|
TQListViewItemIterator it(this);
|
|
|
|
while(it.current())
|
|
|
|
{
|
|
|
|
if(it.current()->isSelected())
|
|
|
|
{
|
|
|
|
selItem = it.current();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!selItem)
|
|
|
|
{
|
|
|
|
d->albumMan->setCurrentAlbum(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem *albumitem = dynamic_cast<AlbumFolderViewItem*>(selItem);
|
|
|
|
if(!albumitem)
|
|
|
|
{
|
|
|
|
d->albumMan->setCurrentAlbum(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->albumMan->setCurrentAlbum(albumitem->album());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotContextMenu(TQListViewItem *listitem, const TQPoint &, int)
|
|
|
|
{
|
|
|
|
TDEActionMenu menuImport(i18n("Import"));
|
|
|
|
TDEActionMenu menuExport(i18n("Export"));
|
|
|
|
TDEActionMenu menuKIPIBatch(i18n("Batch Process"));
|
|
|
|
|
|
|
|
TDEPopupMenu popmenu(this);
|
|
|
|
popmenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popmenu.insertItem(SmallIcon("albumfolder-new"), i18n("New Album..."), 10);
|
|
|
|
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(listitem);
|
|
|
|
if (item && !item->album())
|
|
|
|
{
|
|
|
|
// if collection/date return
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Root folder only shows "New Album..."
|
|
|
|
if(item && item->parent())
|
|
|
|
{
|
|
|
|
popmenu.insertItem(SmallIcon("pencil"), i18n("Rename..."), 14);
|
|
|
|
popmenu.insertItem(SmallIcon("albumfolder-properties"), i18n("Album Properties..."), 11);
|
|
|
|
popmenu.insertItem(SmallIcon("reload_page"), i18n("Reset Album Icon"), 13);
|
|
|
|
popmenu.insertSeparator();
|
|
|
|
|
|
|
|
// Add KIPI Albums plugins Actions
|
|
|
|
TDEAction *action;
|
|
|
|
const TQPtrList<TDEAction>& albumActions = DigikamApp::getinstance()->menuAlbumActions();
|
|
|
|
if(!albumActions.isEmpty())
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TDEAction> it(albumActions);
|
|
|
|
while((action = it.current()))
|
|
|
|
{
|
|
|
|
action->plug(&popmenu);
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add All Import Actions
|
|
|
|
const TQPtrList<TDEAction> importActions = DigikamApp::getinstance()->menuImportActions();
|
|
|
|
if(!importActions.isEmpty())
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TDEAction> it3(importActions);
|
|
|
|
while((action = it3.current()))
|
|
|
|
{
|
|
|
|
menuImport.insert(action);
|
|
|
|
++it3;
|
|
|
|
}
|
|
|
|
menuImport.plug(&popmenu);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add All Export Actions
|
|
|
|
const TQPtrList<TDEAction> exportActions = DigikamApp::getinstance()->menuExportActions();
|
|
|
|
if(!exportActions.isEmpty())
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TDEAction> it4(exportActions);
|
|
|
|
while((action = it4.current()))
|
|
|
|
{
|
|
|
|
menuExport.insert(action);
|
|
|
|
++it4;
|
|
|
|
}
|
|
|
|
menuExport.plug(&popmenu);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add KIPI Batch processes plugins Actions
|
|
|
|
const TQPtrList<TDEAction>& batchActions = DigikamApp::getinstance()->menuBatchActions();
|
|
|
|
if(!batchActions.isEmpty())
|
|
|
|
{
|
|
|
|
TQPtrListIterator<TDEAction> it2(batchActions);
|
|
|
|
while((action = it2.current()))
|
|
|
|
{
|
|
|
|
menuKIPIBatch.insert(action);
|
|
|
|
++it2;
|
|
|
|
}
|
|
|
|
menuKIPIBatch.plug(&popmenu);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!albumActions.isEmpty() || !batchActions.isEmpty() ||
|
|
|
|
!importActions.isEmpty())
|
|
|
|
{
|
|
|
|
popmenu.insertSeparator(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(AlbumSettings::instance()->getUseTrash())
|
|
|
|
{
|
|
|
|
popmenu.insertItem(SmallIcon("edittrash"),
|
|
|
|
i18n("Move Album to Trash"), 12);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
popmenu.insertItem(SmallIcon("editdelete"),
|
|
|
|
i18n("Delete Album"), 12);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(popmenu.exec((TQCursor::pos())))
|
|
|
|
{
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
albumNew(item);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
albumEdit(item);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
albumDelete(item);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 13:
|
|
|
|
{
|
|
|
|
TQString err;
|
|
|
|
d->albumMan->updatePAlbumIcon(item->album(), 0, err);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 14:
|
|
|
|
{
|
|
|
|
albumRename(item);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumNew()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
item = dynamic_cast<AlbumFolderViewItem*>(firstChild());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
albumNew(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumNew(AlbumFolderViewItem *item)
|
|
|
|
{
|
|
|
|
AlbumSettings* settings = AlbumSettings::instance();
|
|
|
|
if(!settings)
|
|
|
|
{
|
|
|
|
DWarning() << "AlbumFolderView: Couldn't get Album Settings" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDir libraryDir(settings->getAlbumLibraryPath());
|
|
|
|
if(!libraryDir.exists())
|
|
|
|
{
|
|
|
|
KMessageBox::error(0,
|
|
|
|
i18n("The album library has not been set correctly.\n"
|
|
|
|
"Select \"Configure Digikam\" from the Settings "
|
|
|
|
"menu and choose a folder to use for the album "
|
|
|
|
"library."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PAlbum *parent;
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
parent = d->albumMan->findPAlbum(0);
|
|
|
|
else
|
|
|
|
parent = item->album();
|
|
|
|
|
|
|
|
if (!parent)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString title;
|
|
|
|
TQString comments;
|
|
|
|
TQString collection;
|
|
|
|
TQDate date;
|
|
|
|
TQStringList albumCollections;
|
|
|
|
|
|
|
|
if(!AlbumPropsEdit::createNew(parent, title, comments, date, collection,
|
|
|
|
albumCollections))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQStringList oldAlbumCollections(AlbumSettings::instance()->getAlbumCollectionNames());
|
|
|
|
if(albumCollections != oldAlbumCollections)
|
|
|
|
{
|
|
|
|
AlbumSettings::instance()->setAlbumCollectionNames(albumCollections);
|
|
|
|
resort();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString errMsg;
|
|
|
|
PAlbum* album = d->albumMan->createPAlbum(parent, title, comments,
|
|
|
|
date, collection, errMsg);
|
|
|
|
if (!album)
|
|
|
|
{
|
|
|
|
KMessageBox::error(0, errMsg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// by this time the signalAlbumAdded has been fired and the appropriate
|
|
|
|
// AlbumFolderViewItem has been created. Now make this folderviewitem visible
|
|
|
|
AlbumFolderViewItem* newItem = (AlbumFolderViewItem*)album->extraData(this);
|
|
|
|
if (newItem)
|
|
|
|
{
|
|
|
|
if(item)
|
|
|
|
item->setOpen(true);
|
|
|
|
|
|
|
|
ensureItemVisible(newItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumDelete()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
albumDelete(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumDelete(AlbumFolderViewItem *item)
|
|
|
|
{
|
|
|
|
PAlbum *album = item->album();
|
|
|
|
|
|
|
|
if(!album || album->isRoot())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// find subalbums
|
|
|
|
KURL::List childrenList;
|
|
|
|
addAlbumChildrenToList(childrenList, album);
|
|
|
|
|
|
|
|
DeleteDialog dialog(this);
|
|
|
|
|
|
|
|
// All subalbums will be presented in the list as well
|
|
|
|
if (!dialog.confirmDeleteList(childrenList,
|
|
|
|
childrenList.size() == 1 ?
|
|
|
|
DeleteDialogMode::Albums : DeleteDialogMode::Subalbums,
|
|
|
|
DeleteDialogMode::UserPreference))
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool useTrash = !dialog.shouldDelete();
|
|
|
|
|
|
|
|
// Currently trash tdeioslave can handle only full paths.
|
|
|
|
// pass full folder path to the trashing job
|
|
|
|
KURL u;
|
|
|
|
u.setProtocol("file");
|
|
|
|
u.setPath(album->folderPath());
|
|
|
|
TDEIO::Job* job = DIO::del(u, useTrash);
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job *)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::addAlbumChildrenToList(KURL::List &list, Album *album)
|
|
|
|
{
|
|
|
|
// simple recursive helper function
|
|
|
|
if (album)
|
|
|
|
{
|
|
|
|
list.append(album->kurl());
|
|
|
|
AlbumIterator it(album);
|
|
|
|
while(it.current())
|
|
|
|
{
|
|
|
|
addAlbumChildrenToList(list, *it);
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotDIOResult(TDEIO::Job* job)
|
|
|
|
{
|
|
|
|
if (job->error())
|
|
|
|
job->showErrorDialog(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumRename()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
albumRename(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumRename(AlbumFolderViewItem* item)
|
|
|
|
{
|
|
|
|
PAlbum *album = item->album();
|
|
|
|
|
|
|
|
if (!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString oldTitle(album->title());
|
|
|
|
bool ok;
|
|
|
|
|
|
|
|
#if KDE_IS_VERSION(3,2,0)
|
|
|
|
TQString title = KInputDialog::getText(i18n("Rename Album (%1)").arg(oldTitle),
|
|
|
|
i18n("Enter new album name:"),
|
|
|
|
oldTitle, &ok, this);
|
|
|
|
#else
|
|
|
|
TQString title = KLineEditDlg::getText(i18n("Rename Item (%1)").arg(oldTitle),
|
|
|
|
i18n("Enter new album name:"),
|
|
|
|
oldTitle, &ok, this);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(title != oldTitle)
|
|
|
|
{
|
|
|
|
TQString errMsg;
|
|
|
|
if (!d->albumMan->renamePAlbum(album, title, errMsg))
|
|
|
|
KMessageBox::error(0, errMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit signalAlbumModified();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumEdit()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
albumEdit(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumEdit(AlbumFolderViewItem* item)
|
|
|
|
{
|
|
|
|
PAlbum *album = item->album();
|
|
|
|
|
|
|
|
if (!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString oldTitle(album->title());
|
|
|
|
TQString oldComments(album->caption());
|
|
|
|
TQString oldCollection(album->collection());
|
|
|
|
TQDate oldDate(album->date());
|
|
|
|
TQStringList oldAlbumCollections(AlbumSettings::instance()->getAlbumCollectionNames());
|
|
|
|
|
|
|
|
TQString title, comments, collection;
|
|
|
|
TQDate date;
|
|
|
|
TQStringList albumCollections;
|
|
|
|
|
|
|
|
if(AlbumPropsEdit::editProps(album, title, comments, date,
|
|
|
|
collection, albumCollections))
|
|
|
|
{
|
|
|
|
if(comments != oldComments)
|
|
|
|
album->setCaption(comments);
|
|
|
|
|
|
|
|
if(date != oldDate && date.isValid())
|
|
|
|
album->setDate(date);
|
|
|
|
|
|
|
|
if(collection != oldCollection)
|
|
|
|
album->setCollection(collection);
|
|
|
|
|
|
|
|
AlbumSettings::instance()->setAlbumCollectionNames(albumCollections);
|
|
|
|
resort();
|
|
|
|
|
|
|
|
// Do this last : so that if anything else changed we can
|
|
|
|
// successfuly save to the db with the old name
|
|
|
|
|
|
|
|
if(title != oldTitle)
|
|
|
|
{
|
|
|
|
TQString errMsg;
|
|
|
|
if (!d->albumMan->renamePAlbum(album, title, errMsg))
|
|
|
|
KMessageBox::error(0, errMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit signalAlbumModified();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDragObject* AlbumFolderView::dragObject()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *item = dynamic_cast<AlbumFolderViewItem*>(dragItem());
|
|
|
|
if(!item)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
PAlbum *album = item->album();
|
|
|
|
if(album->isRoot())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
AlbumDrag *a = new AlbumDrag(album->kurl(), album->id(), this);
|
|
|
|
if(!a)
|
|
|
|
return 0;
|
|
|
|
a->setPixmap(*item->pixmap(0));
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AlbumFolderView::acceptDrop(const TQDropEvent *e) const
|
|
|
|
{
|
|
|
|
TQPoint vp = contentsToViewport(e->pos());
|
|
|
|
AlbumFolderViewItem *itemDrop = dynamic_cast<AlbumFolderViewItem*>(itemAt(vp));
|
|
|
|
AlbumFolderViewItem *itemDrag = dynamic_cast<AlbumFolderViewItem*>(dragItem());
|
|
|
|
|
|
|
|
if(AlbumDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
switch(AlbumSettings::instance()->getAlbumSortOrder())
|
|
|
|
{
|
|
|
|
case(AlbumSettings::ByFolder):
|
|
|
|
{
|
|
|
|
// Allow dragging at the root, to move the album at the root
|
|
|
|
if(!itemDrop)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Dragging an item on itself makes no sense
|
|
|
|
if(itemDrag == itemDrop)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Dragging a parent on its child makes no sense
|
|
|
|
if(itemDrag && itemDrag->album()->isAncestorOf(itemDrop->album()))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case (AlbumSettings::ByCollection):
|
|
|
|
{
|
|
|
|
if (!itemDrop)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Only allow dragging onto Collection
|
|
|
|
if (itemDrop->isGroupItem())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(itemDrop && !itemDrop->parent())
|
|
|
|
{
|
|
|
|
// Do not allow drop images on album root
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemDrop && itemDrop->isGroupItem())
|
|
|
|
{
|
|
|
|
// do not allow drop on a group item
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ItemDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CameraItemListDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(TQUriDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::contentsDropEvent(TQDropEvent *e)
|
|
|
|
{
|
|
|
|
FolderView::contentsDropEvent(e);
|
|
|
|
|
|
|
|
if(!acceptDrop(e))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQPoint vp = contentsToViewport(e->pos());
|
|
|
|
AlbumFolderViewItem *itemDrop = dynamic_cast<AlbumFolderViewItem*>(itemAt(vp));
|
|
|
|
|
|
|
|
if(AlbumDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *itemDrag = dynamic_cast<AlbumFolderViewItem*>(dragItem());
|
|
|
|
if(!itemDrag)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (AlbumSettings::instance()->getAlbumSortOrder()
|
|
|
|
== AlbumSettings::ByFolder)
|
|
|
|
{
|
|
|
|
// TODO: Copy?
|
|
|
|
TDEPopupMenu popMenu(this);
|
|
|
|
popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popMenu.insertItem(SmallIcon("goto"), i18n("&Move Here"), 10);
|
|
|
|
popMenu.insertSeparator(-1);
|
|
|
|
popMenu.insertItem(SmallIcon("cancel"), i18n("C&ancel"), 20);
|
|
|
|
popMenu.setMouseTracking(true);
|
|
|
|
int id = popMenu.exec(TQCursor::pos());
|
|
|
|
|
|
|
|
if(id == 10)
|
|
|
|
{
|
|
|
|
PAlbum *album = itemDrag->album();
|
|
|
|
PAlbum *destAlbum;
|
|
|
|
if(!itemDrop)
|
|
|
|
{
|
|
|
|
// move dragItem to the root
|
|
|
|
destAlbum = d->albumMan->findPAlbum(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// move dragItem below dropItem
|
|
|
|
destAlbum = itemDrop->album();
|
|
|
|
}
|
|
|
|
TDEIO::Job* job = DIO::move(album->kurl(), destAlbum->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (AlbumSettings::instance()->getAlbumSortOrder()
|
|
|
|
== AlbumSettings::ByCollection)
|
|
|
|
{
|
|
|
|
if (!itemDrop)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (itemDrop->isGroupItem())
|
|
|
|
{
|
|
|
|
PAlbum *album = itemDrag->album();
|
|
|
|
if (!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
album->setCollection(itemDrop->text(0));
|
|
|
|
resort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ItemDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
if (!itemDrop)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PAlbum *destAlbum = itemDrop->album();
|
|
|
|
|
|
|
|
KURL::List urls;
|
|
|
|
KURL::List kioURLs;
|
|
|
|
TQValueList<int> albumIDs;
|
|
|
|
TQValueList<int> imageIDs;
|
|
|
|
|
|
|
|
if (!ItemDrag::decode(e, urls, kioURLs, albumIDs, imageIDs))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Check if items dropped come from outside current album.
|
|
|
|
// This can be the case with reccursive content album mode.
|
|
|
|
KURL::List extUrls;
|
|
|
|
ImageInfoList extImgInfList;
|
|
|
|
for (TQValueList<int>::iterator it = imageIDs.begin(); it != imageIDs.end(); ++it)
|
|
|
|
{
|
|
|
|
ImageInfo *info = new ImageInfo(*it);
|
|
|
|
if (info->albumID() != destAlbum->id())
|
|
|
|
{
|
|
|
|
extUrls.append(info->kurlForKIO());
|
|
|
|
extImgInfList.append(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int id = 0;
|
|
|
|
char keys_return[32];
|
|
|
|
XQueryKeymap(x11Display(), keys_return);
|
|
|
|
int key_1 = XKeysymToKeycode(x11Display(), 0xFFE3);
|
|
|
|
int key_2 = XKeysymToKeycode(x11Display(), 0xFFE4);
|
|
|
|
int key_3 = XKeysymToKeycode(x11Display(), 0xFFE1);
|
|
|
|
int key_4 = XKeysymToKeycode(x11Display(), 0xFFE2);
|
|
|
|
|
|
|
|
if(extUrls.isEmpty())
|
|
|
|
{
|
|
|
|
// Setting the dropped image as the album thumbnail
|
|
|
|
// If the ctrl key is pressed, when dropping the image, the
|
|
|
|
// thumbnail is set without a popup menu
|
|
|
|
if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
|
|
|
|
((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
|
|
|
|
{
|
|
|
|
id = 12;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TDEPopupMenu popMenu(this);
|
|
|
|
popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popMenu.insertItem(i18n("Set as Album Thumbnail"), 12);
|
|
|
|
popMenu.insertSeparator(-1);
|
|
|
|
popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
|
|
|
|
popMenu.setMouseTracking(true);
|
|
|
|
id = popMenu.exec(TQCursor::pos());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(id == 12)
|
|
|
|
{
|
|
|
|
TQString errMsg;
|
|
|
|
d->albumMan->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If shift key is pressed while dragging, move the drag object without
|
|
|
|
// displaying popup menu -> move
|
|
|
|
if (((keys_return[key_3 / 8]) && (1 << (key_3 % 8))) ||
|
|
|
|
((keys_return[key_4 / 8]) && (1 << (key_4 % 8))))
|
|
|
|
{
|
|
|
|
id = 10;
|
|
|
|
}
|
|
|
|
// If ctrl key is pressed while dragging, copy the drag object without
|
|
|
|
// displaying popup menu -> copy
|
|
|
|
else if (((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
|
|
|
|
((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
|
|
|
|
{
|
|
|
|
id = 11;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TDEPopupMenu popMenu(this);
|
|
|
|
popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popMenu.insertItem( SmallIcon("goto"), i18n("&Move Here"), 10 );
|
|
|
|
popMenu.insertItem( SmallIcon("editcopy"), i18n("&Copy Here"), 11 );
|
|
|
|
if (imageIDs.count() == 1)
|
|
|
|
popMenu.insertItem(i18n("Set as Album Thumbnail"), 12);
|
|
|
|
popMenu.insertSeparator(-1);
|
|
|
|
popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
|
|
|
|
popMenu.setMouseTracking(true);
|
|
|
|
id = popMenu.exec(TQCursor::pos());
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(id)
|
|
|
|
{
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
TDEIO::Job* job = DIO::move(extUrls, destAlbum->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
|
|
|
|
|
|
|
|
// In recurssive album contents mode, we need to force AlbumLister to take a care about
|
|
|
|
// moved items. This will have no incidence in normal mode.
|
|
|
|
ImageInfo* item;
|
|
|
|
for (ImageInfoListIterator it(extImgInfList); (item = it.current()) ; ++it)
|
|
|
|
{
|
|
|
|
AlbumLister::instance()->invalidateItem(item);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
TDEIO::Job* job = DIO::copy(extUrls, destAlbum->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
TQString errMsg;
|
|
|
|
d->albumMan->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- DnD from Camera GUI ------------------------------------------------
|
|
|
|
|
|
|
|
if(CameraItemListDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
Album *album = dynamic_cast<Album*>(itemDrop->album());
|
|
|
|
if (!album) return;
|
|
|
|
|
|
|
|
CameraUI *ui = dynamic_cast<CameraUI*>(e->source());
|
|
|
|
if (ui)
|
|
|
|
{
|
|
|
|
TDEPopupMenu popMenu(this);
|
|
|
|
popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popMenu.insertItem(SmallIcon("down"), i18n("Download from camera"), 10);
|
|
|
|
popMenu.insertItem(SmallIcon("down"), i18n("Download && Delete from camera"), 11);
|
|
|
|
popMenu.insertSeparator(-1);
|
|
|
|
popMenu.insertItem(SmallIcon("cancel"), i18n("&Cancel"));
|
|
|
|
popMenu.setMouseTracking(true);
|
|
|
|
int id = popMenu.exec(TQCursor::pos());
|
|
|
|
switch(id)
|
|
|
|
{
|
|
|
|
case 10: // Download from camera
|
|
|
|
{
|
|
|
|
ui->slotDownload(true, false, album);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 11: // Download and Delete from camera
|
|
|
|
{
|
|
|
|
ui->slotDownload(true, true, album);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- DnD from an external source ----------------------------------------
|
|
|
|
|
|
|
|
if(TQUriDrag::canDecode(e))
|
|
|
|
{
|
|
|
|
PAlbum* destAlbum = 0;
|
|
|
|
|
|
|
|
if (itemDrop)
|
|
|
|
destAlbum = itemDrop->album();
|
|
|
|
else
|
|
|
|
destAlbum = d->albumMan->findPAlbum(0);
|
|
|
|
|
|
|
|
// B.K.O #119205: do not handle root album.
|
|
|
|
if (destAlbum->isRoot())
|
|
|
|
return;
|
|
|
|
|
|
|
|
KURL destURL(destAlbum->kurl());
|
|
|
|
|
|
|
|
KURL::List srcURLs;
|
|
|
|
KURLDrag::decode(e, srcURLs);
|
|
|
|
|
|
|
|
char keys_return[32];
|
|
|
|
XQueryKeymap(x11Display(), keys_return);
|
|
|
|
int id = 0;
|
|
|
|
|
|
|
|
int key_1 = XKeysymToKeycode(x11Display(), 0xFFE3);
|
|
|
|
int key_2 = XKeysymToKeycode(x11Display(), 0xFFE4);
|
|
|
|
int key_3 = XKeysymToKeycode(x11Display(), 0xFFE1);
|
|
|
|
int key_4 = XKeysymToKeycode(x11Display(), 0xFFE2);
|
|
|
|
// If shift key is pressed while dropping, move the drag object without
|
|
|
|
// displaying popup menu -> move
|
|
|
|
if(((keys_return[key_3 / 8]) && (1 << (key_3 % 8))) ||
|
|
|
|
((keys_return[key_4 / 8]) && (1 << (key_4 % 8))))
|
|
|
|
{
|
|
|
|
id = 10;
|
|
|
|
}
|
|
|
|
// If ctrl key is pressed while dropping, copy the drag object without
|
|
|
|
// displaying popup menu -> copy
|
|
|
|
else if(((keys_return[key_1 / 8]) && (1 << (key_1 % 8))) ||
|
|
|
|
((keys_return[key_2 / 8]) && (1 << (key_2 % 8))))
|
|
|
|
{
|
|
|
|
id = 11;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TDEPopupMenu popMenu(this);
|
|
|
|
popMenu.insertTitle(SmallIcon("digikam"), i18n("My Albums"));
|
|
|
|
popMenu.insertItem( SmallIcon("goto"), i18n("&Move Here"), 10 );
|
|
|
|
popMenu.insertItem( SmallIcon("editcopy"), i18n("&Copy Here"), 11 );
|
|
|
|
popMenu.insertSeparator(-1);
|
|
|
|
popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
|
|
|
|
popMenu.setMouseTracking(true);
|
|
|
|
id = popMenu.exec(TQCursor::pos());
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(id)
|
|
|
|
{
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
TDEIO::Job* job = DIO::move(srcURLs, destAlbum->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
TDEIO::Job* job = DIO::copy(srcURLs, destAlbum->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job*)));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::albumImportFolder()
|
|
|
|
{
|
|
|
|
AlbumSettings* settings = AlbumSettings::instance();
|
|
|
|
TQDir libraryDir(settings->getAlbumLibraryPath());
|
|
|
|
if(!libraryDir.exists())
|
|
|
|
{
|
|
|
|
KMessageBox::error(0,
|
|
|
|
i18n("The album library has not been set correctly.\n"
|
|
|
|
"Select \"Configure digiKam\" from the Settings "
|
|
|
|
"menu and choose a folder to use for the album "
|
|
|
|
"library."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PAlbum* parent = 0;
|
|
|
|
if(selectedItem())
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem *folderItem = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
Album *album = folderItem->album();
|
|
|
|
if (album && album->type() == Album::PHYSICAL)
|
|
|
|
{
|
|
|
|
parent = dynamic_cast<PAlbum*>(album);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!parent)
|
|
|
|
parent = dynamic_cast<PAlbum*>(d->albumMan->findPAlbum(0));
|
|
|
|
|
|
|
|
TQString libraryPath = parent->folderPath();
|
|
|
|
|
|
|
|
KFileDialog dlg(TQString(), "inode/directory", this, "importFolder", true);
|
|
|
|
dlg.setCaption(i18n("Select folders to import"));
|
|
|
|
dlg.setMode(KFile::Directory | KFile::Files);
|
|
|
|
if(dlg.exec() != TQDialog::Accepted)
|
|
|
|
return;
|
|
|
|
|
|
|
|
KURL::List urls = dlg.selectedURLs();
|
|
|
|
if(urls.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
TDEIO::Job* job = DIO::copy(urls, parent->kurl());
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
|
|
|
|
this, TQT_SLOT(slotDIOResult(TDEIO::Job *)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::selectItem(int id)
|
|
|
|
{
|
|
|
|
PAlbum* album = d->albumMan->findPAlbum(id);
|
|
|
|
if(!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem *item = (AlbumFolderViewItem*)album->extraData(this);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
setSelected(item, true);
|
|
|
|
ensureItemVisible(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem* AlbumFolderView::findParent(PAlbum* album, bool& failed)
|
|
|
|
{
|
|
|
|
if (album->isRoot())
|
|
|
|
{
|
|
|
|
failed = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(AlbumSettings::instance()->getAlbumSortOrder())
|
|
|
|
{
|
|
|
|
case(AlbumSettings::ByFolder):
|
|
|
|
{
|
|
|
|
return findParentByFolder(album, failed);
|
|
|
|
}
|
|
|
|
case(AlbumSettings::ByCollection):
|
|
|
|
{
|
|
|
|
return findParentByCollection(album, failed);
|
|
|
|
}
|
|
|
|
case(AlbumSettings::ByDate):
|
|
|
|
{
|
|
|
|
return findParentByDate(album, failed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
failed = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem* AlbumFolderView::findParentByFolder(PAlbum* album, bool& failed)
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* parent =
|
|
|
|
(AlbumFolderViewItem*) album->parent()->extraData(this);
|
|
|
|
if (!parent)
|
|
|
|
{
|
|
|
|
failed = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
failed = false;
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem* AlbumFolderView::findParentByCollection(PAlbum* album, bool& failed)
|
|
|
|
{
|
|
|
|
TQStringList collectionList = AlbumSettings::instance()->getAlbumCollectionNames();
|
|
|
|
TQString collection = album->collection();
|
|
|
|
|
|
|
|
if (collection.isEmpty() || !collectionList.contains(collection))
|
|
|
|
collection = i18n("Uncategorized Albums");
|
|
|
|
|
|
|
|
AlbumFolderViewItem* parent = 0;
|
|
|
|
|
|
|
|
for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
|
|
|
|
it != d->groupItems.end(); ++it)
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* groupItem = *it;
|
|
|
|
if (groupItem->text(0) == collection)
|
|
|
|
{
|
|
|
|
parent = groupItem;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Need to create a new parent item
|
|
|
|
if (!parent)
|
|
|
|
{
|
|
|
|
parent = new AlbumFolderViewItem(firstChild(), collection, 0, 0);
|
|
|
|
d->groupItems.append(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
failed = false;
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumFolderViewItem* AlbumFolderView::findParentByDate(PAlbum* album, bool& failed)
|
|
|
|
{
|
|
|
|
TQDate date = album->date();
|
|
|
|
|
|
|
|
TQString timeString = TQString::number(date.year()) + ", " +
|
|
|
|
TDEGlobal::locale()->calendar()->monthName(date, false);
|
|
|
|
|
|
|
|
AlbumFolderViewItem* parent = 0;
|
|
|
|
|
|
|
|
for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
|
|
|
|
it != d->groupItems.end(); ++it)
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* groupItem = *it;
|
|
|
|
if (groupItem->text(0) == timeString)
|
|
|
|
{
|
|
|
|
parent = groupItem;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Need to create a new parent item
|
|
|
|
if (!parent)
|
|
|
|
{
|
|
|
|
parent = new AlbumFolderViewItem(firstChild(), timeString,
|
|
|
|
date.year(), date.month());
|
|
|
|
d->groupItems.append(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
failed = false;
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::resort()
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* prevSelectedItem = dynamic_cast<AlbumFolderViewItem*>(selectedItem());
|
|
|
|
if (prevSelectedItem && prevSelectedItem->isGroupItem())
|
|
|
|
prevSelectedItem = 0;
|
|
|
|
|
|
|
|
AlbumList pList(d->albumMan->allPAlbums());
|
|
|
|
for (AlbumList::iterator it = pList.begin(); it != pList.end(); ++it)
|
|
|
|
{
|
|
|
|
PAlbum *album = (PAlbum*)(*it);
|
|
|
|
if (!album->isRoot() && album->extraData(this))
|
|
|
|
{
|
|
|
|
reparentItem(static_cast<AlbumFolderViewItem*>(album->extraData(this)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear any groupitems which have been left empty
|
|
|
|
clearEmptyGroupItems();
|
|
|
|
|
|
|
|
if (prevSelectedItem)
|
|
|
|
{
|
|
|
|
ensureItemVisible(prevSelectedItem);
|
|
|
|
setSelected(prevSelectedItem, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::reparentItem(AlbumFolderViewItem* folderItem)
|
|
|
|
{
|
|
|
|
if (!folderItem)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PAlbum* album = folderItem->album();
|
|
|
|
if (!album || album->isRoot())
|
|
|
|
return;
|
|
|
|
|
|
|
|
AlbumFolderViewItem* oldParent = dynamic_cast<AlbumFolderViewItem*>(folderItem->parent());
|
|
|
|
|
|
|
|
bool failed;
|
|
|
|
AlbumFolderViewItem* newParent = findParent(album, failed);
|
|
|
|
if (failed)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (oldParent == newParent)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (oldParent)
|
|
|
|
oldParent->removeItem(folderItem);
|
|
|
|
else
|
|
|
|
removeItem(folderItem);
|
|
|
|
|
|
|
|
// insert into new parent
|
|
|
|
if (newParent)
|
|
|
|
newParent->insertItem(folderItem);
|
|
|
|
else
|
|
|
|
insertItem(folderItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::clearEmptyGroupItems()
|
|
|
|
{
|
|
|
|
TQValueList<AlbumFolderViewItem*> deleteItems;
|
|
|
|
|
|
|
|
for (TQValueList<AlbumFolderViewItem*>::iterator it=d->groupItems.begin();
|
|
|
|
it != d->groupItems.end(); ++it)
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* groupItem = *it;
|
|
|
|
|
|
|
|
if (!groupItem->firstChild())
|
|
|
|
{
|
|
|
|
deleteItems.append(groupItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (TQValueList<AlbumFolderViewItem*>::iterator it=deleteItems.begin();
|
|
|
|
it != deleteItems.end(); ++it)
|
|
|
|
{
|
|
|
|
d->groupItems.remove(*it);
|
|
|
|
delete *it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::refresh()
|
|
|
|
{
|
|
|
|
TQListViewItemIterator it(this);
|
|
|
|
|
|
|
|
while (it.current())
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* item = dynamic_cast<AlbumFolderViewItem*>(*it);
|
|
|
|
if (item)
|
|
|
|
item->refresh();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumFolderView::slotRefresh(const TQMap<int, int>& albumsStatMap)
|
|
|
|
{
|
|
|
|
TQListViewItemIterator it(this);
|
|
|
|
|
|
|
|
while (it.current())
|
|
|
|
{
|
|
|
|
AlbumFolderViewItem* item = dynamic_cast<AlbumFolderViewItem*>(*it);
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
if (item->album())
|
|
|
|
{
|
|
|
|
int id = item->id();
|
|
|
|
TQMap<int, int>::const_iterator it2 = albumsStatMap.find(id);
|
|
|
|
if ( it2 != albumsStatMap.end() )
|
|
|
|
item->setCount(it2.data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Digikam
|