You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/utilities/cameragui/cameracontroller.cpp

1228 lines
41 KiB

/* ============================================================
*
* 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 <klocale.h>
#include <kurl.h>
#include <kmessagebox.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;
TQMap<TQString,TQVariant> 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;
TQMap<TQString,TQVariant> 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, TQ_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, TQT_SIGNAL(timeout()),
this, TQT_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, 0));
cmd->map.insert("fixDateTime", TQVariant(downloadSettings.fixDateTime, 0));
cmd->map.insert("newDateTime", TQVariant(downloadSettings.newDateTime));
cmd->map.insert("setPhotographerId", TQVariant(downloadSettings.setPhotographerId, 0));
cmd->map.insert("author", TQVariant(downloadSettings.author));
cmd->map.insert("authorTitle", TQVariant(downloadSettings.authorTitle));
cmd->map.insert("setCredits", TQVariant(downloadSettings.setCredits, 0));
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, 0));
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, 0));
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