2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2010-03-05 11:25:49 +01:00
|
|
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** 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.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** 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.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-08-14 09:30:56 +02:00
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "taskwindow.h"
|
|
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
#include "itaskhandler.h"
|
|
|
|
|
#include "projectexplorerconstants.h"
|
2010-06-16 14:12:30 +02:00
|
|
|
#include "task.h"
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2010-06-18 11:18:48 +02:00
|
|
|
#include <coreplugin/actionmanager/command.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2010-06-18 11:18:48 +02:00
|
|
|
#include <coreplugin/icontext.h>
|
2009-01-23 13:03:36 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2010-06-18 11:18:48 +02:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
#include <QtCore/QDir>
|
2009-11-11 09:54:13 +01:00
|
|
|
#include <QtCore/QFileInfo>
|
2010-03-19 17:22:18 +01:00
|
|
|
#include <QtCore/QDebug>
|
2009-11-11 09:54:13 +01:00
|
|
|
#include <QtGui/QApplication>
|
|
|
|
|
#include <QtGui/QClipboard>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtGui/QKeyEvent>
|
|
|
|
|
#include <QtGui/QListView>
|
|
|
|
|
#include <QtGui/QPainter>
|
2009-11-11 09:54:13 +01:00
|
|
|
#include <QtGui/QStyledItemDelegate>
|
2009-07-16 12:11:32 +02:00
|
|
|
#include <QtGui/QSortFilterProxyModel>
|
2010-03-18 10:59:06 +01:00
|
|
|
#include <QtGui/QMenu>
|
2010-05-27 13:28:07 +02:00
|
|
|
#include <QtGui/QToolButton>
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2010-02-19 13:06:28 +01:00
|
|
|
namespace {
|
2010-04-19 16:03:28 +02:00
|
|
|
const int TASK_ICON_SIZE = 16;
|
|
|
|
|
const int TASK_ICON_MARGIN = 2;
|
2010-02-19 13:06:28 +01:00
|
|
|
}
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
namespace ProjectExplorer {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
class TaskView : public QListView
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TaskView(QWidget *parent = 0);
|
|
|
|
|
~TaskView();
|
|
|
|
|
void resizeEvent(QResizeEvent *e);
|
|
|
|
|
void keyPressEvent(QKeyEvent *e);
|
|
|
|
|
};
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
class TaskDelegate : public QStyledItemDelegate
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-11-11 09:54:13 +01:00
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
|
|
|
|
TaskDelegate(QObject * parent = 0);
|
|
|
|
|
~TaskDelegate();
|
|
|
|
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
|
|
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
|
|
|
|
|
|
|
|
// TaskView uses this method if the size of the taskview changes
|
|
|
|
|
void emitSizeHintChanged(const QModelIndex &index);
|
|
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void generateGradientPixmap(int width, int height, QColor color, bool selected) const;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
class TaskWindowContext : public Core::IContext
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TaskWindowContext(QWidget *widget);
|
2010-06-25 12:56:16 +02:00
|
|
|
virtual Core::Context context() const;
|
2009-11-11 09:54:13 +01:00
|
|
|
virtual QWidget *widget();
|
|
|
|
|
private:
|
|
|
|
|
QWidget *m_taskList;
|
2010-06-25 17:37:59 +02:00
|
|
|
const Core::Context m_context;
|
2009-11-11 09:54:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class TaskModel : public QAbstractItemModel
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
// Model stuff
|
|
|
|
|
TaskModel();
|
|
|
|
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
|
|
|
|
QModelIndex parent(const QModelIndex &child) const;
|
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
|
|
|
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
|
|
|
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
2010-06-24 15:07:42 +02:00
|
|
|
Task task(const QModelIndex &index) const;
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2009-11-11 12:36:44 +01:00
|
|
|
QStringList categoryIds() const;
|
|
|
|
|
QString categoryDisplayName(const QString &categoryId) const;
|
2009-11-11 09:54:13 +01:00
|
|
|
void addCategory(const QString &categoryId, const QString &categoryName);
|
|
|
|
|
|
2010-03-12 13:53:00 +01:00
|
|
|
QList<Task> tasks(const QString &categoryId = QString()) const;
|
|
|
|
|
void addTask(const Task &task);
|
2010-04-16 12:41:26 +02:00
|
|
|
void removeTask(const Task &task);
|
2009-11-11 09:54:13 +01:00
|
|
|
void clearTasks(const QString &categoryId = QString());
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
int sizeOfFile();
|
|
|
|
|
int sizeOfLineNumber();
|
|
|
|
|
void setFileNotFound(const QModelIndex &index, bool b);
|
|
|
|
|
|
2010-04-19 16:03:28 +02:00
|
|
|
enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type, Category, Icon, Task_t };
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2010-05-26 11:57:39 +02:00
|
|
|
QIcon taskTypeIcon(Task::TaskType t) const;
|
|
|
|
|
|
2010-06-08 17:18:53 +02:00
|
|
|
int taskCount();
|
|
|
|
|
int errorTaskCount();
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
private:
|
2009-11-11 09:54:13 +01:00
|
|
|
QHash<QString,QString> m_categories; // category id -> display name
|
2010-03-12 13:53:00 +01:00
|
|
|
QList<Task> m_tasks; // all tasks (in order of insertion)
|
|
|
|
|
QMap<QString,QList<Task> > m_tasksInCategory; // categoryId->tasks
|
2009-11-11 09:54:13 +01:00
|
|
|
|
|
|
|
|
QHash<QString,bool> m_fileNotFound;
|
2008-12-02 12:01:29 +01:00
|
|
|
int m_maxSizeOfFileName;
|
2010-05-26 11:57:39 +02:00
|
|
|
const QIcon m_errorIcon;
|
|
|
|
|
const QIcon m_warningIcon;
|
2010-06-08 17:18:53 +02:00
|
|
|
int m_taskCount;
|
|
|
|
|
int m_errorTaskCount;
|
2010-06-08 17:36:47 +02:00
|
|
|
int m_sizeOfLineNumber;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
class TaskFilterModel : public QSortFilterProxyModel
|
2009-07-16 12:11:32 +02:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TaskFilterModel(TaskModel *sourceModel, QObject *parent = 0);
|
|
|
|
|
|
|
|
|
|
TaskModel *taskModel() const;
|
|
|
|
|
|
|
|
|
|
bool filterIncludesUnknowns() const { return m_includeUnknowns; }
|
|
|
|
|
void setFilterIncludesUnknowns(bool b) { m_includeUnknowns = b; invalidateFilter(); }
|
|
|
|
|
|
|
|
|
|
bool filterIncludesWarnings() const { return m_includeWarnings; }
|
|
|
|
|
void setFilterIncludesWarnings(bool b) { m_includeWarnings = b; invalidateFilter(); }
|
|
|
|
|
|
|
|
|
|
bool filterIncludesErrors() const { return m_includeErrors; }
|
|
|
|
|
void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); }
|
|
|
|
|
|
2009-11-11 12:36:44 +01:00
|
|
|
QStringList filteredCategories() const { return m_categoryIds; }
|
|
|
|
|
void setFilteredCategories(const QStringList &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); }
|
|
|
|
|
|
2009-07-16 12:11:32 +02:00
|
|
|
protected:
|
|
|
|
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool m_includeUnknowns;
|
|
|
|
|
bool m_includeWarnings;
|
|
|
|
|
bool m_includeErrors;
|
2009-11-11 12:36:44 +01:00
|
|
|
QStringList m_categoryIds;
|
2009-07-16 12:11:32 +02:00
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
TaskView::TaskView(QWidget *parent)
|
|
|
|
|
: QListView(parent)
|
|
|
|
|
{
|
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskView::~TaskView()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskView::resizeEvent(QResizeEvent *e)
|
|
|
|
|
{
|
2009-07-13 17:35:17 +02:00
|
|
|
Q_UNUSED(e)
|
2008-12-02 12:01:29 +01:00
|
|
|
static_cast<TaskDelegate *>(itemDelegate())->emitSizeHintChanged(selectionModel()->currentIndex());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskView::keyPressEvent(QKeyEvent *e)
|
|
|
|
|
{
|
|
|
|
|
if (!e->modifiers() && e->key() == Qt::Key_Return) {
|
|
|
|
|
emit activated(currentIndex());
|
|
|
|
|
e->accept();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
QListView::keyPressEvent(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
// TaskModel
|
|
|
|
|
/////
|
|
|
|
|
|
2010-05-26 11:57:39 +02:00
|
|
|
TaskModel::TaskModel() :
|
|
|
|
|
m_maxSizeOfFileName(0),
|
|
|
|
|
m_errorIcon(QLatin1String(":/projectexplorer/images/compile_error.png")),
|
2010-06-08 17:18:53 +02:00
|
|
|
m_warningIcon(QLatin1String(":/projectexplorer/images/compile_warning.png")),
|
|
|
|
|
m_taskCount(0),
|
2010-06-08 17:36:47 +02:00
|
|
|
m_errorTaskCount(0),
|
|
|
|
|
m_sizeOfLineNumber(0)
|
2010-06-08 17:18:53 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::taskCount()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-06-08 17:18:53 +02:00
|
|
|
return m_taskCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::errorTaskCount()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-06-08 17:18:53 +02:00
|
|
|
return m_errorTaskCount;
|
2010-05-26 11:57:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QIcon TaskModel::taskTypeIcon(Task::TaskType t) const
|
|
|
|
|
{
|
|
|
|
|
switch (t) {
|
|
|
|
|
case Task::Warning:
|
|
|
|
|
return m_warningIcon;
|
|
|
|
|
case Task::Error:
|
|
|
|
|
return m_errorIcon;
|
|
|
|
|
case Task::Unknown:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return QIcon();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
void TaskModel::addCategory(const QString &categoryId, const QString &categoryName)
|
|
|
|
|
{
|
|
|
|
|
Q_ASSERT(!categoryId.isEmpty());
|
|
|
|
|
m_categories.insert(categoryId, categoryName);
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 13:53:00 +01:00
|
|
|
QList<Task> TaskModel::tasks(const QString &categoryId) const
|
2009-11-11 09:54:13 +01:00
|
|
|
{
|
|
|
|
|
if (categoryId.isEmpty()) {
|
|
|
|
|
return m_tasks;
|
|
|
|
|
} else {
|
|
|
|
|
return m_tasksInCategory.value(categoryId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 13:53:00 +01:00
|
|
|
void TaskModel::addTask(const Task &task)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-11-11 09:54:13 +01:00
|
|
|
Q_ASSERT(m_categories.keys().contains(task.category));
|
|
|
|
|
|
2010-06-08 11:57:50 +02:00
|
|
|
if (m_tasksInCategory.contains(task.category)) {
|
|
|
|
|
m_tasksInCategory[task.category].append(task);
|
|
|
|
|
} else {
|
|
|
|
|
QList<Task> temp;
|
|
|
|
|
temp.append(task);
|
|
|
|
|
m_tasksInCategory.insert(task.category, temp);
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size());
|
|
|
|
|
m_tasks.append(task);
|
2008-12-02 12:01:29 +01:00
|
|
|
endInsertRows();
|
|
|
|
|
|
|
|
|
|
QFont font;
|
|
|
|
|
QFontMetrics fm(font);
|
|
|
|
|
QString filename = task.file;
|
2010-02-01 12:43:56 +01:00
|
|
|
const int pos = filename.lastIndexOf(QLatin1Char('/'));
|
2008-12-02 12:01:29 +01:00
|
|
|
if (pos != -1)
|
2009-11-11 09:54:13 +01:00
|
|
|
filename = task.file.mid(pos +1);
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename));
|
2010-06-08 17:18:53 +02:00
|
|
|
++m_taskCount;
|
|
|
|
|
if (task.type == Task::Error)
|
|
|
|
|
++m_errorTaskCount;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-04-16 12:41:26 +02:00
|
|
|
|
|
|
|
|
void TaskModel::removeTask(const Task &task)
|
|
|
|
|
{
|
|
|
|
|
if (m_tasks.contains(task)) {
|
|
|
|
|
int index = m_tasks.indexOf(task);
|
|
|
|
|
beginRemoveRows(QModelIndex(), index, index);
|
|
|
|
|
m_tasks.removeAt(index);
|
2010-06-08 17:18:53 +02:00
|
|
|
--m_taskCount;
|
|
|
|
|
if (task.type == Task::Error)
|
|
|
|
|
--m_errorTaskCount;
|
2010-04-16 12:41:26 +02:00
|
|
|
endRemoveRows();
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-11-11 09:54:13 +01:00
|
|
|
|
|
|
|
|
void TaskModel::clearTasks(const QString &categoryId)
|
|
|
|
|
{
|
|
|
|
|
if (categoryId.isEmpty()) {
|
|
|
|
|
if (m_tasks.size() == 0)
|
|
|
|
|
return;
|
|
|
|
|
beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1);
|
|
|
|
|
m_tasks.clear();
|
|
|
|
|
m_tasksInCategory.clear();
|
2010-06-08 17:18:53 +02:00
|
|
|
m_taskCount = 0;
|
|
|
|
|
m_errorTaskCount = 0;
|
2009-11-11 09:54:13 +01:00
|
|
|
endRemoveRows();
|
|
|
|
|
m_maxSizeOfFileName = 0;
|
|
|
|
|
} else {
|
2010-06-08 15:38:59 +02:00
|
|
|
int index = 0;
|
|
|
|
|
int start = 0;
|
2010-06-08 17:18:53 +02:00
|
|
|
int subErrorTaskCount = 0;
|
2010-06-08 15:38:59 +02:00
|
|
|
while (index < m_tasks.size()) {
|
|
|
|
|
while (index < m_tasks.size() && m_tasks.at(index).category != categoryId) {
|
|
|
|
|
++start;
|
|
|
|
|
++index;
|
|
|
|
|
}
|
|
|
|
|
if (index == m_tasks.size())
|
|
|
|
|
break;
|
|
|
|
|
while (index < m_tasks.size() && m_tasks.at(index).category == categoryId) {
|
2010-06-08 17:18:53 +02:00
|
|
|
if (m_tasks.at(index).type == Task::Error)
|
|
|
|
|
++subErrorTaskCount;
|
2010-06-08 15:38:59 +02:00
|
|
|
++index;
|
|
|
|
|
}
|
|
|
|
|
// Index is now on the first non category
|
|
|
|
|
beginRemoveRows(QModelIndex(), start, index - 1);
|
|
|
|
|
|
|
|
|
|
for (int i = start; i < index; ++i) {
|
|
|
|
|
m_tasksInCategory[categoryId].removeOne(m_tasks.at(i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_tasks.erase(m_tasks.begin() + start, m_tasks.begin() + index);
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2010-06-08 17:18:53 +02:00
|
|
|
m_taskCount -= index - start;
|
|
|
|
|
m_errorTaskCount -= subErrorTaskCount;
|
2009-11-11 09:54:13 +01:00
|
|
|
|
|
|
|
|
endRemoveRows();
|
2010-06-08 15:38:59 +02:00
|
|
|
index = start;
|
2009-11-11 09:54:13 +01:00
|
|
|
}
|
|
|
|
|
// what to do with m_maxSizeOfFileName ?
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QModelIndex TaskModel::index(int row, int column, const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
if (parent.isValid())
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
return createIndex(row, column, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QModelIndex TaskModel::parent(const QModelIndex &child) const
|
|
|
|
|
{
|
2009-07-13 17:35:17 +02:00
|
|
|
Q_UNUSED(child)
|
2008-12-02 12:01:29 +01:00
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::rowCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
2009-11-11 09:54:13 +01:00
|
|
|
return parent.isValid() ? 0 : m_tasks.count();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::columnCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
return parent.isValid() ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant TaskModel::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
2009-11-11 09:54:13 +01:00
|
|
|
if (!index.isValid() || index.row() >= m_tasks.size() || index.column() != 0)
|
2008-12-02 12:01:29 +01:00
|
|
|
return QVariant();
|
|
|
|
|
|
2009-11-11 14:08:48 +01:00
|
|
|
if (role == TaskModel::File) {
|
2009-11-11 09:54:13 +01:00
|
|
|
return m_tasks.at(index.row()).file;
|
2009-11-11 14:08:48 +01:00
|
|
|
} else if (role == TaskModel::Line) {
|
|
|
|
|
if (m_tasks.at(index.row()).line <= 0)
|
|
|
|
|
return QVariant();
|
|
|
|
|
else
|
|
|
|
|
return m_tasks.at(index.row()).line;
|
|
|
|
|
} else if (role == TaskModel::Description) {
|
2009-11-11 09:54:13 +01:00
|
|
|
return m_tasks.at(index.row()).description;
|
2009-11-11 14:08:48 +01:00
|
|
|
} else if (role == TaskModel::FileNotFound) {
|
2009-11-11 09:54:13 +01:00
|
|
|
return m_fileNotFound.value(m_tasks.at(index.row()).file);
|
2009-11-11 14:08:48 +01:00
|
|
|
} else if (role == TaskModel::Type) {
|
2009-11-11 09:54:13 +01:00
|
|
|
return (int)m_tasks.at(index.row()).type;
|
2009-11-11 14:08:48 +01:00
|
|
|
} else if (role == TaskModel::Category) {
|
2009-11-11 12:36:44 +01:00
|
|
|
return m_tasks.at(index.row()).category;
|
2010-04-19 16:03:28 +02:00
|
|
|
} else if (role == TaskModel::Icon) {
|
2010-05-26 11:57:39 +02:00
|
|
|
return taskTypeIcon(m_tasks.at(index.row()).type);
|
2010-04-09 18:46:34 +02:00
|
|
|
} else if (role == TaskModel::Task_t) {
|
2010-06-24 15:07:42 +02:00
|
|
|
return QVariant::fromValue(task(index));
|
2009-11-11 14:08:48 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-24 15:07:42 +02:00
|
|
|
Task TaskModel::task(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
return m_tasks.at(index.row());
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-11 12:36:44 +01:00
|
|
|
QStringList TaskModel::categoryIds() const
|
|
|
|
|
{
|
|
|
|
|
return m_categories.keys();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString TaskModel::categoryDisplayName(const QString &categoryId) const
|
|
|
|
|
{
|
|
|
|
|
return m_categories.value(categoryId);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
int TaskModel::sizeOfFile()
|
|
|
|
|
{
|
|
|
|
|
return m_maxSizeOfFileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::sizeOfLineNumber()
|
|
|
|
|
{
|
2010-06-08 17:36:47 +02:00
|
|
|
if (m_sizeOfLineNumber == 0) {
|
|
|
|
|
QFont font;
|
|
|
|
|
QFontMetrics fm(font);
|
|
|
|
|
m_sizeOfLineNumber = fm.width("8888");
|
|
|
|
|
}
|
|
|
|
|
return m_sizeOfLineNumber;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskModel::setFileNotFound(const QModelIndex &idx, bool b)
|
|
|
|
|
{
|
2009-11-11 09:54:13 +01:00
|
|
|
if (idx.isValid() && idx.row() < m_tasks.size()) {
|
|
|
|
|
m_fileNotFound.insert(m_tasks[idx.row()].file, b);
|
2008-12-02 12:01:29 +01:00
|
|
|
emit dataChanged(idx, idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-16 12:11:32 +02:00
|
|
|
/////
|
|
|
|
|
// TaskFilterModel
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
|
|
TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent)
|
|
|
|
|
: QSortFilterProxyModel(parent)
|
|
|
|
|
{
|
|
|
|
|
setSourceModel(sourceModel);
|
|
|
|
|
setDynamicSortFilter(true);
|
|
|
|
|
m_includeUnknowns = m_includeWarnings = m_includeErrors = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskModel *TaskFilterModel::taskModel() const
|
|
|
|
|
{
|
|
|
|
|
return static_cast<TaskModel*>(sourceModel());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
|
|
|
{
|
2009-11-11 12:36:44 +01:00
|
|
|
bool accept = true;
|
|
|
|
|
|
2009-07-16 12:11:32 +02:00
|
|
|
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
2010-03-12 13:53:00 +01:00
|
|
|
Task::TaskType type = Task::TaskType(index.data(TaskModel::Type).toInt());
|
2009-07-16 12:11:32 +02:00
|
|
|
switch (type) {
|
2010-03-12 13:53:00 +01:00
|
|
|
case Task::Unknown:
|
2009-11-11 12:36:44 +01:00
|
|
|
accept = m_includeUnknowns;
|
|
|
|
|
break;
|
2010-03-12 13:53:00 +01:00
|
|
|
case Task::Warning:
|
2009-11-11 12:36:44 +01:00
|
|
|
accept = m_includeWarnings;
|
|
|
|
|
break;
|
2010-03-12 13:53:00 +01:00
|
|
|
case Task::Error:
|
2009-11-11 12:36:44 +01:00
|
|
|
accept = m_includeErrors;
|
|
|
|
|
break;
|
2009-07-16 12:11:32 +02:00
|
|
|
}
|
|
|
|
|
|
2009-11-11 12:36:44 +01:00
|
|
|
const QString &categoryId = index.data(TaskModel::Category).toString();
|
|
|
|
|
if (m_categoryIds.contains(categoryId))
|
|
|
|
|
accept = false;
|
|
|
|
|
|
|
|
|
|
return accept;
|
2009-07-16 12:11:32 +02:00
|
|
|
}
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
} // namespace Internal
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/////
|
|
|
|
|
// TaskWindow
|
|
|
|
|
/////
|
|
|
|
|
|
2010-06-16 14:24:22 +02:00
|
|
|
class TaskWindowPrivate
|
|
|
|
|
{
|
|
|
|
|
public:
|
2010-05-27 13:28:07 +02:00
|
|
|
Internal::TaskModel *m_model;
|
|
|
|
|
Internal::TaskFilterModel *m_filter;
|
|
|
|
|
Internal::TaskView *m_listview;
|
|
|
|
|
Internal::TaskWindowContext *m_taskWindowContext;
|
2010-06-18 11:18:48 +02:00
|
|
|
QMenu *m_contextMenu;
|
|
|
|
|
QModelIndex m_contextMenuIndex;
|
|
|
|
|
ITaskHandler *m_defaultHandler;
|
2010-05-27 13:28:07 +02:00
|
|
|
QToolButton *m_filterWarningsButton;
|
|
|
|
|
QToolButton *m_categoriesButton;
|
|
|
|
|
QMenu *m_categoriesMenu;
|
|
|
|
|
};
|
|
|
|
|
|
2010-04-19 16:03:28 +02:00
|
|
|
static QToolButton *createFilterButton(QIcon icon, const QString &toolTip,
|
2009-07-16 12:11:32 +02:00
|
|
|
QObject *receiver, const char *slot)
|
|
|
|
|
{
|
|
|
|
|
QToolButton *button = new QToolButton;
|
2010-04-19 16:03:28 +02:00
|
|
|
button->setIcon(icon);
|
2009-07-16 12:11:32 +02:00
|
|
|
button->setToolTip(toolTip);
|
|
|
|
|
button->setCheckable(true);
|
|
|
|
|
button->setChecked(true);
|
|
|
|
|
button->setAutoRaise(true);
|
|
|
|
|
button->setEnabled(true);
|
|
|
|
|
QObject::connect(button, SIGNAL(toggled(bool)), receiver, slot);
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
TaskWindow::TaskWindow() : d(new TaskWindowPrivate)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-06-18 11:18:48 +02:00
|
|
|
d->m_defaultHandler = 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_model = new Internal::TaskModel;
|
|
|
|
|
d->m_filter = new Internal::TaskFilterModel(d->m_model);
|
|
|
|
|
d->m_listview = new Internal::TaskView;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_listview->setModel(d->m_filter);
|
|
|
|
|
d->m_listview->setFrameStyle(QFrame::NoFrame);
|
|
|
|
|
d->m_listview->setWindowTitle(tr("Build Issues"));
|
|
|
|
|
d->m_listview->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
|
Internal::TaskDelegate *tld = new Internal::TaskDelegate(this);
|
|
|
|
|
d->m_listview->setItemDelegate(tld);
|
|
|
|
|
d->m_listview->setWindowIcon(QIcon(":/qt4projectmanager/images/window.png"));
|
|
|
|
|
d->m_listview->setContextMenuPolicy(Qt::ActionsContextMenu);
|
|
|
|
|
d->m_listview->setAttribute(Qt::WA_MacShowFocusRect, false);
|
2008-12-03 21:50:31 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_taskWindowContext = new Internal::TaskWindowContext(d->m_listview);
|
2010-06-18 11:18:48 +02:00
|
|
|
Core::ICore::instance()->addContextObject(d->m_taskWindowContext);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
2010-03-19 17:22:18 +01:00
|
|
|
tld, SLOT(currentChanged(QModelIndex,QModelIndex)));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
connect(d->m_listview, SIGNAL(activated(QModelIndex)),
|
2010-06-18 11:18:48 +02:00
|
|
|
this, SLOT(triggerDefaultHandler(QModelIndex)));
|
2010-05-27 13:28:07 +02:00
|
|
|
connect(d->m_listview, SIGNAL(clicked(QModelIndex)),
|
2010-06-18 11:18:48 +02:00
|
|
|
this, SLOT(triggerDefaultHandler(QModelIndex)));
|
|
|
|
|
|
|
|
|
|
d->m_contextMenu = new QMenu(d->m_listview);
|
|
|
|
|
connect(d->m_contextMenu, SIGNAL(triggered(QAction*)),
|
|
|
|
|
this, SLOT(contextMenuEntryTriggered(QAction*)));
|
|
|
|
|
|
|
|
|
|
d->m_listview->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
|
|
|
|
|
|
connect(d->m_listview, SIGNAL(customContextMenuRequested(QPoint)),
|
|
|
|
|
this, SLOT(showContextMenu(QPoint)));
|
2008-12-03 21:50:31 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_filterWarningsButton = createFilterButton(taskTypeIcon(Task::Warning),
|
2010-04-19 16:03:28 +02:00
|
|
|
tr("Show Warnings"),
|
2009-07-16 12:11:32 +02:00
|
|
|
this, SLOT(setShowWarnings(bool)));
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_categoriesMenu = new QMenu;
|
|
|
|
|
connect(d->m_categoriesMenu, SIGNAL(aboutToShow()), this, SLOT(updateCategoriesMenu()));
|
|
|
|
|
connect(d->m_categoriesMenu, SIGNAL(triggered(QAction*)), this, SLOT(filterCategoryTriggered(QAction*)));
|
2009-11-11 12:36:44 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_categoriesButton = new QToolButton;
|
|
|
|
|
d->m_categoriesButton->setIcon(QIcon(":/projectexplorer/images/filtericon.png"));
|
|
|
|
|
d->m_categoriesButton->setToolTip(tr("Filter by categories"));
|
|
|
|
|
d->m_categoriesButton->setAutoRaise(true);
|
|
|
|
|
d->m_categoriesButton->setPopupMode(QToolButton::InstantPopup);
|
|
|
|
|
d->m_categoriesButton->setMenu(d->m_categoriesMenu);
|
2009-11-11 12:36:44 +01:00
|
|
|
|
2010-03-12 13:53:00 +01:00
|
|
|
qRegisterMetaType<ProjectExplorer::Task>("ProjectExplorer::Task");
|
|
|
|
|
qRegisterMetaType<QList<ProjectExplorer::Task> >("QList<ProjectExplorer::Task>");
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskWindow::~TaskWindow()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
Core::ICore::instance()->removeContextObject(d->m_taskWindowContext);
|
2010-06-18 11:18:48 +02:00
|
|
|
cleanContextMenu();
|
2010-05-27 13:28:07 +02:00
|
|
|
delete d->m_filterWarningsButton;
|
|
|
|
|
delete d->m_listview;
|
|
|
|
|
delete d->m_filter;
|
|
|
|
|
delete d->m_model;
|
|
|
|
|
delete d;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return QList<QWidget*>() << d->m_filterWarningsButton << d->m_categoriesButton;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *TaskWindow::outputWidget(QWidget *)
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return d->m_listview;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
void TaskWindow::clearTasks(const QString &categoryId)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_model->clearTasks(categoryId);
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
emit tasksChanged();
|
2009-04-30 12:50:52 +02:00
|
|
|
navigateStateChanged();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::visibilityChanged(bool /* b */)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
void TaskWindow::addCategory(const QString &categoryId, const QString &displayName)
|
|
|
|
|
{
|
|
|
|
|
Q_ASSERT(!categoryId.isEmpty());
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_model->addCategory(categoryId, displayName);
|
2009-11-11 09:54:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::addTask(const Task &task)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_model->addTask(task);
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
emit tasksChanged();
|
2009-11-11 09:54:13 +01:00
|
|
|
navigateStateChanged();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-04-16 12:41:26 +02:00
|
|
|
void TaskWindow::removeTask(const Task &task)
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_model->removeTask(task);
|
2010-04-16 12:41:26 +02:00
|
|
|
|
|
|
|
|
emit tasksChanged();
|
|
|
|
|
navigateStateChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
void TaskWindow::triggerDefaultHandler(const QModelIndex &index)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return;
|
|
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
// Find a default handler to use:
|
|
|
|
|
if (!d->m_defaultHandler) {
|
|
|
|
|
QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::instance()->getObjects<ITaskHandler>();
|
|
|
|
|
foreach(ITaskHandler *handler, handlers) {
|
|
|
|
|
if (handler->id() == QLatin1String(Constants::SHOW_TASK_IN_EDITOR)) {
|
|
|
|
|
d->m_defaultHandler = handler;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Q_ASSERT(d->m_defaultHandler);
|
2010-06-24 15:07:42 +02:00
|
|
|
Task task(d->m_model->task(index));
|
2010-06-18 11:18:48 +02:00
|
|
|
if (d->m_defaultHandler->canHandle(task)) {
|
|
|
|
|
d->m_defaultHandler->handle(task);
|
|
|
|
|
} else {
|
|
|
|
|
if (!QFileInfo(task.file).exists())
|
|
|
|
|
d->m_model->setFileNotFound(index, true);
|
2008-12-02 17:57:50 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
void TaskWindow::showContextMenu(const QPoint &position)
|
2010-03-19 17:22:18 +01:00
|
|
|
{
|
2010-06-18 11:18:48 +02:00
|
|
|
QModelIndex index = d->m_listview->indexAt(position);
|
2010-03-19 17:22:18 +01:00
|
|
|
if (!index.isValid())
|
|
|
|
|
return;
|
2010-06-18 11:18:48 +02:00
|
|
|
d->m_contextMenuIndex = index;
|
|
|
|
|
cleanContextMenu();
|
|
|
|
|
|
2010-06-24 15:07:42 +02:00
|
|
|
Task task = d->m_model->task(index);
|
2010-06-18 11:18:48 +02:00
|
|
|
|
|
|
|
|
QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::instance()->getObjects<ITaskHandler>();
|
|
|
|
|
foreach(ITaskHandler *handler, handlers) {
|
|
|
|
|
if (handler == d->m_defaultHandler)
|
|
|
|
|
continue;
|
|
|
|
|
QAction * action = handler->createAction(d->m_contextMenu);
|
|
|
|
|
action->setEnabled(handler->canHandle(task));
|
|
|
|
|
action->setData(qVariantFromValue(qobject_cast<QObject*>(handler)));
|
|
|
|
|
d->m_contextMenu->addAction(action);
|
|
|
|
|
}
|
|
|
|
|
d->m_contextMenu->popup(d->m_listview->mapToGlobal(position));
|
2010-03-19 17:22:18 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
void TaskWindow::contextMenuEntryTriggered(QAction *action)
|
2008-12-03 21:50:31 +01:00
|
|
|
{
|
2010-06-18 11:18:48 +02:00
|
|
|
if (action->isEnabled()) {
|
2010-06-24 15:07:42 +02:00
|
|
|
Task task = d->m_model->task(d->m_contextMenuIndex);
|
2010-06-18 11:18:48 +02:00
|
|
|
ITaskHandler *handler = qobject_cast<ITaskHandler*>(action->data().value<QObject*>());
|
|
|
|
|
if (!handler)
|
|
|
|
|
return;
|
|
|
|
|
handler->handle(task);
|
2008-12-03 21:50:31 +01:00
|
|
|
}
|
2010-06-18 11:18:48 +02:00
|
|
|
}
|
2008-12-03 21:50:31 +01:00
|
|
|
|
2010-06-18 11:18:48 +02:00
|
|
|
void TaskWindow::cleanContextMenu()
|
|
|
|
|
{
|
|
|
|
|
QList<QAction *> actions = d->m_contextMenu->actions();
|
|
|
|
|
qDeleteAll(actions);
|
|
|
|
|
d->m_contextMenu->clear();
|
2008-12-03 21:50:31 +01:00
|
|
|
}
|
|
|
|
|
|
2009-07-16 12:11:32 +02:00
|
|
|
void TaskWindow::setShowWarnings(bool show)
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_filter->setFilterIncludesWarnings(show);
|
|
|
|
|
d->m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings
|
2009-07-16 12:11:32 +02:00
|
|
|
}
|
|
|
|
|
|
2009-11-11 12:36:44 +01:00
|
|
|
void TaskWindow::updateCategoriesMenu()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_categoriesMenu->clear();
|
2009-11-11 12:36:44 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
const QStringList filteredCategories = d->m_filter->filteredCategories();
|
2009-11-11 12:36:44 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
foreach (const QString &categoryId, d->m_model->categoryIds()) {
|
|
|
|
|
const QString categoryName = d->m_model->categoryDisplayName(categoryId);
|
2009-11-11 12:36:44 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
QAction *action = new QAction(d->m_categoriesMenu);
|
2009-11-11 12:36:44 +01:00
|
|
|
action->setCheckable(true);
|
|
|
|
|
action->setText(categoryName);
|
|
|
|
|
action->setData(categoryId);
|
|
|
|
|
action->setChecked(!filteredCategories.contains(categoryId));
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_categoriesMenu->addAction(action);
|
2009-11-11 12:36:44 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::filterCategoryTriggered(QAction *action)
|
|
|
|
|
{
|
|
|
|
|
QString categoryId = action->data().toString();
|
|
|
|
|
Q_ASSERT(!categoryId.isEmpty());
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
QStringList categories = d->m_filter->filteredCategories();
|
|
|
|
|
Q_ASSERT(d->m_filter->filteredCategories().contains(categoryId) == action->isChecked());
|
2009-11-11 12:36:44 +01:00
|
|
|
|
|
|
|
|
if (action->isChecked()) {
|
|
|
|
|
categories.removeOne(categoryId);
|
|
|
|
|
} else {
|
|
|
|
|
categories.append(categoryId);
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_filter->setFilteredCategories(categories);
|
2009-11-11 12:36:44 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-08 17:18:53 +02:00
|
|
|
int TaskWindow::taskCount() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-06-10 15:00:16 +02:00
|
|
|
return d->m_model->taskCount();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-08 17:18:53 +02:00
|
|
|
int TaskWindow::errorTaskCount() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-06-10 15:00:16 +02:00
|
|
|
return d->m_model->errorTaskCount();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskWindow::priorityInStatusBar() const
|
|
|
|
|
{
|
|
|
|
|
return 90;
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
void TaskWindow::clearContents()
|
|
|
|
|
{
|
|
|
|
|
clearTasks();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool TaskWindow::hasFocus()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return d->m_listview->hasFocus();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canFocus()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return d->m_filter->rowCount();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::setFocus()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
if (d->m_filter->rowCount()) {
|
|
|
|
|
d->m_listview->setFocus();
|
|
|
|
|
if (d->m_listview->currentIndex() == QModelIndex()) {
|
|
|
|
|
d->m_listview->setCurrentIndex(d->m_filter->index(0,0, QModelIndex()));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-30 12:50:52 +02:00
|
|
|
bool TaskWindow::canNext()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return d->m_filter->rowCount();
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canPrevious()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
return d->m_filter->rowCount();
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::goToNext()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
if (!d->m_filter->rowCount())
|
2009-04-30 12:50:52 +02:00
|
|
|
return;
|
2010-05-27 13:28:07 +02:00
|
|
|
QModelIndex currentIndex = d->m_listview->currentIndex();
|
2009-04-30 12:50:52 +02:00
|
|
|
if (currentIndex.isValid()) {
|
|
|
|
|
int row = currentIndex.row() + 1;
|
2010-05-27 13:28:07 +02:00
|
|
|
if (row == d->m_filter->rowCount())
|
2009-04-30 12:50:52 +02:00
|
|
|
row = 0;
|
2010-05-27 13:28:07 +02:00
|
|
|
currentIndex = d->m_filter->index(row, 0);
|
2009-04-30 12:50:52 +02:00
|
|
|
} else {
|
2010-05-27 13:28:07 +02:00
|
|
|
currentIndex = d->m_filter->index(0, 0);
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_listview->setCurrentIndex(currentIndex);
|
2010-06-18 11:18:48 +02:00
|
|
|
triggerDefaultHandler(currentIndex);
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::goToPrev()
|
|
|
|
|
{
|
2010-05-27 13:28:07 +02:00
|
|
|
if (!d->m_filter->rowCount())
|
2009-04-30 12:50:52 +02:00
|
|
|
return;
|
2010-05-27 13:28:07 +02:00
|
|
|
QModelIndex currentIndex = d->m_listview->currentIndex();
|
2009-04-30 12:50:52 +02:00
|
|
|
if (currentIndex.isValid()) {
|
|
|
|
|
int row = currentIndex.row() -1;
|
|
|
|
|
if (row < 0)
|
2010-05-27 13:28:07 +02:00
|
|
|
row = d->m_filter->rowCount() - 1;
|
|
|
|
|
currentIndex = d->m_filter->index(row, 0);
|
2009-04-30 12:50:52 +02:00
|
|
|
} else {
|
2010-05-27 13:28:07 +02:00
|
|
|
currentIndex = d->m_filter->index(d->m_filter->rowCount()-1, 0);
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
2010-05-27 13:28:07 +02:00
|
|
|
d->m_listview->setCurrentIndex(currentIndex);
|
2010-06-18 11:18:48 +02:00
|
|
|
triggerDefaultHandler(currentIndex);
|
2009-04-30 12:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canNavigate()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 14:12:30 +02:00
|
|
|
QIcon TaskWindow::taskTypeIcon(int t) const
|
2010-05-26 11:57:39 +02:00
|
|
|
{
|
2010-06-16 14:12:30 +02:00
|
|
|
return d->m_model->taskTypeIcon(static_cast<Task::TaskType>(t));
|
2010-05-26 11:57:39 +02:00
|
|
|
}
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
namespace Internal {
|
2008-12-02 12:01:29 +01:00
|
|
|
/////
|
|
|
|
|
// Delegate
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
|
|
TaskDelegate::TaskDelegate(QObject *parent)
|
|
|
|
|
: QStyledItemDelegate(parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskDelegate::~TaskDelegate()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
QStyleOptionViewItemV4 opt = option;
|
|
|
|
|
initStyleOption(&opt, index);
|
|
|
|
|
|
|
|
|
|
QFontMetrics fm(option.font);
|
2009-03-27 13:37:24 +01:00
|
|
|
int fontHeight = fm.height();
|
|
|
|
|
int fontLeading = fm.leading();
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
QSize s;
|
|
|
|
|
s.setWidth(option.rect.width());
|
|
|
|
|
const QAbstractItemView * view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
2009-07-16 12:11:32 +02:00
|
|
|
TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel();
|
2008-12-02 12:01:29 +01:00
|
|
|
int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22;
|
|
|
|
|
if (view->selectionModel()->currentIndex() == index) {
|
|
|
|
|
QString description = index.data(TaskModel::Description).toString();
|
|
|
|
|
// Layout the description
|
2009-03-27 13:37:24 +01:00
|
|
|
int leading = fontLeading;
|
2008-12-02 12:01:29 +01:00
|
|
|
int height = 0;
|
2010-04-09 15:37:24 +02:00
|
|
|
description.replace('\n', QChar::LineSeparator);
|
2008-12-02 12:01:29 +01:00
|
|
|
QTextLayout tl(description);
|
|
|
|
|
tl.beginLayout();
|
2008-12-09 11:07:24 +01:00
|
|
|
while (true) {
|
2008-12-02 12:01:29 +01:00
|
|
|
QTextLine line = tl.createLine();
|
|
|
|
|
if (!line.isValid())
|
|
|
|
|
break;
|
|
|
|
|
line.setLineWidth(width);
|
|
|
|
|
height += leading;
|
|
|
|
|
line.setPosition(QPoint(0, height));
|
|
|
|
|
height += static_cast<int>(line.height());
|
|
|
|
|
}
|
|
|
|
|
tl.endLayout();
|
|
|
|
|
|
2009-03-27 13:37:24 +01:00
|
|
|
s.setHeight(height + leading + fontHeight + 3);
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-03-27 13:37:24 +01:00
|
|
|
s.setHeight(fontHeight + 3);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-02-19 13:06:28 +01:00
|
|
|
if (s.height() < TASK_ICON_SIZE + 2 * TASK_ICON_MARGIN)
|
|
|
|
|
s.setHeight(TASK_ICON_SIZE + 2 * TASK_ICON_MARGIN);
|
2008-12-02 12:01:29 +01:00
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskDelegate::emitSizeHintChanged(const QModelIndex &index)
|
|
|
|
|
{
|
|
|
|
|
emit sizeHintChanged(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskDelegate::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
|
|
|
|
{
|
|
|
|
|
emit sizeHintChanged(current);
|
|
|
|
|
emit sizeHintChanged(previous);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
QStyleOptionViewItemV4 opt = option;
|
|
|
|
|
initStyleOption(&opt, index);
|
|
|
|
|
painter->save();
|
|
|
|
|
|
|
|
|
|
QFontMetrics fm(opt.font);
|
|
|
|
|
QColor backgroundColor;
|
|
|
|
|
QColor textColor;
|
|
|
|
|
|
|
|
|
|
const QAbstractItemView * view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
|
|
|
|
bool selected = view->selectionModel()->currentIndex() == index;
|
|
|
|
|
|
|
|
|
|
if (selected) {
|
|
|
|
|
painter->setBrush(opt.palette.highlight().color());
|
|
|
|
|
backgroundColor = opt.palette.highlight().color();
|
|
|
|
|
} else {
|
|
|
|
|
painter->setBrush(opt.palette.background().color());
|
|
|
|
|
backgroundColor = opt.palette.background().color();
|
|
|
|
|
}
|
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
|
painter->drawRect(opt.rect);
|
|
|
|
|
|
|
|
|
|
// Set Text Color
|
|
|
|
|
if (selected)
|
|
|
|
|
textColor = opt.palette.highlightedText().color();
|
|
|
|
|
else
|
|
|
|
|
textColor = opt.palette.text().color();
|
|
|
|
|
|
|
|
|
|
painter->setPen(textColor);
|
|
|
|
|
|
2009-07-16 12:11:32 +02:00
|
|
|
TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel();
|
2010-04-19 16:03:28 +02:00
|
|
|
QIcon icon = index.data(TaskModel::Icon).value<QIcon>();
|
2010-02-19 13:06:28 +01:00
|
|
|
painter->drawPixmap(TASK_ICON_MARGIN, opt.rect.top() + TASK_ICON_MARGIN, icon.pixmap(TASK_ICON_SIZE, TASK_ICON_SIZE));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22;
|
2010-01-29 21:33:57 +01:00
|
|
|
if (!selected) {
|
2008-12-02 12:01:29 +01:00
|
|
|
// in small mode we lay out differently
|
2010-04-09 15:37:24 +02:00
|
|
|
QString bottom = index.data(TaskModel::Description).toString().split('\n').first();
|
2008-12-02 12:01:29 +01:00
|
|
|
painter->drawText(22, 2 + opt.rect.top() + fm.ascent(), bottom);
|
|
|
|
|
if (fm.width(bottom) > width) {
|
|
|
|
|
// draw a gradient to mask the text
|
2010-05-20 16:13:11 +02:00
|
|
|
int gwidth = opt.rect.right() + 1 - width;
|
2008-12-02 12:01:29 +01:00
|
|
|
QLinearGradient lg(QPoint(width, 0), QPoint(width+gwidth, 0));
|
|
|
|
|
QColor c = backgroundColor;
|
|
|
|
|
c.setAlpha(0);
|
|
|
|
|
lg.setColorAt(0, c);
|
|
|
|
|
lg.setColorAt(20.0/gwidth, backgroundColor);
|
|
|
|
|
painter->fillRect(width, 2 + opt.rect.top(), gwidth, fm.height() + 1, lg);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2008-12-03 21:50:31 +01:00
|
|
|
// Description
|
2008-12-02 12:01:29 +01:00
|
|
|
QString description = index.data(TaskModel::Description).toString();
|
|
|
|
|
// Layout the description
|
|
|
|
|
int leading = fm.leading();
|
|
|
|
|
int height = 0;
|
2010-04-09 15:37:24 +02:00
|
|
|
description.replace('\n', QChar::LineSeparator);
|
2008-12-02 12:01:29 +01:00
|
|
|
QTextLayout tl(description);
|
2010-04-09 18:46:34 +02:00
|
|
|
tl.setAdditionalFormats(index.data(TaskModel::Task_t).value<ProjectExplorer::Task>().formats);
|
2008-12-02 12:01:29 +01:00
|
|
|
tl.beginLayout();
|
2008-12-09 11:07:24 +01:00
|
|
|
while (true) {
|
2008-12-02 12:01:29 +01:00
|
|
|
QTextLine line = tl.createLine();
|
|
|
|
|
if (!line.isValid())
|
|
|
|
|
break;
|
|
|
|
|
line.setLineWidth(width);
|
|
|
|
|
height += leading;
|
|
|
|
|
line.setPosition(QPoint(0, height));
|
|
|
|
|
height += static_cast<int>(line.height());
|
|
|
|
|
}
|
|
|
|
|
tl.endLayout();
|
|
|
|
|
tl.draw(painter, QPoint(22, 2 + opt.rect.top()));
|
|
|
|
|
//painter->drawText(22, 2 + opt.rect.top() + fm.ascent(), description);
|
|
|
|
|
|
|
|
|
|
QColor mix;
|
|
|
|
|
mix.setRgb( static_cast<int>(0.7 * textColor.red() + 0.3 * backgroundColor.red()),
|
|
|
|
|
static_cast<int>(0.7 * textColor.green() + 0.3 * backgroundColor.green()),
|
|
|
|
|
static_cast<int>(0.7 * textColor.blue() + 0.3 * backgroundColor.blue()));
|
|
|
|
|
painter->setPen(mix);
|
|
|
|
|
|
2009-04-15 16:34:37 +02:00
|
|
|
const QString directory = QDir::toNativeSeparators(index.data(TaskModel::File).toString());
|
2008-12-02 12:01:29 +01:00
|
|
|
int secondBaseLine = 2 + fm.ascent() + opt.rect.top() + height + leading; //opt.rect.top() + fm.ascent() + fm.height() + 6;
|
|
|
|
|
if (index.data(TaskModel::FileNotFound).toBool()) {
|
|
|
|
|
QString fileNotFound = tr("File not found: %1").arg(directory);
|
|
|
|
|
painter->setPen(Qt::red);
|
|
|
|
|
painter->drawText(22, secondBaseLine, fileNotFound);
|
|
|
|
|
} else {
|
|
|
|
|
painter->drawText(22, secondBaseLine, directory);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
painter->setPen(textColor);
|
|
|
|
|
// Assemble string for the right side
|
|
|
|
|
// just filename + linenumer
|
|
|
|
|
QString file = index.data(TaskModel::File).toString();
|
2010-02-01 12:43:56 +01:00
|
|
|
const int pos = file.lastIndexOf(QLatin1Char('/'));
|
2008-12-02 12:01:29 +01:00
|
|
|
if (pos != -1)
|
|
|
|
|
file = file.mid(pos +1);
|
|
|
|
|
painter->drawText(width + 22 + 4, 2 + opt.rect.top() + fm.ascent(), file);
|
|
|
|
|
|
|
|
|
|
QString topRight = index.data(TaskModel::Line).toString();
|
|
|
|
|
painter->drawText(opt.rect.right() - fm.width(topRight) - 6 , 2 + opt.rect.top() + fm.ascent(), topRight);
|
|
|
|
|
// Separator lines
|
|
|
|
|
painter->setPen(QColor::fromRgb(150,150,150));
|
|
|
|
|
painter->drawLine(0, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
|
|
|
|
|
painter->restore();
|
|
|
|
|
}
|
2008-12-03 21:50:31 +01:00
|
|
|
|
|
|
|
|
TaskWindowContext::TaskWindowContext(QWidget *widget)
|
2010-06-25 17:37:59 +02:00
|
|
|
: Core::IContext(widget),
|
|
|
|
|
m_taskList(widget),
|
|
|
|
|
m_context(Core::Constants::C_PROBLEM_PANE)
|
2008-12-03 21:50:31 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-25 12:56:16 +02:00
|
|
|
Core::Context TaskWindowContext::context() const
|
2008-12-03 21:50:31 +01:00
|
|
|
{
|
|
|
|
|
return m_context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *TaskWindowContext::widget()
|
|
|
|
|
{
|
|
|
|
|
return m_taskList;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
} // namespace Internal
|
2009-11-11 09:54:13 +01:00
|
|
|
|
2010-05-27 13:28:07 +02:00
|
|
|
} // namespace ProjectExplorer
|
|
|
|
|
|
2009-11-11 09:54:13 +01:00
|
|
|
#include "taskwindow.moc"
|