OSDN Git Service

The copy_file() function now accepts an optional callback function.
authorLoRd_MuldeR <mulder2@gmx.de>
Sun, 22 Mar 2015 20:29:30 +0000 (21:29 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Sun, 22 Mar 2015 20:29:30 +0000 (21:29 +0100)
include/MUtils/OSSupport.h
src/OSSupport_Win32.cpp

index f8eef72..5845c15 100644 (file)
@@ -105,7 +105,8 @@ namespace MUtils
                MUTILS_API const ArgumentMap &arguments(void);
 
                //Copy file
-               MUTILS_API bool copy_file(const QString &sourcePath, const QString &outputPath, const bool &overwrite = true);
+               typedef bool (*progress_callback_t)(const double &progress, void *const userData);
+               MUTILS_API bool copy_file(const QString &sourcePath, const QString &outputPath, const bool &overwrite = true, const progress_callback_t callback = NULL, void *const userData = NULL);
 
                //Get the OS version
                MUTILS_API const Version::os_version_t &os_version(void);
index e461034..c8a07aa 100644 (file)
@@ -137,14 +137,40 @@ const MUtils::OS::ArgumentMap &MUtils::OS::arguments(void)
 // COPY FILE
 ///////////////////////////////////////////////////////////////////////////////
 
-MUTILS_API bool MUtils::OS::copy_file(const QString &sourcePath, const QString &outputPath, const bool &overwrite)
+typedef struct _progress_callback_data_t
 {
-       const BOOL result = CopyFileW(MUTILS_WCHR(QDir::toNativeSeparators(sourcePath)), MUTILS_WCHR(QDir::toNativeSeparators(outputPath)), overwrite ? FALSE : TRUE);
+       MUtils::OS::progress_callback_t callback_function;
+       void *user_data;
+}
+progress_callback_data_t;
+
+static DWORD __stdcall copy_file_progress(LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData)
+{
+       if(const progress_callback_data_t *data = (progress_callback_data_t*) lpData)
+       {
+               const double progress = qBound(0.0, double(TotalBytesTransferred.QuadPart) / double(TotalFileSize.QuadPart), 1.0);
+               return data->callback_function(progress, data->user_data) ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
+       }
+       return PROGRESS_CONTINUE;
+}
+
+MUTILS_API bool MUtils::OS::copy_file(const QString &sourcePath, const QString &outputPath, const bool &overwrite, const progress_callback_t callback, void *const userData)
+{
+       progress_callback_data_t callback_data = { callback, userData };
+       BOOL cancel = FALSE;
+       const BOOL result = CopyFileExW(MUTILS_WCHR(QDir::toNativeSeparators(sourcePath)), MUTILS_WCHR(QDir::toNativeSeparators(outputPath)), ((callback_data.callback_function) ? copy_file_progress : NULL), ((callback_data.callback_function) ? &callback_data : NULL), &cancel, (overwrite ? 0 : COPY_FILE_FAIL_IF_EXISTS));
 
        if(result == FALSE)
        {
                const DWORD errorCode = GetLastError();
-               qWarning("CopyFile() failed with error code 0x%08X!", errorCode);
+               if(errorCode != ERROR_REQUEST_ABORTED)
+               {
+                       qWarning("CopyFile() failed with error code 0x%08X!", errorCode);
+               }
+               else
+               {
+                       qWarning("CopyFile() operation was abroted by user!");
+               }
        }
 
        return (result != FALSE);