Commit 6fe51eeb authored by dt's avatar dt
Browse files

Merge branch '0.9.1-beta' of git@scm.dev.nokia.troll.no:creator/mainline into 0.9.1-beta

parents a10019ea 0a8a7f65
......@@ -68,8 +68,8 @@ src/corelib/lib
src/network/lib
src/xml/lib/
# Files copied by syncIde
# -----------------------
# Binaries
# --------
bin/Aggregation.dll
bin/CodeModel.dll
bin/ExtensionSystem.dll
......@@ -77,24 +77,4 @@ bin/QtConcurrent.dll
bin/Utils.dll
bin/qtcreator
bin/qtcreator.exe
shared/help/bookmarkdialog.ui
shared/help/bookmarkmanager.cpp
shared/help/bookmarkmanager.h
shared/help/contentwindow.cpp
shared/help/contentwindow.h
shared/help/filternamedialog.cpp
shared/help/filternamedialog.h
shared/help/filternamedialog.ui
shared/help/helpviewer.cpp
shared/help/helpviewer.h
shared/help/indexwindow.cpp
shared/help/indexwindow.h
shared/help/topicchooser.cpp
shared/help/topicchooser.h
shared/help/topicchooser.ui
shared/proparser/abstractproitemvisitor.h
shared/proparser/profileevaluator.cpp
shared/proparser/profileevaluator.h
shared/proparser/proitems.cpp
shared/proparser/proitems.h
shared/proparser/proparserutils.h
tests/manual/cplusplus/cplusplus0
......@@ -1191,6 +1191,11 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node)
NameAST *name = 0;
parseName(name);
bool parsed = false;
const bool previousInFunctionBody = _inFunctionBody;
_inFunctionBody = false;
if (LA() == T_COLON || LA() == T_LBRACE) {
BaseSpecifierAST *base_clause = 0;
if (LA() == T_COLON) {
......@@ -1233,9 +1238,12 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node)
}
}
node = ast;
return true;
parsed = true;
}
return false;
_inFunctionBody = previousInFunctionBody;
return parsed;
}
bool Parser::parseAccessSpecifier(SpecifierAST *&node)
......
......@@ -153,6 +153,11 @@ void Document::appendMacro(const QByteArray &macroName, const QByteArray &text)
_definedMacros += text;
}
void Document::addMacroUse(unsigned offset, unsigned length)
{
_macroUses.append(Block(offset, offset + length));
}
TranslationUnit *Document::translationUnit() const
{
return _translationUnit;
......
......@@ -68,6 +68,8 @@ public:
void appendMacro(const QByteArray &macroName, const QByteArray &text);
void addMacroUse(unsigned offset, unsigned length);
Control *control() const;
TranslationUnit *translationUnit() const;
......@@ -176,6 +178,9 @@ public:
QList<Block> skippedBlocks() const
{ return _skippedBlocks; }
QList<Block> macroUses() const
{ return _macroUses; }
private:
Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const;
......@@ -189,6 +194,7 @@ private:
QByteArray _definedMacros;
QSet<QByteArray> _macroNames;
QList<Block> _skippedBlocks;
QList<Block> _macroUses;
};
} // end of namespace CPlusPlus
......
......@@ -165,7 +165,7 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
int numFilesSearched = 0;
int numMatches = 0;
if (flags & QTextDocument::FindWholeWords)
searchTerm = QString("\b%1\b").arg(searchTerm);
searchTerm = QString("\\b%1\\b").arg(searchTerm);
Qt::CaseSensitivity caseSensitivity = (flags & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive;
QRegExp expression(searchTerm, caseSensitivity);
......
......@@ -44,6 +44,8 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) :
m_filePage(new FileWizardPage)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setOption(QWizard::NoCancelButton, false);
setOption(QWizard::NoDefaultButton, false);
setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png")));
addPage(m_filePage);
connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick()));
......
......@@ -509,6 +509,8 @@ QPixmap BaseFileWizard::watermark()
void BaseFileWizard::setupWizard(QWizard *w)
{
w->setPixmap(QWizard::WatermarkPixmap, watermark());
w->setOption(QWizard::NoCancelButton, false);
w->setOption(QWizard::NoDefaultButton, false);
}
bool BaseFileWizard::postGenerateFiles(const GeneratedFiles &l, QString *errorMessage)
......
......@@ -94,6 +94,7 @@ const char * const C_WELCOME_MODE = "Core.WelcomeMode";
const char * const C_EDIT_MODE = "Core.EditMode";
const char * const C_EDITORMANAGER = "Core.EditorManager";
const char * const C_NAVIGATION_PANE = "Core.NavigationPane";
const char * const C_PROBLEM_PANE = "Core.ProblemPane";
//default editor kind
const char * const K_DEFAULT_TEXT_EDITOR = "Plain Text Editor";
......
......@@ -1003,29 +1003,32 @@ bool EditorManager::saveFile(IEditor *editor)
return success;
}
namespace {
enum ReadOnlyAction { RO_Cancel, RO_OpenSCC, RO_MakeWriteable, RO_SaveAs };
}
static ReadOnlyAction promptReadOnly(const QString &fileName, bool hasSCC, QWidget *parent)
EditorManager::ReadOnlyAction
EditorManager::promptReadOnlyFile(const QString &fileName,
const IVersionControl *versionControl,
QWidget *parent,
bool displaySaveAsButton)
{
QMessageBox msgBox(QMessageBox::Question, QObject::tr("File is Read Only"),
QObject::tr("The file %1 is read only.").arg(fileName),
QMessageBox::Cancel, parent);
QPushButton *sccButton = 0;
if (hasSCC)
sccButton = msgBox.addButton(QObject::tr("Open with SCC"), QMessageBox::AcceptRole);
if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation))
sccButton = msgBox.addButton(QObject::tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole);
QPushButton *makeWritableButton = msgBox.addButton(QObject::tr("Make writable"), QMessageBox::AcceptRole);
QPushButton *saveAsButton = msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole);
if (hasSCC)
msgBox.setDefaultButton(sccButton);
else
msgBox.setDefaultButton(makeWritableButton);
QPushButton *saveAsButton = 0;
if (displaySaveAsButton)
msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole);
msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton);
msgBox.exec();
QAbstractButton *clickedButton = msgBox.clickedButton();
if (clickedButton == sccButton)
return RO_OpenSCC;
return RO_OpenVCS;
if (clickedButton == makeWritableButton)
return RO_MakeWriteable;
if (clickedButton == saveAsButton)
......@@ -1042,8 +1045,8 @@ EditorManager::makeEditorWritable(IEditor *editor)
IFile *file = editor->file();
const QString &fileName = file->fileName();
switch (promptReadOnly(fileName, versionControl, m_d->m_core->mainWindow())) {
case RO_OpenSCC:
switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) {
case RO_OpenVCS:
if (!versionControl->vcsOpen(fileName)) {
QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC."));
return Failed;
......
......@@ -55,6 +55,7 @@ class IEditorFactory;
class MimeType;
class IFile;
class IMode;
class IVersionControl;
enum MakeWritableResult {
OpenedWithVersionControl,
......@@ -159,6 +160,16 @@ public:
QString defaultExternalEditor() const;
QString externalEditorHelpText() const;
// Helper to display a message dialog when encountering a read-only
// file, prompting the user about how to make it writeable.
enum ReadOnlyAction { RO_Cancel, RO_OpenVCS, RO_MakeWriteable, RO_SaveAs };
static ReadOnlyAction promptReadOnlyFile(const QString &fileName,
const IVersionControl *versionControl,
QWidget *parent,
bool displaySaveAsButton = false);
signals:
void currentEditorChanged(Core::IEditor *editor);
void editorCreated(Core::IEditor *editor, const QString &fileName);
......
......@@ -45,51 +45,53 @@ class CORE_EXPORT IVersionControl : public QObject
{
Q_OBJECT
public:
enum Operation { AddOperation, DeleteOperation, OpenOperation };
IVersionControl(QObject *parent = 0) : QObject(parent) {}
virtual ~IVersionControl() {}
// Returns wheter files in this directory should be managed with this
virtual QString name() const = 0;
// Enable the VCS, that is, make its menu actions visible.
virtual bool isEnabled() const = 0;
virtual void setEnabled(bool enabled) = 0;
// Returns whether files in this directory should be managed with this
// version control.
virtual bool managesDirectory(const QString &filename) const = 0;
// This function should return the topmost directory, for
// which this IVersionControl should be used.
// The VCSManager assumes that all files in the returned directory
// are managed by the same IVersionControl
// This function should return the topmost directory, for which this
// IVersionControl should be used. The VCSManager assumes that all files
// in the returned directory are managed by the same IVersionControl
// Note that this is used as an optimization, so that the VCSManager
// doesn't need to call managesDirectory(..) for each directory
// This function is called after finding out that the directory is managed by
// a specific version control
// This function is called after finding out that the directory is managed
// by a specific version control.
virtual QString findTopLevelForDirectory(const QString &directory) const = 0;
// Called prior to save, if the file is read only.
// Should be implemented if the scc requires a operation before editing the file
// E.g. p4 edit
// Note: The EditorManager calls this for the editors
// Called to query whether a VCS supports the respective operations.
virtual bool supportsOperation(Operation operation) const = 0;
// Called prior to save, if the file is read only. Should be implemented
// if the scc requires a operation before editing the file, e.g. 'p4 edit'
// Note: The EditorManager calls this for the editors.
virtual bool vcsOpen(const QString &fileName) = 0;
// Called after a file has been added to a project
// If the version control needs to know which files it needs to track
// you should reimplement this function
// E.g. p4 add, cvs add, svn add
// Note: This function should be called from IProject subclasses after files
// are added to the project
// Called after a file has been added to a project If the version control
// needs to know which files it needs to track you should reimplement this
// function, e.g. 'p4 add', 'cvs add', 'svn add'.
// Note: This function should be called from IProject subclasses after
// files are added to the project
virtual bool vcsAdd(const QString &filename) = 0;
// Called after a file has been removed from the project (if the user wants)
// E.g. p4 delete, svn delete
// You probably want to call SccManager::showDeleteDialog, which asks the user to
// confirm the deletion
// Called after a file has been removed from the project (if the user
// wants), e.g. 'p4 delete', 'svn delete'.
// You probably want to call VcsManager::showDeleteDialog, which asks the
// user to confirm the deletion
virtual bool vcsDelete(const QString &filename) = 0;
// TODO: ADD A WAY TO DETECT WHETHER A FILE IS MANAGED, e.g
// virtual bool sccManaged(const QStryng &filename) = 0;
// TODO
// we probably want to have a function supports( enum Operation ) or
// something which describes which "kind" of revision control system it is.
// That is to check wheter a given operation is needed.
// But well I don't know yet how all different version control systems work
};
} // namespace Core
......
......@@ -45,8 +45,18 @@
#include <QtCore/QFileInfo>
#include <QtGui/QMessageBox>
enum { debug = 0 };
namespace Core {
typedef QList<IVersionControl *> VersionControlList;
static inline VersionControlList allVersionControls()
{
return ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
}
// ---- VCSManagerPrivate
struct VCSManagerPrivate {
QMap<QString, IVersionControl *> m_cachedMatches;
};
......@@ -61,31 +71,54 @@ VCSManager::~VCSManager()
delete m_d;
}
void VCSManager::setVCSEnabled(const QString &directory)
{
if (debug)
qDebug() << Q_FUNC_INFO << directory;
IVersionControl* managingVCS = findVersionControlForDirectory(directory);
const VersionControlList versionControls = allVersionControls();
foreach(IVersionControl *versionControl, versionControls) {
const bool newEnabled = versionControl == managingVCS;
if (newEnabled != versionControl->isEnabled())
versionControl->setEnabled(newEnabled);
}
}
void VCSManager::setAllVCSEnabled()
{
if (debug)
qDebug() << Q_FUNC_INFO;
const VersionControlList versionControls = allVersionControls();
foreach(IVersionControl *versionControl, versionControls)
if (!versionControl->isEnabled())
versionControl->setEnabled(true);
}
IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory)
{
// first look into the cache
int pos = 0;
{ // First try the whole name
QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
if (it != m_d->m_cachedMatches.constEnd()) {
// first look into the cache, check the whole name
{
const QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
if (it != m_d->m_cachedMatches.constEnd())
return it.value();
}
}
int pos = 0;
const QChar slash = QLatin1Char('/');
while(true) {
int index = directory.indexOf('/', pos);
int index = directory.indexOf(slash, pos);
if (index == -1)
break;
QString directoryPart = directory.left(index);
const QString directoryPart = directory.left(index);
QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directoryPart);
if (it != m_d->m_cachedMatches.constEnd()) {
if (it != m_d->m_cachedMatches.constEnd())
return it.value();
}
pos = index+1;
}
// ah nothing so ask the IVersionControls directly
QList<IVersionControl *> versionControls = ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
const VersionControlList versionControls = allVersionControls();
foreach(IVersionControl * versionControl, versionControls) {
if (versionControl->managesDirectory(directory)) {
m_d->m_cachedMatches.insert(versionControl->findTopLevelForDirectory(directory), versionControl);
......@@ -95,20 +128,20 @@ IVersionControl* VCSManager::findVersionControlForDirectory(const QString &direc
return 0;
}
void VCSManager::showDeleteDialog(const QString &fileName)
bool VCSManager::showDeleteDialog(const QString &fileName)
{
IVersionControl *vc = findVersionControlForDirectory(QFileInfo(fileName).absolutePath());
if (!vc)
return;
if (!vc || !vc->supportsOperation(IVersionControl::DeleteOperation))
return true;
const QString title = QCoreApplication::translate("VCSManager", "Version Control");
const QString msg = QCoreApplication::translate("VCSManager",
"Would you like to remove this file from the version control system?\n"
"Note: This might remove the local file.");
"Would you like to remove this file from the version control system (%1)?\n"
"Note: This might remove the local file.").arg(vc->name());
const QMessageBox::StandardButton button =
QMessageBox::question(0, title, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (button == QMessageBox::Yes) {
vc->vcsDelete(fileName);
}
if (button != QMessageBox::Yes)
return true;
return vc->vcsDelete(fileName);
}
} // namespace Core
......@@ -45,12 +45,12 @@ class IVersionControl;
// The VCSManager has only one notable function:
// findVersionControlFor(), which returns the IVersionControl * for a given
// filename. Note that the VCSManager assumes that if a IVersionControl *
// filename. Note that the VCSManager assumes that if a IVersionControl *
// manages a directory, then it also manages all the files and all the
// subdirectories.
//
// It works by asking all IVersionControl * if they manage the file, and ask
// for the topmost directory it manages. This information is cached and
// for the topmost directory it manages. This information is cached and
// VCSManager thus knows pretty fast which IVersionControl * is responsible.
class CORE_EXPORT VCSManager
......@@ -62,10 +62,16 @@ public:
IVersionControl *findVersionControlForDirectory(const QString &directory);
// Shows a confirmation dialog,
// wheter the file should also be deleted from revision control
// Calls sccDelete on the file
void showDeleteDialog(const QString &fileName);
// Enable the VCS managing a certain directory only. This should
// be used by project manager classes.
void setVCSEnabled(const QString &directory);
// Enable all VCS.
void setAllVCSEnabled();
// Shows a confirmation dialog, whether the file should also be deleted
// from revision control Calls sccDelete on the file. Returns false
// if a failure occurs
bool showDeleteDialog(const QString &fileName);
private:
VCSManagerPrivate *m_d;
......
......@@ -253,6 +253,25 @@ protected:
m_currentDoc->appendMacro(macroName, macroText);
}
virtual void startExpandingMacro(unsigned offset,
const rpp::Macro &macro,
const QByteArray &originalText)
{
if (! m_currentDoc)
return;
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
m_currentDoc->addMacroUse(offset, originalText.length());
}
virtual void stopExpandingMacro(unsigned offset, const rpp::Macro &macro)
{
if (! m_currentDoc)
return;
//qDebug() << "stop expanding:" << macro.name;
}
void mergeEnvironment(Document::Ptr doc)
{
QSet<QString> processed;
......@@ -505,7 +524,7 @@ CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Proj
QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
{
if (qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList();
QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this,
......@@ -595,6 +614,22 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
QList<QTextEdit::ExtraSelection> selections;
#ifdef QTCREATOR_WITH_MACRO_HIGHLIGHTING
// set up the format for the macros
QTextCharFormat macroFormat;
macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
QTextCursor c = ed->textCursor();
foreach (const Document::Block block, doc->macroUses()) {
QTextEdit::ExtraSelection sel;
sel.cursor = c;
sel.cursor.setPosition(block.begin());
sel.cursor.setPosition(block.end(), QTextCursor::KeepAnchor);
sel.format = macroFormat;
selections.append(sel);
}
#endif // QTCREATOR_WITH_MACRO_HIGHLIGHTING
// set up the format for the errors
QTextCharFormat errorFormat;
errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
......@@ -657,6 +692,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
QStringList files,
QMap<QString, QByteArray> workingCopy)
{
Q_ASSERT(! files.isEmpty());
// Change the priority of the background parser thread to idle.
QThread::currentThread()->setPriority(QThread::IdlePriority);
......@@ -698,6 +735,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
#endif
}
future.setProgressValue(files.size());
// Restore the previous thread priority.
QThread::currentThread()->setPriority(QThread::NormalPriority);
}
......
......@@ -40,6 +40,8 @@
namespace rpp {
class Macro;
class Client
{
Client(const Client &other);
......@@ -61,6 +63,13 @@ public:
virtual void macroAdded(const QByteArray &macroId, const QByteArray &text) = 0;
virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
virtual void startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalTextt) = 0;
virtual void stopExpandingMacro(unsigned offset,
const Macro &macro) = 0;
virtual void startSkippingBlocks(unsigned offset) = 0;
virtual void stopSkippingBlocks(unsigned offset) = 0;
};
......
......@@ -575,7 +575,17 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
const QByteArray spell = tokenSpell(*identifierToken);
if (env.isBuiltinMacro(spell)) {
const Macro trivial;
if (client)
client->startExpandingMacro(identifierToken->offset,
trivial, spell);
expand(spell.constBegin(), spell.constEnd(), result);
if (client)
client->stopExpandingMacro(_dot->offset, trivial);
continue;
}
......@@ -585,18 +595,36 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
} else {
if (! m->function_like) {
if (_dot->isNot(T_LPAREN)) {
if (client)
client->startExpandingMacro(identifierToken->offset,
*m, spell);
m->hidden = true;
expand(m->definition.constBegin(),
m->definition.constEnd(),
result);
if (client)
client->stopExpandingMacro(_dot->offset, *m);
m->hidden = false;
continue;
} else {
QByteArray tmp;
m->hidden = true;
if (client)
client->startExpandingMacro(identifierToken->offset,
*m, spell);