update copy function

master
birkeh 7 years ago
parent dc26fdc78a
commit a79d319dbd

@ -0,0 +1,129 @@
#include "ccopier.h"
static QString toString(HRESULT hr)
{
_com_error err{hr};
return QStringLiteral("Error 0x%1: %2").arg((quint32)hr, 8, 16, QLatin1Char('0')).arg(err.ErrorMessage());
}
static QString getLastErrorMsg()
{
return toString(HRESULT_FROM_WIN32(GetLastError()));
}
cCopier::cCopier(const QString& src, const QString& dst, QObject* parent) :
QObject(parent),
m_src(src),
m_dst(dst)
{
}
cCopier::~cCopier()
{
stop();
}
void cCopier::stop()
{
resume();
m_stop = TRUE;
}
void cCopier::pause()
{
m_pause = true;
}
void cCopier::resume()
{
if(m_pause)
m_pauseWait.notify_one();
m_pause = false;
}
void cCopier::newStatus(ULONGLONG part, ULONGLONG whole)
{
if(part != m_lastPart || whole != m_lastWhole)
{
m_lastPart = part;
m_lastWhole = whole;
emit newStatus(static_cast<int>(part*100/whole));
}
}
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
void cCopier::copy()
{
m_lastPart = m_lastWhole = {};
m_stop = FALSE;
m_pause = false;
QtConcurrent::run([this]
{
COPYFILE2_EXTENDED_PARAMETERS params
{
sizeof(COPYFILE2_EXTENDED_PARAMETERS), 0, &m_stop,
Copier::copyProgress2, this
};
auto rc = CopyFile2((PCWSTR)m_src.utf16(), (PCWSTR)m_dst.utf16(), &params);
if(!SUCCEEDED(rc))
emit newStatus(toString(rc));
emit finished();
});
}
COPYFILE2_MESSAGE_ACTION CALLBACK cCopier::copyProgress2(const COPYFILE2_MESSAGE *message, PVOID context)
{
COPYFILE2_MESSAGE_ACTION action = COPYFILE2_PROGRESS_CONTINUE;
auto self = static_cast<Copier*>(context);
if(message->Type == COPYFILE2_CALLBACK_CHUNK_FINISHED)
{
auto& info = message->Info.ChunkFinished;
self->newStatus(info.uliTotalBytesTransferred.QuadPart, info.uliTotalFileSize.QuadPart);
}
else if (message->Type == COPYFILE2_CALLBACK_ERROR)
{
auto& info = message->Info.Error;
self->newStatus(info.uliTotalBytesTransferred.QuadPart, info.uliTotalFileSize.QuadPart);
emit self->newStatus(toString(info.hrFailure));
action = COPYFILE2_PROGRESS_CANCEL;
}
if(self->m_pause)
{
QMutexLocker lock{&self->m_pauseMutex};
self->m_pauseWait.wait(&self->m_pauseMutex);
}
return action;
}
#else
void cCopier::copy()
{
m_lastPart = m_lastWhole = {};
m_stop = FALSE;
m_pause = false;
QtConcurrent::run([this]
{
auto rc = CopyFileExW((LPCWSTR)m_src.utf16(), (LPCWSTR)m_dst.utf16(), &copyProgress, this, &m_stop, 0);
if(!rc)
{
qDebug() << getLastErrorMsg();
emit newStatus(-1);
}
emit finished();
});
}
DWORD CALLBACK cCopier::copyProgress(const LARGE_INTEGER totalSize, const LARGE_INTEGER totalTransferred, LARGE_INTEGER, LARGE_INTEGER, DWORD, DWORD, HANDLE, HANDLE, LPVOID data)
{
auto self = static_cast<cCopier*>(data);
self->newStatus(totalTransferred.QuadPart, totalSize.QuadPart);
if(self->m_pause)
{
QMutexLocker lock{&self->m_pauseMutex};
self->m_pauseWait.wait(&self->m_pauseMutex);
}
return PROGRESS_CONTINUE;
}
#endif

@ -0,0 +1,49 @@
#ifndef CCOPIER_H
#define CCOPIER_H
#include <QObject>
#include <QtConcurrent>
#include <windows.h>
#include <comdef.h>
class cCopier : public QObject
{
Q_OBJECT
BOOL m_stop;
QMutex m_pauseMutex;
QAtomicInt m_pause;
QWaitCondition m_pauseWait;
QString m_src;
QString m_dst;
ULONGLONG m_lastPart;
ULONGLONG m_lastWhole;
void newStatus(ULONGLONG part, ULONGLONG whole);
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
static COPYFILE2_MESSAGE_ACTION CALLBACK copyProgress2(const COPYFILE2_MESSAGE *message, PVOID context);
#else
static DWORD CALLBACK copyProgress(LARGE_INTEGER totalSize, LARGE_INTEGER totalTransferred, LARGE_INTEGER streamSize, LARGE_INTEGER streamTransferred, DWORD streamNo, DWORD callbackReason, HANDLE src, HANDLE dst, LPVOID data);
#endif
public:
explicit cCopier(const QString& src, const QString& dst, QObject* parent = nullptr);
~cCopier() override;
signals:
void newStatus(int percent);
void finished();
public slots:
void copy();
void stop();
void pause();
void resume();
};
#endif // CCOPIER_H

@ -446,6 +446,11 @@ QString cEXIF::gps()
return(szGPS);
}
QString cEXIF::duration()
{
return(getXMPTag("Xmp.video.Duration").toString());
}
QString cEXIF::fileName()
{
return(m_szFileName);

@ -757,6 +757,13 @@ public:
/*!
\brief
\fn duration
\return QString
*/
QString duration();
/*!
\brief
\fn fileName
\return QString
*/

@ -55,6 +55,7 @@ void cImportDialog::initUI()
{
ui->setupUi(this);
ui->m_lpProgress->setVisible(false);
ui->m_lpTotalProgress->setVisible(false);
ui->m_lpImport->setEnabled(false);
m_lpFolderViewModel = new QStandardItemModel;
@ -228,7 +229,9 @@ void cImportDialog::onImport()
QFile file;
ui->m_lpProgress->setVisible(true);
ui->m_lpProgress->setRange(0, ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count());
ui->m_lpProgress->setRange(0, 100);
ui->m_lpTotalProgress->setVisible(true);
ui->m_lpTotalProgress->setRange(0, ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count());
for(int x = 0;x < ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count();x++)
{
@ -255,11 +258,10 @@ void cImportDialog::onImport()
szDest.append(szDestPath);
szDest.append(lpPicture->fileName());
// if(copyFile(szSource, szDest, ui->m_lpMove->isChecked()))
if(copyFile(szSource, szDest, false))
// if(copyFile(ui->m_lpProgress, szSource, szDest, ui->m_lpMove->isChecked()))
if(copyFile(ui->m_lpProgress, szSource, szDest, false))
{
ui->m_lpProgress->setValue(x);
ui->m_lpTotalProgress->setValue(x+1);
qApp->processEvents();
lpPicture->setFilePath(szDestPath.left(szDestPath.length()-1).replace("\\", "/"));
@ -271,6 +273,7 @@ void cImportDialog::onImport()
}
ui->m_lpStatusText->setText("");
ui->m_lpProgress->setVisible(false);
ui->m_lpTotalProgress->setVisible(false);
m_bHasImported = true;
}

@ -15,7 +15,7 @@
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,1,1000,1,1,1">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,1,1000,1,0,0,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@ -222,7 +222,7 @@
<x>0</x>
<y>0</y>
<width>69</width>
<height>342</height>
<height>315</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -263,6 +263,13 @@
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="m_lpTotalProgress">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="m_lpButtonBox">
<property name="orientation">

@ -463,7 +463,7 @@ void cMainWindow::onChangeDate()
QString szPath = QString::number(lpPicture->dateTime().date().year()) + "/" + lpPicture->dateTime().date().toString("yyyy-MM-dd");
m_lpThumbnailSortFilterProxyModel->setData(index, QVariant::fromValue(szPath), Qt::UserRole+2);
if(copyFile(m_pictureLibrary.rootPath() + QDir::separator() + lpPicture->filePath() + QDir::separator() + lpPicture->fileName(),
if(copyFile(0, m_pictureLibrary.rootPath() + QDir::separator() + lpPicture->filePath() + QDir::separator() + lpPicture->fileName(),
m_pictureLibrary.rootPath() + QDir::separator() + szPath + QDir::separator() + lpPicture->fileName(), true))
{
lpPicture->setFilePath(szPath);

@ -10,8 +10,11 @@
#include "common.h"
#include "ccopier.h"
#include <QBuffer>
#include <QDir>
#include <QEventLoop>
QImage blob2Image(const QByteArray& ba)
@ -86,7 +89,8 @@ QStandardItem* insertPath(QString szPath, QStandardItem* lpRootItem)
return(lpCurRoot);
}
bool copyFile(const QString& szSource, const QString& szDest, bool bDelete)
//bool copyFile(cImportDialog* lpImportDialog, const QString& szSource, const QString& szDest, bool bDelete)
bool copyFile(QProgressBar* lpProgressBar, const QString& szSource, const QString& szDest, bool bDelete)
{
QString szDestPath;
QString szDestFilePath = szDest;
@ -102,7 +106,21 @@ bool copyFile(const QString& szSource, const QString& szDest, bool bDelete)
if(file.exists(szDestFilePath))
file.remove(szDestFilePath);
file.copy(szSource, szDestFilePath);
cCopier* lpCopier = new cCopier(szSource, szDest);
if(lpProgressBar)
QObject::connect(lpCopier, SIGNAL(newStatus(int)), lpProgressBar, SLOT(setValue(int)));
// connect(copier, SIGNAL(newStatus(QString)), this, SLOT(newStatus(QString)));
// connect(copier, SIGNAL(finished()), SIGNAL(copyFinished()));
// connect(copier, SIGNAL(finished()), copier, SLOT(deleteLater()));
// connect(this, SIGNAL(stopCopy()), copier, SLOT(stop()));
QEventLoop loop;
lpCopier->copy();
QObject::connect(lpCopier, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
if(bDelete)
file.remove(szSource);

@ -7,11 +7,15 @@
#define COMMON_H
#include "cimportdialog.h"
#include <QImage>
#include <QByteArray>
#include <QStandardItem>
#include <QTreeView>
#include <QProgressBar>
#include <QDebug>
@ -63,6 +67,6 @@ QStandardItem* insertPath(QString szPath, QStandardItem* lpRootItem);
\param bDelete
\return bool
*/
bool copyFile(const QString& szSource, const QString& szDest, bool bDelete = false);
bool copyFile(QProgressBar* lpProgressBar, const QString& szSource, const QString& szDest, bool bDelete = false);
#endif // COMMON_H

@ -38,7 +38,8 @@ cPicture::cPicture(qint32 iID, QObject *parent) :
m_exifVersion(""),
m_whiteBalance(0),
m_focalLength35(0.0),
m_gps("")
m_gps(""),
m_duration(0)
{
}
@ -78,6 +79,7 @@ bool cPicture::fromFile(const QString& szFileName)
m_whiteBalance = exif.whiteBalance();
m_focalLength35 = exif.focalLength35();
m_gps = exif.gps();
m_duration = exif.duration().toLongLong();
return(true);
}
@ -97,12 +99,12 @@ bool cPicture::toDB()
}
if(!query.next())
query.prepare("INSERT INTO picture (fileName, filePath, fileSize, mimeType, imageWidth, imageHeight, imageOrientation, cameraMake, cameraModel, dateTime, fNumber, iso, flashID, focalLength, lensMake, lensModel, exposureTime, exposureBias, exifVersion, dateTimeOriginal, dateTimeDigitized, whiteBalance, focalLength35, gps, thumbnail) VALUES (:fileName, :filePath, :fileSize, :mimeType, :imageWidth, :imageHeight, :imageOrientation, :cameraMake, :cameraModel, :dateTime, :fNumber, :iso, :flashID, :focalLength, :lensMake, :lensModel, :exposureTime, :exposureBias, :exifVersion, :dateTimeOriginal, :dateTimeDigitized, :whiteBalance, :focalLength35, :gps, :thumbnail);");
query.prepare("INSERT INTO picture (fileName, filePath, fileSize, mimeType, imageWidth, imageHeight, imageOrientation, cameraMake, cameraModel, dateTime, fNumber, iso, flashID, focalLength, lensMake, lensModel, exposureTime, exposureBias, exifVersion, dateTimeOriginal, dateTimeDigitized, whiteBalance, focalLength35, gps, duration, thumbnail) VALUES (:fileName, :filePath, :fileSize, :mimeType, :imageWidth, :imageHeight, :imageOrientation, :cameraMake, :cameraModel, :dateTime, :fNumber, :iso, :flashID, :focalLength, :lensMake, :lensModel, :exposureTime, :exposureBias, :exifVersion, :dateTimeOriginal, :dateTimeDigitized, :whiteBalance, :focalLength35, :gps, :duration, :thumbnail);");
else
query.prepare("UPDATE picture SET fileName=:fileName, filePath=:filePath, fileSize=:fileSize, mimeType=:mimeType, imageWidth=:imageWidth, imageHeight=:imageHeight, imageOrientation=:imageOrientation, cameraMake=:cameraMake, cameraModel=:cameraModel, dateTime=:dateTime, fNumber=:fNumber, iso=:iso, flashID=:flashID, focalLength=:focalLength, lensMake=:lensMake, lensModel=:lensModel, exposureTime=:exposureTime, exposureBias=:exposureBias, exifVersion=:exifVersion, dateTimeOriginal=:dateTimeOriginal, dateTimeDigitized=:dateTimeDigitized, whiteBalance=:whiteBalance, focalLength35=:focalLength35, gps=:gps, thumbnail=:thumbnail WHERE id=:id;");
query.prepare("UPDATE picture SET fileName=:fileName, filePath=:filePath, fileSize=:fileSize, mimeType=:mimeType, imageWidth=:imageWidth, imageHeight=:imageHeight, imageOrientation=:imageOrientation, cameraMake=:cameraMake, cameraModel=:cameraModel, dateTime=:dateTime, fNumber=:fNumber, iso=:iso, flashID=:flashID, focalLength=:focalLength, lensMake=:lensMake, lensModel=:lensModel, exposureTime=:exposureTime, exposureBias=:exposureBias, exifVersion=:exifVersion, dateTimeOriginal=:dateTimeOriginal, dateTimeDigitized=:dateTimeDigitized, whiteBalance=:whiteBalance, focalLength35=:focalLength35, gps=:gps, duration=:duration, thumbnail=:thumbnail WHERE id=:id;");
}
else
query.prepare("INSERT INTO picture (fileName, filePath, fileSize, mimeType, imageWidth, imageHeight, imageOrientation, cameraMake, cameraModel, dateTime, fNumber, iso, flashID, focalLength, lensMake, lensModel, exposureTime, exposureBias, exifVersion, dateTimeOriginal, dateTimeDigitized, whiteBalance, focalLength35, gps, thumbnail) VALUES (:fileName, :filePath, :fileSize, :mimeType, :imageWidth, :imageHeight, :imageOrientation, :cameraMake, :cameraModel, :dateTime, :fNumber, :iso, :flashID, :focalLength, :lensMake, :lensModel, :exposureTime, :exposureBias, :exifVersion, :dateTimeOriginal, :dateTimeDigitized, :whiteBalance, :focalLength35, :gps, :thumbnail);");
query.prepare("INSERT INTO picture (fileName, filePath, fileSize, mimeType, imageWidth, imageHeight, imageOrientation, cameraMake, cameraModel, dateTime, fNumber, iso, flashID, focalLength, lensMake, lensModel, exposureTime, exposureBias, exifVersion, dateTimeOriginal, dateTimeDigitized, whiteBalance, focalLength35, gps, duration, thumbnail) VALUES (:fileName, :filePath, :fileSize, :mimeType, :imageWidth, :imageHeight, :imageOrientation, :cameraMake, :cameraModel, :dateTime, :fNumber, :iso, :flashID, :focalLength, :lensMake, :lensModel, :exposureTime, :exposureBias, :exifVersion, :dateTimeOriginal, :dateTimeDigitized, :whiteBalance, :focalLength35, :gps, :duration, :thumbnail);");
query.bindValue(":id", m_iID);
@ -130,6 +132,7 @@ bool cPicture::toDB()
query.bindValue(":whiteBalance", m_whiteBalance);
query.bindValue(":focalLength35", m_focalLength35);
query.bindValue(":gps", m_gps);
query.bindValue(":duration", m_duration);
if(!m_thumbnail.isNull())
query.bindValue(":thumbnail", image2Blob(m_thumbnail));
else
@ -387,6 +390,16 @@ QString cPicture::gps()
return(m_gps);
}
void cPicture::setDuration(const qint64& duration)
{
m_duration = duration;
}
qint64 cPicture::duration()
{
return(m_duration);
}
void cPicture::setFileName(const QString& fileName)
{
m_szFileName = fileName;
@ -475,6 +488,8 @@ bool cPicture::operator==(const cPicture& other) const
return(false);
if(this->m_gps != other.m_gps)
return(false);
if(this->m_duration != other.m_duration)
return(false);
return(true);
}
@ -527,6 +542,8 @@ bool cPicture::operator==(const cPicture*& other) const
return(false);
if(this->m_gps != other->m_gps)
return(false);
if(this->m_duration != other->m_duration)
return(false);
return(true);
}
@ -579,6 +596,8 @@ bool cPicture::operator==(const cPicture* other) const
return(false);
if(this->m_gps != other->m_gps)
return(false);
if(this->m_duration != other->m_duration)
return(false);
return(true);
}
@ -631,6 +650,8 @@ bool cPicture::operator==(cPicture* other)
return(false);
if(this->m_gps != other->m_gps)
return(false);
if(this->m_duration != other->m_duration)
return(false);
return(true);
}
@ -686,6 +707,7 @@ bool cPictureList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressB
" whiteBalance, "
" focalLength35, "
" gps, "
" duration, "
" thumbnail "
"FROM picture "
"ORDER BY filePath, "
@ -700,6 +722,9 @@ bool cPictureList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressB
qint32 count = 0;
qint32 step = max/200;
if(!step)
step = 1;
while(query.next())
{
cPicture* lpPicture = add(query.value("id").toInt(), true);
@ -728,6 +753,7 @@ bool cPictureList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressB
lpPicture->setWhiteBalance(query.value("whiteBalance").toInt());
lpPicture->setFocalLength35(query.value("focalLength35").toDouble());
lpPicture->setGPS(query.value("gps").toString());
lpPicture->setDuration(query.value("duration").toLongLong());
lpPicture->setThumbnail(blob2Image(query.value("thumbnail").toByteArray()));
count++;

@ -398,6 +398,21 @@ public:
*/
QString gps();
/*!
\brief
\fn setDuration
\param duration
*/
void setDuration(const qint64& duration);
/*!
\brief
\fn gps
\return qint64
*/
qint64 duration();
/*!
\brief
@ -526,6 +541,7 @@ private:
qint32 m_whiteBalance; /*!< TODO: describe */
qreal m_focalLength35; /*!< TODO: describe */
QString m_gps; /*!< TODO: describe */
qint64 m_duration; /*!< TODO: describe */
};
Q_DECLARE_METATYPE(cPicture*)

@ -211,6 +211,7 @@ bool cPictureLibrary::updateDatabase3(qint32 version)
" whiteBalance INTEGER, "
" focalLength35 DOUBLE, "
" gps TEXT, "
" duration BIGINT, "
" thumbnail BLOB"
"); "))
return(false);

@ -10,7 +10,7 @@ QMAKE_TARGET_PRODUCT = pictureLibrary
QMAKE_TARGET_DESCRIPTION = pictureLibrary
QMAKE_TARGET_COPYRIGHT = (c) 2019 WIN-DESIGN
QT += core gui sql multimedia
QT += core gui sql multimedia concurrent
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@ -65,7 +65,8 @@ SOURCES += \
cimportdialog.cpp \
cdatetimepicker.cpp \
cthumbnailsortfilterproxymodel.cpp \
cfoldersortfilterproxymodel.cpp
cfoldersortfilterproxymodel.cpp \
ccopier.cpp
HEADERS += \
cmainwindow.h \
@ -79,7 +80,8 @@ HEADERS += \
cimportdialog.h \
cdatetimepicker.h \
cthumbnailsortfilterproxymodel.h \
cfoldersortfilterproxymodel.h
cfoldersortfilterproxymodel.h \
ccopier.h
FORMS += \
cmainwindow.ui \

Loading…
Cancel
Save