2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
|
|
|
|
**
|
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
|
|
|
|
|
** contact the sales department at qt-sales@nokia.com.
|
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"
|
|
|
|
|
|
|
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
|
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2008-12-02 17:57:50 +01:00
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2009-01-23 13:03:36 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2008-12-03 21:50:31 +01:00
|
|
|
#include <coreplugin/uniqueidmanager.h>
|
2009-01-19 12:39:20 +01:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <texteditor/itexteditor.h>
|
|
|
|
|
#include <texteditor/basetexteditor.h>
|
|
|
|
|
#include <projectexplorerconstants.h>
|
|
|
|
|
|
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
|
#include <QtGui/QKeyEvent>
|
|
|
|
|
#include <QtGui/QHeaderView>
|
|
|
|
|
#include <QtGui/QListView>
|
|
|
|
|
#include <QtGui/QPainter>
|
|
|
|
|
#include <QtCore/QAbstractItemModel>
|
2008-12-03 21:50:31 +01:00
|
|
|
#include <QtGui/QApplication>
|
|
|
|
|
#include <QtGui/QClipboard>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtGui/QFont>
|
|
|
|
|
#include <QtGui/QFontMetrics>
|
|
|
|
|
#include <QtGui/QTextLayout>
|
|
|
|
|
|
|
|
|
|
using namespace ProjectExplorer::Internal;
|
|
|
|
|
|
|
|
|
|
// Internal Struct for TaskModel
|
|
|
|
|
struct TaskItem
|
|
|
|
|
{
|
|
|
|
|
QString description;
|
|
|
|
|
QString file;
|
|
|
|
|
int line;
|
|
|
|
|
bool fileNotFound;
|
|
|
|
|
ProjectExplorer::BuildParserInterface::PatternType type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class ProjectExplorer::Internal::TaskModel : public QAbstractItemModel
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
void clear();
|
|
|
|
|
void addTask(ProjectExplorer::BuildParserInterface::PatternType type,
|
|
|
|
|
const QString &description, const QString &file, int line);
|
|
|
|
|
int sizeOfFile();
|
|
|
|
|
int sizeOfLineNumber();
|
|
|
|
|
QModelIndex firstError() const;
|
|
|
|
|
void setFileNotFound(const QModelIndex &index, bool b);
|
|
|
|
|
|
2008-12-03 21:50:31 +01:00
|
|
|
enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type };
|
2009-03-27 13:37:24 +01:00
|
|
|
|
|
|
|
|
QIcon iconFor(ProjectExplorer::BuildParserInterface::PatternType type);
|
2008-12-02 12:01:29 +01:00
|
|
|
private:
|
|
|
|
|
QList<TaskItem> m_items;
|
|
|
|
|
int m_maxSizeOfFileName;
|
2009-03-27 13:37:24 +01:00
|
|
|
QIcon m_errorIcon;
|
|
|
|
|
QIcon m_warningIcon;
|
|
|
|
|
QIcon m_unspecifiedIcon;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////
|
|
|
|
|
// TaskView
|
|
|
|
|
////
|
|
|
|
|
|
|
|
|
|
TaskView::TaskView(QWidget *parent)
|
|
|
|
|
: QListView(parent)
|
|
|
|
|
{
|
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskView::~TaskView()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskView::resizeEvent(QResizeEvent *e)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(e);
|
|
|
|
|
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
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
|
|
TaskModel::TaskModel()
|
|
|
|
|
{
|
|
|
|
|
m_maxSizeOfFileName = 0;
|
2009-03-27 13:37:24 +01:00
|
|
|
m_errorIcon = QIcon(":/projectexplorer/images/compile_error.png");
|
|
|
|
|
m_warningIcon = QIcon(":/projectexplorer/images/compile_warning.png");
|
|
|
|
|
m_unspecifiedIcon = QIcon(":/projectexplorer/images/compile_unspecified.png");
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskModel::addTask(ProjectExplorer::BuildParserInterface::PatternType type, const QString &description, const QString &file, int line)
|
|
|
|
|
{
|
|
|
|
|
TaskItem task;
|
|
|
|
|
task.description = description;
|
|
|
|
|
task.file = file;
|
|
|
|
|
task.line = line;
|
|
|
|
|
task.type = type;
|
|
|
|
|
task.fileNotFound = false;
|
|
|
|
|
|
|
|
|
|
beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
|
|
|
|
|
m_items.append(task);
|
|
|
|
|
endInsertRows();
|
|
|
|
|
|
|
|
|
|
QFont font;
|
|
|
|
|
QFontMetrics fm(font);
|
|
|
|
|
QString filename = task.file;
|
|
|
|
|
int pos = filename.lastIndexOf("/");
|
|
|
|
|
if (pos != -1)
|
|
|
|
|
filename = file.mid(pos +1);
|
|
|
|
|
m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskModel::clear()
|
|
|
|
|
{
|
|
|
|
|
if (m_items.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
beginRemoveRows(QModelIndex(), 0, m_items.size() -1);
|
|
|
|
|
m_items.clear();
|
|
|
|
|
endRemoveRows();
|
|
|
|
|
m_maxSizeOfFileName = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(child);
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::rowCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
return parent.isValid() ? 0 : m_items.count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::columnCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
return parent.isValid() ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant TaskModel::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid() || index.row() >= m_items.size() || index.column() != 0)
|
|
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
|
|
if (role == TaskModel::File)
|
|
|
|
|
return m_items.at(index.row()).file;
|
|
|
|
|
else if (role == TaskModel::Line)
|
|
|
|
|
return m_items.at(index.row()).line;
|
|
|
|
|
else if (role == TaskModel::Description)
|
|
|
|
|
return m_items.at(index.row()).description;
|
|
|
|
|
else if (role == TaskModel::FileNotFound)
|
|
|
|
|
return m_items.at(index.row()).fileNotFound;
|
2008-12-03 21:50:31 +01:00
|
|
|
else if (role == TaskModel::Type)
|
|
|
|
|
return (int)m_items.at(index.row()).type;
|
2008-12-02 12:01:29 +01:00
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-27 13:37:24 +01:00
|
|
|
QIcon TaskModel::iconFor(ProjectExplorer::BuildParserInterface::PatternType type)
|
|
|
|
|
{
|
|
|
|
|
if (type == ProjectExplorer::BuildParserInterface::Error)
|
|
|
|
|
return m_errorIcon;
|
|
|
|
|
else if (type == ProjectExplorer::BuildParserInterface::Warning)
|
|
|
|
|
return m_warningIcon;
|
|
|
|
|
else
|
|
|
|
|
return m_unspecifiedIcon;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
int TaskModel::sizeOfFile()
|
|
|
|
|
{
|
|
|
|
|
return m_maxSizeOfFileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskModel::sizeOfLineNumber()
|
|
|
|
|
{
|
|
|
|
|
QFont font;
|
|
|
|
|
QFontMetrics fm(font);
|
|
|
|
|
return fm.width("8888");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QModelIndex TaskModel::firstError() const
|
|
|
|
|
{
|
|
|
|
|
int size = m_items.size();
|
|
|
|
|
for (int i=0; i<size; ++i) {
|
|
|
|
|
if (m_items.at(i).type == ProjectExplorer::BuildParserInterface::Error) {
|
|
|
|
|
return index(i, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskModel::setFileNotFound(const QModelIndex &idx, bool b)
|
|
|
|
|
{
|
|
|
|
|
if (idx.isValid() && idx.row() < m_items.size()) {
|
|
|
|
|
m_items[idx.row()].fileNotFound = b;
|
|
|
|
|
emit dataChanged(idx, idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////
|
|
|
|
|
// TaskWindow
|
|
|
|
|
/////
|
|
|
|
|
|
|
|
|
|
TaskWindow::TaskWindow()
|
|
|
|
|
{
|
2009-01-20 11:52:04 +01:00
|
|
|
Core::ICore *core = Core::ICore::instance();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_model = new TaskModel;
|
|
|
|
|
m_listview = new TaskView;
|
|
|
|
|
|
|
|
|
|
m_listview->setModel(m_model);
|
|
|
|
|
m_listview->setFrameStyle(QFrame::NoFrame);
|
2008-12-09 17:04:50 +01:00
|
|
|
m_listview->setWindowTitle(tr("Build Issues"));
|
2008-12-02 12:01:29 +01:00
|
|
|
m_listview->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
|
TaskDelegate *tld = new TaskDelegate(this);
|
|
|
|
|
m_listview->setItemDelegate(tld);
|
|
|
|
|
m_listview->setWindowIcon(QIcon(":/qt4projectmanager/images/window.png"));
|
2008-12-03 21:50:31 +01:00
|
|
|
m_listview->setContextMenuPolicy(Qt::ActionsContextMenu);
|
2009-01-30 17:09:09 +01:00
|
|
|
m_listview->setAttribute(Qt::WA_MacShowFocusRect, false);
|
2008-12-03 21:50:31 +01:00
|
|
|
|
|
|
|
|
m_taskWindowContext = new TaskWindowContext(m_listview);
|
2009-01-20 11:52:04 +01:00
|
|
|
core->addContextObject(m_taskWindowContext);
|
2008-12-03 21:50:31 +01:00
|
|
|
|
|
|
|
|
m_copyAction = new QAction(QIcon(Core::Constants::ICON_COPY), tr("&Copy"), this);
|
2009-01-20 11:52:04 +01:00
|
|
|
core->actionManager()->
|
2008-12-03 21:50:31 +01:00
|
|
|
registerAction(m_copyAction, Core::Constants::COPY, m_taskWindowContext->context());
|
|
|
|
|
m_listview->addAction(m_copyAction);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
connect(m_listview->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
|
|
|
|
|
tld, SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
|
|
|
|
|
|
|
|
|
|
connect(m_listview, SIGNAL(activated(const QModelIndex &)),
|
|
|
|
|
this, SLOT(showTaskInFile(const QModelIndex &)));
|
|
|
|
|
connect(m_listview, SIGNAL(clicked(const QModelIndex &)),
|
|
|
|
|
this, SLOT(showTaskInFile(const QModelIndex &)));
|
|
|
|
|
|
2008-12-03 21:50:31 +01:00
|
|
|
connect(m_copyAction, SIGNAL(triggered()), SLOT(copy()));
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_errorCount = 0;
|
|
|
|
|
m_currentTask = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskWindow::~TaskWindow()
|
|
|
|
|
{
|
2009-01-20 11:52:04 +01:00
|
|
|
Core::ICore::instance()->removeContextObject(m_taskWindowContext);
|
2008-12-02 12:01:29 +01:00
|
|
|
delete m_listview;
|
|
|
|
|
delete m_model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
|
|
|
|
{
|
|
|
|
|
return QList<QWidget*>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *TaskWindow::outputWidget(QWidget *)
|
|
|
|
|
{
|
|
|
|
|
return m_listview;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::clearContents()
|
|
|
|
|
{
|
|
|
|
|
m_errorCount = 0;
|
|
|
|
|
m_currentTask = -1;
|
|
|
|
|
m_model->clear();
|
2008-12-03 21:50:31 +01:00
|
|
|
m_copyAction->setEnabled(false);
|
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 */)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::addItem(ProjectExplorer::BuildParserInterface::PatternType type,
|
|
|
|
|
const QString &description, const QString &file, int line)
|
|
|
|
|
{
|
|
|
|
|
m_model->addTask(type, description, file, line);
|
|
|
|
|
if (type == ProjectExplorer::BuildParserInterface::Error)
|
|
|
|
|
++m_errorCount;
|
2008-12-03 21:50:31 +01:00
|
|
|
m_copyAction->setEnabled(true);
|
2008-12-02 12:01:29 +01:00
|
|
|
emit tasksChanged();
|
2009-04-30 12:50:52 +02:00
|
|
|
if (m_model->rowCount() == 1)
|
|
|
|
|
navigateStateChanged();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::showTaskInFile(const QModelIndex &index)
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return;
|
|
|
|
|
QString file = index.data(TaskModel::File).toString();
|
|
|
|
|
int line = index.data(TaskModel::Line).toInt();
|
|
|
|
|
if (file.isEmpty() || line == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-03-12 11:25:29 +01:00
|
|
|
QFileInfo fi(file);
|
|
|
|
|
if (fi.exists()) {
|
|
|
|
|
TextEditor::BaseTextEditor::openEditorAt(fi.canonicalFilePath(), line);
|
2008-12-02 17:57:50 +01:00
|
|
|
Core::EditorManager::instance()->ensureEditorManagerVisible();
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
else
|
|
|
|
|
m_model->setFileNotFound(index, true);
|
|
|
|
|
m_listview->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
|
|
|
|
|
m_listview->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-03 21:50:31 +01:00
|
|
|
void TaskWindow::copy()
|
|
|
|
|
{
|
|
|
|
|
QModelIndex index = m_listview->selectionModel()->currentIndex();
|
|
|
|
|
QString file = index.data(TaskModel::File).toString();
|
|
|
|
|
QString line = index.data(TaskModel::Line).toString();
|
|
|
|
|
QString description = index.data(TaskModel::Description).toString();
|
|
|
|
|
QString type;
|
|
|
|
|
switch (index.data(TaskModel::Type).toInt()) {
|
|
|
|
|
case ProjectExplorer::BuildParserInterface::Error:
|
|
|
|
|
type = "error: ";
|
|
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::BuildParserInterface::Warning:
|
|
|
|
|
type = "warning: ";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QApplication::clipboard()->setText(file + ':' + line + ": " + type + description);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
int TaskWindow::numberOfTasks() const
|
|
|
|
|
{
|
|
|
|
|
return m_model->rowCount(QModelIndex());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskWindow::numberOfErrors() const
|
|
|
|
|
{
|
|
|
|
|
return m_errorCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TaskWindow::priorityInStatusBar() const
|
|
|
|
|
{
|
|
|
|
|
return 90;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::gotoFirstError()
|
|
|
|
|
{
|
|
|
|
|
QModelIndex idx = m_model->firstError();
|
|
|
|
|
if (idx.isValid())
|
|
|
|
|
showTaskInFile(idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::hasFocus()
|
|
|
|
|
{
|
|
|
|
|
return m_listview->hasFocus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canFocus()
|
|
|
|
|
{
|
|
|
|
|
return m_model->rowCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::setFocus()
|
|
|
|
|
{
|
|
|
|
|
if (m_model->rowCount()) {
|
|
|
|
|
m_listview->setFocus();
|
|
|
|
|
if (m_listview->currentIndex() == QModelIndex()) {
|
|
|
|
|
m_listview->setCurrentIndex(m_model->index(0,0, QModelIndex()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-30 12:50:52 +02:00
|
|
|
bool TaskWindow::canNext()
|
|
|
|
|
{
|
|
|
|
|
return m_model->rowCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canPrevious()
|
|
|
|
|
{
|
|
|
|
|
return m_model->rowCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::goToNext()
|
|
|
|
|
{
|
|
|
|
|
if (!m_model->rowCount())
|
|
|
|
|
return;
|
|
|
|
|
QModelIndex currentIndex = m_listview->currentIndex();
|
|
|
|
|
if (currentIndex.isValid()) {
|
|
|
|
|
int row = currentIndex.row() + 1;
|
|
|
|
|
if (row == m_model->rowCount())
|
|
|
|
|
row = 0;
|
|
|
|
|
currentIndex = m_model->index(row, 0);
|
|
|
|
|
} else {
|
|
|
|
|
currentIndex = m_model->index(0, 0);
|
|
|
|
|
}
|
|
|
|
|
m_listview->setCurrentIndex(currentIndex);
|
|
|
|
|
showTaskInFile(currentIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TaskWindow::goToPrev()
|
|
|
|
|
{
|
|
|
|
|
if (!m_model->rowCount())
|
|
|
|
|
return;
|
|
|
|
|
QModelIndex currentIndex = m_listview->currentIndex();
|
|
|
|
|
if (currentIndex.isValid()) {
|
|
|
|
|
int row = currentIndex.row() -1;
|
|
|
|
|
if (row < 0)
|
|
|
|
|
row = m_model->rowCount() - 1;
|
|
|
|
|
currentIndex = m_model->index(row, 0);
|
|
|
|
|
} else {
|
|
|
|
|
currentIndex = m_model->index(m_model->rowCount()-1, 0);
|
|
|
|
|
}
|
|
|
|
|
m_listview->setCurrentIndex(currentIndex);
|
|
|
|
|
showTaskInFile(currentIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TaskWindow::canNavigate()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
TaskModel *model = static_cast<TaskModel *>(view->model());
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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-03-27 13:37:24 +01:00
|
|
|
TaskModel *model = static_cast<TaskModel *>(view->model());
|
|
|
|
|
ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt());
|
|
|
|
|
QIcon icon = model->iconFor(type);
|
2008-12-02 12:01:29 +01:00
|
|
|
painter->drawPixmap(2, opt.rect.top() + 2, icon.pixmap(16, 16));
|
|
|
|
|
|
|
|
|
|
int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22;
|
2009-03-27 13:37:24 +01:00
|
|
|
if (!selected) {
|
2008-12-02 12:01:29 +01:00
|
|
|
// in small mode we lay out differently
|
|
|
|
|
QString bottom = index.data(TaskModel::Description).toString();
|
|
|
|
|
painter->drawText(22, 2 + opt.rect.top() + fm.ascent(), bottom);
|
|
|
|
|
if (fm.width(bottom) > width) {
|
|
|
|
|
// draw a gradient to mask the text
|
|
|
|
|
int gwidth = opt.rect.right() - width;
|
|
|
|
|
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;
|
|
|
|
|
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();
|
|
|
|
|
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();
|
|
|
|
|
int pos = file.lastIndexOf("/");
|
|
|
|
|
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)
|
2009-01-30 14:32:28 +01:00
|
|
|
: Core::IContext(widget), m_taskList(widget)
|
2008-12-03 21:50:31 +01:00
|
|
|
{
|
2009-01-21 15:52:34 +01:00
|
|
|
Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
|
|
|
|
|
m_context << uidm->uniqueIdentifier(Core::Constants::C_PROBLEM_PANE);
|
2008-12-03 21:50:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<int> TaskWindowContext::context() const
|
|
|
|
|
{
|
|
|
|
|
return m_context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *TaskWindowContext::widget()
|
|
|
|
|
{
|
|
|
|
|
return m_taskList;
|
|
|
|
|
}
|
|
|
|
|
|