/* ============================================================ * * 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 * Copyright (C) 2006-2009 by Gilles Caulier * * 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 } // C++ includes. #include #include // Qt includes. #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include // 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; QMap map; }; class CameraEvent : public QCustomEvent { 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) : QCustomEvent(QEvent::User+state) {} bool result; QString msg; QMap 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; QWidget *parent; QTimer *timer; CameraThread *thread; DKCamera *camera; MTQueue cmdQueue; }; class CameraThread : public QThread { public: CameraThread(CameraController* controller); ~CameraThread(); void sendBusy(bool busy); void sendError(const QString& msg); void sendInfo(const QString& msg); protected: void run(); private: CameraControllerPriv *d; QObject *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; QApplication::postEvent(parent, event); if (result) sendInfo(i18n("Connection established")); else sendInfo(i18n("Connection failed")); break; } case(CameraCommand::gp_cameraInformations): { sendInfo(i18n("Getting camera information...")); QString 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", QVariant(summary)); event->map.insert("manual", QVariant(manual)); event->map.insert("about", QVariant(about)); QApplication::postEvent(parent, event); break; } case(CameraCommand::gp_listfolders): { sendInfo(i18n("Listing folders...")); QStringList folderList; folderList.append(d->camera->path()); d->camera->getAllFolders(d->camera->path(), folderList); /* TODO: ugly hack since qt <= 3.1.2 does not define QStringList with QDeepCopy as a friend. */ QValueList flist(folderList); CameraEvent* event = new CameraEvent(CameraEvent::gp_listedfolders); event->map.insert("folders", QVariant(flist)); QApplication::postEvent(parent, event); sendInfo(i18n("The folders have been listed.")); break; } case(CameraCommand::gp_listfiles): { QString 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", QVariant(folder)); QByteArray ba; QDataStream ds(ba, IO_WriteOnly); ds << itemsList; event->map.insert("files", QVariant(ba)); QApplication::postEvent(parent, event); } sendInfo(i18n("Listing files in %1 is complete").arg(folder)); break; } case(CameraCommand::gp_thumbnail): { QString folder = cmd->map["folder"].asString(); QString file = cmd->map["file"].asString(); sendInfo(i18n("Getting thumbnails...")); QImage thumbnail; d->camera->getThumbnail(folder, file, thumbnail); if (!thumbnail.isNull()) { thumbnail = thumbnail.smoothScale(ThumbnailSize::Huge, ThumbnailSize::Huge, QImage::ScaleMin); CameraEvent* event = new CameraEvent(CameraEvent::gp_thumbnailed); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("thumbnail", QVariant(thumbnail)); QApplication::postEvent(parent, event); } break; } case(CameraCommand::gp_exif): { QString folder = cmd->map["folder"].asString(); QString 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) { QByteArray ba; QDataStream ds(ba, IO_WriteOnly); ds.writeRawBytes(edata, esize); delete [] edata; CameraEvent* event = new CameraEvent(CameraEvent::gp_exif); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("exifSize", QVariant(esize)); event->map.insert("exifData", QVariant(ba)); QApplication::postEvent(parent, event); } break; } case(CameraCommand::gp_download): { QString folder = cmd->map["folder"].asString(); QString file = cmd->map["file"].asString(); QString dest = cmd->map["dest"].asString(); bool autoRotate = cmd->map["autoRotate"].asBool(); bool fixDateTime = cmd->map["fixDateTime"].asBool(); QDateTime newDateTime = cmd->map["newDateTime"].asDateTime(); bool setPhotographerId = cmd->map["setPhotographerId"].asBool(); QString author = cmd->map["author"].asString(); QString authorTitle = cmd->map["authorTitle"].asString(); bool setCredits = cmd->map["setCredits"].asBool(); QString credit = cmd->map["credit"].asString(); QString source = cmd->map["source"].asString(); QString copyright = cmd->map["copyright"].asString(); bool convertJpeg = cmd->map["convertJpeg"].asBool(); QString 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", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("dest", QVariant(dest)); QApplication::postEvent(parent, event); KURL tempURL(dest); tempURL = tempURL.upURL(); tempURL.addPath( QString(".digikam-camera-tmp1-%1").arg(getpid()).append(file)); DDebug() << "Downloading: " << file << " using (" << tempURL.path() << ")" << endl; QString 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( QString(".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(QFile::encodeName(tempURL.path())); unlink(QFile::encodeName(tempURL2.path())); result = false; } else { // Else remove only the first temp file. unlink(QFile::encodeName(tempURL.path())); } } } if (result) { CameraEvent* event = new CameraEvent(CameraEvent::gp_downloaded); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("dest", QVariant(dest)); event->map.insert("temp", QVariant(temp)); QApplication::postEvent(parent, event); } else { CameraEvent* event = new CameraEvent(CameraEvent::gp_downloadFailed); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("dest", QVariant(dest)); QApplication::postEvent(parent, event); } break; } case(CameraCommand::gp_open): { QString folder = cmd->map["folder"].asString(); QString file = cmd->map["file"].asString(); QString 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", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("dest", QVariant(dest)); QApplication::postEvent(parent, event); } else { sendError(i18n("Failed to retrieve file %1 from camera").arg(file)); } break; } case(CameraCommand::gp_upload): { QString folder = cmd->map["destFolder"].asString(); // We will using the same source file name to create the dest file // name in camera. QString file = cmd->map["destFile"].asString(); // The source file path to download in camera. QString 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); QByteArray ba; QDataStream ds(ba, IO_WriteOnly); ds << itemsInfo; event->map.insert("info", QVariant(ba)); QApplication::postEvent(parent, event); } else { CameraEvent* event = new CameraEvent(CameraEvent::gp_uploadFailed); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); event->map.insert("src", QVariant(src)); QApplication::postEvent(parent, event); } break; } case(CameraCommand::gp_delete): { QString folder = cmd->map["folder"].asString(); QString 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", QVariant(folder)); event->map.insert("file", QVariant(file)); QApplication::postEvent(parent, event); } else { CameraEvent* event = new CameraEvent(CameraEvent::gp_deleteFailed); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); QApplication::postEvent(parent, event); } break; } case(CameraCommand::gp_lock): { QString folder = cmd->map["folder"].asString(); QString 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", QVariant(folder)); event->map.insert("file", QVariant(file)); QApplication::postEvent(parent, event); } else { CameraEvent* event = new CameraEvent(CameraEvent::gp_lockFailed); event->map.insert("folder", QVariant(folder)); event->map.insert("file", QVariant(file)); QApplication::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; QApplication::postEvent(parent, event); } void CameraThread::sendError(const QString& msg) { CameraEvent* event = new CameraEvent(CameraEvent::gp_errormsg); event->msg = msg; QApplication::postEvent(parent, event); } void CameraThread::sendInfo(const QString& msg) { CameraEvent* event = new CameraEvent(CameraEvent::gp_infomsg); event->msg = msg; QApplication::postEvent(parent, event); } //-- Camera Controller ------------------------------------------------------ CameraController::CameraController(QWidget* parent, const QString& title, const QString& model, const QString& port, const QString& path) : QObject(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; QString xport = url.host(); if (xport.startsWith("usb:")) { DDebug() << "xport " << xport << endl; QRegExp x = QRegExp("(usb:[0-9,]*)"); if (x.search(xport) != -1) { QString 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 QTimer(this); connect(d->timer, SIGNAL(timeout()), this, 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; } QString CameraController::getCameraPath() { if (!d->camera) return QString(); return d->camera->path(); } QString CameraController::getCameraTitle() { if (!d->camera) return QString(); 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 QString& folder) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_listfiles; cmd->map.insert("folder", QVariant(folder)); d->cmdQueue.enqueue(cmd); } void CameraController::getThumbnail(const QString& folder, const QString& file) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_thumbnail; cmd->map.insert("folder", QVariant(folder)); cmd->map.insert("file", QVariant(file)); d->cmdQueue.enqueue(cmd); } void CameraController::getExif(const QString& folder, const QString& file) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_exif; cmd->map.insert("folder", QVariant(folder)); cmd->map.insert("file", QVariant(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 QFileInfo& srcFileInfo, const QString& destFile, const QString& destFolder) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_upload; cmd->map.insert("srcFilePath", QVariant(srcFileInfo.filePath())); cmd->map.insert("destFile", QVariant(destFile)); cmd->map.insert("destFolder", QVariant(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", QVariant(downloadSettings.folder)); cmd->map.insert("file", QVariant(downloadSettings.file)); cmd->map.insert("dest", QVariant(downloadSettings.dest)); cmd->map.insert("autoRotate", QVariant(downloadSettings.autoRotate, 0)); cmd->map.insert("fixDateTime", QVariant(downloadSettings.fixDateTime, 0)); cmd->map.insert("newDateTime", QVariant(downloadSettings.newDateTime)); cmd->map.insert("setPhotographerId", QVariant(downloadSettings.setPhotographerId, 0)); cmd->map.insert("author", QVariant(downloadSettings.author)); cmd->map.insert("authorTitle", QVariant(downloadSettings.authorTitle)); cmd->map.insert("setCredits", QVariant(downloadSettings.setCredits, 0)); cmd->map.insert("credit", QVariant(downloadSettings.credit)); cmd->map.insert("source", QVariant(downloadSettings.source)); cmd->map.insert("copyright", QVariant(downloadSettings.copyright)); cmd->map.insert("convertJpeg", QVariant(downloadSettings.convertJpeg, 0)); cmd->map.insert("losslessFormat", QVariant(downloadSettings.losslessFormat)); d->cmdQueue.enqueue(cmd); } void CameraController::deleteFile(const QString& folder, const QString& file) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_delete; cmd->map.insert("folder", QVariant(folder)); cmd->map.insert("file", QVariant(file)); d->cmdQueue.enqueue(cmd); } void CameraController::lockFile(const QString& folder, const QString& file, bool lock) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_lock; cmd->map.insert("folder", QVariant(folder)); cmd->map.insert("file", QVariant(file)); cmd->map.insert("lock", QVariant(lock, 0)); d->cmdQueue.enqueue(cmd); } void CameraController::openFile(const QString& folder, const QString& file) { d->canceled = false; CameraCommand *cmd = new CameraCommand; cmd->action = CameraCommand::gp_open; cmd->map.insert("folder", QVariant(folder)); cmd->map.insert("file", QVariant(file)); cmd->map.insert("dest", QVariant(locateLocal("tmp", file))); d->cmdQueue.enqueue(cmd); } void CameraController::slotCancel() { d->canceled = true; d->cmdQueue.flush(); d->camera->cancel(); } void CameraController::customEvent(QCustomEvent* e) { CameraEvent* event = dynamic_cast(e); if (!event) { return; } switch(event->type()-QEvent::User) { case (CameraEvent::gp_connected) : { emit signalConnected(event->result); break; } case (CameraEvent::gp_cameraInformations) : { QString summary = QDeepCopy(event->map["summary"].asString()); QString manual = QDeepCopy(event->map["manual"].asString()); QString about = QDeepCopy(event->map["about"].asString()); emit signalCameraInformations(summary, manual, about); break; } case (CameraEvent::gp_errormsg) : { emit signalErrorMsg(QDeepCopy(event->msg)); break; } case (CameraEvent::gp_busy) : { if (event->result) emit signalBusy(true); break; } case (CameraEvent::gp_infomsg) : { if (!d->canceled) emit signalInfoMsg(QDeepCopy(event->msg)); break; } case (CameraEvent::gp_listedfolders) : { /* TODO: ugly hack since qt <= 3.1.2 does not define QStringList with QDeepCopy as a friend. */ QValueList flist = QDeepCopy< QValueList >(event->map["folders"].toList()); QStringList folderList; QValueList::Iterator it; for (it = flist.begin(); it != flist.end(); ++it ) { folderList.append(QDeepCopy((*it).asString())); } emit signalFolderList(folderList); break; } case (CameraEvent::gp_listedfiles) : { QString folder = QDeepCopy(event->map["folder"].asString()); QByteArray ba = QDeepCopy(event->map["files"].asByteArray()); QDataStream ds(ba, IO_ReadOnly); GPItemInfoList items; ds >> items; emit signalFileList(items); break; } case (CameraEvent::gp_thumbnailed) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); QImage thumb = QDeepCopy(event->map["thumbnail"].asImage()); emit signalThumbnail(folder, file, thumb); break; } case (CameraEvent::gp_exif) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); QByteArray ba = QDeepCopy(event->map["exifData"].asByteArray()); emit signalExifData(ba); break; } case (CameraEvent::gp_downloadstarted) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); emit signalDownloaded(folder, file, GPItemInfo::DownloadStarted); break; } case (CameraEvent::gp_downloaded) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); QString dest = QDeepCopy(event->map["dest"].asString()); QString temp = QDeepCopy(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) { QFileInfo info(dest); while (info.exists()) { if (d->skipAll) { skip = true; break; } KIO::RenameDlg dlg(d->parent, i18n("Rename File"), folder + QString("/") + file, dest, KIO::RenameDlg_Mode(KIO::M_MULTI | KIO::M_OVERWRITE | KIO::M_SKIP)); int result = dlg.exec(); dest = dlg.newDestURL().path(); info = QFileInfo(dest); switch (result) { case KIO::R_CANCEL: { cancel = true; break; } case KIO::R_SKIP: { skip = true; break; } case KIO::R_AUTO_SKIP: { d->skipAll = true; skip = true; break; } case KIO::R_OVERWRITE: { overwrite = true; break; } case KIO::R_OVERWRITE_ALL: { d->overwriteAll = true; overwrite = true; break; } default: break; } if (cancel || skip || overwrite) break; } } if (cancel) { unlink(QFile::encodeName(temp)); slotCancel(); d->timer->start(50); emit signalSkipped(folder, file); return; } else if (skip) { unlink(QFile::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(QFile::encodeName(temp), QFile::encodeName(dest)) != 0) { // rename failed. delete the temp file unlink(QFile::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) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); d->timer->stop(); QString 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) : { QByteArray ba = QDeepCopy(event->map["info"].asByteArray()); QDataStream ds(ba, IO_ReadOnly); GPItemInfo itemInfo; ds >> itemInfo; emit signalUploaded(itemInfo); break; } case (CameraEvent::gp_uploadFailed) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); QString src = QDeepCopy(event->map["src"].asString()); d->timer->stop(); QString 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) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); emit signalDeleted(folder, file, true); break; } case (CameraEvent::gp_deleteFailed) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); d->timer->stop(); emit signalDeleted(folder, file, false); QString 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) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); emit signalLocked(folder, file, true); break; } case (CameraEvent::gp_lockFailed) : { QString folder = QDeepCopy(event->map["folder"].asString()); QString file = QDeepCopy(event->map["file"].asString()); d->timer->stop(); emit signalLocked(folder, file, false); QString 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) : { QString file = QDeepCopy(event->map["file"].asString()); QString dest = QDeepCopy(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(); QString folder; QString file; QString dest; if ((cmd->action == CameraCommand::gp_exif) && (typeid(*(d->camera)) == typeid(UMSCamera))) { folder = QDeepCopy(cmd->map["folder"].asString()); file = QDeepCopy(cmd->map["file"].asString()); emit signalExifFromFile(folder, file); d->cmdQueue.dequeue(); d->timer->start(50, false); return; } if (cmd->action == CameraCommand::gp_download) { folder = QDeepCopy(cmd->map["folder"].asString()); file = QDeepCopy(cmd->map["file"].asString()); dest = QDeepCopy(cmd->map["dest"].asString()); cmd->map["dest"] = QVariant(QDeepCopy(dest)); } d->thread->start(); d->timer->start(50, false); } } // namespace Digikam