added filter

This commit is contained in:
2023-03-28 08:55:15 +02:00
parent 44bba9bbdc
commit d8f5c2dff6
17 changed files with 3118 additions and 83 deletions
+34 -3
View File
@@ -13,7 +13,8 @@ cAlbumRoots::cAlbumRoots(const qint32& id, QObject* parent) :
m_type(0),
m_identifier(""),
m_specificPath(""),
m_item(nullptr)
m_item(nullptr),
m_drive("")
{
}
@@ -28,6 +29,10 @@ cAlbumRoots::cAlbumRoots(const qint32& id, const QString& label, const quint32 s
{
}
cAlbumRoots::~cAlbumRoots()
{
}
qint32 cAlbumRoots::id()
{
return(m_id);
@@ -93,6 +98,19 @@ QStandardItem* cAlbumRoots::item()
return(m_item);
}
void cAlbumRoots::setDrive(const QString& drive)
{
m_drive = drive;
if(m_drive.right(1) == "/")
m_drive = m_drive.left(m_drive.length()-1);
}
QString cAlbumRoots::drive()
{
return(m_drive);
}
cAlbumRootsList::cAlbumRootsList(QSqlDatabase* dbDigikam, QSqlDatabase *dbThumbnail, QObject* parent) :
QObject(parent),
m_dbDigikam(dbDigikam),
@@ -100,7 +118,11 @@ cAlbumRootsList::cAlbumRootsList(QSqlDatabase* dbDigikam, QSqlDatabase *dbThumbn
{
}
bool cAlbumRootsList::load()
cAlbumRootsList::~cAlbumRootsList()
{
}
bool cAlbumRootsList::load(QList<SolidVolumeInfo>* volumes)
{
if(!m_dbDigikam)
return(false);
@@ -121,7 +143,16 @@ bool cAlbumRootsList::load()
}
while(query.next())
add(query.value("id").toInt(), query.value("label").toString(), query.value("status").toInt(), query.value("type").toInt(), query.value("identifier").toString(), query.value("specificPath").toString(), this);
{
cAlbumRoots* albumRoots = add(query.value("id").toInt(), query.value("label").toString(), query.value("status").toInt(), query.value("type").toInt(), query.value("identifier").toString(), query.value("specificPath").toString(), this);
QString identifier = albumRoots->identifier().mid(albumRoots->identifier().lastIndexOf("=")+1);
for(int x = 0;x < volumes->count();x++)
{
if(volumes->at(x).uuid == identifier)
albumRoots->setDrive(volumes->at(x).path);
}
}
return(true);
}
+14 -6
View File
@@ -2,6 +2,8 @@
#define CALBUMROOTS_H
#include "common.h"
#include <QString>
#include <QList>
#include <QStandardItem>
@@ -20,6 +22,7 @@ class cAlbumRoots : public QObject
public:
cAlbumRoots(const qint32& id, QObject* parent = nullptr);
cAlbumRoots(const qint32& id, const QString& label, const quint32 status, const qint32 type, const QString& identifier, const QString& specificPath, QObject* parent = nullptr);
~cAlbumRoots();
qint32 id();
@@ -41,6 +44,9 @@ public:
void setItem(QStandardItem* item);
QStandardItem* item();
void setDrive(const QString &drive);
QString drive();
private:
qint32 m_id;
QString m_label;
@@ -49,6 +55,7 @@ private:
QString m_identifier;
QString m_specificPath;
QStandardItem* m_item;
QString m_drive;
};
Q_DECLARE_METATYPE(cAlbumRoots*)
@@ -59,15 +66,16 @@ class cAlbumRootsList : public QObject, public QList<cAlbumRoots*>
public:
cAlbumRootsList(QSqlDatabase* dbDigikam, QSqlDatabase* dbThumbnail, QObject* parent = nullptr);
~cAlbumRootsList();
bool load();
cAlbumRoots* add(const qint32 &id, QObject* parent = nullptr);
cAlbumRoots* add(const qint32& id, const QString& label, const quint32 status, const qint32 type, const QString& identifier, const QString& specificPath, QObject* parent = nullptr);
cAlbumRoots* find(const qint32& id);
bool load(QList<SolidVolumeInfo>* volumes);
cAlbumRoots* add(const qint32 &id, QObject* parent = nullptr);
cAlbumRoots* add(const qint32& id, const QString& label, const quint32 status, const qint32 type, const QString& identifier, const QString& specificPath, QObject* parent = nullptr);
cAlbumRoots* find(const qint32& id);
private:
QSqlDatabase* m_dbDigikam;
QSqlDatabase* m_dbThumbnail;
QSqlDatabase* m_dbDigikam;
QSqlDatabase* m_dbThumbnail;
};
Q_DECLARE_METATYPE(cAlbumRootsList*)
+10
View File
@@ -41,6 +41,12 @@ cAlbums::cAlbums(const qint32& id, cAlbumRoots* albumRoots, const QString& relat
{
}
cAlbums::~cAlbums()
{
if(m_imagesList)
delete m_imagesList;
}
qint32 cAlbums::id()
{
return(m_id);
@@ -159,6 +165,10 @@ cAlbumsList::cAlbumsList(QSqlDatabase* dbDigikam, QSqlDatabase *dbThumbnail, cAl
{
}
cAlbumsList::~cAlbumsList()
{
}
bool cAlbumsList::load()
{
if(!m_dbDigikam)
+2
View File
@@ -23,6 +23,7 @@ class cAlbums : public QObject
public:
cAlbums(const qint32& id, cAlbumsList* albumsList, QSqlDatabase* dbDigikam, QSqlDatabase* m_dbThumbnail, QObject *parent = nullptr);
cAlbums(const qint32& id, cAlbumRoots* albumRoots, const QString& relativePath, const QDate& date, const QString& caption, const QString& collection, const QDateTime& modificationDate, cAlbumsList* albumsList, QSqlDatabase* dbDigikam, QSqlDatabase* dbThumbnail, QObject *parent = nullptr);
~cAlbums();
qint32 id();
@@ -79,6 +80,7 @@ class cAlbumsList : public QObject, public QList<cAlbums*>
public:
cAlbumsList(QSqlDatabase* dbDigikam, QSqlDatabase* dbThumbnail, cAlbumRootsList* albumRootsList, QObject* parent = nullptr);
~cAlbumsList();
bool load();
cAlbums* add(const qint32& id, QObject* parent = nullptr);
+1118
View File
File diff suppressed because it is too large Load Diff
+889
View File
@@ -0,0 +1,889 @@
/*!
\file cexif.h
*/
#ifndef CEXIF_H
#define CEXIF_H
#include <QString>
#include <QVariant>
#include <QDateTime>
#include <QImage>
#include <QMetaType>
#include <QList>
#include <QSqlDatabase>
/*!
\brief
\class cEXIFCompression cexif.h "cexif.h"
*/
class cEXIFCompression
{
public:
cEXIFCompression(const qint32& iID, const QString& szCompression);
qint32 m_iID; /*!< TODO: describe */
QString m_szCompression; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cEXIFCompression*)
/*!
\brief
\class cEXIFCompressionList cexif.h "cexif.h"
*/
class cEXIFCompressionList : public QList<cEXIFCompression*>
{
public:
cEXIFCompressionList(QSqlDatabase* db);
/*!
\brief
\fn add
\param iID
\param szCompression
\return cEXIFCompression
*/
cEXIFCompression* add(const qint32& iID, const QString& szCompression);
/*!
\brief
\fn find
\param iID
\return cEXIFCompression
*/
cEXIFCompression* find(const qint32& iID);
/*!
\brief
\fn compression
\param iID
\return QString
*/
QString compression(const qint32& iID);
private:
QSqlDatabase* m_dbExportDigikam;
};
//Q_DECLARE_METATYPE(cEXIFCompressionList)
/*!
\brief
\class cEXIFLightSource cexif.h "cexif.h"
*/
class cEXIFLightSource
{
public:
cEXIFLightSource(const qint32& iID, const QString& szLightSource);
qint32 m_iID; /*!< TODO: describe */
QString m_szLightSource; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cEXIFLightSource*)
/*!
\brief
\class cEXIFLightSourceList cexif.h "cexif.h"
*/
class cEXIFLightSourceList : public QList<cEXIFLightSource*>
{
public:
cEXIFLightSourceList(QSqlDatabase* db);
/*!
\brief
\fn add
\param iID
\param szLightSource
\return cEXIFLightSource
*/
cEXIFLightSource* add(const qint32& iID, const QString& szLightSource);
/*!
\brief
\fn find
\param iID
\return cEXIFLightSource
*/
cEXIFLightSource* find(const qint32& iID);
/*!
\brief
\fn lightSource
\param iID
\return QString
*/
QString lightSource(const qint32& iID);
private:
QSqlDatabase* m_dbExportDigikam;
};
/*!
\brief
\class cEXIFFlash cexif.h "cexif.h"
*/
class cEXIFFlash
{
public:
cEXIFFlash(const qint32& iID, const QString& szFlash);
qint32 m_iID; /*!< TODO: describe */
QString m_szFlash; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cEXIFFlash*)
/*!
\brief
\class cEXIFFlashList cexif.h "cexif.h"
*/
class cEXIFFlashList : public QList<cEXIFFlash*>
{
public:
cEXIFFlashList(QSqlDatabase* db);
/*!
\brief
\fn add
\param iID
\param szFlash
\return cEXIFFlash
*/
cEXIFFlash* add(const qint32& iID, const QString& szFlash);
/*!
\brief
\fn find
\param iID
\return cEXIFFlash
*/
cEXIFFlash* find(const qint32& iID);
/*!
\brief
\fn flash
\param iID
\return QString
*/
QString flash(const qint32& iID);
private:
QSqlDatabase* m_dbExportDigikam;
};
/**
* @brief
*
*/
class cEXIFTag
{
public:
cEXIFTag(const qint32& iTAGID, const QString& szTAGName, const QString& szIFD, const QString& szKey, const QString& szType, const QString& szDescription);
qint32 m_iTAGID; /*!< TODO: describe */
QString m_szTAGName; /*!< TODO: describe */
QString m_szIFD; /*!< TODO: describe */
QString m_szKey; /*!< TODO: describe */
QString m_szType; /*!< TODO: describe */
QString m_szDescription; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cEXIFTag*)
/*!
\brief
\class cEXIFTagList cexif.h "cexif.h"
*/
class cEXIFTagList : public QList<cEXIFTag*>
{
public:
cEXIFTagList(QSqlDatabase* db);
/*!
\brief
\fn add
\param iTAGID
\param szTAGName
\param szIFD
\param szType
\param szDescription
\return cEXIFTag
*/
cEXIFTag* add(const qint32& iTAGID, const QString& szTAGName, const QString& szIFD, const QString& szKey, const QString& szType, const QString& szDescription);
/*!
\brief
\fn find
\param szKey
\return cEXIFTag
*/
cEXIFTag* find(const QString& szKey);
/*!
\brief
\fn find
\param iTAGID
\param szIFD
\return cEXIFTag
*/
cEXIFTag* find(const qint32& iTAGID, const QString& szIFD);
/*!
\brief
\fn find
\param szTAG
\param szIFD
\return cEXIFTag
*/
cEXIFTag* find(const QString& szTAG, const QString& szIFD);
private:
QSqlDatabase* m_dbExportDigikam;
};
/*!
\brief
*/
class cEXIFValue
{
public:
cEXIFValue(cEXIFTag* lpEXIFTag);
/*!
\brief
\fn exifTag
\return cEXIFTag
*/
cEXIFTag* exifTag();
/*!
\brief
\fn setValue
\param szValue
\param iTypeId
\param iCount
*/
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
/*!
\brief
\fn value
\return QVariant
*/
QVariant value();
/*!
\brief
\fn valueList
\return QList<QVariant>
*/
QList<QVariant> valueList();
private:
cEXIFTag* m_lpEXIFTag; /*!< TODO: describe */
QList<QVariant> m_valueList; /*!< TODO: describe */
/*!
\brief
\fn convertValue
\param szValue
\param iTypeId
\return QVariant
*/
QVariant convertValue(const QString& szValue, qint32 iTypeId);
};
Q_DECLARE_METATYPE(cEXIFValue*)
/*!
\brief
\class cEXIFValueList cexif.h "cexif.h"
*/
class cEXIFValueList : public QList<cEXIFValue*>
{
public:
cEXIFValueList();
/*!
\brief
\fn add
\param lpEXIFTag
\return cEXIFValue
*/
cEXIFValue* add(cEXIFTag* lpEXIFTag);
/*!
\brief
\fn find
\param lpEXIFTag
\return cEXIFValue
*/
cEXIFValue* find(cEXIFTag* lpEXIFTag);
};
/**
* @brief
*
*/
class cIPTCTag
{
public:
cIPTCTag(const qint32& iTAGID, const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
qint32 m_iTAGID; /*!< TODO: describe */
QString m_szTAGName; /*!< TODO: describe */
qint32 m_iTypeID; /*!< TODO: describe */
QString m_szDescription; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cIPTCTag*)
/*!
\brief
\class cIPTCTagList cexif.h "cexif.h"
*/
class cIPTCTagList : public QList<cIPTCTag*>
{
public:
cIPTCTagList(QSqlDatabase* db);
/*!
\brief
\fn add
\param iTAGID
\param szTAGName
\param iTypeID
\param szDescription
\return cIPTCTag
*/
cIPTCTag* add(const qint32& iTAGID, const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
/*!
\brief
\fn find
\param iTAGID
\return cIPTCTag
*/
cIPTCTag* find(const qint32& iTAGID);
private:
QSqlDatabase* m_dbExportDigikam;
};
/*!
\brief
*/
class cIPTCValue
{
public:
cIPTCValue(cIPTCTag* lpIPTCTag);
/*!
\brief
\fn iptcTag
\return cIPTCTag
*/
cIPTCTag* iptcTag();
/*!
\brief
\fn setValue
\param szValue
\param iTypeId
\param iCount
*/
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
/*!
\brief
\fn value
\return QVariant
*/
QVariant value();
/*!
\brief
\fn valueList
\return QList<QVariant>
*/
QList<QVariant> valueList();
private:
cIPTCTag* m_lpIPTCTag; /*!< TODO: describe */
QList<QVariant> m_valueList; /*!< TODO: describe */
/*!
\brief
\fn convertValue
\param szValue
\param iTypeId
\return QVariant
*/
QVariant convertValue(const QString& szValue, qint32 iTypeId);
};
Q_DECLARE_METATYPE(cIPTCValue*)
/*!
\brief
\class cIPTCValueList cexif.h "cexif.h"
*/
class cIPTCValueList : public QList<cIPTCValue*>
{
public:
cIPTCValueList();
/*!
\brief
\fn add
\param lpIPTCTag
\return cIPTCValue
*/
cIPTCValue* add(cIPTCTag* lpIPTCTag);
/*!
\brief
\fn find
\param lpIPTCTag
\return cIPTCValue
*/
cIPTCValue* find(cIPTCTag* lpIPTCTag);
};
/**
* @brief
*
*/
class cXMPTag
{
public:
cXMPTag(const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
QString m_szTAGName; /*!< TODO: describe */
qint32 m_iTypeID; /*!< TODO: describe */
QString m_szDescription; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cXMPTag*)
/*!
\brief
\class cXMPTagList cexif.h "cexif.h"
*/
class cXMPTagList : public QList<cXMPTag*>
{
public:
cXMPTagList(QSqlDatabase* db);
/*!
\brief
\fn add
\param szTAGName
\param iTypeID
\param szDescription
\return cXMPTag
*/
cXMPTag* add(const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
/*!
\brief
\fn find
\param szTAGName
\return cXMPTag
*/
cXMPTag* find(const QString& szTAGName);
private:
QSqlDatabase* m_dbExportDigikam;
};
/*!
\brief
*/
class cXMPValue
{
public:
cXMPValue(cXMPTag* lpXMPTag);
/*!
\brief
\fn exifTag
\return cXMPTag
*/
cXMPTag* xmpTag();
/*!
\brief
\fn setValue
\param szValue
\param iTypeId
\param iCount
*/
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
/*!
\brief
\fn value
\return QVariant
*/
QVariant value();
/*!
\brief
\fn valueList
\return QList<QVariant>
*/
QList<QVariant> valueList();
private:
cXMPTag* m_lpXMPTag; /*!< TODO: describe */
QList<QVariant> m_valueList; /*!< TODO: describe */
/*!
\brief
\fn convertValue
\param szValue
\param iTypeId
\return QVariant
*/
QVariant convertValue(const QString& szValue, qint32 iTypeId);
};
Q_DECLARE_METATYPE(cXMPValue*)
/*!
\brief
\class cXMPValueList cexif.h "cexif.h"
*/
class cXMPValueList : public QList<cXMPValue*>
{
public:
cXMPValueList();
/*!
\brief
\fn add
\param lpXMPTag
\return cXMPValue
*/
cXMPValue* add(cXMPTag* lpXMPTag);
/*!
\brief
\fn find
\param lpXMPTag
\return cXMPValue
*/
cXMPValue* find(cXMPTag* lpXMPTag);
};
/*!
\brief
\class cEXIF cexif.h "cexif.h"
*/
class cEXIF
{
public:
cEXIF(cEXIFTagList* lpEXIFTagList, cEXIFCompressionList* lpEXIFCompressionList, cEXIFLightSourceList* lpEXIFLightSourceList, cEXIFFlashList* lpEXIFFlashList, cIPTCTagList* lpIPTCTagList, cXMPTagList* lpXMPTagList);
/*!
\brief
\fn fromFile
\param szFileName
\param withThumbnail
\return bool
*/
bool fromFile(const QString& szFileName, bool withThumbnail = true);
/*!
\brief
\fn mimeType
\return QString
*/
QString mimeType();
/*!
\brief
\fn imageWidth
\return qint32
*/
qint32 imageWidth();
/*!
\brief
\fn imageHeight
\return qint32
*/
qint32 imageHeight();
/*!
\brief
\fn imageOrientation
\return qint16
*/
qint16 imageOrientation();
/*!
\brief
\fn cameraMake
\return QString
*/
QString cameraMake();
/*!
\brief
\fn cameraModel
\return QString
*/
QString cameraModel();
/*!
\brief
\fn dateTime
\return QDateTime
*/
QDateTime dateTime();
/*!
\brief
\fn fNumber
\return QString
*/
QString fNumber();
/*!
\brief
\fn iso
\return qint32
*/
qint32 iso();
/*!
\brief
\fn flash
\return QString
*/
QString flash();
/*!
\brief
\fn flashID
\return qint32
*/
qint32 flashID();
/*!
\brief
\fn focalLength
\return qreal
*/
qreal focalLength();
/*!
\brief
\fn lensMake
\return QString
*/
QString lensMake();
/*!
\brief
\fn lensModel
\return QString
*/
QString lensModel();
/*!
\brief
\fn exposureTime
\return QString
*/
QString exposureTime();
/*!
\brief
\fn exposureBias
\return qint32
*/
qint32 exposureBias();
/*!
\brief
\fn exifVersion
\return QString
*/
QString exifVersion();
/*!
\brief
\fn dateTimeOriginal
\return QDateTime
*/
QDateTime dateTimeOriginal();
/*!
\brief
\fn dateTimeDigitized
\return QDateTime
*/
QDateTime dateTimeDigitized();
/*!
\brief
\fn whiteBalance
\return qint32
*/
qint32 whiteBalance();
/*!
\brief
\fn focalLength35
\return qreal
*/
qreal focalLength35();
/*!
\brief
\fn gps
\return QString
*/
QString gps();
/*!
\brief
\fn duration
\return QString
*/
QString duration();
/*!
\brief
\fn fileName
\return QString
*/
QString fileName();
/*!
\brief
\fn previewList
\return QList<QImage>
*/
QList<QImage> previewList();
/*!
\brief
\fn thumbnail
\return QImage
*/
QImage thumbnail();
/*!
\brief
\fn copyTo
\param fileName
*/
bool copyTo(const QString& fileName);
private:
cEXIFValueList m_exifValueList; /*!< TODO: describe */
cIPTCValueList m_iptcValueList; /*!< TODO: describe */
cXMPValueList m_xmpValueList; /*!< TODO: describe */
QString m_szMimeType; /*!< TODO: describe */
qint32 m_iWidth; /*!< TODO: describe */
qint32 m_iHeight; /*!< TODO: describe */
QString m_szFileName; /*!< TODO: describe */
QList<QImage> m_previewList; /*!< TODO: describe */
QImage m_thumbnail; /*!< TODO: describe */
cEXIFTagList* m_lpEXIFTagList; /*!< TODO: describe */
cEXIFCompressionList* m_lpEXIFCompressionList; /*!< TODO: describe */
cEXIFLightSourceList* m_lpEXIFLightSourceList; /*!< TODO: describe */
cEXIFFlashList* m_lpEXIFFlashList; /*!< TODO: describe */
cIPTCTagList* m_lpIPTCTagList; /*!< TODO: describe */
cXMPTagList* m_lpXMPTagList; /*!< TODO: describe */
/*!
\brief
\fn getEXIFTag
\param iTAGID
\param szIFD
\return QVariant
*/
QVariant getEXIFTag(qint32 iTAGID, const QString& szIFD);
/*!
\brief
\fn getIPTCTag
\param iTAGID
\return QVariant
*/
QVariant getIPTCTag(qint32 iTAGID);
/*!
\brief
\fn getXMPTag
\param szTAGName
\return QVariant
*/
QVariant getXMPTag(const QString& szTAGName);
/*!
\brief
\fn getTagList
\param iTAGID
\param iIFDID
\return QList<QVariant>
*/
QList<QVariant> getTagList(qint32 iTAGID, const QString& szIFD);
};
Q_DECLARE_METATYPE(cEXIF*)
#endif // CEXIF_H
+30
View File
@@ -16,6 +16,8 @@
#include <QDebug>
#include <QElapsedTimer>
#include <fileapi.h>
cImage::cImage() :
QImage(),
@@ -119,7 +121,35 @@ bool cImage::openBuffer(const QString &fileName, const QScopedPointer<QByteArray
QFileInfo fi(fileName);
if(fi.suffix().contains("iiq", Qt::CaseInsensitive) || !ba || ba->isEmpty())
{
#ifdef Q_OS_WIN
QString in = fileName;
long length = 0;
TCHAR input[fileName.length()];
TCHAR* buffer = NULL;
QString x;
in.toWCharArray(input);
length = GetShortPathName(input, NULL, 0);
buffer = new TCHAR[length];
length = GetShortPathName(input, buffer, length);
if(length)
{
x = QString::fromWCharArray(buffer);
error = iProcessor.open_file(x.toStdString().c_str());
delete [] buffer;
}
else
{
delete [] buffer;
return(false);
}
#elif Q_OS_UNIX
error = iProcessor.open_file(fileName.toStdString().c_str());
#endif
}
else
{
if(ba->isEmpty() || ba->size() < 100)
+13
View File
@@ -41,6 +41,15 @@ cImages::cImages(const qint32& id, cAlbums* albums, const QString& name, const q
{
}
cImages::~cImages()
{
if(m_thumbnail)
delete m_thumbnail;
if(m_item)
delete m_item;
}
qint32 cImages::id()
{
return(m_id);
@@ -308,6 +317,10 @@ cImagesList::cImagesList(QSqlDatabase* dbDigikam, QSqlDatabase *dbThumbnail, cAl
{
}
cImagesList::~cImagesList()
{
}
bool cImagesList::load(bool loadThumbnails, cAlbums* albums)
{
if(!m_dbDigikam)
+2
View File
@@ -26,6 +26,7 @@ class cImages : public QObject
public:
cImages(const qint32& id, QObject *parent = nullptr);
cImages(const qint32& id, cAlbums* albums, const QString& name, const qint8& status, const qint8& category, const QDateTime& modificationDate, const qint32& fileSize, const QString& uniqueHash, const qint32& manualOrder, QSqlDatabase* dbThumbnail, QObject *parent = nullptr);
~cImages();
qint32 id();
@@ -114,6 +115,7 @@ class cImagesList : public QObject, public QList<cImages*>
public:
cImagesList(QSqlDatabase* dbDigikam, QSqlDatabase* dbThumbnail, cAlbumsList* albumsList, QObject* parent = nullptr);
~cImagesList();
bool load(bool loadThumbnails, cAlbums* albums);
bool load(bool loadThumbnails, const qint32& albumsID);
+540 -62
View File
@@ -1,3 +1,5 @@
#include "common.h"
#include "cmainwindow.h"
#include "ui_cmainwindow.h"
@@ -17,6 +19,12 @@
#include <QMessageBox>
#include <QElapsedTimer>
#include <QFileInfo>
#include <QDir>
#include <QStorageInfo>
#define DBROOT "C:\\Users\\birkeh\\OneDrive\\__MEDIA__"
void addToExportLog(QString& exportLog, const QString& text)
{
@@ -30,7 +38,7 @@ cMainWindow::cMainWindow(QWidget *parent) :
ui(new Ui::cMainWindow),
m_progressBar(nullptr),
m_listToolBar(nullptr),
m_refreshAction(nullptr),
// m_refreshAction(nullptr),
m_actionToolBar(nullptr),
m_exportAction(nullptr),
m_stopAction(nullptr),
@@ -38,9 +46,17 @@ cMainWindow::cMainWindow(QWidget *parent) :
m_albumsList(nullptr),
m_folderViewModel(nullptr),
m_folderSortFilterProxyModel(nullptr),
m_includeViewModel(nullptr),
m_excludeViewModel(nullptr),
m_thumbnailViewModel(nullptr),
m_thumbnailSortFilterProxyModel(nullptr),
m_rootItem(nullptr),
m_exifTAGList(nullptr),
m_exifCompressionList(nullptr),
m_exifLightSourceList(nullptr),
m_exifFlashList(nullptr),
m_iptcTagList(nullptr),
m_xmpTagList(nullptr),
m_loading(false),
m_working(false),
m_stopIt(false),
@@ -48,6 +64,9 @@ cMainWindow::cMainWindow(QWidget *parent) :
{
initUI();
createActions();
m_volumes = actuallyListVolumes();
setImageFormats();
loadData();
initSignals();
@@ -55,8 +74,27 @@ cMainWindow::cMainWindow(QWidget *parent) :
cMainWindow::~cMainWindow()
{
if(m_albumRootsList)
delete m_albumRootsList;
_DELETE_(m_progressBar);
_DELETE_(m_listToolBar);
_DELETE_(m_refreshAction);
_DELETE_(m_actionToolBar);
_DELETE_(m_exportAction);
_DELETE_(m_stopAction);
_DELETE_(m_albumRootsList);
_DELETE_(m_albumsList);
_DELETE_(m_excludeViewModel);
_DELETE_(m_includeViewModel);
_DELETE_(m_folderViewModel);
_DELETE_(m_folderSortFilterProxyModel);
_DELETE_(m_thumbnailViewModel);
_DELETE_(m_thumbnailSortFilterProxyModel);
_DELETE_(m_rootItem);
_DELETE_(m_exifTAGList);
_DELETE_(m_exifCompressionList);
_DELETE_(m_exifLightSourceList);
_DELETE_(m_exifFlashList);
_DELETE_(m_iptcTagList);
_DELETE_(m_xmpTagList);
if(m_dbThumbnail.isOpen())
m_dbThumbnail.close();
@@ -64,6 +102,9 @@ cMainWindow::~cMainWindow()
if(m_dbDigikam.isOpen())
m_dbDigikam.close();
if(m_dbExportDigikam.isOpen())
m_dbExportDigikam.close();
delete ui;
}
@@ -100,11 +141,17 @@ void cMainWindow::initUI()
ui->m_folderView->setModel(m_folderSortFilterProxyModel);
m_folderSortFilterProxyModel->setSourceModel(m_folderViewModel);
m_thumbnailViewModel = new QStandardItemModel;
m_thumbnailViewModel = new QStandardItemModel;
m_thumbnailSortFilterProxyModel = new cThumbnailSortFilterProxyModel(this);
ui->m_thumbnailView->setModel(m_thumbnailSortFilterProxyModel);
m_thumbnailSortFilterProxyModel->setSourceModel(m_thumbnailViewModel);
m_includeViewModel = new QStandardItemModel;
ui->m_includeView->setModel(m_includeViewModel);
m_excludeViewModel = new QStandardItemModel;
ui->m_excludeView->setModel(m_excludeViewModel);
QSettings settings;
if(!settings.value("main/maximized").toBool())
@@ -167,26 +214,31 @@ void cMainWindow::setImageFormats()
QList<QByteArray> readList = QImageReader::supportedImageFormats();
QList<QByteArray> writeList = QImageWriter::supportedImageFormats();
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "exportDigikam");
db.setHostName("localhost");
db.setDatabaseName("exportDigikam.db");
m_dbExportDigikam = QSqlDatabase::addDatabase("QSQLITE", "exportDigikam");
m_dbExportDigikam.setHostName("localhost");
m_dbExportDigikam.setDatabaseName("exportDigikam.db");
if(!db.open())
if(!m_dbExportDigikam.open())
return;
QSqlQuery query(db);
QSqlQuery query(m_dbExportDigikam);
query.prepare("SELECT shortname, description, extension FROM imageFormat;");
if(!query.exec())
{
db.close();
qDebug() << "reading from exportDigikam.db failed. " << query.lastError();
return;
}
while(query.next())
addImageFormat(query.value("shortname").toString(), query.value("description").toString(), query.value("extension").toString(), readList, writeList);
db.close();
m_exifTAGList = new cEXIFTagList(&m_dbExportDigikam);
m_exifCompressionList = new cEXIFCompressionList(&m_dbExportDigikam);
m_exifLightSourceList = new cEXIFLightSourceList(&m_dbExportDigikam);
m_exifFlashList = new cEXIFFlashList(&m_dbExportDigikam);
m_iptcTagList = new cIPTCTagList(&m_dbExportDigikam);
m_xmpTagList = new cXMPTagList(&m_dbExportDigikam);
}
void cMainWindow::addImageFormat(const QString& shortName, const QString& description, const QString& extension, QList<QByteArray>& readList, QList<QByteArray>& writeList)
@@ -208,12 +260,14 @@ void cMainWindow::addImageFormat(const QString& shortName, const QString& descri
void cMainWindow::loadData()
{
m_includeViewModel->clear();
m_excludeViewModel->clear();
m_thumbnailViewModel->clear();
m_folderViewModel->clear();
QElapsedTimer timer;
// QElapsedTimer timer;
timer.start();
// timer.start();
if(m_albumRootsList)
delete m_albumRootsList;
@@ -224,7 +278,7 @@ void cMainWindow::loadData()
if(!m_dbDigikam.isOpen())
{
m_dbDigikam = QSqlDatabase::addDatabase("QSQLITE", "digikam4");
m_dbDigikam.setDatabaseName("C:\\Temp\\__DIGIKAM__\\digikam4.db");
m_dbDigikam.setDatabaseName(QString(DBROOT) + QString("\\digikam4.db"));
if(!m_dbDigikam.open())
{
qDebug() << "Digikam: DB Open failed. " << m_dbDigikam.lastError().text();
@@ -235,7 +289,7 @@ void cMainWindow::loadData()
if(!m_dbThumbnail.isOpen())
{
m_dbThumbnail = QSqlDatabase::addDatabase("QSQLITE", "thumbnails-digikam");
m_dbThumbnail.setDatabaseName("C:\\Temp\\__DIGIKAM__\\thumbnails-digikam.db");
m_dbThumbnail.setDatabaseName(DBROOT + QString("\\thumbnails-digikam.db"));
if(!m_dbThumbnail.open())
{
qDebug() << "Thumbnail: DB Open failed. " << m_dbDigikam.lastError().text();
@@ -243,6 +297,19 @@ void cMainWindow::loadData()
}
}
m_tagsList = new cTagsList(&m_dbDigikam);
if(!m_tagsList)
{
qDebug() << "Tags List: out of memory.";
return;
}
if(!m_tagsList->load())
{
qDebug() << "Tags List: load failed.";
return;
}
m_albumRootsList = new cAlbumRootsList(&m_dbDigikam, &m_dbThumbnail, this);
if(!m_albumRootsList)
{
@@ -250,7 +317,7 @@ void cMainWindow::loadData()
return;
}
if(!m_albumRootsList->load())
if(!m_albumRootsList->load(&m_volumes))
{
qDebug() << "Album Root List: load failed.";
return;
@@ -269,7 +336,7 @@ void cMainWindow::loadData()
return;
}
qDebug() << "Loading took " << timer.elapsed() << "ms";
// qDebug() << "Loading took " << timer.elapsed() << "ms";
displayData();
ui->m_folderView->expandAll();
@@ -279,6 +346,33 @@ void cMainWindow::displayData()
{
m_loading = true;
m_includeViewModel->clear();
m_excludeViewModel->clear();
for(int x = 0;x < m_tagsList->count();x++)
{
cTags* lpTags = m_tagsList->at(x);
if(!lpTags->parent())
{
QStandardItem* lpInclude = new QStandardItem(lpTags->name());
lpInclude->setData(QVariant::fromValue(lpTags), Qt::UserRole+1);
lpInclude->setCheckable(true);
QStandardItem* lpExclude = new QStandardItem(lpTags->name());
lpExclude->setData(QVariant::fromValue(lpTags), Qt::UserRole+1);
lpExclude->setCheckable(true);
lpTags->setIncludeItem(lpInclude);
lpTags->setExcludeItem(lpExclude);
m_includeViewModel->appendRow(lpInclude);
m_excludeViewModel->appendRow(lpExclude);
addChildren(lpTags, lpInclude, lpExclude);
}
}
m_thumbnailViewModel->clear();
m_folderViewModel->clear();
@@ -307,13 +401,47 @@ void cMainWindow::displayData()
if(lpAlbums->parentAlbums())
lpRootItem = lpAlbums->parentAlbums()->item();
lpAlbums->setItem(lpItem);
lpRootItem->appendRow(lpItem);
if(!lpRootItem)
delete(lpItem);
else
{
lpAlbums->setItem(lpItem);
lpRootItem->appendRow(lpItem);
}
}
m_loading = false;
}
void cMainWindow::addChildren(cTags* tags, QStandardItem* include, QStandardItem* exclude)
{
cTagsList* tagsList = tags->childList();
if(!tagsList)
return;
for(int i = 0;i < tagsList->count();i++)
{
cTags* tags = tagsList->at(i);
QStandardItem* lpInclude = new QStandardItem(tags->name());
lpInclude->setData(QVariant::fromValue(tags), Qt::UserRole+1);
lpInclude->setCheckable(true);
QStandardItem* lpExclude = new QStandardItem(tags->name());
lpExclude->setData(QVariant::fromValue(tags), Qt::UserRole+1);
lpExclude->setCheckable(true);
tags->setIncludeItem(lpInclude);
tags->setExcludeItem(lpExclude);
include->appendRow(lpInclude);
exclude->appendRow(lpExclude);
addChildren(tags, lpInclude, lpExclude);
}
}
QStandardItem* cMainWindow::findDBRootItem(QStandardItemModel* model, QStandardItem *rootItem, cAlbumRoots* albumRoots)
{
QModelIndex parent;
@@ -359,6 +487,8 @@ QStandardItem* cMainWindow::findParentItem(QStandardItemModel* model, QStandardI
void cMainWindow::initSignals()
{
connect(m_folderViewModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onFolderViewItemChanged);
connect(m_includeViewModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onIncludeViewItemChanged);
connect(m_excludeViewModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onExcludeViewItemChanged);
connect(ui->m_folderView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onFolderSelected);
connect(ui->m_thumbnailView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onThumbnailSelected);
}
@@ -411,6 +541,36 @@ void cMainWindow::onFolderViewItemChanged(QStandardItem* item)
}
}
void cMainWindow::onIncludeViewItemChanged(QStandardItem* item)
{
Qt::CheckState state = item->checkState();
QModelIndex parent = item->index();
for(int x = 0;x < m_includeViewModel->rowCount(parent);x++)
{
QStandardItem* curItem = m_includeViewModel->itemFromIndex(m_includeViewModel->index(x, 0, parent));
if(!curItem)
continue;
curItem->setCheckState(state);
}
}
void cMainWindow::onExcludeViewItemChanged(QStandardItem* item)
{
Qt::CheckState state = item->checkState();
QModelIndex parent = item->index();
for(int x = 0;x < m_excludeViewModel->rowCount(parent);x++)
{
QStandardItem* curItem = m_excludeViewModel->itemFromIndex(m_excludeViewModel->index(x, 0, parent));
if(!curItem)
continue;
curItem->setCheckState(state);
}
}
void cMainWindow::onFolderSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/)
{
if(m_loading)
@@ -565,6 +725,28 @@ done:
if(exportDialog.exec() == QDialog::Rejected)
return;
m_exportInclude.clear();
m_exportExclude.clear();
for(int i = 0;i < m_tagsList->count();i++)
{
cTags* tags = m_tagsList->at(i);
QStandardItem* included = tags->includeItem();
QStandardItem* excluded = tags->excludeItem();
if(included)
{
if(included->checkState())
m_exportInclude.append(tags->id());
}
if(excluded)
{
if(excluded->checkState())
m_exportExclude.append(tags->id());
}
}
m_working = true;
m_stopIt = false;
// setActionEnabled(false, false, false, false, false, true);
@@ -575,6 +757,7 @@ done:
void cMainWindow::onStop()
{
m_stopIt = true;
}
void cMainWindow::doExport()
@@ -606,16 +789,25 @@ void cMainWindow::doExport()
qint32 fileCount = 0;
for(int x = 0;x < m_albumsList->count();x++)
{
if(m_stopIt)
break;
cAlbums* albums = m_albumsList->at(x);
if(albums)
{
if(m_stopIt)
break;
cImagesList* imagesList = albums->imagesList();
if(imagesList)
{
for(int y = 0;y < imagesList->count();y++)
{
if(m_stopIt)
break;
cImages* images = albums->imagesList()->at(y);
if(images)
@@ -660,12 +852,23 @@ void cMainWindow::doExport()
{
if(item->checkState() == Qt::Checked)
{
m_progressBar->setValue(curFile);
ui->m_statusBar->showMessage(images->name());
qApp->processEvents();
// overwrite = exportFile(exportSettings, overwrite);
if(m_stopIt)
break;
curFile++;
cAlbums* albums = images->albums();
QString path = albums->albumRoots()->drive() + albums->albumRoots()->specificPath() + "/" + albums->relativePath();
QString file = path + "/" + images->name();
ui->m_statusBar->showMessage(QString(tr("checking file %1...")).arg(file));
m_progressBar->setValue(curFile);
qApp->processEvents();
cEXIF exif(m_exifTAGList, m_exifCompressionList, m_exifLightSourceList, m_exifFlashList, m_iptcTagList, m_xmpTagList);
if(exif.fromFile(file, false))
{
overwrite = exportFile(exportSettings, &exif, images, overwrite);
curFile++;
}
}
}
}
@@ -674,29 +877,6 @@ void cMainWindow::doExport()
}
}
// for(int i = 0;i < m_lpFileListModel->rowCount();i++)
// {
// QStandardItem* lpItem = m_lpFileListModel->item(i, 0);
// if(!lpItem)
// continue;
// cEXIF* lpExif = lpItem->data(Qt::UserRole+1).value<cEXIF*>();
// if(!lpExif)
// continue;
// overwrite = exportFile(exportSettings, lpExif, overwrite);
// m_lpProgressBar->setValue(i+1);
// qApp->processEvents();
// if(m_stopIt)
// {
// addToExportLog(m_exportLog, "<b>aborted.</b>");
// break;
// }
// }
m_progressBar->setVisible(false);
ui->m_statusBar->showMessage(tr("export done."), 3000);
@@ -710,21 +890,6 @@ void cMainWindow::doExport()
logWindow.exec();
}
/*
DIRECTORY_METHOD directoryMethod;
QString directory;
bool keepStructure;
QString directoryTag;
STRIP_LAST_FOLDER_METHOD stripLastFolderMethod;
QStringList stripLastFolderIfList;
FILE_METHOD fileMethod;
FILE_ADD fileAdd;
QString fileTag;
OVERWRITE_METHOD overwriteMethod;
bool copyEXIF;
QString fileFormat;
int quality;
*/
void cMainWindow::getExportSettings(EXPORTSETTINGS& exportSettings)
{
QSettings settings;
@@ -840,3 +1005,316 @@ void cMainWindow::getExportSettings(EXPORTSETTINGS& exportSettings)
addToExportLog(m_exportLog, "File Format: <span class='option'>" + exportSettings.fileFormat + "</span>");
addToExportLog(m_exportLog, "Default Output Quality: <span class='option'>" + QString::number(exportSettings.quality) + "</span>");
}
OVERWRITE cMainWindow::exportFile(const EXPORTSETTINGS& exportSettings, cEXIF* lpExif, cImages* images, OVERWRITE overwrite)
{
addToExportLog(m_exportLog, "Loading file: <span class='option'>" + lpExif->fileName() + "</span>");
if(m_exportExclude.count() || m_exportInclude.count())
{
QSqlQuery query(m_dbDigikam);
QString sql = QString("SELECT tagId "
"FROM ImageTags "
"WHERE imageId=%1;").arg(images->id());
bool doExport = false;
QList<qint32> idList;
if(query.exec(sql))
{
while(query.next())
idList.append(query.value("tagId").toInt());
}
if(!m_exportInclude.count())
doExport = true;
else
{
for(int i = 0;i < idList.count();i++)
{
if(m_exportInclude.contains(idList.at(i)))
{
doExport = true;
break;
}
}
}
if(doExport)
{
for(int i = 0;i < idList.count();i++)
{
if(m_exportExclude.contains(idList.at(i)))
{
doExport = false;
break;
}
}
}
if(!doExport)
{
addToExportLog(m_exportLog, "Skipped due to exclude/include list");
return(overwrite);
}
}
QString destPath;
QString destFile;
QFileInfo fileInfo(lpExif->fileName());
QString extension = exportSettings.fileFormat;
bool isMovie = false;
extension = extension.mid(extension.lastIndexOf(".")+1);
extension = extension.left(extension.length()-1);
if(!images->videoMetadata().videoCodec.isEmpty())
{
extension = lpExif->fileName().mid(lpExif->fileName().lastIndexOf(".")+1);
isMovie = true;
}
switch(exportSettings.directoryMethod)
{
case DIRECTORY_METHOD_NEW:
destPath = exportSettings.directory;
if(exportSettings.keepStructure)
{
destPath.append(images->albums()->relativePath());
if(exportSettings.stripLastFolderMethod != STRIP_LAST_FOLDER_NO)
{
bool strip = true;
if(exportSettings.stripLastFolderMethod == STRIP_LAST_FOLDER_IF)
{
QString lastFolder = destPath.mid(destPath.lastIndexOf("/")+1);
if(!exportSettings.stripLastFolderIfList.contains(lastFolder, Qt::CaseInsensitive))
strip = false;
}
if(strip)
destPath = destPath.left(destPath.lastIndexOf("/"));
}
}
break;
case DIRECTORY_METHOD_KEEP:
destPath = fileInfo.absolutePath();
break;
case DIRECTORY_METHOD_TAG:
destPath = replaceTags(exportSettings.directoryTag, lpExif, extension);
break;
}
switch(exportSettings.fileMethod)
{
case FILE_METHOD_KEEP:
destFile = fileInfo.completeBaseName() + "." + extension;
break;
case FILE_METHOD_RENAME:
switch(exportSettings.fileAdd)
{
case FILE_ADD_CONVERTED:
destFile = fileInfo.completeBaseName() + "_converted" + "." + extension;
break;
case FILE_ADD_TAG:
destFile = replaceTags(exportSettings.fileTag, lpExif, extension, false) + "." + extension;
break;
}
break;
}
destFile.prepend(destPath + "/");
QFileInfo destInfo(destFile);
addToExportLog(m_exportLog, "Destination: <span class='option'>" + destFile + "</span>");
if(destInfo.exists() && overwrite != OVERWRITE_ALL)
{
switch(exportSettings.overwriteMethod)
{
case OVERWRITE_METHOD_ASK:
{
QMessageBox::StandardButton ret = QMessageBox::question(this, tr("File Exists"), QString(tr("File %1 exists. Do you want to overwrite?")).arg(destFile), QMessageBox::Yes | QMessageBox::No | QMessageBox::YesAll | QMessageBox::NoAll);
if(ret == QMessageBox::YesAll)
{
overwrite = OVERWRITE_ALL;
addToExportLog(m_exportLog, "New Option: <span class='optionok'>overwrite all</span>");
}
else if(ret == QMessageBox::NoAll)
{
overwrite = OVERWRITE_NONE;
addToExportLog(m_exportLog, "New Option: <span class='optionnok'>overwrite none</span>");
addToExportLog(m_exportLog, "<span class='optionnok'>aborting, destination file exists</span>");
return(overwrite);
}
else if(ret == QMessageBox::No)
{
addToExportLog(m_exportLog, "<span class='optionnok'>aborting, destination file exists</span>");
return(overwrite);
}
else
addToExportLog(m_exportLog, "<span class='optionok'>file exists, overwrite</span>");
}
break;
case OVERWRITE_METHOD_RENAME:
destFile = findFreeFileName(destFile);
if(destFile.isEmpty())
{
QMessageBox::information(this, tr("File Export"), QString("%1 cannot be renamed.").arg(lpExif->fileName()));
addToExportLog(m_exportLog, "<span class='optionnok'>aborting, file cannot be renamed</span>");
return(overwrite);
}
addToExportLog(m_exportLog, "renaming to <span class='optionok'>" + destFile + "</span>");
break;
case OVERWRITE_METHOD_OVERWRITE:
break;
case OVERWRITE_METHOD_NOEXPORT:
addToExportLog(m_exportLog, "<span class='optionnok'>aborting, destination file exists</span>");
return(overwrite);
break;
}
}
else if(destInfo.exists() && (overwrite == OVERWRITE_NONE || exportSettings.overwriteMethod == OVERWRITE_METHOD_NOEXPORT))
{
addToExportLog(m_exportLog, "<span class='optionnok'>aborting, destination file exists</span>");
return(overwrite);
}
ui->m_statusBar->showMessage(QString(tr("loading %1...")).arg(lpExif->fileName()));
qApp->processEvents();
if(!isMovie)
{
cImage image(lpExif->fileName());
if(!image.isNull())
{
if(!image.isRaw() || !fileInfo.suffix().compare("cr3", Qt::CaseInsensitive))
{
QTransform rotation;
int angle = 0;
switch(images->imageInformation().orientation)
{
case 8:
angle = 270;
break;
case 3:
angle = 180;
break;
case 6:
angle = 90;
break;
}
if(angle != 0)
{
rotation.rotate(angle);
image = image.transformed(rotation);
}
}
addToExportLog(m_exportLog, "Loading file: <span class='optionok'>successful</span>");
QFileInfo info(destFile);
ui->m_statusBar->showMessage(QString(tr("converting to %1...")).arg(destFile));
qApp->processEvents();
QDir dir;
if(dir.mkpath(info.absolutePath()))
{
QImageWriter writer(destFile);
addToExportLog(m_exportLog, "Writing file: <span class='option'>" + destFile + "</span>");
writer.setQuality(exportSettings.quality);
if(writer.write(image))
{
addToExportLog(m_exportLog, "Writing file: <span class='optionok'>successful</span>");
if(exportSettings.copyEXIF)
{
if(lpExif->copyTo(destFile))
addToExportLog(m_exportLog, "Copy EXIF: <span class='optionok'>successful</span>");
else
addToExportLog(m_exportLog, "Copy EXIF: <span class='optionnok'>error</span>");
}
}
else
addToExportLog(m_exportLog, "Writing file: <span class='optionnok'>error: " + writer.errorString() + "</span>");
}
}
}
else
{
addToExportLog(m_exportLog, "Loading file: <span class='optionok'>no image</span>");
QFileInfo info(destFile);
ui->m_statusBar->showMessage(QString(tr("copying to %1...")).arg(destFile));
qApp->processEvents();
QDir dir;
if(dir.mkpath(info.absolutePath()))
{
if(QFile::copy(lpExif->fileName(), destFile))
addToExportLog(m_exportLog, "Writing file: <span class='optionok'>successful</span>");
else
addToExportLog(m_exportLog, "Copy EXIF: <span class='optionnok'>error</span>");
}
}
return(overwrite);
}
QString cMainWindow::replaceTags(const QString& path, cEXIF* lpExif, const QString& extension, bool directory)
{
QString dest = path;
QFileInfo fileInfo(lpExif->fileName());
QString model = lpExif->cameraModel().replace("/", "_").replace("\\", "_").replace(":", "_");
QString maker = lpExif->cameraMake().replace("/", "_").replace("\\", "_").replace(":", "_");
if(model.isEmpty())
model = "UNKNOWN";
if(maker.isEmpty())
maker = "UNKNOWN";
if(directory)
dest = dest.replace("%o", fileInfo.absolutePath());
else
dest = dest.replace("%o", fileInfo.fileName());
dest = dest.replace("%y", lpExif->dateTime().toString("yyyy"));
dest = dest.replace("%m", lpExif->dateTime().toString("MM"));
dest = dest.replace("%d", lpExif->dateTime().toString("dd"));
dest = dest.replace("%H", lpExif->dateTime().toString("hh"));
dest = dest.replace("%M", lpExif->dateTime().toString("mm"));
dest = dest.replace("%S", lpExif->dateTime().toString("ss"));
dest = dest.replace("%c", maker);
dest = dest.replace("%l", model);
dest = dest.replace("%t", extension);
dest = dest.replace("\\", "/");
return(dest);
}
QString cMainWindow::findFreeFileName(const QString& fileName)
{
QFileInfo fileInfo(fileName);
QString newName;
int number = 1;
for(;;)
{
newName = fileInfo.absolutePath() + "/" + fileInfo.completeBaseName() + "-" + QStringLiteral("%1").arg(number, 3, 10, QLatin1Char('0')) + "." + fileInfo.suffix();
if(!QFileInfo::exists(newName))
return(newName);
number++;
}
}
+26
View File
@@ -6,9 +6,12 @@
#include "calbumroots.h"
#include "calbums.h"
#include "ctags.h"
#include "cfoldersortfilterproxymodel.h"
#include "cthumbnailsortfilterproxymodel.h"
#include "cexif.h"
#include <QMainWindow>
#include <QCloseEvent>
@@ -109,23 +112,39 @@ private:
QSqlDatabase m_dbDigikam;
QSqlDatabase m_dbThumbnail;
QSqlDatabase m_dbExportDigikam;
cAlbumRootsList* m_albumRootsList;
cAlbumsList* m_albumsList;
cTagsList* m_tagsList;
QStandardItemModel* m_folderViewModel;
cFolderSortFilterProxyModel* m_folderSortFilterProxyModel;
QStandardItemModel* m_includeViewModel;
QStandardItemModel* m_excludeViewModel;
QStandardItemModel* m_thumbnailViewModel;
cThumbnailSortFilterProxyModel* m_thumbnailSortFilterProxyModel;
QStandardItem* m_rootItem;
QList<IMAGEFORMAT> m_imageFormats;
cEXIFTagList* m_exifTAGList;
cEXIFCompressionList* m_exifCompressionList;
cEXIFLightSourceList* m_exifLightSourceList;
cEXIFFlashList* m_exifFlashList;
cIPTCTagList* m_iptcTagList;
cXMPTagList* m_xmpTagList;
bool m_loading;
bool m_working;
bool m_stopIt;
QList<qint32> m_exportInclude;
QList<qint32> m_exportExclude;
QString m_exportLog;
QList<SolidVolumeInfo> m_volumes;
void initUI();
void createActions();
void createMenuActions();
@@ -134,6 +153,7 @@ private:
void addImageFormat(const QString& shortName, const QString& description, const QString& extension, QList<QByteArray>& readList, QList<QByteArray>& writeList);
void loadData();
void displayData();
void addChildren(cTags* tags, QStandardItem* include, QStandardItem* exclude);
void initSignals();
QStandardItem* findDBRootItem(QStandardItemModel* model, QStandardItem* rootItem, cAlbumRoots* albumRoots);
@@ -141,6 +161,10 @@ private:
void doExport();
void getExportSettings(EXPORTSETTINGS& exportSettings);
OVERWRITE exportFile(const EXPORTSETTINGS& exportSettings, cEXIF* lpExif, cImages *images, OVERWRITE overwrite);
QString replaceTags(const QString& path, cEXIF* lpExif, const QString& extension = QString(""), bool directory = true);
QString findFreeFileName(const QString& fileName);
protected:
void closeEvent(QCloseEvent* event);
@@ -149,6 +173,8 @@ private slots:
void onExport();
void onStop();
void onFolderViewItemChanged(QStandardItem* item);
void onIncludeViewItemChanged(QStandardItem* item);
void onExcludeViewItemChanged(QStandardItem* item);
void onFolderSelected(const QItemSelection& selection, const QItemSelection& previous);
void onThumbnailSelected(const QItemSelection& selection, const QItemSelection& previous);
};
+54 -9
View File
@@ -20,16 +20,61 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeView" name="m_folderView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
<widget class="QSplitter" name="m_splitter1">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTreeView" name="m_folderView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
<widget class="QGroupBox" name="m_includeGroup">
<property name="title">
<string>include</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTreeView" name="m_includeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="m_excludeGroup">
<property name="title">
<string>exclude</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTreeView" name="m_excludeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QListView" name="m_thumbnailView">
<property name="editTriggers">
+74
View File
@@ -5,6 +5,9 @@
#include "common.h"
#include <QDebug>
#include <QDir>
QString generateReadList(const QList<IMAGEFORMAT>& imageFormats)
{
@@ -58,3 +61,74 @@ QString generateWriteList(const QList<IMAGEFORMAT>& imageFormats)
return(writeList);
}
QList<SolidVolumeInfo> actuallyListVolumes()
{
QList<SolidVolumeInfo> volumes;
QList<Solid::Device> devices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
foreach (const Solid::Device& accessDevice, devices)
{
if (!accessDevice.is<Solid::StorageAccess>())
continue;
const Solid::StorageAccess* access = accessDevice.as<Solid::StorageAccess>();
if (!access->isAccessible())
continue;
Solid::Device driveDevice;
for (Solid::Device currentDevice = accessDevice; currentDevice.isValid() ; currentDevice = currentDevice.parent())
{
if(currentDevice.is<Solid::StorageDrive>())
{
driveDevice = currentDevice;
break;
}
}
Solid::StorageDrive* drive = driveDevice.as<Solid::StorageDrive>();
// check for StorageVolume
Solid::Device volumeDevice;
for (Solid::Device currentDevice = accessDevice; currentDevice.isValid() ; currentDevice = currentDevice.parent())
{
if (currentDevice.is<Solid::StorageVolume>())
{
volumeDevice = currentDevice;
break;
}
}
if (!volumeDevice.isValid())
continue;
Solid::StorageVolume* const volume = volumeDevice.as<Solid::StorageVolume>();
SolidVolumeInfo info;
info.udi = accessDevice.udi();
info.path = QDir::fromNativeSeparators(access->filePath());
info.isMounted = access->isAccessible();
if (!info.path.isEmpty() && !info.path.endsWith(QLatin1Char('/')))
{
info.path += QLatin1Char('/');
}
info.uuid = volume->uuid();
info.label = volume->label();
if (drive)
info.isRemovable = (drive->isHotpluggable() || drive->isRemovable());
else
info.isRemovable = false;
volumes << info;
}
return volumes;
}
+41
View File
@@ -7,6 +7,16 @@
#define COMMON_H
#include <solid/solidnamespace.h>
#include <solid/camera.h>
#include <solid/device.h>
#include <solid/deviceinterface.h>
#include <solid/devicenotifier.h>
#include <solid/predicate.h>
#include <solid/storageaccess.h>
#include <solid/storagedrive.h>
#include <solid/storagevolume.h>
#include <QDateTime>
#include <QDebug>
@@ -14,6 +24,7 @@
#define THUMBNAIL_WIDTH 160
#define THUMBNAIL_HEIGHT 120
#define _DELETE_(x) {if(x) delete(x); x = nullptr;}
#ifdef __GNUC__
#define myDebug qDebug() << __FILE__ << "(" << __LINE__ << ") - " << __PRETTY_FUNCTION__ << ":"
@@ -133,6 +144,34 @@ typedef struct tagVIDEOMETADATA
QString videoCodec;
} VIDEOMETADATA;
class Q_DECL_HIDDEN SolidVolumeInfo
{
public:
SolidVolumeInfo()
: isRemovable (false),
isOpticalDisc(false),
isMounted (false)
{
}
bool isNull() const
{
return path.isNull();
}
public:
QString udi; ///< Solid device UDI of the StorageAccess device
QString path; ///< mount path of volume, with trailing slash
QString uuid; ///< UUID as from Solid
QString label; ///< volume label (think of CDs)
bool isRemovable; ///< may be removed
bool isOpticalDisc; ///< is an optical disk device as CD/DVD/BR
bool isMounted; ///< is mounted on File System.
};
/*!
\brief
@@ -150,5 +189,7 @@ QString generateReadList(const QList<IMAGEFORMAT>& imageFormats);
*/
QString generateWriteList(const QList<IMAGEFORMAT>& imageFormats);
QList<SolidVolumeInfo> actuallyListVolumes();
#endif // COMMON_H
+186
View File
@@ -0,0 +1,186 @@
#include "ctags.h"
#include <QSqlQuery>
#include <QDebug>
cTags::cTags(const qint32& id, QObject *parent) :
QObject(parent),
m_id(id),
m_pid(0),
m_name(""),
m_parent(nullptr),
m_childList(nullptr),
m_includeItem(nullptr),
m_excludeItem(nullptr)
{
}
cTags::cTags(const qint32& id, const qint32& pid, const QString& name, QObject *parent) :
QObject(parent),
m_id(id),
m_pid(pid),
m_name(name),
m_parent(nullptr),
m_childList(nullptr),
m_includeItem(nullptr),
m_excludeItem(nullptr)
{
}
qint32 cTags::id()
{
return(m_id);
}
void cTags::setName(const QString& name)
{
m_name = name;
}
QString cTags::name()
{
return(m_name);
}
void cTags::setPID(const qint32& pid)
{
m_pid = pid;
}
qint32 cTags::pid()
{
return(m_pid);
}
void cTags::setParent(cTags* parent)
{
m_parent = parent;
}
cTags* cTags::parent()
{
return(m_parent);
}
void cTags::setIncludeItem(QStandardItem* includeItem)
{
m_includeItem = includeItem;
}
QStandardItem* cTags::includeItem()
{
return(m_includeItem);
}
void cTags::setExcludeItem(QStandardItem* excludeItem)
{
m_excludeItem = excludeItem;
}
QStandardItem* cTags::excludeItem()
{
return(m_excludeItem);
}
void cTags::addChild(cTags* tags)
{
if(!m_childList)
m_childList = new cTagsList(nullptr);
m_childList->append(tags);
}
cTagsList* cTags::childList()
{
return(m_childList);
}
cTagsList::cTagsList(QSqlDatabase* dbDigikam, QObject* parent) :
QObject(parent),
m_dbDigikam(dbDigikam)
{
}
cTagsList::~cTagsList()
{
}
bool cTagsList::load()
{
if(!m_dbDigikam)
return(false);
QSqlQuery query(*m_dbDigikam);
if(!query.exec("SELECT id, "
" pid, "
" name "
"FROM Tags "
"ORDER BY name;"))
{
qDebug() << "cTagsList: loading failed.";
return(false);
}
while(query.next())
{
add(query.value("id").toInt(), query.value("pid").toInt(), query.value("name").toString(), this);
}
processParent();
return(true);
}
cTags* cTagsList::add(const qint32& id, QObject* parent)
{
cTags* lpNew = find(id);
if(lpNew)
return(lpNew);
lpNew = new cTags(id, parent);
append(lpNew);
return(lpNew);
}
cTags* cTagsList::add(const qint32& id, const qint32& pid, const QString& name, QObject* parent)
{
cTags* lpNew = find(id);
if(lpNew)
return(lpNew);
lpNew = new cTags(id, pid, name, parent);
append(lpNew);
return(lpNew);
}
cTags* cTagsList::find(const qint32& id)
{
for(int i = 0;i < count();i++)
{
if(at(i)->id() == id)
return(at(i));
}
return(nullptr);
}
void cTagsList::processParent()
{
for(int i = 0;i < count();i++)
{
cTags* tags = at(i);
if(tags->pid())
{
cTags* parent = find(tags->pid());
if(parent)
{
tags->setParent(parent);
parent->addChild(tags);
}
}
}
}
+77
View File
@@ -0,0 +1,77 @@
#ifndef CTAGS_H
#define CTAGS_H
#include "common.h"
#include <QString>
#include <QList>
#include <QStandardItem>
#include <QSqlDatabase>
#include <QObject>
#include <QMetaType>
class cTagsList;
class cTags : public QObject
{
Q_OBJECT
public:
cTags(const qint32& id, QObject *parent = nullptr);
cTags(const qint32& id, const qint32& pid, const QString& name, QObject *parent = nullptr);
qint32 id();
void setName(const QString& name);
QString name();
void setPID(const qint32& pid);
qint32 pid();
void setParent(cTags* parent);
cTags* parent();
void setIncludeItem(QStandardItem* includeItem);
QStandardItem* includeItem();
void setExcludeItem(QStandardItem* excludeItem);
QStandardItem* excludeItem();
void addChild(cTags* tags);
cTagsList* childList();
private:
qint32 m_id;
qint32 m_pid;
QString m_name;
cTags* m_parent;
cTagsList* m_childList;
QStandardItem* m_includeItem;
QStandardItem* m_excludeItem;
};
Q_DECLARE_METATYPE(cTags*)
class cTagsList : public QObject, public QList<cTags*>
{
Q_OBJECT
public:
cTagsList(QSqlDatabase* dbDigikam, QObject* parent = nullptr);
~cTagsList();
bool load();
cTags* add(const qint32& id, QObject* parent = nullptr);
cTags* add(const qint32& id, const qint32& pid, const QString& name, QObject* parent = nullptr);
cTags* find(const qint32& id);
void processParent();
private:
QSqlDatabase* m_dbDigikam;
};
#endif // CTAGS_H
+8 -3
View File
@@ -20,8 +20,8 @@ win32-msvc* {
win32-g++ {
message("mingw")
INCLUDEPATH += C:\dev\3rdParty\exiv2-0.27.5\include C:\dev\3rdParty\libraw C:\dev\3rdParty\libjpeg\include C:\dev\3rdParty\opencv\include dng
LIBS += -LC:\dev\3rdParty\exiv2-0.27.5\lib -lexiv2.dll -LC:\dev\3rdParty\libraw\lib -LC:\dev\3rdParty\opencv\x64\mingw\lib -lraw -lws2_32 -lz -lopencv_core412.dll -lopencv_imgproc412.dll
INCLUDEPATH += C:\dev\3rdParty\libsolid\ucrt64\include\KF5\Solid C:\dev\3rdParty\exiv2-0.27.5\include C:\dev\3rdParty\libraw C:\dev\3rdParty\libjpeg\include C:\dev\3rdParty\opencv\include dng
LIBS += -LC:\dev\3rdParty\libsolid\ucrt64\lib -lKF5Solid.dll -LC:\dev\3rdParty\exiv2-0.27.5\lib -lexiv2.dll -LC:\dev\3rdParty\libraw\lib -LC:\dev\3rdParty\opencv\x64\mingw\lib -lraw -lws2_32 -lz -lopencv_core412.dll -lopencv_imgproc412.dll
}
unix {
@@ -41,12 +41,14 @@ DEFINES += APP_VERSION=\\\"$$VERSION\\\"
SOURCES += \
calbumroots.cpp \
calbums.cpp \
cexif.cpp \
cexportdialog.cpp \
cfoldersortfilterproxymodel.cpp \
cimage.cpp \
cimages.cpp \
clogwindow.cpp \
common.cpp \
ctags.cpp \
cthumbnailsortfilterproxymodel.cpp \
main.cpp \
cmainwindow.cpp \
@@ -61,6 +63,7 @@ SOURCES += \
HEADERS += \
calbumroots.h \
calbums.h \
cexif.h \
cexportdialog.h \
cfoldersortfilterproxymodel.h \
cimage.h \
@@ -68,6 +71,7 @@ HEADERS += \
clogwindow.h \
cmainwindow.h \
common.h \
ctags.h \
cthumbnailsortfilterproxymodel.h \
pgfutils/libpgf/BitStream.h \
pgfutils/libpgf/Decoder.h \
@@ -78,7 +82,8 @@ HEADERS += \
pgfutils/libpgf/PGFtypes.h \
pgfutils/libpgf/Subband.h \
pgfutils/libpgf/WaveletTransform.h \
pgfutils/pgfutils.h
pgfutils/pgfutils.h \
solid/device_p.h
FORMS += \
cexportdialog.ui \