diff options
Diffstat (limited to 'src/utilities/cameragui/cameracontroller.cpp')
-rw-r--r-- | src/utilities/cameragui/cameracontroller.cpp | 1227 |
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 <renchi@pooh.tam.uiuc.edu> + * 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 |