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.
613 lines
17 KiB
613 lines
17 KiB
/* ============================================================
|
|
* File : gpcamera.cpp
|
|
* Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
* Date : 2003-01-21
|
|
* Description :
|
|
*
|
|
* Copyright 2003 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* 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.
|
|
*
|
|
* ============================================================ */
|
|
|
|
// TQt
|
|
#include <tqstring.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqimage.h>
|
|
#include <tqfile.h>
|
|
// KDE
|
|
#include <kdebug.h>
|
|
// Standard
|
|
#include <iostream>
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
#include <gphoto2.h>
|
|
}
|
|
// Local
|
|
#include "gpstatus.h"
|
|
#include "gpcamera.h"
|
|
#include "cameralist.h"
|
|
#include "config.h"
|
|
|
|
namespace KIPIKameraKlientPlugin
|
|
{
|
|
|
|
class GPCameraPrivate {
|
|
public:
|
|
Camera *camera;
|
|
CameraAbilities cameraAbilities;
|
|
TQString model;
|
|
TQString port;
|
|
bool cameraSetup;
|
|
bool cameraInitialized;
|
|
bool thumbnailSupport;
|
|
bool deleteSupport;
|
|
bool uploadSupport;
|
|
bool mkDirSupport;
|
|
bool delDirSupport;
|
|
};
|
|
|
|
GPCamera::GPCamera(const TQString& model, const TQString& port) {
|
|
status = 0;
|
|
d = new GPCameraPrivate;
|
|
d->camera = 0;
|
|
d->model = model;
|
|
d->port = port;
|
|
d->cameraSetup = false;
|
|
d->cameraInitialized = false;
|
|
d->thumbnailSupport = false;
|
|
d->deleteSupport = false;
|
|
d->uploadSupport = false;
|
|
d->mkDirSupport = false;
|
|
d->delDirSupport = false;
|
|
setup();
|
|
}
|
|
|
|
GPCamera::~GPCamera() {
|
|
if (d->camera) {
|
|
gp_camera_unref(d->camera);
|
|
d->camera = 0;
|
|
}
|
|
delete d;
|
|
}
|
|
|
|
int GPCamera::setup() {
|
|
if (d->camera) {
|
|
gp_camera_unref(d->camera);
|
|
d->camera = 0;
|
|
}
|
|
CameraAbilitiesList *abilList;
|
|
GPPortInfoList *infoList;
|
|
GPPortInfo info;
|
|
|
|
gp_camera_new(&d->camera);
|
|
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
|
|
status = new GPStatus();
|
|
|
|
gp_abilities_list_new(&abilList);
|
|
gp_abilities_list_load(abilList, status->context);
|
|
gp_port_info_list_new(&infoList);
|
|
gp_port_info_list_load(infoList);
|
|
|
|
delete status;
|
|
status = 0;
|
|
|
|
int modelNum = -1, portNum = -1;
|
|
modelNum = gp_abilities_list_lookup_model(abilList, d->model.latin1());
|
|
portNum = gp_port_info_list_lookup_path (infoList, d->port.latin1());
|
|
|
|
gp_abilities_list_get_abilities(abilList, modelNum, &d->cameraAbilities);
|
|
|
|
if (gp_camera_set_abilities(d->camera, d->cameraAbilities) != GP_OK) {
|
|
gp_camera_unref(d->camera);
|
|
d->camera = 0;
|
|
gp_abilities_list_free(abilList);
|
|
gp_port_info_list_free(infoList);
|
|
return GPSetup;
|
|
}
|
|
if (d->model != "Directory Browse") {
|
|
gp_port_info_list_get_info(infoList, portNum, &info);
|
|
if (gp_camera_set_port_info(d->camera, info) != GP_OK) {
|
|
gp_camera_unref(d->camera);
|
|
d->camera = 0;
|
|
gp_abilities_list_free (abilList);
|
|
gp_port_info_list_free (infoList);
|
|
return GPSetup;
|
|
}
|
|
}
|
|
gp_abilities_list_free (abilList);
|
|
gp_port_info_list_free (infoList);
|
|
if (d->cameraAbilities.file_operations & GP_FILE_OPERATION_PREVIEW) {
|
|
d->thumbnailSupport = true;
|
|
}
|
|
if (d->cameraAbilities.file_operations & GP_FILE_OPERATION_DELETE) {
|
|
d->deleteSupport = true;
|
|
}
|
|
if (d->cameraAbilities.folder_operations & GP_FOLDER_OPERATION_PUT_FILE) {
|
|
d->uploadSupport = true;
|
|
}
|
|
if (d->cameraAbilities.folder_operations & GP_FOLDER_OPERATION_MAKE_DIR) {
|
|
d->mkDirSupport = true;
|
|
}
|
|
if (d->cameraAbilities.folder_operations & GP_FOLDER_OPERATION_REMOVE_DIR) {
|
|
d->delDirSupport = true;
|
|
}
|
|
d->cameraSetup = true;
|
|
return GPSuccess;
|
|
}
|
|
|
|
int GPCamera::initialize() {
|
|
if (!d->cameraSetup || !d->camera) {
|
|
int result = setup();
|
|
if (result != GPSuccess) {
|
|
return result;
|
|
}
|
|
}
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus();
|
|
// Try and initialize the camera to see if its connected
|
|
if (gp_camera_init(d->camera, status->context) != GP_OK) {
|
|
gp_camera_unref(d->camera);
|
|
d->camera = 0;
|
|
delete status;
|
|
status = 0;
|
|
return GPInit;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
d->cameraInitialized = true;
|
|
return GPSuccess;
|
|
}
|
|
|
|
void GPCamera::cancel() {
|
|
if (!status) {
|
|
return;
|
|
}
|
|
status->cancelOperation();
|
|
}
|
|
|
|
bool GPCamera::thumbnailSupport() {
|
|
return d->thumbnailSupport;
|
|
}
|
|
|
|
bool GPCamera::deleteSupport() {
|
|
return d->deleteSupport;
|
|
}
|
|
|
|
bool GPCamera::uploadSupport() {
|
|
return d->uploadSupport;
|
|
}
|
|
|
|
bool GPCamera::mkDirSupport() {
|
|
return d->mkDirSupport;
|
|
}
|
|
|
|
bool GPCamera::delDirSupport() {
|
|
return d->delDirSupport;
|
|
}
|
|
|
|
int GPCamera::getSubFolders(const TQString& folder, TQValueList<TQString>& subFolderList) {
|
|
::CameraList *clist;
|
|
gp_list_new(&clist);
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus();
|
|
if (gp_camera_folder_list_folders(d->camera, folder.latin1(), clist, status->context) != GP_OK) {
|
|
gp_list_unref(clist);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
int count = gp_list_count(clist);
|
|
for (int i=0; i<count; i++) {
|
|
const char* subFolder;
|
|
if (gp_list_get_name(clist, i, &subFolder) != GP_OK) {
|
|
gp_list_unref(clist);
|
|
return GPError;
|
|
}
|
|
subFolderList.append(TQString(subFolder));
|
|
}
|
|
gp_list_unref(clist);
|
|
return GPSuccess;
|
|
}
|
|
|
|
void GPCamera::getAllItemsInfo(const TQString& folder, GPFileItemInfoList& infoList) {
|
|
TQValueList<TQString> folderList;
|
|
folderList.clear();
|
|
// Get all items in this folder first
|
|
getItemsInfo(folder, infoList);
|
|
// Get all subfolders in this folder
|
|
getSubFolders(folder, folderList);
|
|
if (folderList.count() > 0) {
|
|
for (unsigned int i=0; i<folderList.count(); i++) {
|
|
TQString subFolder(folder);
|
|
if (!subFolder.endsWith("/")) {
|
|
subFolder += "/";
|
|
}
|
|
subFolder += folderList[i];
|
|
getAllItemsInfo(subFolder, infoList);
|
|
}
|
|
}
|
|
}
|
|
|
|
int GPCamera::getItemsInfo(const TQString& folder, GPFileItemInfoList& infoList) {
|
|
::CameraList *clist;
|
|
const char *cname;
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
gp_list_new(&clist);
|
|
if (gp_camera_folder_list_files(d->camera, folder.latin1(), clist, status->context) != GP_OK) {
|
|
gp_list_unref(clist);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
int count = gp_list_count(clist);
|
|
for (int i=0; i<count; i++) {
|
|
if (gp_list_get_name(clist, i, &cname) != GP_OK) {
|
|
gp_list_unref(clist);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
GPFileItemInfo camFileInfo;
|
|
camFileInfo.name = TQString(cname);
|
|
camFileInfo.folder = folder;
|
|
CameraFileInfo info;
|
|
if (gp_camera_file_get_info(d->camera, folder.latin1(), cname, &info, status->context) == GP_OK) {
|
|
if (info.file.fields != GP_FILE_INFO_NONE) {
|
|
camFileInfo.fileInfoAvailable = true;
|
|
|
|
if (info.file.fields & GP_FILE_INFO_TYPE) {
|
|
camFileInfo.mime = TQString(info.file.type);
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_SIZE) {
|
|
camFileInfo.size = info.file.size;
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_WIDTH) {
|
|
camFileInfo.width = info.file.width;
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_HEIGHT) {
|
|
camFileInfo.height = info.file.height;
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_STATUS) {
|
|
if (info.file.status == GP_FILE_STATUS_DOWNLOADED) {
|
|
camFileInfo.downloaded = 1;
|
|
} else {
|
|
camFileInfo.downloaded = 0;
|
|
}
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_PERMISSIONS) {
|
|
if (info.file.permissions & GP_FILE_PERM_READ) {
|
|
camFileInfo.readPermissions = 1;
|
|
} else {
|
|
camFileInfo.readPermissions = 0;
|
|
}
|
|
if (info.file.permissions & GP_FILE_PERM_DELETE) {
|
|
camFileInfo.writePermissions = 1;
|
|
} else {
|
|
camFileInfo.writePermissions = 0;
|
|
}
|
|
}
|
|
if (info.file.fields & GP_FILE_INFO_MTIME) {
|
|
TQString time = TQString(asctime(localtime(&info.file.mtime)));
|
|
time.truncate(time.length()-1);
|
|
camFileInfo.time = time;
|
|
}
|
|
|
|
}
|
|
}
|
|
infoList.append(camFileInfo);
|
|
}
|
|
gp_list_unref(clist);
|
|
delete status;
|
|
status = 0;
|
|
return GPSuccess;
|
|
}
|
|
|
|
int GPCamera::getThumbnail(const TQString& folder, const TQString& imageName, TQImage& thumbnail) {
|
|
CameraFile *cfile;
|
|
const char* data;
|
|
unsigned long int size;
|
|
gp_file_new(&cfile);
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
if (gp_camera_file_get(d->camera, folder.latin1(), imageName.latin1(), GP_FILE_TYPE_PREVIEW, cfile, status->context) != GP_OK) {
|
|
gp_file_unref(cfile);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
gp_file_get_data_and_size(cfile, &data, &size);
|
|
thumbnail.loadFromData((const uchar*) data, (uint) size);
|
|
gp_file_unref (cfile);
|
|
return GPSuccess;
|
|
}
|
|
|
|
int GPCamera::downloadItem(const TQString& folder, const TQString& itemName, const TQString& saveFile) {
|
|
CameraFile *cfile;
|
|
gp_file_new(&cfile);
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
if (gp_camera_file_get(d->camera, folder.latin1(), itemName.latin1(), GP_FILE_TYPE_NORMAL, cfile, status->context) != GP_OK) {
|
|
gp_file_unref(cfile);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
if (gp_file_save(cfile, saveFile.latin1()) != GP_OK) {
|
|
gp_file_unref(cfile);
|
|
return GPError;
|
|
}
|
|
gp_file_unref(cfile);
|
|
return GPSuccess;
|
|
}
|
|
|
|
int GPCamera::deleteItem(const TQString& folder, const TQString& itemName) {
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
if(gp_camera_file_delete(d->camera, folder.latin1(), itemName.latin1(), status->context) != GP_OK) {
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
return GPSuccess;
|
|
}
|
|
|
|
// recursively delete all items
|
|
int GPCamera::deleteAllItems(const TQString& folder) {
|
|
TQValueList<TQString> folderList;
|
|
folderList.clear();
|
|
// Get all subfolders in this folder
|
|
getSubFolders(folder, folderList);
|
|
if (folderList.count() > 0) {
|
|
for (unsigned int i=0; i<folderList.count(); i++) {
|
|
TQString subFolder(folder);
|
|
if (!subFolder.endsWith("/"))
|
|
subFolder += "/";
|
|
subFolder += folderList[i];
|
|
|
|
deleteAllItems(subFolder);
|
|
}
|
|
}
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
if (gp_camera_folder_delete_all(d->camera, folder.latin1(), status->context) != GP_OK) {
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
delete status;
|
|
status = 0;
|
|
return GPSuccess;
|
|
}
|
|
|
|
int GPCamera::uploadItem(const TQString& folder, const TQString& itemName, const TQString& localFile) {
|
|
CameraFile *cfile;
|
|
gp_file_new(&cfile);
|
|
if (gp_file_open(cfile, TQFile::encodeName( localFile )) != GP_OK) {
|
|
gp_file_unref(cfile);
|
|
return GPError;
|
|
}
|
|
gp_file_set_name(cfile, TQFile::encodeName( itemName ));
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
if (gp_camera_folder_put_file(d->camera, TQFile::encodeName( folder ),
|
|
# ifdef HAVE_GPHOTO2_5
|
|
TQFile::encodeName( localFile ), GP_FILE_TYPE_NORMAL,
|
|
# endif
|
|
cfile, status->context) != GP_OK) {
|
|
gp_file_unref(cfile);
|
|
delete status;
|
|
status = 0;
|
|
return GPError;
|
|
}
|
|
gp_file_unref(cfile);
|
|
delete status;
|
|
status = 0;
|
|
return GPSuccess;
|
|
}
|
|
|
|
void GPCamera::cameraSummary(TQString& summary) {
|
|
CameraText sum;
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
gp_camera_get_summary(d->camera, &sum, status->context);
|
|
summary = TQString(sum.text);
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
|
|
void GPCamera::cameraManual(TQString& manual) {
|
|
CameraText man;
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
gp_camera_get_manual(d->camera, &man, status->context);
|
|
manual = TQString(man.text);
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
|
|
void GPCamera::cameraAbout(TQString& about) {
|
|
CameraText abt;
|
|
if (status) {
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
status = new GPStatus;
|
|
gp_camera_get_about(d->camera, &abt, status->context);
|
|
about = TQString(abt.text);
|
|
delete status;
|
|
status = 0;
|
|
}
|
|
|
|
// Static functions
|
|
void GPCamera::getSupportedCameras(int& count, TQStringList& clist) {
|
|
clist.clear();
|
|
count = 0;
|
|
|
|
CameraAbilitiesList *abilList;
|
|
CameraAbilities abil;
|
|
GPContext *context;
|
|
|
|
context = gp_context_new ();
|
|
|
|
gp_abilities_list_new( &abilList );
|
|
gp_abilities_list_load( abilList, context );
|
|
|
|
count = gp_abilities_list_count( abilList );
|
|
if ( count < 0) {
|
|
gp_context_unref( context );
|
|
tqWarning("failed to get list of cameras");
|
|
return;
|
|
} else {
|
|
for (int i=0; i<count; i++) {
|
|
const char *cname;
|
|
gp_abilities_list_get_abilities( abilList, i, &abil );
|
|
cname = abil.model;
|
|
clist.append( TQString( cname ) );
|
|
}
|
|
}
|
|
gp_abilities_list_free( abilList );
|
|
gp_context_unref( context );
|
|
}
|
|
|
|
void GPCamera::getSupportedPorts(TQStringList& plist) {
|
|
GPPortInfoList *list;
|
|
GPPortInfo info;
|
|
|
|
plist.clear();
|
|
|
|
gp_port_info_list_new( &list );
|
|
gp_port_info_list_load( list );
|
|
|
|
int numPorts = gp_port_info_list_count( list );
|
|
for (int i = 0; i < numPorts; i++) {
|
|
gp_port_info_list_get_info( list, i, &info );
|
|
# ifdef HAVE_GPHOTO2_5
|
|
char *xpath;
|
|
gp_port_info_get_path (info, &xpath);
|
|
plist.append(xpath);
|
|
# else
|
|
plist.append(info.path);
|
|
# endif
|
|
}
|
|
gp_port_info_list_free( list );
|
|
}
|
|
|
|
void GPCamera::getCameraSupportedPorts(const TQString& model, TQStringList& plist) {
|
|
int i = 0;
|
|
plist.clear();
|
|
|
|
CameraAbilities abilities;
|
|
CameraAbilitiesList *abilList;
|
|
GPContext *context;
|
|
|
|
context = gp_context_new ();
|
|
|
|
gp_abilities_list_new (&abilList);
|
|
gp_abilities_list_load (abilList, context);
|
|
i = gp_abilities_list_lookup_model (abilList, model.local8Bit().data());
|
|
gp_abilities_list_get_abilities (abilList, i, &abilities);
|
|
gp_abilities_list_free (abilList);
|
|
|
|
if (abilities.port & GP_PORT_SERIAL) {
|
|
plist.append("serial");
|
|
}
|
|
if (abilities.port & GP_PORT_USB) {
|
|
plist.append("usb");
|
|
}
|
|
gp_context_unref( context );
|
|
|
|
}
|
|
|
|
int GPCamera::autoDetect(TQString& model, TQString& port) {
|
|
::CameraList *pCamList;
|
|
CameraAbilitiesList *abilList;
|
|
GPPortInfoList *infoList;
|
|
const char *camModel_, *camPort_;
|
|
GPContext *context;
|
|
|
|
context = gp_context_new ();
|
|
gp_list_new(&pCamList);
|
|
|
|
gp_abilities_list_new (&abilList);
|
|
gp_abilities_list_load (abilList, context);
|
|
gp_port_info_list_new (&infoList);
|
|
gp_port_info_list_load (infoList);
|
|
gp_abilities_list_detect (abilList, infoList, pCamList, context);
|
|
gp_abilities_list_free (abilList);
|
|
gp_port_info_list_free (infoList);
|
|
|
|
gp_context_unref( context );
|
|
|
|
int count = gp_list_count (pCamList);
|
|
|
|
if (count<=0) {
|
|
gp_list_free(pCamList);
|
|
return -1;
|
|
}
|
|
for (int i = 0; i < count; i++) {
|
|
gp_list_get_name (pCamList, i, &camModel_);
|
|
gp_list_get_value (pCamList, i, &camPort_);
|
|
}
|
|
model = camModel_;
|
|
port = camPort_;
|
|
gp_list_free(pCamList);
|
|
|
|
return 0;
|
|
}
|
|
|
|
} // NameSpace KIPIKameraKlientPlugin
|