• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

digikam

albumdragdrop.cpp

Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of digiKam project
00004  * http://www.digikam.org
00005  *
00006  * Date        : 2009-04-16
00007  * Description : Qt Model for Albums - drag and drop handling
00008  *
00009  * Copyright (C) 2005-2006 by Joern Ahrens <joern.ahrens@kdemail.net>
00010  * Copyright (C) 2006-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
00011  * Copyright (C) 2009 by Andi Clemens <andi dot clemens at gmx dot net>
00012  * Copyright (C) 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
00013  *
00014  * This program is free software; you can redistribute it
00015  * and/or modify it under the terms of the GNU General
00016  * Public License as published by the Free Software Foundation;
00017  * either version 2, or (at your option)
00018  * any later version.
00019  *
00020  * This program is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * ============================================================ */
00026 
00027 #include "albumdragdrop.moc"
00028 
00029 // Qt includes
00030 
00031 #include <QDropEvent>
00032 
00033 // KDE includes
00034 
00035 #include <kiconloader.h>
00036 #include <kio/job.h>
00037 #include <klocale.h>
00038 #include <kmenu.h>
00039 #include <kdebug.h>
00040 
00041 // Local includes
00042 
00043 #include "albummanager.h"
00044 #include "cameraui.h"
00045 #include "ddragobjects.h"
00046 #include "dio.h"
00047 #include "imageinfo.h"
00048 #include "imageinfolist.h"
00049 
00050 namespace Digikam
00051 {
00052 
00053 AlbumDragDropHandler::AlbumDragDropHandler(AlbumModel *model)
00054                     : AlbumModelDragDropHandler(model)
00055 {
00056 }
00057 
00058 bool AlbumDragDropHandler::dropEvent(QAbstractItemView *view, QDropEvent *e, const QModelIndex& droppedOn)
00059 {
00060     if(accepts(e->mimeData(), droppedOn) == Qt::IgnoreAction)
00061         return false;
00062 
00063     PAlbum *destAlbum = model()->albumForIndex(droppedOn);
00064 
00065     if (DAlbumDrag::canDecode(e->mimeData()))
00066     {
00067         KUrl::List urls;
00068         int albumId;
00069         if (!DAlbumDrag::decode(e->mimeData(), urls, albumId))
00070             return false;
00071 
00072         PAlbum *droppedAlbum = AlbumManager::instance()->findPAlbum(albumId);
00073 
00074         // TODO: Copy?
00075         KMenu popMenu(view);
00076         popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
00077         QAction *moveAction = popMenu.addAction(SmallIcon("go-jump"), i18n("&Move Here"));
00078         popMenu.addSeparator();
00079         popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
00080         popMenu.setMouseTracking(true);
00081         QAction *choice = popMenu.exec(QCursor::pos());
00082 
00083         if(choice == moveAction)
00084         {
00085             KIO::Job* job = DIO::move(droppedAlbum, destAlbum);
00086             connect(job, SIGNAL(result(KJob*)),
00087                     this, SLOT(slotDIOResult(KJob*)));
00088         }
00089 
00090         return true;
00091     }
00092 
00093     if (DItemDrag::canDecode(e->mimeData()))
00094     {
00095 
00096         KUrl::List urls;
00097         KUrl::List kioURLs;
00098         QList<int> albumIDs;
00099         QList<int> imageIDs;
00100 
00101         if (!DItemDrag::decode(e->mimeData(), urls, kioURLs, albumIDs, imageIDs))
00102             return false;
00103 
00104         if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
00105             return false;
00106 
00107         // Check if items dropped come from outside current album.
00108         // This can be the case with recursive content album mode.
00109         KUrl::List extUrls;
00110         ImageInfoList extImgInfList;
00111         QList<qlonglong> extImageIDs;
00112         for (QList<int>::const_iterator it = imageIDs.constBegin(); it != imageIDs.constEnd(); ++it)
00113         {
00114             ImageInfo info(*it);
00115             if (info.albumId() != destAlbum->id())
00116             {
00117                 extUrls.append(info.databaseUrl());
00118                 extImgInfList.append(info);
00119                 extImageIDs << *it;
00120             }
00121         }
00122 
00123         if(extUrls.isEmpty())
00124         {
00125             // Setting the dropped image as the album thumbnail
00126             // If the ctrl key is pressed, when dropping the image, the
00127             // thumbnail is set without a popup menu
00128             bool set = false;
00129             if (e->keyboardModifiers() == Qt::ControlModifier)
00130             {
00131                 set = true;
00132             }
00133             else
00134             {
00135                 KMenu popMenu(view);
00136                 popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
00137                 QAction *setAction = 0;
00138                 if (imageIDs.count() == 1)
00139                     setAction = popMenu.addAction(i18n("Set as Album Thumbnail"));
00140                 popMenu.addSeparator();
00141                 popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
00142                 popMenu.setMouseTracking(true);
00143                 QAction *choice = popMenu.exec(QCursor::pos());
00144                 set = (setAction == choice);
00145             }
00146 
00147             if(set)
00148             {
00149                 QString errMsg;
00150                 AlbumManager::instance()->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
00151             }
00152             return true;
00153         }
00154 
00155         // If shift key is pressed while dragging, move the drag object without
00156         // displaying popup menu -> move
00157         bool move = false, copy = false, setThumbnail = false;
00158         if (e->keyboardModifiers() == Qt::ShiftModifier)
00159         {
00160             move = true;
00161         }
00162         // If ctrl key is pressed while dragging, copy the drag object without
00163         // displaying popup menu -> copy
00164         else if (e->keyboardModifiers() == Qt::ControlModifier)
00165         {
00166             copy = true;
00167         }
00168         else
00169         {
00170             KMenu popMenu(view);
00171             popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
00172             QAction *moveAction = popMenu.addAction(SmallIcon("go-jump"), i18n("&Move Here"));
00173             QAction *copyAction = popMenu.addAction(SmallIcon("edit-copy"), i18n("&Copy Here"));
00174             QAction *thumbnailAction = 0;
00175             if (imageIDs.count() == 1)
00176                 thumbnailAction = popMenu.addAction(i18n("Set as Album Thumbnail"));
00177             popMenu.addSeparator();
00178             popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
00179             popMenu.setMouseTracking(true);
00180             QAction *choice = popMenu.exec(QCursor::pos());
00181             if (choice)
00182             {
00183                 if (choice == moveAction)
00184                     move = true;
00185                 else if (choice == copyAction)
00186                     copy = true;
00187                 else if (choice == thumbnailAction)
00188                     setThumbnail = true;
00189             }
00190         }
00191 
00192         if (move)
00193         {
00194             KIO::Job* job = DIO::move(extUrls, extImageIDs, destAlbum);
00195             connect(job, SIGNAL(result(KJob*)),
00196                     this, SLOT(slotDIOResult(KJob*)));
00197 
00198             /*
00199             // In recurssive album contents mode, we need to force AlbumLister to take a care about
00200             // moved items. This will have no incidence in normal mode.
00201             for (ImageInfoListIterator it = extImgInfList.begin(); it != extImgInfList.end(); ++it)
00202             {
00203                 AlbumLister::instance()->invalidateItem(*it);
00204             }*/
00205         }
00206         else if (copy)
00207         {
00208             KIO::Job* job = DIO::copy(extUrls, extImageIDs, destAlbum);
00209             connect(job, SIGNAL(result(KJob*)),
00210                     this, SLOT(slotDIOResult(KJob*)));
00211         }
00212         else if (setThumbnail)
00213         {
00214             QString errMsg;
00215             AlbumManager::instance()->updatePAlbumIcon(destAlbum, imageIDs.first(), errMsg);
00216         }
00217 
00218         return true;
00219     }
00220 
00221     // -- DnD from Camera GUI ----------------------------
00222 
00223     if (DCameraItemListDrag::canDecode(e->mimeData()))
00224     {
00225         CameraUI *ui = dynamic_cast<CameraUI*>(e->source());
00226         if (ui)
00227         {
00228             KMenu popMenu(view);
00229             popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
00230             QAction *downAction    = popMenu.addAction(SmallIcon("file-export"),
00231                                                        i18n("Download From Camera"));
00232             QAction *downDelAction = popMenu.addAction(SmallIcon("file-export"),
00233                                                        i18n("Download && Delete From Camera"));
00234             popMenu.addSeparator();
00235             popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
00236             popMenu.setMouseTracking(true);
00237             QAction *choice = popMenu.exec(QCursor::pos());
00238             if (choice)
00239             {
00240                 if (choice == downAction)
00241                     ui->slotDownload(true, false, destAlbum);
00242                 else if (choice == downDelAction)
00243                     ui->slotDownload(true, true, destAlbum);
00244             }
00245         }
00246     }
00247 
00248     // -- DnD from an external source ---------------------
00249 
00250     if (KUrl::List::canDecode(e->mimeData()))
00251     {
00252         KUrl destURL(destAlbum->databaseUrl());
00253 
00254         KUrl::List srcURLs = KUrl::List::fromMimeData(e->mimeData());
00255 
00256         bool move = false, copy = false;
00257         // If shift key is pressed while dropping, move the drag object without
00258         // displaying popup menu -> move
00259         if (e->keyboardModifiers() == Qt::ShiftModifier)
00260         {
00261             move = true;
00262         }
00263         // If ctrl key is pressed while dropping, copy the drag object without
00264         // displaying popup menu -> copy
00265         else if (e->keyboardModifiers() == Qt::ControlModifier)
00266         {
00267             copy = true;
00268         }
00269         else
00270         {
00271             KMenu popMenu(view);
00272             popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
00273             QAction *moveAction = popMenu.addAction( SmallIcon("go-jump"), i18n("&Move Here"));
00274             QAction *copyAction = popMenu.addAction( SmallIcon("edit-copy"), i18n("&Copy Here"));
00275             popMenu.addSeparator();
00276             popMenu.addAction( SmallIcon("dialog-cancel"), i18n("C&ancel") );
00277             popMenu.setMouseTracking(true);
00278             QAction *choice = popMenu.exec(QCursor::pos());
00279             if (choice == copyAction)
00280                 copy = true;
00281             else if (choice == moveAction)
00282                 move = true;
00283         }
00284 
00285         if (move)
00286         {
00287             KIO::Job* job = DIO::move(srcURLs, destAlbum);
00288             connect(job, SIGNAL(result(KJob*)),
00289                     this, SLOT(slotDIOResult(KJob*)));
00290         }
00291         else if (copy)
00292         {
00293             KIO::Job* job = DIO::copy(srcURLs, destAlbum);
00294             connect(job, SIGNAL(result(KJob*)),
00295                     this, SLOT(slotDIOResult(KJob*)));
00296         }
00297 
00298         return true;
00299     }
00300 
00301     return false;
00302 }
00303 
00304 Qt::DropAction AlbumDragDropHandler::accepts(const QMimeData *data, const QModelIndex& dropIndex)
00305 {
00306     PAlbum *destAlbum = model()->albumForIndex(dropIndex);
00307 
00308     if (DAlbumDrag::canDecode(data))
00309     {
00310         // do not allow to drop on root
00311         if (dropIndex == model()->rootAlbumIndex())
00312             return Qt::IgnoreAction;
00313 
00314         if (!destAlbum)
00315             return Qt::IgnoreAction;
00316 
00317         KUrl::List urls;
00318         int albumId;
00319         if (!DAlbumDrag::decode(data, urls, albumId))
00320             return Qt::IgnoreAction;
00321 
00322         PAlbum *droppedAlbum = AlbumManager::instance()->findPAlbum(albumId);
00323         if (!droppedAlbum)
00324             return Qt::IgnoreAction;
00325 
00326         // Dragging an item on itself makes no sense
00327         if(droppedAlbum == destAlbum)
00328             return Qt::IgnoreAction;
00329 
00330         // Dragging a parent on its child makes no sense
00331         if(droppedAlbum->isAncestorOf(destAlbum))
00332             return Qt::IgnoreAction;
00333 
00334         return Qt::MoveAction;
00335     }
00336 
00337     if(DItemDrag::canDecode(data)
00338        || DCameraItemListDrag::canDecode(data)
00339        || KUrl::List::canDecode(data))
00340     {
00341         // Do not allow drop images on album root
00342         if (destAlbum && !destAlbum->isRoot())
00343             return Qt::MoveAction;
00344     }
00345 
00346     return Qt::IgnoreAction;
00347 }
00348 
00349 QStringList AlbumDragDropHandler::mimeTypes() const
00350 {
00351     QStringList mimeTypes;
00352     mimeTypes << DAlbumDrag::mimeTypes()
00353               << DItemDrag::mimeTypes()
00354               << DCameraItemListDrag::mimeTypes()
00355               << KUrl::List::mimeDataTypes();
00356     return mimeTypes;
00357 }
00358 
00359 QMimeData *AlbumDragDropHandler::createMimeData(const QList<Album*>& albums)
00360 {
00361     if (albums.isEmpty())
00362         return 0;
00363 
00364     if (albums.size() > 1)
00365         kWarning() << "Dragging multiple albums is not implemented";
00366 
00367     return new DAlbumDrag(albums.first()->databaseUrl(), albums.first()->id());
00368 }
00369 
00370 } // namespace Digikam

digikam

Skip menu "digikam"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • digikam
Generated for API Reference by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal