Commit 092a6106 authored by Konstantin Vlasov's avatar Konstantin Vlasov

Implemented Dock progress bar in OS X

1. Added OS X specific implementation for displaying write progress over the application icon in the Dock.
2. Code refactoring for the "icon progress bar" implementation (OS X implementation must be in a separate file with extension .mm, so other platforms were splitted too for unification.)
parent 94790893
......@@ -22,21 +22,23 @@ TEMPLATE = app
SOURCES += main.cpp\
maindialog.cpp \
maindialog.cpp \
imagewriter.cpp \
common.cpp \
externalprogressbar.cpp \
physicaldevice.cpp \
usbdevicemonitor.cpp
win32 {
SOURCES += platform_win.cpp
SOURCES += platform_win.cpp \
externalprogressbar_win.cpp
}
linux {
SOURCES += platform_lin.cpp
SOURCES += platform_lin.cpp \
externalprogressbar_lin.cpp
}
macx {
OBJECTIVE_SOURCES += platform_mac.mm
OBJECTIVE_SOURCES += platform_mac.mm \
externalprogressbar_mac.mm
ICON = res/icon-rosa.icns
}
......
......@@ -8,8 +8,12 @@
#include "common.h"
class ExternalProgressBarPrivate;
class ExternalProgressBar
{
protected:
ExternalProgressBarPrivate* const d_ptr;
public:
ExternalProgressBar(QWidget* mainWindow);
~ExternalProgressBar();
......@@ -32,14 +36,6 @@ public:
protected:
// Maximum counter value for the progress bar
quint64 m_MaxValue;
#if defined(Q_OS_WIN32)
// Windows7 Taskbar interface for mirroring the progress bar
ITaskbarList3* m_Win7TaskbarList;
// Main window handle for selecting the correct taskbar button
HWND m_hWnd;
#endif
};
#endif // EXTERNALPROGRESSBAR_H
////////////////////////////////////////////////////////////////////////////////
// Linux implementation of ExternalProgressBar
// Not implemented yet, contains only stubs
#include <QWidget>
#include "externalprogressbar.h"
// Class with platform-specific data
class ExternalProgressBarPrivate
{
public:
ExternalProgressBarPrivate();
~ExternalProgressBarPrivate();
};
ExternalProgressBarPrivate::ExternalProgressBarPrivate()
{
}
ExternalProgressBarPrivate::~ExternalProgressBarPrivate()
{
}
ExternalProgressBar::ExternalProgressBar(QWidget* mainWindow) :
d_ptr(new ExternalProgressBarPrivate()),
m_MaxValue(0)
{
Q_UNUSED(mainWindow);
}
ExternalProgressBar::~ExternalProgressBar()
{
DestroyProgressBar();
delete d_ptr;
}
// Initializes the external progress bar and sets its limits
bool ExternalProgressBar::InitProgressBar(quint64 maxSteps)
{
m_MaxValue = maxSteps;
Q_UNUSED(maxSteps);
return false;
}
// Deinitializes the external progress bar and returns into the normal state
bool ExternalProgressBar::DestroyProgressBar()
{
return false;
}
// Updates the current progress bar position
bool ExternalProgressBar::SetProgressValue(quint64 currentSteps)
{
Q_UNUSED(currentSteps);
return false;
}
// Sets the progress bar to indicate pause
bool ExternalProgressBar::ProgressSetPause()
{
return false;
}
// Sets the progress bar to indicate an error
bool ExternalProgressBar::ProgressSetError()
{
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Mac OS X implementation of ExternalProgressBar
#include <QWidget>
#include "externalprogressbar.h"
#include <Cocoa/Cocoa.h>
// Class with platform-specific data
class ExternalProgressBarPrivate
{
public:
ExternalProgressBarPrivate();
~ExternalProgressBarPrivate();
NSProgressIndicator* progressIndicator;
};
ExternalProgressBarPrivate::ExternalProgressBarPrivate() :
progressIndicator(nil)
{
}
ExternalProgressBarPrivate::~ExternalProgressBarPrivate()
{
}
ExternalProgressBar::ExternalProgressBar(QWidget* mainWindow) :
d_ptr(new ExternalProgressBarPrivate()),
m_MaxValue(0)
{
Q_UNUSED(mainWindow);
// Create a new view based on the current application icon with progress bar positioned over it
// and replace the Dock icon with this view
NSImageView* iv = [[NSImageView alloc] init];
[iv setImage: [[NSApplication sharedApplication] applicationIconImage]];
[[NSApp dockTile] setContentView: iv];
d_ptr->progressIndicator = [[NSProgressIndicator alloc] initWithFrame: NSMakeRect(0, 0, [NSApp dockTile].size.width, 20)];
[d_ptr->progressIndicator setHidden: YES];
[d_ptr->progressIndicator setStyle: NSProgressIndicatorBarStyle];
[d_ptr->progressIndicator setIndeterminate: NO];
[d_ptr->progressIndicator setBezeled: YES];
[iv addSubview: d_ptr->progressIndicator];
[d_ptr->progressIndicator release];
[[NSApp dockTile] display];
}
ExternalProgressBar::~ExternalProgressBar()
{
DestroyProgressBar();
delete d_ptr;
}
// Initializes the external progress bar and sets its limits
bool ExternalProgressBar::InitProgressBar(quint64 maxSteps)
{
m_MaxValue = maxSteps;
[d_ptr->progressIndicator setMinValue: 0];
[d_ptr->progressIndicator setMaxValue: maxSteps];
[d_ptr->progressIndicator setDoubleValue: 0];
[d_ptr->progressIndicator setHidden: NO];
[[NSApp dockTile] display];
return true;
}
// Deinitializes the external progress bar and returns into the normal state
bool ExternalProgressBar::DestroyProgressBar()
{
[d_ptr->progressIndicator setHidden: YES];
[[NSApp dockTile] display];
return true;
}
// Updates the current progress bar position
bool ExternalProgressBar::SetProgressValue(quint64 currentSteps)
{
[d_ptr->progressIndicator setDoubleValue: currentSteps];
[d_ptr->progressIndicator setHidden: NO];
[[NSApp dockTile] display];
return true;
}
// Sets the progress bar to indicate pause
bool ExternalProgressBar::ProgressSetPause()
{
// Not supported by OS X
return false;
}
// Sets the progress bar to indicate an error
bool ExternalProgressBar::ProgressSetError()
{
// Not supported by OS X
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Implementation of ExternalProgressBar
// Windows implementation of ExternalProgressBar
#include <QWidget>
#include "externalprogressbar.h"
// Class with platform-specific data
class ExternalProgressBarPrivate
{
public:
ExternalProgressBarPrivate();
~ExternalProgressBarPrivate();
// Windows7 Taskbar interface for mirroring the progress bar
ITaskbarList3* m_Win7TaskbarList;
// Main window handle for selecting the correct taskbar button
HWND m_hWnd;
};
ExternalProgressBarPrivate::ExternalProgressBarPrivate() :
m_Win7TaskbarList(NULL),
m_hWnd(NULL)
{
}
ExternalProgressBarPrivate::~ExternalProgressBarPrivate()
{
}
ExternalProgressBar::ExternalProgressBar(QWidget* mainWindow) :
d_ptr(new ExternalProgressBarPrivate()),
m_MaxValue(0)
{
#if defined(Q_OS_WIN32)
// Get the taskbar object (if NULL is returned it won't be used - e.g. on pre-7 Windows versions)
CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, reinterpret_cast<void**>(&m_Win7TaskbarList));
CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, reinterpret_cast<void**>(&d_ptr->m_Win7TaskbarList));
// Store the window handle. In Windows winId() returns HWND.
m_hWnd = reinterpret_cast<HWND>(mainWindow->winId());
#else
Q_UNUSED(mainWindow);
#endif
d_ptr->m_hWnd = reinterpret_cast<HWND>(mainWindow->winId());
}
ExternalProgressBar::~ExternalProgressBar()
{
DestroyProgressBar();
#if defined(Q_OS_WIN32)
if (m_Win7TaskbarList != NULL)
m_Win7TaskbarList->Release();
if (d_ptr->m_Win7TaskbarList != NULL)
d_ptr->m_Win7TaskbarList->Release();
#endif
delete d_ptr;
}
// Initializes the external progress bar and sets its limits
......@@ -33,13 +56,11 @@ bool ExternalProgressBar::InitProgressBar(quint64 maxSteps)
{
bool res = true;
m_MaxValue = maxSteps;
#if defined(Q_OS_WIN32)
// When we set the progress value, TBPF_NORMAL is set automatically
if (m_Win7TaskbarList != NULL)
res = (m_Win7TaskbarList->SetProgressValue(m_hWnd, 0, maxSteps) == S_OK);
#else
Q_UNUSED(maxSteps);
#endif
if (d_ptr->m_Win7TaskbarList != NULL)
res = (d_ptr->m_Win7TaskbarList->SetProgressValue(d_ptr->m_hWnd, 0, maxSteps) == S_OK);
return res;
}
......@@ -47,10 +68,10 @@ bool ExternalProgressBar::InitProgressBar(quint64 maxSteps)
bool ExternalProgressBar::DestroyProgressBar()
{
bool res = true;
#if defined(Q_OS_WIN32)
if (m_Win7TaskbarList != NULL)
res = (m_Win7TaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS) == S_OK);
#endif
if (d_ptr->m_Win7TaskbarList != NULL)
res = (d_ptr->m_Win7TaskbarList->SetProgressState(d_ptr->m_hWnd, TBPF_NOPROGRESS) == S_OK);
return res;
}
......@@ -58,12 +79,10 @@ bool ExternalProgressBar::DestroyProgressBar()
bool ExternalProgressBar::SetProgressValue(quint64 currentSteps)
{
bool res = true;
#if defined(Q_OS_WIN32)
if (m_Win7TaskbarList != NULL)
res = (m_Win7TaskbarList->SetProgressValue(m_hWnd, currentSteps, m_MaxValue) == S_OK);
#else
Q_UNUSED(currentSteps);
#endif
if (d_ptr->m_Win7TaskbarList != NULL)
res = (d_ptr->m_Win7TaskbarList->SetProgressValue(d_ptr->m_hWnd, currentSteps, m_MaxValue) == S_OK);
return res;
}
......@@ -71,10 +90,10 @@ bool ExternalProgressBar::SetProgressValue(quint64 currentSteps)
bool ExternalProgressBar::ProgressSetPause()
{
bool res = true;
#if defined(Q_OS_WIN32)
if (m_Win7TaskbarList != NULL)
res = (m_Win7TaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED) == S_OK);
#endif
if (d_ptr->m_Win7TaskbarList != NULL)
res = (d_ptr->m_Win7TaskbarList->SetProgressState(d_ptr->m_hWnd, TBPF_PAUSED) == S_OK);
return res;
}
......@@ -82,10 +101,10 @@ bool ExternalProgressBar::ProgressSetPause()
bool ExternalProgressBar::ProgressSetError()
{
bool res = true;
#if defined(Q_OS_WIN32)
if (m_Win7TaskbarList != NULL)
res = (m_Win7TaskbarList->SetProgressState(m_hWnd, TBPF_ERROR) == S_OK);
#endif
if (d_ptr->m_Win7TaskbarList != NULL)
res = (d_ptr->m_Win7TaskbarList->SetProgressState(d_ptr->m_hWnd, TBPF_ERROR) == S_OK);
return res;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment