summaryrefslogtreecommitdiffstats
path: root/src/utilities/cameragui/cameracontroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utilities/cameragui/cameracontroller.cpp')
-rw-r--r--src/utilities/cameragui/cameracontroller.cpp1227
1 files changed, 1227 insertions, 0 deletions
diff --git a/src/utilities/cameragui/cameracontroller.cpp b/src/utilities/cameragui/cameracontroller.cpp
new file mode 100644
index 00000000..34afa8ab
--- /dev/null
+++ b/src/utilities/cameragui/cameracontroller.cpp
@@ -0,0 +1,1227 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-17
+ * Description : digital camera controller
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <[email protected]>
+ * Copyright (C) 2006-2009 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.
+ *
+ * ============================================================ */
+
+extern "C"
+{
+#include <unistd.h>
+}
+
+// C++ includes.
+
+#include <typeinfo>
+#include <cstdio>
+
+// TQt includes.
+
+#include <tqthread.h>
+#include <tqmutex.h>
+#include <tqwaitcondition.h>
+#include <tqevent.h>
+#include <tqapplication.h>
+#include <tqdeepcopy.h>
+#include <tqvariant.h>
+#include <tqimage.h>
+#include <tqdatastream.h>
+#include <tqfile.h>
+#include <tqtimer.h>
+#include <tqregexp.h>
+
+// KDE includes.
+
+#include <tdelocale.h>
+#include <kurl.h>
+#include <tdemessagebox.h>
+#include <tdeio/renamedlg.h>
+#include <kstandarddirs.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "thumbnailsize.h"
+#include "imagewindow.h"
+#include "gpcamera.h"
+#include "umscamera.h"
+#include "dmetadata.h"
+#include "jpegutils.h"
+#include "mtqueue.h"
+#include "cameracontroller.h"
+#include "cameracontroller.moc"
+
+namespace Digikam
+{
+
+class CameraThread;
+
+class CameraCommand
+{
+public:
+
+ enum Action
+ {
+ gp_none = 0,
+ gp_connect,
+ gp_cancel,
+ gp_cameraInformations,
+ gp_listfolders,
+ gp_listfiles,
+ gp_download,
+ gp_upload,
+ gp_delete,
+ gp_lock,
+ gp_thumbnail,
+ gp_exif,
+ gp_open
+ };
+
+ Action action;
+ TQStringVariantMap map;
+};
+
+class CameraEvent : public TQCustomEvent
+{
+public:
+
+ enum State
+ {
+ gp_connected = 0,
+ gp_busy,
+ gp_listedfolders,
+ gp_listedfiles,
+ gp_downloadstarted,
+ gp_downloaded,
+ gp_downloadFailed,
+ gp_opened,
+ gp_uploaded,
+ gp_uploadFailed,
+ gp_deleted,
+ gp_deleteFailed,
+ gp_locked,
+ gp_lockFailed,
+ gp_thumbnailed,
+ gp_exif,
+ gp_cameraInformations,
+ gp_infomsg,
+ gp_errormsg
+ };
+
+ CameraEvent(State state) :
+ TQCustomEvent(TQEvent::User+state)
+ {}
+
+ bool result;
+ TQString msg;
+ TQStringVariantMap map;
+};
+
+class CameraControllerPriv
+{
+public:
+
+ CameraControllerPriv()
+ {
+ close = false;
+ overwriteAll = false;
+ skipAll = false;
+ canceled = false;
+ downloadTotal = 0;
+ parent = 0;
+ timer = 0;
+ camera = 0;
+ thread = 0;
+ }
+
+ bool close;
+ bool overwriteAll;
+ bool skipAll;
+ bool canceled;
+
+ int downloadTotal;
+
+ TQWidget *parent;
+
+ TQTimer *timer;
+
+ CameraThread *thread;
+
+ DKCamera *camera;
+
+ MTQueue<CameraCommand> cmdQueue;
+};
+
+class CameraThread : public TQThread
+{
+public:
+
+ CameraThread(CameraController* controller);
+ ~CameraThread();
+
+ void sendBusy(bool busy);
+ void sendError(const TQString& msg);
+ void sendInfo(const TQString& msg);
+
+protected:
+
+ void run();
+
+private:
+
+ CameraControllerPriv *d;
+
+ TQObject *parent;
+};
+
+CameraThread::CameraThread(CameraController* controller)
+ : d(controller->d), parent(controller)
+{
+}
+
+CameraThread::~CameraThread()
+{
+}
+
+void CameraThread::run()
+{
+ if (d->close)
+ return;
+
+ sendBusy(true);
+
+ CameraCommand* cmd = d->cmdQueue.dequeue();
+ if (cmd)
+ {
+ switch (cmd->action)
+ {
+ case(CameraCommand::gp_connect):
+ {
+ sendInfo(i18n("Connecting to camera..."));
+
+ bool result = d->camera->doConnect();
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_connected);
+ event->result = result;
+ TQApplication::postEvent(parent, event);
+
+ if (result)
+ sendInfo(i18n("Connection established"));
+ else
+ sendInfo(i18n("Connection failed"));
+
+ break;
+ }
+ case(CameraCommand::gp_cameraInformations):
+ {
+ sendInfo(i18n("Getting camera information..."));
+
+ TQString summary, manual, about;
+
+ d->camera->cameraSummary(summary);
+ d->camera->cameraManual(manual);
+ d->camera->cameraAbout(about);
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_cameraInformations);
+ event->map.insert("summary", TQVariant(summary));
+ event->map.insert("manual", TQVariant(manual));
+ event->map.insert("about", TQVariant(about));
+ TQApplication::postEvent(parent, event);
+ break;
+ }
+ case(CameraCommand::gp_listfolders):
+ {
+ sendInfo(i18n("Listing folders..."));
+
+ TQStringList folderList;
+ folderList.append(d->camera->path());
+ d->camera->getAllFolders(d->camera->path(), folderList);
+
+ /* TODO: ugly hack since qt <= 3.1.2 does not define
+ TQStringList with TQDeepCopy as a friend. */
+ TQValueList<TQString> flist(folderList);
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_listedfolders);
+ event->map.insert("folders", TQVariant(flist));
+ TQApplication::postEvent(parent, event);
+
+ sendInfo(i18n("The folders have been listed."));
+
+ break;
+ }
+ case(CameraCommand::gp_listfiles):
+ {
+ TQString folder = cmd->map["folder"].asString();
+
+ sendInfo(i18n("The files in %1 have been listed.").arg(folder));
+
+ GPItemInfoList itemsList;
+ // setting getImageDimensions to false is a huge speedup for UMSCamera
+ if (!d->camera->getItemsInfoList(folder, itemsList, false))
+ {
+ sendError(i18n("Failed to list files in %1").arg(folder));
+ }
+
+ if (!itemsList.isEmpty())
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_listedfiles);
+ event->map.insert("folder", TQVariant(folder));
+
+ TQByteArray ba;
+ TQDataStream ds(ba, IO_WriteOnly);
+ ds << itemsList;
+
+ event->map.insert("files", TQVariant(ba));
+ TQApplication::postEvent(parent, event);
+ }
+
+ sendInfo(i18n("Listing files in %1 is complete").arg(folder));
+
+ break;
+ }
+ case(CameraCommand::gp_thumbnail):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+
+ sendInfo(i18n("Getting thumbnails..."));
+
+ TQImage thumbnail;
+ d->camera->getThumbnail(folder, file, thumbnail);
+
+ if (!thumbnail.isNull())
+ {
+ thumbnail = thumbnail.smoothScale(ThumbnailSize::Huge, ThumbnailSize::Huge, TQImage::ScaleMin);
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_thumbnailed);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("thumbnail", TQVariant(thumbnail));
+ TQApplication::postEvent(parent, event);
+ }
+
+ break;
+ }
+ case(CameraCommand::gp_exif):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+
+ sendInfo(i18n("Getting EXIF information for %1/%2...").arg(folder).arg(file));
+
+ char* edata = 0;
+ int esize = 0;
+ d->camera->getExif(folder, file, &edata, esize);
+
+ if (edata || esize)
+ {
+ TQByteArray ba;
+ TQDataStream ds(ba, IO_WriteOnly);
+ ds.writeRawBytes(edata, esize);
+ delete [] edata;
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_exif);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("exifSize", TQVariant(esize));
+ event->map.insert("exifData", TQVariant(ba));
+ TQApplication::postEvent(parent, event);
+ }
+ break;
+ }
+ case(CameraCommand::gp_download):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+ TQString dest = cmd->map["dest"].asString();
+ bool autoRotate = cmd->map["autoRotate"].asBool();
+ bool fixDateTime = cmd->map["fixDateTime"].asBool();
+ TQDateTime newDateTime = cmd->map["newDateTime"].asDateTime();
+ bool setPhotographerId = cmd->map["setPhotographerId"].asBool();
+ TQString author = cmd->map["author"].asString();
+ TQString authorTitle = cmd->map["authorTitle"].asString();
+ bool setCredits = cmd->map["setCredits"].asBool();
+ TQString credit = cmd->map["credit"].asString();
+ TQString source = cmd->map["source"].asString();
+ TQString copyright = cmd->map["copyright"].asString();
+ bool convertJpeg = cmd->map["convertJpeg"].asBool();
+ TQString losslessFormat = cmd->map["losslessFormat"].asString();
+ sendInfo(i18n("Downloading file %1...").arg(file));
+
+ // download to a temp file
+
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_downloadstarted);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("dest", TQVariant(dest));
+ TQApplication::postEvent(parent, event);
+
+ KURL tempURL(dest);
+ tempURL = tempURL.upURL();
+ tempURL.addPath( TQString(".digikam-camera-tmp1-%1").arg(getpid()).append(file));
+ DDebug() << "Downloading: " << file << " using (" << tempURL.path() << ")" << endl;
+ TQString temp = tempURL.path();
+
+ bool result = d->camera->downloadItem(folder, file, tempURL.path());
+
+ if (result && isJpegImage(tempURL.path()))
+ {
+ if (autoRotate)
+ {
+ DDebug() << "Exif autorotate: " << file << " using (" << tempURL.path() << ")" << endl;
+ sendInfo(i18n("EXIF rotating file %1...").arg(file));
+ exifRotate(tempURL.path(), file);
+ }
+
+ if (fixDateTime || setPhotographerId || setCredits)
+ {
+ DDebug() << "Set Metadata from: " << file << " using (" << tempURL.path() << ")" << endl;
+ sendInfo(i18n("Setting Metadata tags to file %1...").arg(file));
+ DMetadata metadata(tempURL.path());
+
+ if (fixDateTime)
+ metadata.setImageDateTime(newDateTime, true);
+
+ if (setPhotographerId)
+ metadata.setImagePhotographerId(author, authorTitle);
+
+ if (setCredits)
+ metadata.setImageCredits(credit, source, copyright);
+
+ metadata.applyChanges();
+ }
+
+ // Convert Jpeg file to lossless format if necessary,
+ // and move converted image to destination.
+
+ if (convertJpeg)
+ {
+ DDebug() << "Convert to LossLess: " << file << " using (" << tempURL.path() << ")" << endl;
+ sendInfo(i18n("Converting %1 to lossless file format...").arg(file));
+
+ KURL tempURL2(dest);
+ tempURL2 = tempURL2.upURL();
+ tempURL2.addPath( TQString(".digikam-camera-tmp2-%1").arg(getpid()).append(file));
+ temp = tempURL2.path();
+
+ if (!jpegConvert(tempURL.path(), tempURL2.path(), file, losslessFormat))
+ {
+ // convert failed. delete the temp file
+ unlink(TQFile::encodeName(tempURL.path()));
+ unlink(TQFile::encodeName(tempURL2.path()));
+ result = false;
+ }
+ else
+ {
+ // Else remove only the first temp file.
+ unlink(TQFile::encodeName(tempURL.path()));
+ }
+ }
+ }
+
+ if (result)
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_downloaded);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("dest", TQVariant(dest));
+ event->map.insert("temp", TQVariant(temp));
+ TQApplication::postEvent(parent, event);
+ }
+ else
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_downloadFailed);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("dest", TQVariant(dest));
+ TQApplication::postEvent(parent, event);
+ }
+ break;
+ }
+ case(CameraCommand::gp_open):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+ TQString dest = cmd->map["dest"].asString();
+
+ sendInfo(i18n("Retrieving file %1 from camera...").arg(file));
+
+ bool result = d->camera->downloadItem(folder, file, dest);
+
+ if (result)
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_opened);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("dest", TQVariant(dest));
+ TQApplication::postEvent(parent, event);
+ }
+ else
+ {
+ sendError(i18n("Failed to retrieve file %1 from camera").arg(file));
+ }
+ break;
+ }
+ case(CameraCommand::gp_upload):
+ {
+ TQString folder = cmd->map["destFolder"].asString();
+
+ // We will using the same source file name to create the dest file
+ // name in camera.
+ TQString file = cmd->map["destFile"].asString();
+
+ // The source file path to download in camera.
+ TQString src = cmd->map["srcFilePath"].asString();
+
+ sendInfo(i18n("Uploading file %1 to camera...").arg(file));
+
+ GPItemInfo itemsInfo;
+
+ bool result = d->camera->uploadItem(folder, file, src, itemsInfo);
+
+ if (result)
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_uploaded);
+ TQByteArray ba;
+ TQDataStream ds(ba, IO_WriteOnly);
+ ds << itemsInfo;
+ event->map.insert("info", TQVariant(ba));
+
+ TQApplication::postEvent(parent, event);
+ }
+ else
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_uploadFailed);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ event->map.insert("src", TQVariant(src));
+ TQApplication::postEvent(parent, event);
+ }
+ break;
+ }
+ case(CameraCommand::gp_delete):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+
+ sendInfo(i18n("Deleting file %1...").arg(file));
+
+ bool result = d->camera->deleteItem(folder, file);
+
+ if (result)
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_deleted);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ TQApplication::postEvent(parent, event);
+ }
+ else
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_deleteFailed);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ TQApplication::postEvent(parent, event);
+ }
+ break;
+ }
+ case(CameraCommand::gp_lock):
+ {
+ TQString folder = cmd->map["folder"].asString();
+ TQString file = cmd->map["file"].asString();
+ bool lock = cmd->map["lock"].asBool();
+
+ sendInfo(i18n("Toggle lock file %1...").arg(file));
+
+ bool result = d->camera->setLockItem(folder, file, lock);
+
+ if (result)
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_locked);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ TQApplication::postEvent(parent, event);
+ }
+ else
+ {
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_lockFailed);
+ event->map.insert("folder", TQVariant(folder));
+ event->map.insert("file", TQVariant(file));
+ TQApplication::postEvent(parent, event);
+ }
+ break;
+ }
+ default:
+ DWarning() << k_funcinfo << " unknown action specified" << endl;
+ }
+
+ delete cmd;
+ }
+
+ sendBusy(false);
+}
+
+void CameraThread::sendBusy(bool val)
+{
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_busy);
+ event->result = val;
+ TQApplication::postEvent(parent, event);
+}
+
+void CameraThread::sendError(const TQString& msg)
+{
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_errormsg);
+ event->msg = msg;
+ TQApplication::postEvent(parent, event);
+}
+
+void CameraThread::sendInfo(const TQString& msg)
+{
+ CameraEvent* event = new CameraEvent(CameraEvent::gp_infomsg);
+ event->msg = msg;
+ TQApplication::postEvent(parent, event);
+}
+
+
+//-- Camera Controller ------------------------------------------------------
+
+
+CameraController::CameraController(TQWidget* parent, const TQString& title, const TQString& model,
+ const TQString& port, const TQString& path)
+ : TQObject(parent)
+{
+ d = new CameraControllerPriv;
+ d->parent = parent;
+ d->canceled = false;
+ d->close = false;
+ d->overwriteAll = false;
+ d->skipAll = false;
+ d->downloadTotal = 0;
+ d->camera = 0;
+
+ // URL parsing (c) Stephan Kulow
+ if (path.startsWith("camera:/"))
+ {
+ KURL url(path);
+ DDebug() << "path " << path << " " << url << " " << url.host() << endl;
+ TQString xport = url.host();
+ if (xport.startsWith("usb:"))
+ {
+ DDebug() << "xport " << xport << endl;
+ TQRegExp x = TQRegExp("(usb:[0-9,]*)");
+
+ if (x.search(xport) != -1)
+ {
+ TQString usbport = x.cap(1);
+ DDebug() << "USB " << xport << " " << usbport << endl;
+ // if ((xport == usbport) || ((count == 1) && (xport == "usb:"))) {
+ // model = xmodel;
+ d->camera = new GPCamera(title, url.user(), "usb:", "/");
+ // }
+ }
+ }
+ }
+
+ if (!d->camera)
+ {
+ if (model.lower() == "directory browse")
+ d->camera = new UMSCamera(title, model, port, path);
+ else
+ d->camera = new GPCamera(title, model, port, path);
+ }
+
+ d->thread = new CameraThread(this);
+ d->timer = new TQTimer(this);
+
+ connect(d->timer, TQ_SIGNAL(timeout()),
+ this, TQ_SLOT(slotProcessNext()));
+
+ d->timer->start(50, false);
+}
+
+CameraController::~CameraController()
+{
+ if (d->timer->isActive())
+ {
+ d->timer->stop();
+ delete d->timer;
+ }
+
+ d->camera->cancel();
+ d->canceled = true;
+ d->close = true;
+
+ while (d->thread->running())
+ d->thread->wait();
+
+ delete d->thread;
+ delete d->camera;
+ delete d;
+}
+
+TQString CameraController::getCameraPath()
+{
+ if (!d->camera) return TQString();
+ return d->camera->path();
+}
+
+TQString CameraController::getCameraTitle()
+{
+ if (!d->camera) return TQString();
+ return d->camera->title();
+}
+
+void CameraController::slotConnect()
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_connect;
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::listFolders()
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_listfolders;
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::listFiles(const TQString& folder)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_listfiles;
+ cmd->map.insert("folder", TQVariant(folder));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::getThumbnail(const TQString& folder, const TQString& file)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_thumbnail;
+ cmd->map.insert("folder", TQVariant(folder));
+ cmd->map.insert("file", TQVariant(file));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::getExif(const TQString& folder, const TQString& file)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_exif;
+ cmd->map.insert("folder", TQVariant(folder));
+ cmd->map.insert("file", TQVariant(file));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::getCameraInformations()
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_cameraInformations;
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::upload(const TQFileInfo& srcFileInfo, const TQString& destFile, const TQString& destFolder)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_upload;
+ cmd->map.insert("srcFilePath", TQVariant(srcFileInfo.filePath()));
+ cmd->map.insert("destFile", TQVariant(destFile));
+ cmd->map.insert("destFolder", TQVariant(destFolder));
+ d->cmdQueue.enqueue(cmd);
+ DDebug() << "Uploading '" << srcFileInfo.filePath() << "' into camera : '" << destFolder <<
+ "' (" << destFile << ")" << endl;
+}
+
+void CameraController::downloadPrep()
+{
+ d->overwriteAll = false;
+ d->skipAll = false;
+ d->downloadTotal = 0;
+}
+
+void CameraController::download(DownloadSettingsContainer downloadSettings)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_download;
+ cmd->map.insert("folder", TQVariant(downloadSettings.folder));
+ cmd->map.insert("file", TQVariant(downloadSettings.file));
+ cmd->map.insert("dest", TQVariant(downloadSettings.dest));
+ cmd->map.insert("autoRotate", TQVariant(downloadSettings.autoRotate));
+ cmd->map.insert("fixDateTime", TQVariant(downloadSettings.fixDateTime));
+ cmd->map.insert("newDateTime", TQVariant(downloadSettings.newDateTime));
+ cmd->map.insert("setPhotographerId", TQVariant(downloadSettings.setPhotographerId));
+ cmd->map.insert("author", TQVariant(downloadSettings.author));
+ cmd->map.insert("authorTitle", TQVariant(downloadSettings.authorTitle));
+ cmd->map.insert("setCredits", TQVariant(downloadSettings.setCredits));
+ cmd->map.insert("credit", TQVariant(downloadSettings.credit));
+ cmd->map.insert("source", TQVariant(downloadSettings.source));
+ cmd->map.insert("copyright", TQVariant(downloadSettings.copyright));
+ cmd->map.insert("convertJpeg", TQVariant(downloadSettings.convertJpeg));
+ cmd->map.insert("losslessFormat", TQVariant(downloadSettings.losslessFormat));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::deleteFile(const TQString& folder, const TQString& file)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_delete;
+ cmd->map.insert("folder", TQVariant(folder));
+ cmd->map.insert("file", TQVariant(file));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::lockFile(const TQString& folder, const TQString& file, bool lock)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_lock;
+ cmd->map.insert("folder", TQVariant(folder));
+ cmd->map.insert("file", TQVariant(file));
+ cmd->map.insert("lock", TQVariant(lock));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::openFile(const TQString& folder, const TQString& file)
+{
+ d->canceled = false;
+ CameraCommand *cmd = new CameraCommand;
+ cmd->action = CameraCommand::gp_open;
+ cmd->map.insert("folder", TQVariant(folder));
+ cmd->map.insert("file", TQVariant(file));
+ cmd->map.insert("dest", TQVariant(locateLocal("tmp", file)));
+ d->cmdQueue.enqueue(cmd);
+}
+
+void CameraController::slotCancel()
+{
+ d->canceled = true;
+ d->cmdQueue.flush();
+ d->camera->cancel();
+}
+
+void CameraController::customEvent(TQCustomEvent* e)
+{
+ CameraEvent* event = dynamic_cast<CameraEvent*>(e);
+ if (!event)
+ {
+ return;
+ }
+
+ switch(event->type()-TQEvent::User)
+ {
+ case (CameraEvent::gp_connected) :
+ {
+ emit signalConnected(event->result);
+ break;
+ }
+ case (CameraEvent::gp_cameraInformations) :
+ {
+ TQString summary = TQDeepCopy<TQString>(event->map["summary"].asString());
+ TQString manual = TQDeepCopy<TQString>(event->map["manual"].asString());
+ TQString about = TQDeepCopy<TQString>(event->map["about"].asString());
+ emit signalCameraInformations(summary, manual, about);
+ break;
+ }
+ case (CameraEvent::gp_errormsg) :
+ {
+ emit signalErrorMsg(TQDeepCopy<TQString>(event->msg));
+ break;
+ }
+ case (CameraEvent::gp_busy) :
+ {
+ if (event->result)
+ emit signalBusy(true);
+ break;
+ }
+ case (CameraEvent::gp_infomsg) :
+ {
+ if (!d->canceled)
+ emit signalInfoMsg(TQDeepCopy<TQString>(event->msg));
+ break;
+ }
+ case (CameraEvent::gp_listedfolders) :
+ {
+ /* TODO: ugly hack since qt <= 3.1.2 does not define
+ TQStringList with TQDeepCopy as a friend. */
+ TQValueList<TQVariant> flist = TQDeepCopy< TQValueList<TQVariant> >(event->map["folders"].toList());
+
+ TQStringList folderList;
+ TQValueList<TQVariant>::Iterator it;
+ for (it = flist.begin(); it != flist.end(); ++it )
+ {
+ folderList.append(TQDeepCopy<TQString>((*it).asString()));
+ }
+
+ emit signalFolderList(folderList);
+ break;
+ }
+ case (CameraEvent::gp_listedfiles) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQByteArray ba = TQDeepCopy<TQByteArray>(event->map["files"].asByteArray());
+ TQDataStream ds(ba, IO_ReadOnly);
+ GPItemInfoList items;
+ ds >> items;
+ emit signalFileList(items);
+ break;
+ }
+ case (CameraEvent::gp_thumbnailed) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ TQImage thumb = TQDeepCopy<TQImage>(event->map["thumbnail"].asImage());
+ emit signalThumbnail(folder, file, thumb);
+ break;
+ }
+ case (CameraEvent::gp_exif) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ TQByteArray ba = TQDeepCopy<TQByteArray>(event->map["exifData"].asByteArray());
+ emit signalExifData(ba);
+ break;
+ }
+ case (CameraEvent::gp_downloadstarted) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ emit signalDownloaded(folder, file, GPItemInfo::DownloadStarted);
+ break;
+ }
+ case (CameraEvent::gp_downloaded) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ TQString dest = TQDeepCopy<TQString>(event->map["dest"].asString());
+ TQString temp = TQDeepCopy<TQString>(event->map["temp"].asString());
+
+ d->timer->stop();
+
+ bool skip = false;
+ bool cancel = false;
+ bool overwrite = false;
+
+ // Check if dest file already exist.
+
+ if (!d->overwriteAll)
+ {
+ TQFileInfo info(dest);
+
+ while (info.exists())
+ {
+ if (d->skipAll)
+ {
+ skip = true;
+ break;
+ }
+
+ TDEIO::RenameDlg dlg(d->parent, i18n("Rename File"),
+ folder + TQString("/") + file, dest,
+ TDEIO::RenameDlg_Mode(TDEIO::M_MULTI | TDEIO::M_OVERWRITE | TDEIO::M_SKIP));
+
+ int result = dlg.exec();
+ dest = dlg.newDestURL().path();
+ info = TQFileInfo(dest);
+
+ switch (result)
+ {
+ case TDEIO::R_CANCEL:
+ {
+ cancel = true;
+ break;
+ }
+ case TDEIO::R_SKIP:
+ {
+ skip = true;
+ break;
+ }
+ case TDEIO::R_AUTO_SKIP:
+ {
+ d->skipAll = true;
+ skip = true;
+ break;
+ }
+ case TDEIO::R_OVERWRITE:
+ {
+ overwrite = true;
+ break;
+ }
+ case TDEIO::R_OVERWRITE_ALL:
+ {
+ d->overwriteAll = true;
+ overwrite = true;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (cancel || skip || overwrite)
+ break;
+ }
+ }
+
+ if (cancel)
+ {
+ unlink(TQFile::encodeName(temp));
+ slotCancel();
+ d->timer->start(50);
+ emit signalSkipped(folder, file);
+ return;
+ }
+ else if (skip)
+ {
+ unlink(TQFile::encodeName(temp));
+ d->timer->start(50);
+ emit signalInfoMsg(i18n("Skipped file %1").arg(file));
+ emit signalSkipped(folder, file);
+ return;
+ }
+
+ // move the file to the destination file
+ if (rename(TQFile::encodeName(temp), TQFile::encodeName(dest)) != 0)
+ {
+ // rename failed. delete the temp file
+ unlink(TQFile::encodeName(temp));
+ d->timer->start(50);
+ emit signalDownloaded(folder, file, GPItemInfo::DownloadFailed);
+ }
+ else
+ {
+ d->timer->start(50);
+ emit signalDownloaded(folder, file, GPItemInfo::DownloadedYes);
+ }
+ break;
+ }
+ case (CameraEvent::gp_downloadFailed) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+
+ d->timer->stop();
+
+ TQString msg = i18n("Failed to download file \"%1\".").arg(file);
+
+ if (!d->canceled)
+ {
+ if (d->cmdQueue.isEmpty())
+ {
+ KMessageBox::error(d->parent, msg);
+ }
+ else
+ {
+ msg += i18n(" Do you want to continue?");
+ int result = KMessageBox::warningContinueCancel(d->parent, msg);
+ if (result != KMessageBox::Continue)
+ slotCancel();
+ }
+ }
+
+ d->timer->start(50);
+ emit signalDownloaded(folder, file, GPItemInfo::DownloadFailed);
+ break;
+ }
+ case (CameraEvent::gp_uploaded) :
+ {
+ TQByteArray ba = TQDeepCopy<TQByteArray>(event->map["info"].asByteArray());
+ TQDataStream ds(ba, IO_ReadOnly);
+ GPItemInfo itemInfo;
+ ds >> itemInfo;
+
+ emit signalUploaded(itemInfo);
+ break;
+ }
+ case (CameraEvent::gp_uploadFailed) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ TQString src = TQDeepCopy<TQString>(event->map["src"].asString());
+
+ d->timer->stop();
+
+ TQString msg = i18n("Failed to upload file \"%1\".").arg(file);
+
+ if (!d->canceled)
+ {
+ if (d->cmdQueue.isEmpty())
+ {
+ KMessageBox::error(d->parent, msg);
+ }
+ else
+ {
+ msg += i18n(" Do you want to continue?");
+ int result = KMessageBox::warningContinueCancel(d->parent, msg);
+ if (result != KMessageBox::Continue)
+ slotCancel();
+ }
+ }
+
+ d->timer->start(50);
+ break;
+ }
+ case (CameraEvent::gp_deleted) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ emit signalDeleted(folder, file, true);
+ break;
+ }
+ case (CameraEvent::gp_deleteFailed) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+
+ d->timer->stop();
+ emit signalDeleted(folder, file, false);
+
+ TQString msg = i18n("Failed to delete file \"%1\".").arg(file);
+
+ if (!d->canceled)
+ {
+ if (d->cmdQueue.isEmpty())
+ {
+ KMessageBox::error(d->parent, msg);
+ }
+ else
+ {
+ msg += i18n(" Do you want to continue?");
+ int result = KMessageBox::warningContinueCancel(d->parent, msg);
+ if (result != KMessageBox::Continue)
+ slotCancel();
+ }
+ }
+
+ d->timer->start(50);
+ break;
+ }
+ case (CameraEvent::gp_locked) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ emit signalLocked(folder, file, true);
+ break;
+ }
+ case (CameraEvent::gp_lockFailed) :
+ {
+ TQString folder = TQDeepCopy<TQString>(event->map["folder"].asString());
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+
+ d->timer->stop();
+ emit signalLocked(folder, file, false);
+
+ TQString msg = i18n("Failed to toggle lock file \"%1\".").arg(file);
+
+ if (!d->canceled)
+ {
+ if (d->cmdQueue.isEmpty())
+ {
+ KMessageBox::error(d->parent, msg);
+ }
+ else
+ {
+ msg += i18n(" Do you want to continue?");
+ int result = KMessageBox::warningContinueCancel(d->parent, msg);
+ if (result != KMessageBox::Continue)
+ slotCancel();
+ }
+ }
+
+ d->timer->start(50);
+ break;
+ }
+ case (CameraEvent::gp_opened) :
+ {
+ TQString file = TQDeepCopy<TQString>(event->map["file"].asString());
+ TQString dest = TQDeepCopy<TQString>(event->map["dest"].asString());
+
+ KURL url(dest);
+ KURL::List urlList;
+ urlList << url;
+
+ ImageWindow *im = ImageWindow::imagewindow();
+ im->loadURL(urlList, url, i18n("Camera \"%1\"").arg(d->camera->model()), false);
+
+ if (im->isHidden())
+ im->show();
+ else
+ im->raise();
+
+ im->setFocus();
+ break;
+ }
+ default:
+ {
+ DWarning() << k_funcinfo << "Unknown event" << endl;
+ }
+ }
+}
+
+void CameraController::slotProcessNext()
+{
+ if (d->thread->running())
+ return;
+
+ if (d->cmdQueue.isEmpty())
+ {
+ emit signalBusy(false);
+ return;
+ }
+
+ d->timer->stop();
+ emit signalBusy(true);
+
+ CameraCommand* cmd = d->cmdQueue.head();
+
+ TQString folder;
+ TQString file;
+ TQString dest;
+
+ if ((cmd->action == CameraCommand::gp_exif) &&
+ (typeid(*(d->camera)) == typeid(UMSCamera)))
+ {
+ folder = TQDeepCopy<TQString>(cmd->map["folder"].asString());
+ file = TQDeepCopy<TQString>(cmd->map["file"].asString());
+
+ emit signalExifFromFile(folder, file);
+
+ d->cmdQueue.dequeue();
+ d->timer->start(50, false);
+ return;
+ }
+
+ if (cmd->action == CameraCommand::gp_download)
+ {
+ folder = TQDeepCopy<TQString>(cmd->map["folder"].asString());
+ file = TQDeepCopy<TQString>(cmd->map["file"].asString());
+ dest = TQDeepCopy<TQString>(cmd->map["dest"].asString());
+ cmd->map["dest"] = TQVariant(TQDeepCopy<TQString>(dest));
+ }
+
+ d->thread->start();
+ d->timer->start(50, false);
+}
+
+} // namespace Digikam