Commit 90c03d32 authored by con's avatar con

Add functionality to show progress for the application in task bar/dock.

Move the API to the progress manager.
Added a first Mac implementation, other
platforms are pending.
parent 4688634f
...@@ -165,7 +165,17 @@ FORMS += dialogs/newdialog.ui \ ...@@ -165,7 +165,17 @@ FORMS += dialogs/newdialog.ui \
generalsettings.ui generalsettings.ui
RESOURCES += core.qrc \ RESOURCES += core.qrc \
fancyactionbar.qrc fancyactionbar.qrc
unix:!macx {
win32 {
SOURCES += progressmanager/progressmanager_win.cpp
}
else:macx {
OBJECTIVE_SOURCES += progressmanager/progressmanager_mac.mm
LIBS += -framework AppKit
}
else:unix {
SOURCES += progressmanager/progressmanager_x11.cpp
images.files = images/qtcreator_logo_*.png images.files = images/qtcreator_logo_*.png
images.path = /share/pixmaps images.path = /share/pixmaps
INSTALLS += images INSTALLS += images
......
...@@ -40,7 +40,8 @@ using namespace Core; ...@@ -40,7 +40,8 @@ using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
ProgressManagerPrivate::ProgressManagerPrivate(QObject *parent) ProgressManagerPrivate::ProgressManagerPrivate(QObject *parent)
: ProgressManager(parent) : ProgressManager(parent),
m_applicationTask(0)
{ {
m_progressView = new ProgressView; m_progressView = new ProgressView;
ICore *core = ICore::instance(); ICore *core = ICore::instance();
...@@ -66,6 +67,8 @@ void ProgressManagerPrivate::cancelTasks(const QString &type) ...@@ -66,6 +67,8 @@ void ProgressManagerPrivate::cancelTasks(const QString &type)
} }
found = true; found = true;
disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished())); disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished()));
if (m_applicationTask == task.key())
disconnectApplicationTask();
task.key()->cancel(); task.key()->cancel();
delete task.key(); delete task.key();
task = m_runningTasks.erase(task); task = m_runningTasks.erase(task);
...@@ -80,6 +83,8 @@ void ProgressManagerPrivate::cancelAllRunningTasks() ...@@ -80,6 +83,8 @@ void ProgressManagerPrivate::cancelAllRunningTasks()
QMap<QFutureWatcher<void> *, QString>::const_iterator task = m_runningTasks.constBegin(); QMap<QFutureWatcher<void> *, QString>::const_iterator task = m_runningTasks.constBegin();
while (task != m_runningTasks.constEnd()) { while (task != m_runningTasks.constEnd()) {
disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished())); disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished()));
if (m_applicationTask == task.key())
disconnectApplicationTask();
task.key()->cancel(); task.key()->cancel();
delete task.key(); delete task.key();
++task; ++task;
...@@ -87,14 +92,23 @@ void ProgressManagerPrivate::cancelAllRunningTasks() ...@@ -87,14 +92,23 @@ void ProgressManagerPrivate::cancelAllRunningTasks()
m_runningTasks.clear(); m_runningTasks.clear();
} }
FutureProgress *ProgressManagerPrivate::addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency) FutureProgress *ProgressManagerPrivate::addTask(const QFuture<void> &future, const QString &title,
const QString &type, ProgressFlags flags)
{ {
QFutureWatcher<void> *watcher = new QFutureWatcher<void>(); QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
m_runningTasks.insert(watcher, type); m_runningTasks.insert(watcher, type);
connect(watcher, SIGNAL(finished()), this, SLOT(taskFinished())); connect(watcher, SIGNAL(finished()), this, SLOT(taskFinished()));
if (flags & ShowInApplicationIcon) {
m_applicationTask = watcher;
connect(m_applicationTask, SIGNAL(progressRangeChanged(int,int)),
this, SLOT(setApplicationProgressRange(int,int)));
connect(m_applicationTask, SIGNAL(progressValueChanged(int)),
this, SLOT(setApplicationProgressValue(int)));
setApplicationProgressVisible(true);
}
watcher->setFuture(future); watcher->setFuture(future);
emit taskStarted(type); emit taskStarted(type);
return m_progressView->addTask(future, title, type, persistency); return m_progressView->addTask(future, title, type, flags);
} }
QWidget *ProgressManagerPrivate::progressView() QWidget *ProgressManagerPrivate::progressView()
...@@ -107,6 +121,8 @@ void ProgressManagerPrivate::taskFinished() ...@@ -107,6 +121,8 @@ void ProgressManagerPrivate::taskFinished()
QObject *taskObject = sender(); QObject *taskObject = sender();
QTC_ASSERT(taskObject, return); QTC_ASSERT(taskObject, return);
QFutureWatcher<void> *task = static_cast<QFutureWatcher<void> *>(taskObject); QFutureWatcher<void> *task = static_cast<QFutureWatcher<void> *>(taskObject);
if (m_applicationTask == task)
disconnectApplicationTask();
QString type = m_runningTasks.value(task); QString type = m_runningTasks.value(task);
m_runningTasks.remove(task); m_runningTasks.remove(task);
delete task; delete task;
...@@ -115,3 +131,13 @@ void ProgressManagerPrivate::taskFinished() ...@@ -115,3 +131,13 @@ void ProgressManagerPrivate::taskFinished()
emit allTasksFinished(type); emit allTasksFinished(type);
} }
} }
void ProgressManagerPrivate::disconnectApplicationTask()
{
disconnect(m_applicationTask, SIGNAL(progressRangeChanged(int,int)),
this, SLOT(setApplicationProgressRange(int,int)));
disconnect(m_applicationTask, SIGNAL(progressValueChanged(int)),
this, SLOT(setApplicationProgressValue(int)));
setApplicationProgressVisible(false);
m_applicationTask = 0;
}
...@@ -42,12 +42,18 @@ class CORE_EXPORT ProgressManager : public QObject ...@@ -42,12 +42,18 @@ class CORE_EXPORT ProgressManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum PersistentType { CloseOnSuccess, KeepOnFinish }; enum ProgressFlag {
KeepOnFinish = 0x01,
ShowInApplicationIcon = 0x02
};
Q_DECLARE_FLAGS(ProgressFlags, ProgressFlag)
ProgressManager(QObject *parent = 0) : QObject(parent) {} ProgressManager(QObject *parent = 0) : QObject(parent) {}
virtual ~ProgressManager() {} virtual ~ProgressManager() {}
virtual FutureProgress *addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency = KeepOnFinish) = 0; virtual FutureProgress *addTask(const QFuture<void> &future, const QString &title,
const QString &type, ProgressFlags flags = 0) = 0;
virtual void setApplicationLabel(const QString &text) = 0;
public slots: public slots:
virtual void cancelTasks(const QString &type) = 0; virtual void cancelTasks(const QString &type) = 0;
...@@ -59,4 +65,6 @@ signals: ...@@ -59,4 +65,6 @@ signals:
} // namespace Core } // namespace Core
Q_DECLARE_OPERATORS_FOR_FLAGS(Core::ProgressManager::ProgressFlags)
#endif //PROGRESSMANAGER_H #endif //PROGRESSMANAGER_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "progressmanager_p.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
#import <AppKit/NSDockTile.h>
#import <AppKit/NSApplication.h>
#import <AppKit/NSImageView.h>
#import <Foundation/NSString.h>
@interface ApplicationProgressView : NSView {
int min;
int max;
int value;
}
+ (ApplicationProgressView *)sharedProgressView;
- (void)setRangeMin:(int)v1 max:(int)v2;
- (void)setValue:(int)v;
- (void)updateBadge;
@end
static ApplicationProgressView *sharedProgressView = nil;
@implementation ApplicationProgressView
+ (ApplicationProgressView *)sharedProgressView
{
if (sharedProgressView == nil) {
sharedProgressView = [[ApplicationProgressView alloc] init];
}
return sharedProgressView;
}
- (void)setRangeMin:(int)v1 max:(int)v2
{
min = v1;
max = v2;
[self updateBadge];
}
- (void)setValue:(int)v
{
value = v;
[self updateBadge];
}
- (void)updateBadge
{
[[NSApp dockTile] display];
}
- (void)drawRect:(NSRect)rect
{
NSRect boundary = [self bounds];
[[NSApp applicationIconImage] drawInRect:boundary
fromRect:NSZeroRect
operation:NSCompositeCopy
fraction:1.0];
NSRect progressBoundary = boundary;
progressBoundary.size.height *= 0.13;
progressBoundary.size.width *= 0.8;
progressBoundary.origin.x = (NSWidth(boundary) - NSWidth(progressBoundary))/2.;
progressBoundary.origin.y = NSHeight(boundary)*0.13;
double range = max - min;
double percent = 0.50;
if (range != 0)
percent = (value - min) / range;
if (percent > 1)
percent = 1;
else if (percent < 0)
percent = 0;
NSRect currentProgress = progressBoundary;
currentProgress.size.width *= percent;
[[NSColor blackColor] setFill];
[NSBezierPath fillRect:progressBoundary];
[[NSColor lightGrayColor] setFill];
[NSBezierPath fillRect:currentProgress];
[[NSColor blackColor] setStroke];
[NSBezierPath strokeRect:progressBoundary];
}
@end
void Core::Internal::ProgressManagerPrivate::setApplicationLabel(const QString &text)
{
const char *utf8String = text.toUtf8().constData();
NSString *cocoaString = [[NSString alloc] initWithUTF8String:utf8String];
[[NSApp dockTile] setBadgeLabel:cocoaString];
[cocoaString release];
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressRange(int min, int max)
{
[[ApplicationProgressView sharedProgressView] setRangeMin:min max:max];
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressValue(int value)
{
[[ApplicationProgressView sharedProgressView] setValue:value];
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressVisible(bool visible)
{
if (visible) {
[[NSApp dockTile] setContentView:[ApplicationProgressView sharedProgressView]];
} else {
[[NSApp dockTile] setContentView:nil];
}
[[NSApp dockTile] display];
}
#else
void Core::Internal::ProgressManagerPrivate::setApplicationLabel(const QString &text)
{
Q_UNUSED(text)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressRange(int min, int max)
{
Q_UNUSED(min)
Q_UNUSED(max)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressValue(int value)
{
Q_UNUSED(value)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressVisible(bool visible)
{
Q_UNUSED(visible)
}
#endif
...@@ -49,8 +49,10 @@ public: ...@@ -49,8 +49,10 @@ public:
~ProgressManagerPrivate(); ~ProgressManagerPrivate();
void init(); void init();
FutureProgress *addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency); FutureProgress *addTask(const QFuture<void> &future, const QString &title, const QString &type,
ProgressFlags flags);
void setApplicationLabel(const QString &text);
QWidget *progressView(); QWidget *progressView();
public slots: public slots:
...@@ -59,9 +61,15 @@ public slots: ...@@ -59,9 +61,15 @@ public slots:
private slots: private slots:
void taskFinished(); void taskFinished();
void cancelAllRunningTasks(); void cancelAllRunningTasks();
void setApplicationProgressRange(int min, int max);
void setApplicationProgressValue(int value);
void setApplicationProgressVisible(bool visible);
void disconnectApplicationTask();
private: private:
QPointer<ProgressView> m_progressView; QPointer<ProgressView> m_progressView;
QMap<QFutureWatcher<void> *, QString> m_runningTasks; QMap<QFutureWatcher<void> *, QString> m_runningTasks;
QFutureWatcher<void> *m_applicationTask;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -27,15 +27,25 @@ ...@@ -27,15 +27,25 @@
** **
**************************************************************************/ **************************************************************************/
#ifndef BUILDPROGRESS_MAC_H #include "progressmanager_p.h"
#define BUILDPROGRESS_MAC_H
#include <QtCore/QString> void Core::Internal::ProgressManagerPrivate::setApplicationLabel(const QString &text)
{
Q_UNUSED(text)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressRange(int min, int max)
{
Q_UNUSED(min)
Q_UNUSED(max)
}
namespace ProjectExplorer { void Core::Internal::ProgressManagerPrivate::setApplicationProgressValue(int value)
namespace Internal { {
void qtcShowDockTileBadgeLabel(const QString &text); Q_UNUSED(value)
}
} }
#endif void Core::Internal::ProgressManagerPrivate::setApplicationProgressVisible(bool visible)
{
Q_UNUSED(visible)
}
...@@ -27,22 +27,25 @@ ...@@ -27,22 +27,25 @@
** **
**************************************************************************/ **************************************************************************/
#include "buildprogress_mac.h" #include "progressmanager_p.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 void Core::Internal::ProgressManagerPrivate::setApplicationLabel(const QString &text)
#include <AppKit/NSDockTile.h>
#include <AppKit/NSApplication.h>
#include <Foundation/NSString.h>
#endif
void ProjectExplorer::Internal::qtcShowDockTileBadgeLabel(const QString &text)
{ {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
const char *utf8String = text.toUtf8().constData();
NSString *cocoaString = [[NSString alloc] initWithUTF8String:utf8String];
[[NSApp dockTile] setBadgeLabel:cocoaString];
[cocoaString release];
#else
Q_UNUSED(text) Q_UNUSED(text)
#endif }
void Core::Internal::ProgressManagerPrivate::setApplicationProgressRange(int min, int max)
{
Q_UNUSED(min)
Q_UNUSED(max)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressValue(int value)
{
Q_UNUSED(value)
}
void Core::Internal::ProgressManagerPrivate::setApplicationProgressVisible(bool visible)
{
Q_UNUSED(visible)
} }
...@@ -58,7 +58,7 @@ ProgressView::~ProgressView() ...@@ -58,7 +58,7 @@ ProgressView::~ProgressView()
FutureProgress *ProgressView::addTask(const QFuture<void> &future, FutureProgress *ProgressView::addTask(const QFuture<void> &future,
const QString &title, const QString &title,
const QString &type, const QString &type,
ProgressManager::PersistentType persistency) ProgressManager::ProgressFlags flags)
{ {
removeOldTasks(type); removeOldTasks(type);
if (m_taskList.size() == 3) if (m_taskList.size() == 3)
...@@ -69,7 +69,7 @@ FutureProgress *ProgressView::addTask(const QFuture<void> &future, ...@@ -69,7 +69,7 @@ FutureProgress *ProgressView::addTask(const QFuture<void> &future,
m_layout->insertWidget(0, progress); m_layout->insertWidget(0, progress);
m_taskList.append(progress); m_taskList.append(progress);
m_type.insert(progress, type); m_type.insert(progress, type);
m_keep.insert(progress, (persistency == ProgressManager::KeepOnFinish)); m_keep.insert(progress, (flags & ProgressManager::KeepOnFinish));
connect(progress, SIGNAL(finished()), this, SLOT(slotFinished())); connect(progress, SIGNAL(finished()), this, SLOT(slotFinished()));
return progress; return progress;
} }
......
...@@ -55,7 +55,7 @@ public: ...@@ -55,7 +55,7 @@ public:
FutureProgress *addTask(const QFuture<void> &future, FutureProgress *addTask(const QFuture<void> &future,
const QString &title, const QString &title,
const QString &type, const QString &type,
ProgressManager::PersistentType persistency); ProgressManager::ProgressFlags flags);
private slots: private slots:
void slotFinished(); void slotFinished();
......
...@@ -233,8 +233,7 @@ void CppFindReferences::findAll_helper(Symbol *symbol) ...@@ -233,8 +233,7 @@ void CppFindReferences::findAll_helper(Symbol *symbol)
m_watcher.setFuture(result); m_watcher.setFuture(result);
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
CppTools::Constants::TASK_SEARCH, CppTools::Constants::TASK_SEARCH);
Core::ProgressManager::CloseOnSuccess);
connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup())); connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
} }
......
...@@ -857,8 +857,7 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) ...@@ -857,8 +857,7 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
if (pinfo.includePaths.size() > 1) { if (pinfo.includePaths.size() > 1) {
m_core->progressManager()->addTask(result, tr("Scanning"), m_core->progressManager()->addTask(result, tr("Scanning"),
CppTools::Constants::TASK_INDEX, CppTools::Constants::TASK_INDEX);
Core::ProgressManager::CloseOnSuccess);
} }
} }
} }
...@@ -899,8 +898,7 @@ QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles ...@@ -899,8 +898,7 @@ QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles
if (sourceFiles.count() > 1) { if (sourceFiles.count() > 1) {
m_core->progressManager()->addTask(result, tr("Indexing"), m_core->progressManager()->addTask(result, tr("Indexing"),
CppTools::Constants::TASK_INDEX, CppTools::Constants::TASK_INDEX);
Core::ProgressManager::CloseOnSuccess);
} }
return result; return result;
} }
......
...@@ -109,8 +109,7 @@ void GitCommand::execute() ...@@ -109,8 +109,7 @@ void GitCommand::execute()
const QString taskName = QLatin1String("Git ") + m_jobs.front().arguments.at(0); const QString taskName = QLatin1String("Git ") + m_jobs.front().arguments.at(0);
Core::ICore::instance()->progressManager()->addTask(task, taskName, Core::ICore::instance()->progressManager()->addTask(task, taskName,
QLatin1String("Git.action"), QLatin1String("Git.action"));
Core::ProgressManager::CloseOnSuccess);
} }
void GitCommand::run() void GitCommand::run()
......
...@@ -245,8 +245,7 @@ void LocatorPlugin::refresh(QList<ILocatorFilter*> filters) ...@@ -245,8 +245,7 @@ void LocatorPlugin::refresh(QList<ILocatorFilter*> filters)
QFuture<void> task = QtConcurrent::run(&ILocatorFilter::refresh, filters); QFuture<void> task = QtConcurrent::run(&ILocatorFilter::refresh, filters);
Core::FutureProgress *progress = Core::ICore::instance() Core::FutureProgress *progress = Core::ICore::instance()
->progressManager()->addTask(task, tr("Indexing"), ->progressManager()->addTask(task, tr("Indexing"),
Locator::Constants::TASK_INDEX, Locator::Constants::TASK_INDEX);
Core::ProgressManager::CloseOnSuccess);
connect(progress, SIGNAL(finished()), this, SLOT(saveSettings())); connect(progress, SIGNAL(finished()), this, SLOT(saveSettings()));
} }
......
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
#include <QtGui/QHeaderView> #include <QtGui/QHeaderView>
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
...@@ -91,10 +93,12 @@ BuildManager::BuildManager(ProjectExplorerPlugin *parent) ...@@ -91,10 +93,12 @@ BuildManager::BuildManager(ProjectExplorerPlugin *parent)
m_taskWindow->addCategory(Constants::TASK_CATEGORY_BUILDSYSTEM, tr("Buildsystem", "Category for build system isses listened under 'Build Issues'")); m_taskWindow->addCategory(Constants::TASK_CATEGORY_BUILDSYSTEM, tr("Buildsystem", "Category for build system isses listened under 'Build Issues'"));
connect(m_taskWindow, SIGNAL(tasksChanged()), connect(m_taskWindow, SIGNAL(tasksChanged()),
this, SIGNAL(tasksChanged())); this, SLOT(updateTaskCount()));
connect(&m_progressWatcher, SIGNAL(canceled()), connect(&m_progressWatcher, SIGNAL(canceled()),
this, SLOT(cancel())); this, SLOT(cancel()));
connect(&m_progressWatcher, SIGNAL(finished()),