Commit 278ff780 authored by dt's avatar dt
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 920ce6f8 c077ef28
......@@ -4,6 +4,10 @@
Qt Creator is Qt Software's crossplatform IDE. The core of Qt Creator is
basically only a \l{ExtensionSystem}{plugin loader}.
All functionality is implemented in plugins, the basis of Qt Creator is
implemented in the \l{Core} {Core} Plugin. The plugin manager provides
simple means for plugin cooperation that allow plugins to provide
hooks for other plugin's extensions.
\section1 Core Libraries
......
......@@ -6,14 +6,14 @@ language = Cpp
headerdirs = . \
../../src/libs/aggregation \
../../src/libs/extensionsystem \
../../src/plugins/core \
../../src/plugins/core/actionmanager
../../src/plugins/coreplugin \
../../src/plugins/coreplugin/actionmanager
sourcedirs = . \
../../src/libs/aggregation \
../../src/libs/extensionsystem \
../../src/plugins/core \
../../src/plugins/core/actionmanager
../../src/plugins/coreplugin \
../../src/plugins/coreplugin/actionmanager
headers.fileextesnions = "*.h"
sources.fileextensions = "*.cpp *.qdoc"
......
......@@ -54,6 +54,7 @@
\o \l{Navigating Quickly Around Your Code with Locator}
\o \l{Debugging with Qt Creator}
\o \l{Tips and Tricks}
\o \l{Keyboard Shortcuts}
\o \l{Glossary}
\o \l{Known Issues of Version 0.9.1 (Beta)}
\endlist
......@@ -150,6 +151,26 @@
\image qtcreator-compile-pane.png
\section1 Session Management in Qt Creator
### screenshot
In Qt Creator, a session is a collection of loaded projects, opened files,
editor settings, and so on. When you run Qt Creator, you have a default
session. You can create a new session using the \gui{Session Manager...},
available in the \gui{File -> Session} menu.
To switch between sessions, select \gui{File -> Session}. If you do not
create and select any session, Qt Creator will always use the default
session.
\omit
session management can also store project dependencies, thorbjorn is
currently working on it
\endomit
\section1 Qt Help Integration
Qt Creator comes fully integrated with all of Qt's documentation and
......@@ -380,9 +401,11 @@
We begin with a Qt4 Gui Application project generated by Qt Creator. The
\l{Creating a Project in Qt Creator} document describes this process in
detail. Remember to select QWidget as the Text Finder's base class.
detail. Remember to select QWidget as the Text Finder's base class. If
your project is not yet loaded, you can load it by selecting \gui{Open}
from the \gui{File} menu.
Once your project is generated, you will have the following files:
In your project you will have the following files:
\list
\o \c{textfinder.h}
......
......@@ -3898,6 +3898,8 @@ void IdentifierListAST::accept0(ASTVisitor *visitor)
unsigned ObjCClassDeclarationAST::firstToken() const
{
if (attributes)
return attributes->firstToken();
return class_token;
}
......@@ -3911,12 +3913,19 @@ unsigned ObjCClassDeclarationAST::lastToken() const
return it->identifier_token + 1;
}
for (SpecifierAST *it = attributes; it; it = it->next) {
if (! it->next)
return it->lastToken();
}
return class_token + 1;
}
ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
{
ObjCClassDeclarationAST *ast = new (pool) ObjCClassDeclarationAST;
if (attributes)
ast->attributes = attributes->clone(pool);
ast->class_token = class_token;
if (identifier_list)
ast->identifier_list = identifier_list->clone(pool);
......@@ -3927,6 +3936,9 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
for (SpecifierAST *it = attributes; it; it = it->next) {
accept(it, visitor);
}
}
}
......
......@@ -1949,6 +1949,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
{
public:
SpecifierAST *attributes;
unsigned class_token;
IdentifierListAST *identifier_list;
unsigned semicolon_token;
......
This diff is collapsed.
......@@ -206,46 +206,33 @@ public:
bool parseUsingDirective(DeclarationAST *&node);
bool parseWhileStatement(StatementAST *&node);
// Qt MOC run
bool parseQtMethod(ExpressionAST *&node);
// ObjC++
bool parseObjCClassImplementation(DeclarationAST *&node);
bool parseObjCClassDeclaration(DeclarationAST *&node);
bool parseObjCInterfaceDeclaration(DeclarationAST *&node);
bool parseObjCProtocolDeclaration(DeclarationAST *&node);
bool parseObjCEndDeclaration(DeclarationAST *&node);
bool parseObjCAliasDeclaration(DeclarationAST *&node);
bool parseObjCPropertySynthesize(DeclarationAST *&node);
bool parseObjCPropertyDynamic(DeclarationAST *&node);
bool parseObjCInterface(DeclarationAST *&node,
SpecifierAST *attributes = 0);
bool parseObjCProtocol(DeclarationAST *&node,
SpecifierAST *attributes = 0);
bool parseObjCIdentifierList(IdentifierListAST *&node);
bool parseObjCPropertyDeclaration(DeclarationAST *&node);
bool parseObjCProtocolRefs();
bool parseObjCClassInstanceVariables();
bool parseObjClassInstanceVariables();
bool parseObjCInterfaceMemberDeclaration();
bool parseObjCInterfaceDeclList();
bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);
bool parseObjCPropertyDeclaration(DeclarationAST *&node,
SpecifierAST *attributes = 0);
bool parseObjCImplementation(DeclarationAST *&node);
bool parseObjCMethodPrototype();
bool parseObjCExpression(ExpressionAST *&node);
bool parseObjCMessageExpression(ExpressionAST *&node);
bool parseObjCStringLiteral(ExpressionAST *&node);
bool parseObjCEncodeExpression(ExpressionAST *&node);
bool parseObjCProtocolExpression(ExpressionAST *&node);
bool parseObjCSelectorExpression(ExpressionAST *&node);
bool parseObjCMessageReceiver(ExpressionAST *&node);
bool parseObjCMessageArguments();
bool parseObjCMethodSignature();
bool parseObjCMethodDefinitionList();
bool parseObjCAtProperty();
bool parseObjCPropertyAttribute();
bool parseObjCTypeName();
bool parseObjCProtocolQualifiers();
bool parseObjCSelector();
bool parseObjCKeywordDeclaration();
bool parseObjCTypeQualifiers();
bool parseObjCEnd(DeclarationAST *&node);
bool lookAtObjCSelector() const;
// Qt MOC run
bool parseQtMethod(ExpressionAST *&node);
bool skipUntil(int token);
bool skipUntilDeclaration();
bool skipUntilStatement();
......
......@@ -201,9 +201,9 @@ enum Kind {
T___TYPEOF__,
// obj c++ @ keywords
T_FIRST_OBJC_KEYWORD,
T_FIRST_OBJC_AT_KEYWORD,
T_AT_CATCH = T_FIRST_OBJC_KEYWORD,
T_AT_CATCH = T_FIRST_OBJC_AT_KEYWORD,
T_AT_CLASS,
T_AT_COMPATIBILITY_ALIAS,
T_AT_DEFS,
......@@ -228,7 +228,9 @@ enum Kind {
T_AT_THROW,
T_AT_TRY,
T_FIRST_QT_KEYWORD,
T_LAST_OBJC_AT_KEYWORD,
T_FIRST_QT_KEYWORD = T_LAST_OBJC_AT_KEYWORD,
// Qt keywords
T_SIGNAL = T_FIRST_QT_KEYWORD,
......@@ -295,6 +297,9 @@ public:
inline bool isKeyword() const
{ return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
inline bool isObjCAtKeyword() const
{ return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
static const char *name(int kind);
public:
......
......@@ -54,8 +54,7 @@ enum { debugLeaks = 0 };
/*!
\namespace ExtensionSystem
\brief The ExtensionSystem namespace provides
classes that belong to the core plugin system.
\brief The ExtensionSystem namespace provides classes that belong to the core plugin system.
The basic extension system contains of the plugin manager and its supporting classes,
and the IPlugin interface that must be implemented by plugin providers.
......
......@@ -46,7 +46,7 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) :
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setOption(QWizard::NoCancelButton, false);
setOption(QWizard::NoDefaultButton, false);
setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png")));
setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/core/images/qtwatermark.png")));
addPage(m_filePage);
connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick()));
}
......
......@@ -36,6 +36,7 @@
#include <QtCore/QDebug>
#include <QtCore/QPointer>
#include <QtCore/QTimer>
#include <QtGui/QPushButton>
......@@ -70,6 +71,42 @@ void QActionPushButton::actionChanged()
setEnabled(a->isEnabled());
}
// Helpers to retrieve model data
static inline bool listModelChecked(const QAbstractItemModel *model, int row, int column = 0)
{
const QModelIndex checkableIndex = model->index(row, column, QModelIndex());
return model->data(checkableIndex, Qt::CheckStateRole).toInt() == Qt::Checked;
}
static inline QString listModelText(const QAbstractItemModel *model, int row, int column)
{
const QModelIndex index = model->index(row, column, QModelIndex());
return model->data(index, Qt::DisplayRole).toString();
}
// Find a check item in a model
static bool listModelContainsCheckedItem(const QAbstractItemModel *model)
{
const int count = model->rowCount();
for (int i = 0; i < count; i++)
if (listModelChecked(model, i, 0))
return true;
return false;
}
// Convenience to extract a list of selected indexes
QList<int> selectedRows(const QAbstractItemView *view)
{
const QModelIndexList indexList = view->selectionModel()->selectedRows(0);
if (indexList.empty())
return QList<int>();
QList<int> rc;
const QModelIndexList::const_iterator cend = indexList.constEnd();
for (QModelIndexList::const_iterator it = indexList.constBegin(); it != cend; ++it)
rc.push_back(it->row());
return rc;
}
// ----------- SubmitEditorWidgetPrivate
struct SubmitEditorWidgetPrivate
{
......@@ -78,11 +115,15 @@ struct SubmitEditorWidgetPrivate
Ui::SubmitEditorWidget m_ui;
bool m_filesSelected;
bool m_filesChecked;
int m_fileNameColumn;
int m_activatedRow;
};
SubmitEditorWidgetPrivate::SubmitEditorWidgetPrivate() :
m_filesSelected(false),
m_filesChecked(false)
m_filesChecked(false),
m_fileNameColumn(1),
m_activatedRow(-1)
{
}
......@@ -92,10 +133,10 @@ SubmitEditorWidget::SubmitEditorWidget(QWidget *parent) :
{
m_d->m_ui.setupUi(this);
// File List
m_d->m_ui.fileList->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(m_d->m_ui.fileList, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(triggerDiffSelected()));
connect(m_d->m_ui.fileList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(fileItemChanged(QListWidgetItem*)));
connect(m_d->m_ui.fileList, SIGNAL(itemSelectionChanged()), this, SLOT(fileSelectionChanged()));
m_d->m_ui.fileView->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_d->m_ui.fileView->setRootIsDecorated(false);
connect(m_d->m_ui.fileView, SIGNAL(doubleClicked(QModelIndex)),
this, SLOT(diffActivated(QModelIndex)));
// Text
m_d->m_ui.description->setFont(QFont(QLatin1String("Courier")));
......@@ -124,8 +165,12 @@ void SubmitEditorWidget::registerActions(QAction *editorUndoAction, QAction *ed
}
if (submitAction) {
if (debug)
qDebug() << submitAction << m_d->m_ui.fileList->count() << "items" << m_d->m_filesChecked;
if (debug) {
int count = 0;
if (const QAbstractItemModel *model = m_d->m_ui.fileView->model())
count = model->rowCount();
qDebug() << submitAction << count << "items" << m_d->m_filesChecked;
}
submitAction->setEnabled(m_d->m_filesChecked);
connect(this, SIGNAL(fileCheckStateChanged(bool)), submitAction, SLOT(setEnabled(bool)));
m_d->m_ui.buttonLayout->addWidget(new QActionPushButton(submitAction));
......@@ -161,7 +206,6 @@ void SubmitEditorWidget::unregisterActions(QAction *editorUndoAction, QAction *
}
}
QString SubmitEditorWidget::trimmedDescriptionText() const
{
// Make sure we have one terminating NL
......@@ -180,91 +224,70 @@ void SubmitEditorWidget::setDescriptionText(const QString &text)
m_d->m_ui.description->setPlainText(text);
}
QStringList SubmitEditorWidget::fileList() const
int SubmitEditorWidget::fileNameColumn() const
{
QStringList rc;
const int count = m_d->m_ui.fileList->count();
for (int i = 0; i < count; i++)
rc.push_back(m_d->m_ui.fileList->item(i)->text());
return rc;
return m_d->m_fileNameColumn;
}
void SubmitEditorWidget::addFilesUnblocked(const QStringList &list, bool checked, bool userCheckable)
void SubmitEditorWidget::setFileNameColumn(int c)
{
if (debug)
qDebug() << Q_FUNC_INFO << list << checked << userCheckable;
foreach (const QString &f, list) {
QListWidgetItem *item = new QListWidgetItem(f);
item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
if (!userCheckable)
item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
m_d->m_ui.fileList->addItem(item);
}
m_d->m_fileNameColumn = c;
}
void SubmitEditorWidget::addFiles(const QStringList &list, bool checked, bool userCheckable)
void SubmitEditorWidget::setFileModel(QAbstractItemModel *model)
{
if (list.empty())
return;
const bool blocked = m_d->m_ui.fileList->blockSignals(true);
addFilesUnblocked(list, checked, userCheckable);
m_d->m_ui.fileList->blockSignals(blocked);
// Did we gain any checked files..update action accordingly
if (!m_d->m_filesChecked && checked) {
m_d->m_filesChecked = true;
emit fileCheckStateChanged(m_d->m_filesChecked);
}
}
m_d->m_ui.fileView->clearSelection(); // trigger the change signals
void SubmitEditorWidget::setFileList(const QStringList &list)
{
// Trigger enabling of menu action
m_d->m_ui.fileList->clearSelection();
m_d->m_ui.fileView->setModel(model);
const bool blocked = m_d->m_ui.fileList->blockSignals(true);
m_d->m_ui.fileList->clear();
if (!list.empty()) {
addFilesUnblocked(list, true, true);
// Checked files added?
if (!m_d->m_filesChecked) {
m_d->m_filesChecked = true;
emit fileCheckStateChanged(m_d->m_filesChecked);
}
if (model->rowCount()) {
const int columnCount = model->columnCount();
for (int c = 0; c < columnCount; c++)
m_d->m_ui.fileView->resizeColumnToContents(c);
}
m_d->m_ui.fileList->blockSignals(blocked);
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(updateSubmitAction()));
connect(model, SIGNAL(modelReset()),
this, SLOT(updateSubmitAction()));
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(updateSubmitAction()));
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(updateSubmitAction()));
connect(m_d->m_ui.fileView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
this, SLOT(updateDiffAction()));
updateActions();
}
static bool containsCheckState(const QListWidget *lw, Qt::CheckState cs)
QAbstractItemModel *SubmitEditorWidget::fileModel() const
{
const int count = lw->count();
for (int i = 0; i < count; i++)
if (lw->item(i)->checkState() == cs)
return true;
return false;
return m_d->m_ui.fileView->model();
}
QStringList SubmitEditorWidget::selectedFiles() const
{
const QList<int> selection = selectedRows(m_d->m_ui.fileView);
if (selection.empty())
return QStringList();
QStringList rc;
const int count = m_d->m_ui.fileList->count();
for (int i = 0; i < count; i++) {
const QListWidgetItem *item = m_d->m_ui.fileList->item(i);
if (item->isSelected())
rc.push_back(item->text());
}
const QAbstractItemModel *model = m_d->m_ui.fileView->model();
const int count = selection.size();
for (int i = 0; i < count; i++)
rc.push_back(listModelText(model, selection.at(i), fileNameColumn()));
return rc;
}
QStringList SubmitEditorWidget::checkedFiles() const
{
QStringList rc;
const int count = m_d->m_ui.fileList->count();
for (int i = 0; i < count; i++) {
const QListWidgetItem *item = m_d->m_ui.fileList->item(i);
if (item->checkState() == Qt::Checked)
rc.push_back(item->text());
}
const QAbstractItemModel *model = m_d->m_ui.fileView->model();
if (!model)
return rc;
const int count = model->rowCount();
for (int i = 0; i < count; i++)
if (listModelChecked(model, i, 0))
rc.push_back(listModelText(model, i, fileNameColumn()));
return rc;
}
......@@ -280,44 +303,61 @@ void SubmitEditorWidget::triggerDiffSelected()
emit diffSelected(sel);
}
void SubmitEditorWidget::fileItemChanged(QListWidgetItem *item)
{
const Qt::CheckState st = item->checkState();
if (debug)
qDebug() << Q_FUNC_INFO << st << item->text() << m_d->m_filesChecked;
// Enable the actions according to check state
switch (st) {
case Qt::Unchecked: // Item was unchecked: Any checked items left?
if (m_d->m_filesChecked && !containsCheckState(m_d->m_ui.fileList, Qt::Checked)) {
m_d->m_filesChecked = false;
emit fileCheckStateChanged(m_d->m_filesChecked);
}
break;
case Qt::Checked:
// Item was Checked. First one?
if (!m_d->m_filesChecked) {
m_d->m_filesChecked = true;
emit fileCheckStateChanged(m_d->m_filesChecked);
}
break;
case Qt::PartiallyChecked: // Errm?
break;
void SubmitEditorWidget::diffActivatedDelayed()
{
const QStringList files = QStringList(listModelText(m_d->m_ui.fileView->model(), m_d->m_activatedRow, fileNameColumn()));
emit diffSelected(files);
}
void SubmitEditorWidget::diffActivated(const QModelIndex &index)
{
// We need to delay the signal, otherwise, the diff editor will not
// be in the foreground.
m_d->m_activatedRow = index.row();
QTimer::singleShot(0, this, SLOT(diffActivatedDelayed()));
}
void SubmitEditorWidget::updateActions()
{
updateSubmitAction();
updateDiffAction();
}
// Enable submit depending on having checked files
void SubmitEditorWidget::updateSubmitAction()
{
const bool newFilesCheckedState = hasCheckedFiles();
if (m_d->m_filesChecked != newFilesCheckedState) {
m_d->m_filesChecked = newFilesCheckedState;
emit fileCheckStateChanged(m_d->m_filesChecked);
}
}
void SubmitEditorWidget::fileSelectionChanged()
// Enable diff depending on selected files
void SubmitEditorWidget::updateDiffAction()
{
const bool newFilesSelected = !m_d->m_ui.fileList->selectedItems().empty();
if (debug)
qDebug() << Q_FUNC_INFO << newFilesSelected;
if (m_d->m_filesSelected != newFilesSelected) {
m_d->m_filesSelected = newFilesSelected;
const bool filesSelected = hasSelection();
if (m_d->m_filesSelected != filesSelected) {
m_d->m_filesSelected = filesSelected;
emit fileSelectionChanged(m_d->m_filesSelected);
if (debug)
qDebug() << Q_FUNC_INFO << m_d->m_filesSelected;
}
}
bool SubmitEditorWidget::hasSelection() const
{
// Not present until model is set
if (const QItemSelectionModel *sm = m_d->m_ui.fileView->selectionModel())
return sm->hasSelection();
return false;
}
bool SubmitEditorWidget::hasCheckedFiles() const
{
if (const QAbstractItemModel *model = m_d->m_ui.fileView->model())
return listModelContainsCheckedItem(model);
return false;
}
void SubmitEditorWidget::changeEvent(QEvent *e)
{
switch (e->type()) {
......
......@@ -42,6 +42,8 @@ QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QListWidgetItem;
class QAction;
class QAbstractItemModel;
class QModelIndex;
QT_END_NAMESPACE
namespace Core {
......@@ -51,8 +53,9 @@ struct SubmitEditorWidgetPrivate;
/* The submit editor presents the commit message in a text editor and an
* checkable list of modified files in a list window. The user can delete
* files from the list by pressing unchecking them or diff the selection
* by doubleclicking.
* files from the list by unchecking them or diff the selection
* by doubleclicking. A list model which contains the file in a column
* specified by fileNameColumn should be set using setFileModel().
*
* Additionally, standard creator actions can be registered:
* Undo/redo will be set up to work with the description editor.
......@@ -71,7 +74,7 @@ class QWORKBENCH_UTILS_EXPORT SubmitEditorWidget : public QWidget
Q_OBJECT
Q_DISABLE_COPY(SubmitEditorWidget)
Q_PROPERTY(QString descriptionText READ descriptionText WRITE setDescriptionText DESIGNABLE true)
Q_PROPERTY(QStringList fileList READ fileList WRITE setFileList DESIGNABLE true)
Q_PROPERTY(int fileNameColumn READ fileNameColumn WRITE setFileNameColumn DESIGNABLE false)</