Merge commit 'origin/0.9.1-beta'

Conflicts:
	doc/qtcreator.qdoc
	src/plugins/qt4projectmanager/qtversionmanager.cpp
This commit is contained in:
con
2008-12-08 18:52:02 +01:00
95 changed files with 1584 additions and 1092 deletions

View File

@@ -1674,7 +1674,10 @@ static void qDumpQObjectSignal(QDumper &d)
d.beginHash();
P(d, "name", "[" << i << "] slot");
P(d, "type", "");
P(d, "value", conn.receiver->metaObject()->method(conn.method).signature());
if (conn.receiver)
P(d, "value", conn.receiver->metaObject()->method(conn.method).signature());
else
P(d, "value", "<invalid receiver>");
P(d, "numchild", "0");
d.endHash();
d.beginHash();
@@ -1861,17 +1864,25 @@ static void qDumpQSet(QDumper &d)
n = 100;
d << ",children=[";
int i = 0;
for (int bucket = 0; bucket != hd->numBuckets; ++bucket) {
for (int bucket = 0; bucket != hd->numBuckets && i <= 10000; ++bucket) {
for (node = hd->buckets[bucket]; node->next; node = node->next) {
d.beginHash();
P(d, "name", "[" << i << "]");
P(d, "type", d.innertype);
P(d, "exp", "(('QHashNode<" << d.innertype
<< ",QHashDummyValue>'*)"
P(d, "exp", "(('"NS"QHashNode<" << d.innertype
<< ","NS"QHashDummyValue>'*)"
<< static_cast<const void*>(node) << ")->key"
);
d.endHash();
++i;
if (i > 10000) {
d.beginHash();
P(d, "name", "Warning:");
P(d, "value", "<incomplete>");
P(d, "type", "");
d.endHash();
break;
}
}
}
d << "]";

Binary file not shown.

View File

@@ -69,7 +69,7 @@
\image qtcreator-breakdown.png
\seection1 The Mode Selectors
\section1 The Mode Selectors
When working in Qt Creator, you can be in one of five modes: \bold Project,
\bold Edit, \bold Debug, \bold Help, and \bold Output.
@@ -613,7 +613,7 @@
\page creator-debugging.html
\nextpage creator-tips.html
\title Debugging With Qt Creator
\title Debugging with Qt Creator
\table
\row
@@ -677,9 +677,9 @@
\list
\o At a particular line you want the program to stop -- click on the
left margin or press \key F9 (\key F8 for Mac Os X).
\o At the name of a function that you want the program to stop -- enter
the function's name in \gui{Set Breakpoint at Function...} under the
left margin or press \key F9 (\key F8 for Mac OS X).
\o At a function that you want the program to stop -- enter the
function's name in \gui{Set Breakpoint at Function...} under the
\gui Debug menu.
\endlist
@@ -744,7 +744,7 @@
When the program being debugged is stopped, Qt Creator displays the nested
function calls leading to the current position as a \e call stack trace.
This stack trace is built up from \e call stack frames, each representing a
This stack trace is built up from \e{call stack frames}, each representing a
particular function. For each function, Qt Creator will try to retrieve the
file name and line number of the corresponding source files. This data is
shown in the \gui Stack view.
@@ -765,11 +765,10 @@
\section2 Threads
The \gui Thread view displays the state of the program being debugged one
thread at a time. If a multi-threaded program is stopped, the \gui Thread
view or the combobox named \gui Thread in the debugger's status bar can
be used to switch from one thread to another. The \gui Stack view will
adjust itself accordingly.
If a multi-threaded program is stopped, the \gui Thread view or the
combobox named \gui Thread in the debugger's status bar can be used to
switch from one thread to another. The \gui Stack view will adjust itself
accordingly.
\section2 Locals and Watchers
@@ -851,8 +850,7 @@
function, the latter the current state of the CPU registers.
Both views are mainly useful in connection with the low-level
\gui{Step single instruction} and \gui{Step over single instruction}
commands
commands.
\section1 A Walkthrough for the Debugger Frontend
@@ -947,27 +945,27 @@
\bold{Running Qt Creator from the Command Line}
You can start Qt Creator from a command prompt with an existing session or
\c{.pro} file by giving the name as argument on the command line.
You can start Qt Creator from a command prompt with the name of an existing
session or \c{.pro} file by giving the name as argument on the command
line.
\bold{Sidebar}
\bold{Show and Hide the Sidebar}
You can hide/unhide the sidebar in the edit and debug mode
by clicking on the corresponding icon on the left bottom.
Keyboard shortcut is \key{Alt+0}.
You can show and hide the the sidebar in \gui Edit and \gui Debug mode by
clicking on the corresponding icon, or by pressing \key{Alt+0}.
\bold{Display signals and slots}
\bold{Display Signals and Slots}
If you have an instance of a class derived from QObject and
want to find all other objects connected to one of its
slots by Qt's signals-and-slots mechanism, enable
\gui{Debug} and \gui{Use Custom Display for Qt Objects}.
In the \gui{Locals and Watchers View}, expand the object's
entry and open the wanted slot in the "slots" subitem. The
objects connect to this slot are exposed as children of
this slot. The same works with signals.
If you have an instance of a class that is derived from QObject, and you
you would like to find all other objects connected to one of your object's
slots using Qt's signals and slots mechanism -- you can enable
\gui{Use Custom Display for Qt Objects} feature under the \gui Debug menu.
\bold{Low level display}
In the \gui{Locals and Watchers} view, expand the object's entry and open
the slot in the \e slots subitem. The objects connected to this slot are
exposed as children of the slot. This method works with signals too.
\bold{Display Low Level Data}
If the special debugging of Qt objects fails due to data
corruption within the debugged objects, you can switch the
@@ -983,33 +981,38 @@
\title Glossary
\bold{System Qt}
\table
\header
\o Term
\o Meaning
\target glossary-system-qt
The version of Qt installed on your system.
This is the one whose \c qmake command is found in the \c PATH.
\row
\o System Qt \target glossary-system-qt
\o The version of Qt installed on your system. This is the Qt
version for the \c qmake command found in your \c PATH.
\bold{Default Qt}
\row
\o Default Qt \target glossary-default-qt
\o The version of Qt configured in \gui{Tools -> Options -> Qt 4
-> Default Qt Version}. This is the Qt version used by your
new projects. It defaults to System Qt.
\target glossary-default-qt
The version of Qt configured in \gui{Tools
-> Options -> Qt 4 -> Default Qt Version}. This is the version
used by new projects. It defaults to the System Qt.
\row
\o Project Qt \target glossary-project-qt
\o The version of Qt configured in \gui{Build&Run -> Build
Settings -> Build Configurations}. This is the Qt version that
is actually used by a particular project. It defaults to
Default Qt.
\bold{Project Qt}
\target glossary-project-qt
The version of Qt configured in \gui{Build&Run
-> Build Settings -> Build Configurations}. This is the version
actually used by the project. It defaults to the Default Qt.
\bold{Shadow Build}
\target glossary-shadow-build
Shadow building means building the project not in the source directory,
but in a seperate \bold{build directory}. This has the benefit of keeping
the source directory clean. It is also considered "best practice" if
you need many build configurations for a single set of sources.
\row
\o Shadow Build \target glossary-shadow-build
\o Shadow building means building a project in a separate
directory, the \e{build directory}. The build directory is
different from the source directory. One of the benefits of
shadow building is that it keeps your source directory clean.
Shadow building is the best practice if you need many build
configurations for a single set of source.
\endtable
*/

View File

@@ -95,8 +95,10 @@ private:
QSortFilterProxyModel *proxyModel;
};
class TreeView : public QTreeView {
class TreeView : public QTreeView
{
Q_OBJECT
public:
TreeView(QWidget* parent = 0) : QTreeView(parent) {}
void subclassKeyPressEvent(QKeyEvent* event)
@@ -159,18 +161,18 @@ class BookmarkManager : public QObject
Q_OBJECT
public:
BookmarkManager(QHelpEngineCore* helpEngine);
BookmarkManager(QHelpEngineCore *helpEngine);
~BookmarkManager();
BookmarkModel* treeBookmarkModel();
BookmarkModel* listBookmarkModel();
BookmarkModel *treeBookmarkModel();
BookmarkModel *listBookmarkModel();
void saveBookmarks();
QStringList bookmarkFolders() const;
QModelIndex addNewFolder(const QModelIndex& index);
QModelIndex addNewFolder(const QModelIndex &index);
void removeBookmarkItem(QTreeView *treeView, const QModelIndex& index);
void showBookmarkDialog(QWidget* parent, const QString &name, const QString &url);
void addNewBookmark(const QModelIndex& index, const QString &name, const QString &url);
void showBookmarkDialog(QWidget *parent, const QString &name, const QString &url);
void addNewBookmark(const QModelIndex &index, const QString &name, const QString &url);
void setupBookmarkModels();
private slots:

View File

@@ -212,9 +212,9 @@ int main(int argc, char **argv)
pluginManager.setPluginPaths(pluginPaths);
const QStringList arguments = app.arguments();
QMap<QString,QString> foundAppOptions;
QMap<QString, QString> foundAppOptions;
if (arguments.size() > 1) {
QMap<QString,bool> appOptions;
QMap<QString, bool> appOptions;
appOptions.insert(QLatin1String(HELP_OPTION1), false);
appOptions.insert(QLatin1String(HELP_OPTION2), false);
appOptions.insert(QLatin1String(HELP_OPTION3), false);

View File

@@ -138,19 +138,9 @@ void Document::addIncludeFile(const QString &fileName)
_includedFiles.append(fileName);
}
QByteArray Document::definedMacros() const
void Document::appendMacro(const Macro &macro)
{
return _definedMacros;
}
void Document::appendMacro(const QByteArray &macroName, const QByteArray &text)
{
int index = macroName.indexOf('(');
if (index == -1)
_macroNames.insert(macroName);
else
_macroNames.insert(macroName.left(index));
_definedMacros += text;
_definedMacros.append(macro);
}
void Document::addMacroUse(unsigned offset, unsigned length)
@@ -251,11 +241,6 @@ void Document::stopSkippingBlocks(unsigned stop)
_skippedBlocks.back() = Block(start, stop);
}
QSet<QByteArray> Document::macroNames() const
{
return _macroNames;
}
bool Document::parse(ParseMode mode)
{
TranslationUnit::ParseMode m = TranslationUnit::ParseTranlationUnit;

View File

@@ -36,6 +36,8 @@
#include <CPlusPlusForwardDeclarations.h>
#include "pp-macro.h"
#include <QByteArray>
#include <QList>
#include <QSet>
@@ -45,6 +47,8 @@
namespace CPlusPlus {
class Macro;
class CPLUSPLUS_EXPORT Document
{
Document(const Document &other);
@@ -63,10 +67,7 @@ public:
QStringList includedFiles() const;
void addIncludeFile(const QString &fileName);
QByteArray definedMacros() const;
QSet<QByteArray> macroNames() const;
void appendMacro(const QByteArray &macroName, const QByteArray &text);
void appendMacro(const Macro &macro);
void addMacroUse(unsigned offset, unsigned length);
@@ -81,6 +82,9 @@ public:
Scope *globalSymbols() const; // ### deprecate?
Namespace *globalNamespace() const;
QList<Macro> definedMacros() const
{ return _definedMacros; }
Symbol *findSymbolAt(unsigned line, unsigned column) const;
void setSource(const QByteArray &source);
@@ -191,8 +195,7 @@ private:
TranslationUnit *_translationUnit;
Namespace *_globalNamespace;
QList<DiagnosticMessage> _diagnosticMessages;
QByteArray _definedMacros;
QSet<QByteArray> _macroNames;
QList<Macro> _definedMacros;
QList<Block> _skippedBlocks;
QList<Block> _macroUses;
};

View File

@@ -61,11 +61,11 @@ Icons::Icons()
{
}
QIcon Icons::iconForSymbol(Symbol *symbol) const
QIcon Icons::iconForSymbol(const Symbol *symbol) const
{
if (symbol->isFunction() || (symbol->isDeclaration() && symbol->type()->isFunction()))
{
Function *function = symbol->asFunction();
const Function *function = symbol->asFunction();
if (!function)
function = symbol->type()->asFunction();

View File

@@ -47,7 +47,7 @@ class CPLUSPLUS_EXPORT Icons
public:
Icons();
QIcon iconForSymbol(Symbol *symbol) const;
QIcon iconForSymbol(const Symbol *symbol) const;
QIcon keywordIcon() const;
QIcon macroIcon() const;

View File

@@ -74,10 +74,10 @@ Symbol *OverviewModel::globalSymbolAt(unsigned index) const
QModelIndex OverviewModel::index(int row, int column, const QModelIndex &parent) const
{
if (! hasDocument()) {
return QModelIndex();
} else if (! parent.isValid()) {
Symbol *symbol = globalSymbolAt(row);
if (!parent.isValid()) {
if (row == 0) // account for no symbol item
return createIndex(row, column);
Symbol *symbol = globalSymbolAt(row-1); // account for no symbol item
return createIndex(row, column, symbol);
} else {
Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
@@ -96,12 +96,20 @@ QModelIndex OverviewModel::index(int row, int column, const QModelIndex &parent)
QModelIndex OverviewModel::parent(const QModelIndex &child) const
{
Symbol *symbol = static_cast<Symbol *>(child.internalPointer());
Q_ASSERT(symbol != 0);
if (!symbol) // account for no symbol item
return QModelIndex();
if (Scope *scope = symbol->scope()) {
Symbol *parentSymbol = scope->owner();
if (parentSymbol && parentSymbol->scope())
return createIndex(parentSymbol->index(), 0, parentSymbol);
if (parentSymbol && parentSymbol->scope()) {
QModelIndex index;
if (parentSymbol->scope() && parentSymbol->scope()->owner()
&& parentSymbol->scope()->owner()->scope()) // the parent doesn't have a parent
index = createIndex(parentSymbol->index(), 0, parentSymbol);
else //+1 to account for no symbol item
index = createIndex(parentSymbol->index() + 1, 0, parentSymbol);
return index;
}
}
return QModelIndex();
@@ -110,22 +118,27 @@ QModelIndex OverviewModel::parent(const QModelIndex &child) const
int OverviewModel::rowCount(const QModelIndex &parent) const
{
if (hasDocument()) {
if (! parent.isValid()) {
return globalSymbolCount();
if (!parent.isValid()) {
return globalSymbolCount()+1; // account for no symbol item
} else {
if (!parent.parent().isValid() && parent.row() == 0) // account for no symbol item
return 0;
Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
Q_ASSERT(parentSymbol != 0);
if (ScopedSymbol *scopedSymbol = parentSymbol->asScopedSymbol()) {
if (! scopedSymbol->isFunction()) {
if (!scopedSymbol->isFunction()) {
Scope *parentScope = scopedSymbol->members();
Q_ASSERT(parentScope != 0);
return parentScope->symbolCount();
}
}
return 0;
}
}
if (!parent.isValid())
return 1; // account for no symbol item
return 0;
}
@@ -136,6 +149,19 @@ int OverviewModel::columnCount(const QModelIndex &) const
QVariant OverviewModel::data(const QModelIndex &index, int role) const
{
// account for no symbol item
if (!index.parent().isValid() && index.row() == 0) {
switch (role) {
case Qt::DisplayRole:
if (rowCount() > 1)
return tr("<Select Symbol>");
else
return tr("<No Symbols>");
default:
return QVariant();
} //switch
}
switch (role) {
case Qt::DisplayRole: {
Symbol *symbol = static_cast<Symbol *>(index.internalPointer());

View File

@@ -48,6 +48,7 @@ TypeOfExpression::TypeOfExpression():
void TypeOfExpression::setDocuments(const QMap<QString, Document::Ptr> &documents)
{
m_documents = documents;
m_lookupContext = LookupContext();
}
QList<TypeOfExpression::Result> TypeOfExpression::operator()(const QString &expression,

View File

@@ -54,6 +54,9 @@ public:
/**
* Sets the documents used to evaluate expressions. Should be set before
* calling this functor.
*
* Also clears the lookup context, so can be used to make sure references
* to the documents previously used are removed.
*/
void setDocuments(const QMap<QString, Document::Ptr> &documents);

View File

@@ -21,7 +21,16 @@ HEADERS += \
TypeOfExpression.h \
TypePrettyPrinter.h \
ResolveExpression.h \
LookupContext.h
LookupContext.h \
pp-cctype.h \
pp-engine.h \
pp-fwd.h \
pp-macro-expander.h \
pp-scanner.h \
pp-client.h \
pp-environment.h \
pp-internal.h \
pp-macro.h
SOURCES += \
SimpleLexer.cpp \
@@ -35,6 +44,9 @@ SOURCES += \
TypeOfExpression.cpp \
TypePrettyPrinter.cpp \
ResolveExpression.cpp \
LookupContext.cpp
LookupContext.cpp \
pp-engine.cpp \
pp-environment.cpp \
pp-macro-expander.cpp
RESOURCES += cplusplus.qrc

View File

@@ -53,22 +53,24 @@
#ifndef PP_CCTYPE_H
#define PP_CCTYPE_H
#include <CPlusPlusForwardDeclarations.h>
#include <cctype>
namespace rpp {
namespace CPlusPlus {
inline bool pp_isalpha (int __ch)
inline bool CPLUSPLUS_EXPORT pp_isalpha (int __ch)
{ return std::isalpha ((unsigned char) __ch) != 0; }
inline bool pp_isalnum (int __ch)
inline bool CPLUSPLUS_EXPORT pp_isalnum (int __ch)
{ return std::isalnum ((unsigned char) __ch) != 0; }
inline bool pp_isdigit (int __ch)
inline bool CPLUSPLUS_EXPORT pp_isdigit (int __ch)
{ return std::isdigit ((unsigned char) __ch) != 0; }
inline bool pp_isspace (int __ch)
inline bool CPLUSPLUS_EXPORT pp_isspace (int __ch)
{ return std::isspace ((unsigned char) __ch) != 0; }
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_CCTYPE_H

View File

@@ -34,15 +34,17 @@
#ifndef PP_CLIENT_H
#define PP_CLIENT_H
#include <CPlusPlusForwardDeclarations.h>
#include <QByteArray>
#include <QString>
#include <QFile>
namespace rpp {
namespace CPlusPlus {
class Macro;
class Client
class CPLUSPLUS_EXPORT Client
{
Client(const Client &other);
void operator=(const Client &other);
@@ -60,7 +62,7 @@ public:
virtual ~Client()
{ }
virtual void macroAdded(const QByteArray &macroId, const QByteArray &text) = 0;
virtual void macroAdded(const Macro &macro) = 0;
virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
virtual void startExpandingMacro(unsigned offset,
@@ -74,6 +76,6 @@ public:
virtual void stopSkippingBlocks(unsigned offset) = 0;
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_CLIENT_H

View File

@@ -57,7 +57,6 @@
#include <QtDebug>
#include <algorithm>
using namespace rpp;
using namespace CPlusPlus;
namespace {
@@ -907,16 +906,8 @@ void pp::processDefine(TokenIterator firstToken, TokenIterator lastToken)
env.bind(macro);
QByteArray macroText;
macroText.reserve(64);
macroText += "#define ";
macroText += macroId;
macroText += ' ';
macroText += macro.definition;
macroText += '\n';
client->macroAdded(macroId, macroText);
if (client)
client->macroAdded(macro);
}
void pp::processIf(TokenIterator firstToken, TokenIterator lastToken)
@@ -1020,13 +1011,10 @@ void pp::processUndef(TokenIterator firstToken, TokenIterator lastToken)
if (tk->is(T_IDENTIFIER)) {
const QByteArray macroName = tokenText(*tk);
env.remove(macroName);
const Macro *macro = env.remove(macroName);
QByteArray macroText;
macroText += "#undef ";
macroText += macroName;
macroText += '\n';
client->macroAdded(macroName, macroText);
if (client && macro)
client->macroAdded(*macro);
}
}

View File

@@ -62,7 +62,7 @@ namespace CPlusPlus {
class Token;
}
namespace rpp {
namespace CPlusPlus {
struct Value
{
@@ -134,7 +134,7 @@ namespace rpp {
#undef PP_DEFINE_BIN_OP
};
class pp
class CPLUSPLUS_EXPORT pp
{
Client *client;
Environment &env;
@@ -200,7 +200,7 @@ namespace rpp {
Value evalExpression(TokenIterator firstToken,
TokenIterator lastToken,
const QByteArray &source) const;
const QByteArray &source) const;
QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const;
@@ -226,6 +226,6 @@ namespace rpp {
bool isQtReservedWord(const QByteArray &name) const;
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_ENGINE_H

View File

@@ -54,7 +54,7 @@
#include "pp.h"
#include <cstring>
using namespace rpp;
using namespace CPlusPlus;
Environment::Environment ()
: currentLine(0),
@@ -115,12 +115,12 @@ Macro *Environment::bind(const Macro &__macro)
return m;
}
void Environment::remove (const QByteArray &name)
Macro *Environment::remove (const QByteArray &name)
{
Macro macro;
macro.name = name;
macro.hidden = true;
bind(macro);
return bind(macro);
}
bool Environment::isBuiltinMacro(const QByteArray &s) const

View File

@@ -53,14 +53,16 @@
#ifndef PP_ENVIRONMENT_H
#define PP_ENVIRONMENT_H
#include "CPlusPlusForwardDeclarations.h"
#include <QVector>
#include <QByteArray>
namespace rpp {
namespace CPlusPlus {
struct Macro;
class Macro;
class Environment
class CPLUSPLUS_EXPORT Environment
{
public:
Environment();
@@ -70,7 +72,7 @@ public:
Macro *macroAt(unsigned index) const;
Macro *bind(const Macro &macro);
void remove(const QByteArray &name);
Macro *remove(const QByteArray &name);
Macro *resolve(const QByteArray &name) const;
bool isBuiltinMacro(const QByteArray &name) const;
@@ -104,6 +106,6 @@ private:
int _hash_count;
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_ENVIRONMENT_H

View File

View File

@@ -55,7 +55,7 @@
#include <QByteArray>
namespace rpp {
namespace CPlusPlus {
namespace _PP_internal {
inline bool comment_p (const char *__first, const char *__last)
@@ -73,6 +73,6 @@ inline bool comment_p (const char *__first, const char *__last)
}
} // _PP_internal
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_INTERNAL_H

View File

@@ -35,7 +35,7 @@
#include "pp-macro-expander.h"
#include <QDateTime>
using namespace rpp;
using namespace CPlusPlus;
MacroExpander::MacroExpander (Environment &env, pp_frame *frame)
: env(env), frame(frame),

View File

@@ -53,7 +53,7 @@
#ifndef PP_MACRO_EXPANDER_H
#define PP_MACRO_EXPANDER_H
namespace rpp {
namespace CPlusPlus {
struct pp_frame
{
@@ -97,7 +97,7 @@ namespace rpp {
int generated_lines;
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_MACRO_EXPANDER_H

View File

@@ -53,43 +53,44 @@
#ifndef PP_MACRO_H
#define PP_MACRO_H
#include <CPlusPlusForwardDeclarations.h>
#include <QByteArray>
#include <QVector>
namespace rpp {
namespace CPlusPlus {
struct Macro
class CPLUSPLUS_EXPORT Macro
{
public:
QByteArray name;
QByteArray definition;
QVector<QByteArray> formals;
QByteArray fileName;
int line;
Macro *next;
unsigned hashcode;
union
{
QByteArray name;
QByteArray definition;
QVector<QByteArray> formals;
QByteArray fileName;
int line;
int lines;
Macro *next;
unsigned hashcode;
unsigned state;
union
struct
{
unsigned state;
struct
{
unsigned hidden: 1;
unsigned function_like: 1;
unsigned variadics: 1;
};
unsigned hidden: 1;
unsigned function_like: 1;
unsigned variadics: 1;
};
};
inline Macro():
inline Macro():
line(0),
lines(0),
next(0),
hashcode(0),
state(0)
{ }
};
{ }
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_MACRO_H

View File

@@ -53,7 +53,7 @@
#ifndef PP_SCANNER_H
#define PP_SCANNER_H
namespace rpp {
namespace CPlusPlus {
struct pp_skip_blanks
{
@@ -373,7 +373,7 @@ struct pp_skip_argument
}
};
} // namespace rpp
} // namespace CPlusPlus
#endif // PP_SCANNER_H

View File

@@ -33,26 +33,65 @@
#include "filenamevalidatinglineedit.h"
#include <QtCore/QRegExp>
#include <QtCore/QDebug>
namespace Core {
namespace Utils {
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent)
{
}
/* Validate a file base name, check for forbidden characters/strings. */
static const char *notAllowedChars = "/?:&\\*\"|#%<> ";
static const char *notAllowedSubStrings[] = {".."};
// Naming a file like a device name will break on Windows, even if it is
// "com1.txt". Since we are cross-platform, we generally disallow such file
// names.
static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" };
static const QRegExp &windowsDeviceNoSubDirPattern()
{
static const QRegExp rc(QLatin1String("CON|AUX|PRN|COM1|COM2|LPT1|LPT2|NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/)
static const QRegExp &windowsDeviceSubDirPattern()
{
static const QRegExp rc(QLatin1String(".*[/\\\\]CON|.*[/\\\\]AUX|.*[/\\\\]PRN|.*[/\\\\]COM1|.*[/\\\\]COM2|.*[/\\\\]LPT1|.*[/\\\\]LPT2|.*[/\\\\]NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
// ----------- FileNameValidatingLineEdit
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent),
m_allowDirectories(false),
m_unused(0)
{
}
bool FileNameValidatingLineEdit::allowDirectories() const
{
return m_allowDirectories;
}
void FileNameValidatingLineEdit::setAllowDirectories(bool v)
{
m_allowDirectories = v;
}
/* Validate a file base name, check for forbidden characters/strings. */
#ifdef Q_OS_WIN
# define SLASHES "/\\"
#else
# define SLASHES "/"
#endif
static const char *notAllowedCharsSubDir = "?:&*\"|#%<> ";
static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES;
static const char *notAllowedSubStrings[] = {".."};
bool FileNameValidatingLineEdit::validateFileName(const QString &name,
bool allowDirectories,
QString *errorMessage /* = 0*/)
{
if (name.isEmpty()) {
if (errorMessage)
@@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false;
}
// Characters
const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir;
for (const char *c = notAllowedChars; *c; c++)
if (name.contains(QLatin1Char(*c))) {
if (errorMessage)
@@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false;
}
}
// Strings
const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *);
for (int s = 0; s < notAllowedStringCount; s++) {
const QLatin1String notAllowedString(notAllowedStrings[s]);
if (name == notAllowedString) {
if (errorMessage)
*errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString));
return false;
}
// Windows devices
bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name);
if (!matchesWinDevice && allowDirectories)
matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name);
if (matchesWinDevice) {
if (errorMessage)
*errorMessage = tr("The name must not match that of a MS Windows device. (%1).").
arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(',')));
return false;
}
return true;
}
bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
{
return validateFileName(value, errorMessage);
return validateFileName(value, m_allowDirectories, errorMessage);
}
} // namespace Utils

View File

@@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating
{
Q_OBJECT
Q_DISABLE_COPY(FileNameValidatingLineEdit)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
public:
explicit FileNameValidatingLineEdit(QWidget *parent = 0);
static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/);
static bool validateFileName(const QString &name,
bool allowDirectories = false,
QString *errorMessage = 0);
bool allowDirectories() const;
void setAllowDirectories(bool v);
protected:
virtual bool validate(const QString &value, QString *errorMessage) const;
private:
bool m_allowDirectories;
void *m_unused;
};
} // namespace Utils

View File

@@ -123,7 +123,7 @@ void FileWizardPage::slotActivated()
bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/)
{
return FileNameValidatingLineEdit::validateFileName(name, errorMessage);
return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage);
}
} // namespace Utils

View File

@@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &e)
m_d->m_formExtension = fixSuffix(e);
}
bool NewClassWidget::allowDirectories() const
{
return m_d->m_ui.headerFileLineEdit->allowDirectories();
}
void NewClassWidget::setAllowDirectories(bool v)
{
// We keep all in sync
if (allowDirectories() != v) {
m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v);
m_d->m_ui.headerFileLineEdit->setAllowDirectories(v);
m_d->m_ui.formFileLineEdit->setAllowDirectories(v);
}
}
void NewClassWidget::slotValidChanged()
{
const bool newValid = isValid();

View File

@@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true)
Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
// Utility "USER" property for wizards containing file names.
Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
public:
@@ -97,7 +98,7 @@ public:
QString sourceExtension() const;
QString headerExtension() const;
QString formExtension() const;
bool allowDirectories() const;
bool isValid(QString *error = 0) const;
@@ -125,6 +126,7 @@ public slots:
void setSourceExtension(const QString &e);
void setHeaderExtension(const QString &e);
void setFormExtension(const QString &e);
void setAllowDirectories(bool v);
/* Suggest a class name from the base class by stripping the leading 'Q'
* character. This will happen automagically if the base class combo

View File

@@ -48,40 +48,54 @@
namespace Core {
namespace Utils {
#ifdef Q_OS_OSX
/*static*/ const char * const PathChooser::browseButtonLabel = "Choose...";
#else
/*static*/ const char * const PathChooser::browseButtonLabel = "Browse...";
#endif
// ------------------ PathValidatingLineEdit
class PathValidatingLineEdit : public BaseValidatingLineEdit {
public:
explicit PathValidatingLineEdit(QWidget *parent = 0);
explicit PathValidatingLineEdit(PathChooser *chooser, QWidget *parent = 0);
protected:
virtual bool validate(const QString &value, QString *errorMessage) const;
private:
PathChooser *m_chooser;
};
PathValidatingLineEdit::PathValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent)
PathValidatingLineEdit::PathValidatingLineEdit(PathChooser *chooser, QWidget *parent) :
BaseValidatingLineEdit(parent),
m_chooser(chooser)
{
Q_ASSERT(chooser != NULL);
}
bool PathValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
{
return PathChooser::validatePath(value, errorMessage);
return m_chooser->validatePath(value, errorMessage);
}
// ------------------ PathChooserPrivate
struct PathChooserPrivate {
PathChooserPrivate();
PathChooserPrivate(PathChooser *chooser);
PathValidatingLineEdit *m_lineEdit;
PathChooser::Kind m_acceptingKind;
QString m_dialogTitleOverride;
};
PathChooserPrivate::PathChooserPrivate() :
m_lineEdit(new PathValidatingLineEdit)
PathChooserPrivate::PathChooserPrivate(PathChooser *chooser) :
m_lineEdit(new PathValidatingLineEdit(chooser)),
m_acceptingKind(PathChooser::Directory)
{
}
PathChooser::PathChooser(QWidget *parent) :
QWidget(parent),
m_d(new PathChooserPrivate)
m_d(new PathChooserPrivate(this))
{
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->setContentsMargins(0, 0, 0, 0);
@@ -90,11 +104,12 @@ PathChooser::PathChooser(QWidget *parent) :
connect(m_d->m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
connect(m_d->m_lineEdit, SIGNAL(validChanged()), this, SIGNAL(validChanged()));
m_d->m_lineEdit->setMinimumWidth(300);
m_d->m_lineEdit->setMinimumWidth(260);
hLayout->addWidget(m_d->m_lineEdit);
hLayout->setSizeConstraint(QLayout::SetMinimumSize);
QToolButton *browseButton = new QToolButton;
browseButton->setText(tr("..."));
browseButton->setText(tr(browseButtonLabel));
connect(browseButton, SIGNAL(clicked()), this, SLOT(slotBrowse()));
hLayout->addWidget(browseButton);
@@ -123,8 +138,28 @@ void PathChooser::slotBrowse()
QString predefined = path();
if (!predefined.isEmpty() && !QFileInfo(predefined).isDir())
predefined.clear();
// Prompt for a directory, delete trailing slashes unless it is "/", only
QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose a path"), predefined);
// Prompt for a file/dir
QString dialogTitle;
QString newPath;
switch (m_d->m_acceptingKind) {
case PathChooser::Directory:
newPath = QFileDialog::getExistingDirectory(this,
makeDialogTitle(tr("Choose a directory")), predefined);
break;
case PathChooser::File: // fall through
case PathChooser::Command:
newPath = QFileDialog::getOpenFileName(this,
makeDialogTitle(tr("Choose a file")), predefined);
break;
default:
;
}
// TODO make cross-platform
// Delete trailing slashes unless it is "/", only
if (!newPath .isEmpty()) {
if (newPath .size() > 1 && newPath .endsWith(QDir::separator()))
newPath .truncate(newPath .size() - 1);
@@ -149,20 +184,52 @@ bool PathChooser::validatePath(const QString &path, QString *errorMessage)
*errorMessage = tr("The path must not be empty.");
return false;
}
// Must be a directory?
const QFileInfo fi(path);
if (fi.isDir())
return true; // Happy!
if (!fi.exists()) {
if (errorMessage)
*errorMessage = tr("The path '%1' does not exist.").arg(path);
return false;
const QFileInfo fi(path);
const bool isDir = fi.isDir();
// Check if existing
switch (m_d->m_acceptingKind) {
case PathChooser::Directory: // fall through
case PathChooser::File:
if (!fi.exists()) {
if (errorMessage)
*errorMessage = tr("The path '%1' does not exist.").arg(path);
return false;
}
break;
case PathChooser::Command: // fall through
default:
;
}
// Must be something weird
if (errorMessage)
*errorMessage = tr("The path '%1' is not a directory.").arg(path);
return false;
// Check expected kind
switch (m_d->m_acceptingKind) {
case PathChooser::Directory:
if (!isDir)
if (errorMessage)
*errorMessage = tr("The path '%1' is not a directory.").arg(path);
return false;
break;
case PathChooser::File:
if (isDir)
if (errorMessage)
*errorMessage = tr("The path '%1' is not a file.").arg(path);
return false;
break;
case PathChooser::Command:
// TODO do proper command validation
// i.e. search $PATH for a matching file
break;
default:
;
}
return true;
}
QString PathChooser::label()
@@ -182,5 +249,23 @@ QString PathChooser::homePath()
#endif
}
void PathChooser::setExpectedKind(Kind expected)
{
m_d->m_acceptingKind = expected;
}
void PathChooser::setPromptDialogTitle(const QString &title)
{
m_d->m_dialogTitleOverride = title;
}
QString PathChooser::makeDialogTitle(const QString &title)
{
if (m_d->m_dialogTitleOverride.isNull())
return title;
else
return m_d->m_dialogTitleOverride;
}
} // namespace Utils
} // namespace Core

View File

@@ -30,6 +30,7 @@
** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef PATHCHOOSER_H
#define PATHCHOOSER_H
@@ -53,9 +54,23 @@ class QWORKBENCH_UTILS_EXPORT PathChooser : public QWidget
Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
public:
static const char * const browseButtonLabel;
explicit PathChooser(QWidget *parent = 0);
virtual ~PathChooser();
enum Kind {
Directory,
File,
Command,
// ,Any
};
// Default is <Directory>
void setExpectedKind(Kind expected);
void setPromptDialogTitle(const QString &title);
bool isValid() const;
QString errorMessage() const;
@@ -64,11 +79,15 @@ public:
// Returns the suggested label title when used in a form layout
static QString label();
static bool validatePath(const QString &path, QString *errorMessage = 0);
bool validatePath(const QString &path, QString *errorMessage = 0);
// Return the home directory, which needs some fixing under Windows.
static QString homePath();
private:
// Returns overridden title or the one from <title>
QString makeDialogTitle(const QString &title);
signals:
void validChanged();
void changed();

View File

@@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent)
bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/)
{
// Validation is file name + checking for dots
if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage))
if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage))
return false;
// We don't want dots in the directory name for some legacy Windows

View File

@@ -396,11 +396,16 @@ void BookmarkManager::toggleBookmark()
if (!editor)
return;
const QFileInfo fi(editor->file()->fileName());
const int editorLine = editor->currentLine();
toggleBookmark(editor->file()->fileName(), editor->currentLine());
}
void BookmarkManager::toggleBookmark(const QString &fileName, int lineNumber)
{
const QFileInfo fi(fileName);
const int editorLine = lineNumber;
// Remove any existing bookmark on this line
if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), editorLine)) {
if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), lineNumber)) {
// TODO check if the bookmark is really on the same markable Interface
removeBookmark(mark);
return;

View File

@@ -34,15 +34,15 @@
#ifndef BOOKMARKMANAGER_H
#define BOOKMARKMANAGER_H
#include <QtCore/QAbstractItemModel>
#include <QtGui/QListView>
#include <QtCore/QList>
#include <QtGui/QPixmap>
#include <QtGui/QStyledItemDelegate>
#include <coreplugin/icontext.h>
#include <coreplugin/inavigationwidgetfactory.h>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QList>
#include <QtGui/QListView>
#include <QtGui/QPixmap>
#include <QtGui/QStyledItemDelegate>
namespace ProjectExplorer {
class SessionManager;
}
@@ -89,10 +89,16 @@ public:
// this QItemSelectionModel is shared by all views
QItemSelectionModel *selectionModel() const;
enum Roles {Filename = Qt::UserRole, LineNumber = Qt::UserRole + 1, Directory = Qt::UserRole + 2, LineText = Qt::UserRole + 3};
enum Roles {
Filename = Qt::UserRole,
LineNumber = Qt::UserRole + 1,
Directory = Qt::UserRole + 2,
LineText = Qt::UserRole + 3
};
public slots:
void toggleBookmark();
void toggleBookmark(const QString &fileName, int lineNumber);
void nextInDocument();
void prevInDocument();
void next();
@@ -108,6 +114,7 @@ private slots:
void updateActionStatus();
void gotoBookmark(Bookmark *bookmark);
void loadBookmarks();
private:
TextEditor::ITextEditor *currentTextEditor() const;
ProjectExplorer::SessionManager* sessionManager() const;
@@ -120,8 +127,8 @@ private:
static QString bookmarkToString(const Bookmark *b);
void saveBookmarks();
typedef QMultiMap<QString, Bookmark*> FileNameBookmarksMap;
typedef QMap<QString, FileNameBookmarksMap*> DirectoryFileBookmarksMap;
typedef QMultiMap<QString, Bookmark *> FileNameBookmarksMap;
typedef QMap<QString, FileNameBookmarksMap *> DirectoryFileBookmarksMap;
DirectoryFileBookmarksMap m_bookmarksMap;
Core::ICore *m_core;
@@ -138,7 +145,7 @@ class BookmarkView : public QListView
public:
BookmarkView(QWidget *parent = 0);
~BookmarkView();
void setModel(QAbstractItemModel * model);
void setModel(QAbstractItemModel *model);
public slots:
void gotoBookmark(const QModelIndex &index);
protected slots:
@@ -146,7 +153,7 @@ protected slots:
void removeAll();
protected:
void contextMenuEvent(QContextMenuEvent *event);
void removeBookmark(const QModelIndex& index);
void removeBookmark(const QModelIndex &index);
private:
BookmarkContext *m_bookmarkContext;
QModelIndex m_contextMenuIndex;

View File

@@ -36,17 +36,22 @@
#include "bookmarks_global.h"
#include <texteditor/texteditorconstants.h>
#include <texteditor/itexteditor.h>
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <QtCore/qplugin.h>
#include <QtCore/QDebug>
#include <QtGui/QMenu>
#include <QDebug>
using namespace Bookmarks::Constants;
using namespace Bookmarks::Internal;
using namespace TextEditor;
BookmarksPlugin *BookmarksPlugin::m_instance = 0;
@@ -159,6 +164,19 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
updateActions(m_bookmarkManager->state());
addAutoReleasedObject(new BookmarkViewFactory(m_bookmarkManager));
m_bookmarkMarginAction = new QAction(this);
m_bookmarkMarginAction->setText("Toggle Bookmark");
//m_bookmarkAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
connect(m_bookmarkMarginAction, SIGNAL(triggered()),
this, SLOT(bookmarkMarginActionTriggered()));
// EditorManager
QObject *editorManager = m_core->editorManager();
connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
this, SLOT(editorAboutToClose(Core::IEditor*)));
connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
this, SLOT(editorOpened(Core::IEditor*)));
return true;
}
@@ -169,7 +187,6 @@ BookmarksPlugin::~BookmarksPlugin()
void BookmarksPlugin::updateActions(int state)
{
const bool hasbm = state >= BookmarkManager::HasBookMarks;
const bool hasdocbm = state == BookmarkManager::HasBookmarksInDocument;
@@ -182,4 +199,32 @@ void BookmarksPlugin::updateActions(int state)
m_moveDownAction->setEnabled(hasbm);
}
void BookmarksPlugin::editorOpened(Core::IEditor *editor)
{
connect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
}
void BookmarksPlugin::editorAboutToClose(Core::IEditor *editor)
{
disconnect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
}
void BookmarksPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
int lineNumber, QMenu *menu)
{
m_bookmarkMarginActionLineNumber = lineNumber;
m_bookmarkMarginActionFileName = editor->file()->fileName();
menu->addAction(m_bookmarkMarginAction);
}
void BookmarksPlugin::bookmarkMarginActionTriggered()
{
m_bookmarkManager->toggleBookmark(
m_bookmarkMarginActionFileName,
m_bookmarkMarginActionLineNumber
);
}
Q_EXPORT_PLUGIN(BookmarksPlugin)

View File

@@ -31,18 +31,26 @@
**
***************************************************************************/
#ifndef BOOKMARKS_H
#define BOOKMARKS_H
#ifndef BOOKMARKSPLUGIN_H
#define BOOKMARKSPLUGIN_H
#include <extensionsystem/iplugin.h>
#include <QtCore/QObject>
#include <QtCore/QMultiMap>
#include <extensionsystem/iplugin.h>
QT_FORWARD_DECLARE_CLASS(QAction)
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
QT_END_NAMESPACE
namespace Core {
class ICore;
class IEditor;
}
namespace TextEditor {
class ITextEditor;
}
namespace Bookmarks {
@@ -67,6 +75,13 @@ public:
public slots:
void updateActions(int stateMask);
private slots:
void editorOpened(Core::IEditor *editor);
void editorAboutToClose(Core::IEditor *editor);
void requestContextMenu(TextEditor::ITextEditor *editor,
int lineNumber, QMenu *menu);
void bookmarkMarginActionTriggered();
private:
static BookmarksPlugin *m_instance;
BookmarkManager *m_bookmarkManager;
@@ -79,6 +94,10 @@ private:
QAction *m_docNextAction;
QAction *m_moveUpAction;
QAction *m_moveDownAction;
QAction *m_bookmarkMarginAction;
int m_bookmarkMarginActionLineNumber;
QString m_bookmarkMarginActionFileName;
};
} // namespace Internal

View File

@@ -34,6 +34,8 @@
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h"
#include "cmakestep.h"
#include "makestep.h"
#include <extensionsystem/pluginmanager.h>
#include <cpptools/cppmodelmanagerinterface.h>
@@ -62,11 +64,12 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
if (modelmanager) {
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
pinfo->includePaths = cbpparser.includeFiles();
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
pinfo.includePaths = cbpparser.includeFiles();
// TODO we only want C++ files, not all other stuff that might be in the project
pinfo->sourceFiles = m_files;
pinfo.sourceFiles = m_files;
// TODO defines
modelmanager->updateProjectInfo(pinfo);
}
} else {
// TODO report error
@@ -187,7 +190,7 @@ QString CMakeProject::buildDirectory(const QString &buildConfiguration) const
{
Q_UNUSED(buildConfiguration)
//TODO
return "";
return QFileInfo(m_fileName).absolutePath();
}
ProjectExplorer::BuildStepConfigWidget *CMakeProject::createConfigWidget()
@@ -224,13 +227,29 @@ QStringList CMakeProject::files(FilesMode fileMode) const
void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
{
// TODO
Q_UNUSED(writer)
Q_UNUSED(writer);
}
void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
{
// TODO
Q_UNUSED(reader)
Q_UNUSED(reader);
if (buildConfigurations().isEmpty()) {
// No build configuration, adding those
// TODO do we want to create one build configuration per target?
// or how do we want to handle that?
CMakeStep *cmakeStep = new CMakeStep(this);
MakeStep *makeStep = new MakeStep(this);
insertBuildStep(0, cmakeStep);
insertBuildStep(1, makeStep);
addBuildConfiguration("all");
setActiveBuildConfiguration("all");
}
// Restoring is fine
}
@@ -375,12 +394,36 @@ void CMakeCbpParser::parseBuild()
void CMakeCbpParser::parseTarget()
{
m_targetOutput.clear();
m_targetType = false;
while(!atEnd()) {
readNext();
if (isEndElement()) {
if (m_targetType && !m_targetOutput.isEmpty()) {
qDebug()<<"found target "<<m_targetOutput;
m_targets.insert(m_targetOutput);
}
return;
} else if (name() == "Compiler") {
parseCompiler();
} else if (name() == "Option") {
parseTargetOption();
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
void CMakeCbpParser::parseTargetOption()
{
if (attributes().hasAttribute("output"))
m_targetOutput = attributes().value("output").toString();
else if (attributes().hasAttribute("type") && attributes().value("type") == "1")
m_targetType = true;
while(!atEnd()) {
readNext();
if (isEndElement()) {
return;
} else if (name() == "Compiler") {
parseCompiler();
} else if (isStartElement()) {
parseUnknownElement();
}

View File

@@ -123,13 +123,18 @@ private:
void parseProject();
void parseBuild();
void parseTarget();
void parseTargetOption();
void parseCompiler();
void parseAdd();
void parseUnit();
void parseUnknownElement();
QSet<QString> m_targets;
QList<ProjectExplorer::FileNode *> m_fileList;
QStringList m_includeFiles;
QString m_targetOutput;
bool m_targetType;
};
class CMakeFile : public Core::IFile

View File

@@ -54,7 +54,7 @@ bool CMakeStep::init(const QString &buildConfiguration)
setEnabled(buildConfiguration, true);
setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
setCommand(buildConfiguration, "cmake"); // TODO give full path here?
setArguments(buildConfiguration, QStringList()); // TODO
setArguments(buildConfiguration, QStringList() << "-GUnix Makefiles"); // TODO
setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
return AbstractProcessStep::init(buildConfiguration);
}

View File

@@ -100,4 +100,4 @@ signals:
} // namespace Core
#endif //IEDITOR_H
#endif // IEDITOR_H

View File

@@ -63,7 +63,7 @@ ViewManager::ViewManager(MainWindow *mainWnd) :
ViewManagerInterface(mainWnd),
m_mainWnd(mainWnd)
{
for(int i = 0; i< 3; ++i) {
for (int i = 0; i < 3; ++i) {
QWidget *w = new QWidget();
m_mainWnd->statusBar()->insertPermanentWidget(i, w);
w->setLayout(new QHBoxLayout);
@@ -89,7 +89,7 @@ void ViewManager::init()
void ViewManager::objectAdded(QObject *obj)
{
IView * view = Aggregation::query<IView>(obj);
IView *view = Aggregation::query<IView>(obj);
if (!view)
return;
@@ -104,8 +104,8 @@ void ViewManager::objectAdded(QObject *obj)
void ViewManager::aboutToRemoveObject(QObject *obj)
{
IView * view = Aggregation::query<IView>(obj);
if(!view)
IView *view = Aggregation::query<IView>(obj);
if (!view)
return;
m_mainWnd->removeContextObject(view);
}
@@ -121,10 +121,10 @@ void ViewManager::saveSettings(QSettings *settings)
settings->setValue(QLatin1String("ViewGroup_Default"), m_mainWnd->saveState());
}
IView * ViewManager::view(const QString & id)
IView *ViewManager::view(const QString &id)
{
QList<IView *> list = m_mainWnd->pluginManager()->getObjects<IView>();
foreach (IView * view, list) {
foreach (IView *view, list) {
if (view->uniqueViewName() == id)
return view;
}

View File

@@ -1,4 +1,4 @@
<plugin name="CodePaster" version="0.1" compatVersion="0.1">
<plugin name="CodePaster" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>

View File

@@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
m_newClassWidget->setBaseClassEditable(true);
m_newClassWidget->setFormInputVisible(false);
m_newClassWidget->setNamespacesEnabled(true);
m_newClassWidget->setAllowDirectories(true);
connect(m_newClassWidget, SIGNAL(validChanged()),
this, SLOT(slotValidChanged()));

View File

@@ -79,6 +79,7 @@
#include <QtGui/QComboBox>
#include <QtGui/QTreeView>
#include <QtGui/QHeaderView>
#include <QtGui/QStringListModel>
using namespace CPlusPlus;
using namespace CppEditor::Internal;
@@ -344,11 +345,11 @@ void CPPEditor::updateMethodBoxIndex()
QModelIndex lastIndex;
const int rc = m_overviewModel->rowCount(QModelIndex());
const int rc = m_overviewModel->rowCount();
for (int row = 0; row < rc; ++row) {
const QModelIndex index = m_overviewModel->index(row, 0, QModelIndex());
Symbol *symbol = m_overviewModel->symbolFromIndex(index);
if (symbol->line() > unsigned(line))
if (symbol && symbol->line() > unsigned(line))
break;
lastIndex = index;
}

View File

@@ -42,6 +42,7 @@
QT_BEGIN_NAMESPACE
class QAction;
class QComboBox;
class QStringListModel;
QT_END_NAMESPACE
namespace Core {

View File

@@ -42,6 +42,7 @@ CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager
setIncludedByDefault(false);
search.setSymbolsToSearchFor(SearchSymbols::Classes);
search.setSeparateScope(true);
}
CppClassesFilter::~CppClassesFilter()

View File

@@ -699,7 +699,9 @@ void CppCodeCompletion::addMacros(const LookupContext &context)
continue;
processed.insert(fn);
if (Document::Ptr doc = context.document(fn)) {
macroNames += doc->macroNames();
foreach (const Macro macro, doc->definedMacros()) {
macroNames.insert(macro.name);
}
todo += doc->includedFiles();
}
}
@@ -1025,6 +1027,10 @@ bool CppCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem
void CppCodeCompletion::cleanup()
{
m_completions.clear();
// Set empty map in order to avoid referencing old versions of the documents
// until the next completion
typeOfExpression.setDocuments(QMap<QString, Document::Ptr>());
}
int CppCodeCompletion::findStartOfName(const TextEditor::ITextEditor *editor)

View File

@@ -31,8 +31,7 @@
**
***************************************************************************/
#define _SCL_SECURE_NO_WARNINGS 1
#include "pp.h"
#include <cplusplus/pp.h>
#include "cppmodelmanager.h"
#include "cpphoverhandler.h"
@@ -66,14 +65,14 @@
#include <Token.h>
#include <QPlainTextEdit>
#include <QMutexLocker>
#include <QTime>
#include <QDebug>
using namespace CppTools;
using namespace CppTools::Internal;
using namespace CPlusPlus;
namespace CppTools {
namespace Internal {
static const char pp_configuration_file[] = "<configuration>";
static const char pp_configuration[] =
@@ -105,299 +104,322 @@ static const char pp_configuration[] =
"#define __declspec(a)\n"
"#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n";
class CppPreprocessor: public rpp::Client
namespace CppTools {
namespace Internal {
class CppPreprocessor: public CPlusPlus::Client
{
public:
CppPreprocessor(QPointer<CppModelManager> modelManager)
: m_modelManager(modelManager),
m_documents(modelManager->documents()),
m_proc(this, env)
{ }
CppPreprocessor(QPointer<CppModelManager> modelManager);
void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
{ m_workingCopy = workingCopy; }
void setIncludePaths(const QStringList &includePaths)
{ m_includePaths = includePaths; }
void setFrameworkPaths(const QStringList &frameworkPaths)
{ m_frameworkPaths = frameworkPaths; }
void addIncludePath(const QString &path)
{ m_includePaths.append(path); }
void setProjectFiles(const QStringList &files)
{ m_projectFiles = files; }
void run(QString &fileName)
{ sourceNeeded(fileName, IncludeGlobal); }
void operator()(QString &fileName)
{ run(fileName); }
void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy);
void setIncludePaths(const QStringList &includePaths);
void setFrameworkPaths(const QStringList &frameworkPaths);
void setProjectFiles(const QStringList &files);
void run(QString &fileName);
void operator()(QString &fileName);
protected:
bool includeFile(const QString &absoluteFilePath, QByteArray *result)
{
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
return true;
}
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
if (m_workingCopy.contains(absoluteFilePath)) {
m_included.insert(absoluteFilePath);
*result = m_workingCopy.value(absoluteFilePath);
return true;
}
bool includeFile(const QString &absoluteFilePath, QByteArray *result);
QByteArray tryIncludeFile(QString &fileName, IncludeType type);
QFileInfo fileInfo(absoluteFilePath);
if (! fileInfo.isFile())
return false;
QFile file(absoluteFilePath);
if (file.open(QFile::ReadOnly)) {
m_included.insert(absoluteFilePath);
QTextStream stream(&file);
const QString contents = stream.readAll();
*result = contents.toUtf8();
file.close();
return true;
}
return false;
}
QByteArray tryIncludeFile(QString &fileName, IncludeType type)
{
QFileInfo fileInfo(fileName);
if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
QByteArray contents;
includeFile(fileName, &contents);
return contents;
}
if (type == IncludeLocal && m_currentDoc) {
QFileInfo currentFileInfo(m_currentDoc->fileName());
QString path = currentFileInfo.absolutePath();
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
foreach (const QString &includePath, m_includePaths) {
QString path = includePath;
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
// look in the system include paths
foreach (const QString &includePath, m_systemIncludePaths) {
QString path = includePath;
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
int index = fileName.indexOf(QLatin1Char('/'));
if (index != -1) {
QString frameworkName = fileName.left(index);
QString name = fileName.mid(index + 1);
foreach (const QString &frameworkPath, m_frameworkPaths) {
QString path = frameworkPath;
path += QLatin1Char('/');
path += frameworkName;
path += QLatin1String(".framework/Headers/");
path += name;
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
}
QString path = fileName;
if (path.at(0) != QLatin1Char('/'))
path.prepend(QLatin1Char('/'));
foreach (const QString &projectFile, m_projectFiles) {
if (projectFile.endsWith(path)) {
fileName = projectFile;
QByteArray contents;
includeFile(fileName, &contents);
return contents;
}
}
//qDebug() << "**** file" << fileName << "not found!";
return QByteArray();
}
virtual void macroAdded(const QByteArray &macroName, const QByteArray &macroText)
{
if (! m_currentDoc)
return;
m_currentDoc->appendMacro(macroName, macroText);
}
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed);
virtual void macroAdded(const Macro &macro);
virtual void startExpandingMacro(unsigned offset,
const rpp::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, const rpp::Macro &)
{
if (! m_currentDoc)
return;
//qDebug() << "stop expanding:" << macro.name;
}
void mergeEnvironment(Document::Ptr doc)
{
QSet<QString> processed;
mergeEnvironment(doc, &processed);
}
void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
{
if (! doc)
return;
const QString fn = doc->fileName();
if (processed->contains(fn))
return;
processed->insert(fn);
foreach (QString includedFile, doc->includedFiles())
mergeEnvironment(m_documents.value(includedFile), processed);
const QByteArray macros = doc->definedMacros();
QByteArray localFileName = doc->fileName().toUtf8();
QByteArray dummy;
m_proc(localFileName, macros, &dummy);
}
virtual void startSkippingBlocks(unsigned offset)
{
//qDebug() << "start skipping blocks:" << offset;
if (m_currentDoc)
m_currentDoc->startSkippingBlocks(offset);
}
virtual void stopSkippingBlocks(unsigned offset)
{
//qDebug() << "stop skipping blocks:" << offset;
if (m_currentDoc)
m_currentDoc->stopSkippingBlocks(offset);
}
virtual void sourceNeeded(QString &fileName, IncludeType type)
{
if (fileName.isEmpty())
return;
QByteArray contents = tryIncludeFile(fileName, type);
if (m_currentDoc) {
m_currentDoc->addIncludeFile(fileName);
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
QString msg;
msg += fileName;
msg += QLatin1String(": No such file or directory");
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
m_currentDoc->fileName(),
env.currentLine, /*column = */ 0,
msg);
m_currentDoc->addDiagnosticMessage(d);
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
}
}
if (! contents.isEmpty()) {
Document::Ptr cachedDoc = m_documents.value(fileName);
if (cachedDoc && m_currentDoc) {
mergeEnvironment(cachedDoc);
} else {
Document::Ptr previousDoc = switchDocument(Document::create(fileName));
const QByteArray previousFile = env.current_file;
const unsigned previousLine = env.currentLine;
env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
m_currentDoc->translationUnit()->fileNameLength());
QByteArray preprocessedCode;
m_proc(contents, &preprocessedCode);
//qDebug() << preprocessedCode;
env.current_file = previousFile;
env.currentLine = previousLine;
m_currentDoc->setSource(preprocessedCode);
m_currentDoc->parse();
m_currentDoc->check();
m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
if (m_modelManager)
m_modelManager->emitDocumentUpdated(m_currentDoc);
(void) switchDocument(previousDoc);
}
}
}
Document::Ptr switchDocument(Document::Ptr doc)
{
Document::Ptr previousDoc = m_currentDoc;
m_currentDoc = doc;
return previousDoc;
}
const Macro &macro,
const QByteArray &originalText);
virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
virtual void startSkippingBlocks(unsigned offset);
virtual void stopSkippingBlocks(unsigned offset);
virtual void sourceNeeded(QString &fileName, IncludeType type);
private:
QPointer<CppModelManager> m_modelManager;
CppModelManager::DocumentTable m_documents;
rpp::Environment env;
rpp::pp m_proc;
Environment env;
pp m_proc;
QStringList m_includePaths;
QStringList m_systemIncludePaths;
QMap<QString, QByteArray> m_workingCopy;
QStringList m_projectFiles;
QStringList m_frameworkPaths;
QSet<QString> m_included;
Document::Ptr m_currentDoc;
CPlusPlus::Document::Ptr m_currentDoc;
};
} // namespace Internal
} // namespace CppTools
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
: m_modelManager(modelManager),
m_documents(modelManager->documents()),
m_proc(this, env)
{ }
void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
{ m_workingCopy = workingCopy; }
void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
{ m_includePaths = includePaths; }
void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
{ m_frameworkPaths = frameworkPaths; }
void CppPreprocessor::setProjectFiles(const QStringList &files)
{ m_projectFiles = files; }
void CppPreprocessor::run(QString &fileName)
{ sourceNeeded(fileName, IncludeGlobal); }
void CppPreprocessor::operator()(QString &fileName)
{ run(fileName); }
bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result)
{
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
return true;
}
if (m_workingCopy.contains(absoluteFilePath)) {
m_included.insert(absoluteFilePath);
*result = m_workingCopy.value(absoluteFilePath);
return true;
}
QFileInfo fileInfo(absoluteFilePath);
if (! fileInfo.isFile())
return false;
QFile file(absoluteFilePath);
if (file.open(QFile::ReadOnly)) {
m_included.insert(absoluteFilePath);
QTextStream stream(&file);
const QString contents = stream.readAll();
*result = contents.toUtf8();
file.close();
return true;
}
return false;
}
QByteArray CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type)
{
QFileInfo fileInfo(fileName);
if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) {
QByteArray contents;
includeFile(fileName, &contents);
return contents;
}
if (type == IncludeLocal && m_currentDoc) {
QFileInfo currentFileInfo(m_currentDoc->fileName());
QString path = currentFileInfo.absolutePath();
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
foreach (const QString &includePath, m_includePaths) {
QString path = includePath;
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
// look in the system include paths
foreach (const QString &includePath, m_systemIncludePaths) {
QString path = includePath;
path += QLatin1Char('/');
path += fileName;
path = QDir::cleanPath(path);
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
int index = fileName.indexOf(QLatin1Char('/'));
if (index != -1) {
QString frameworkName = fileName.left(index);
QString name = fileName.mid(index + 1);
foreach (const QString &frameworkPath, m_frameworkPaths) {
QString path = frameworkPath;
path += QLatin1Char('/');
path += frameworkName;
path += QLatin1String(".framework/Headers/");
path += name;
QByteArray contents;
if (includeFile(path, &contents)) {
fileName = path;
return contents;
}
}
}
QString path = fileName;
if (path.at(0) != QLatin1Char('/'))
path.prepend(QLatin1Char('/'));
foreach (const QString &projectFile, m_projectFiles) {
if (projectFile.endsWith(path)) {
fileName = projectFile;
QByteArray contents;
includeFile(fileName, &contents);
return contents;
}
}
//qDebug() << "**** file" << fileName << "not found!";
return QByteArray();
}
void CppPreprocessor::macroAdded(const Macro &macro)
{
if (! m_currentDoc)
return;
m_currentDoc->appendMacro(macro);
}
void CppPreprocessor::startExpandingMacro(unsigned offset,
const Macro &,
const QByteArray &originalText)
{
if (! m_currentDoc)
return;
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
m_currentDoc->addMacroUse(offset, originalText.length());
}
void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
{
if (! m_currentDoc)
return;
//qDebug() << "stop expanding:" << macro.name;
}
void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
{
QSet<QString> processed;
mergeEnvironment(doc, &processed);
}
void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
{
if (! doc)
return;
const QString fn = doc->fileName();
if (processed->contains(fn))
return;
processed->insert(fn);
foreach (QString includedFile, doc->includedFiles()) {
mergeEnvironment(m_documents.value(includedFile), processed);
}
foreach (const Macro macro, doc->definedMacros()) {
env.bind(macro);
}
}
void CppPreprocessor::startSkippingBlocks(unsigned offset)
{
//qDebug() << "start skipping blocks:" << offset;
if (m_currentDoc)
m_currentDoc->startSkippingBlocks(offset);
}
void CppPreprocessor::stopSkippingBlocks(unsigned offset)
{
//qDebug() << "stop skipping blocks:" << offset;
if (m_currentDoc)
m_currentDoc->stopSkippingBlocks(offset);
}
void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type)
{
if (fileName.isEmpty())
return;
QByteArray contents = tryIncludeFile(fileName, type);
if (m_currentDoc) {
m_currentDoc->addIncludeFile(fileName);
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
QString msg;
msg += fileName;
msg += QLatin1String(": No such file or directory");
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
m_currentDoc->fileName(),
env.currentLine, /*column = */ 0,
msg);
m_currentDoc->addDiagnosticMessage(d);
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
}
}
if (! contents.isEmpty()) {
Document::Ptr cachedDoc = m_documents.value(fileName);
if (cachedDoc && m_currentDoc) {
mergeEnvironment(cachedDoc);
} else {
Document::Ptr previousDoc = switchDocument(Document::create(fileName));
const QByteArray previousFile = env.current_file;
const unsigned previousLine = env.currentLine;
env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
m_currentDoc->translationUnit()->fileNameLength());
QByteArray preprocessedCode;
m_proc(contents, &preprocessedCode);
//qDebug() << preprocessedCode;
env.current_file = previousFile;
env.currentLine = previousLine;
m_currentDoc->setSource(preprocessedCode);
m_currentDoc->parse();
m_currentDoc->check();
m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
if (m_modelManager)
m_modelManager->emitDocumentUpdated(m_currentDoc);
(void) switchDocument(previousDoc);
}
}
}
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
{
Document::Ptr previousDoc = m_currentDoc;
m_currentDoc = doc;
return previousDoc;
}
using namespace CppTools;
using namespace CppTools::Internal;
/*!
\class CppTools::CppModelManager
@@ -450,13 +472,26 @@ CppModelManager::CppModelManager(QObject *parent) :
CppModelManager::~CppModelManager()
{ }
Document::Ptr CppModelManager::document(const QString &fileName)
Document::Ptr CppModelManager::document(const QString &fileName) const
{ return m_documents.value(fileName); }
CppModelManager::DocumentTable CppModelManager::documents()
CppModelManager::DocumentTable CppModelManager::documents() const
{ return m_documents; }
QStringList CppModelManager::updateProjectFiles() const
void CppModelManager::ensureUpdated()
{
QMutexLocker locker(&mutex);
if (! m_dirty)
return;
m_projectFiles = internalProjectFiles();
m_includePaths = internalIncludePaths();
m_frameworkPaths = internalFrameworkPaths();
m_definedMacros = internalDefinedMacros();
m_dirty = false;
}
QStringList CppModelManager::internalProjectFiles() const
{
QStringList files;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -465,10 +500,11 @@ QStringList CppModelManager::updateProjectFiles() const
ProjectInfo pinfo = it.value();
files += pinfo.sourceFiles;
}
files.removeDuplicates();
return files;
}
QStringList CppModelManager::updateIncludePaths() const
QStringList CppModelManager::internalIncludePaths() const
{
QStringList includePaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -477,10 +513,11 @@ QStringList CppModelManager::updateIncludePaths() const
ProjectInfo pinfo = it.value();
includePaths += pinfo.includePaths;
}
includePaths.removeDuplicates();
return includePaths;
}
QStringList CppModelManager::updateFrameworkPaths() const
QStringList CppModelManager::internalFrameworkPaths() const
{
QStringList frameworkPaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -489,10 +526,11 @@ QStringList CppModelManager::updateFrameworkPaths() const
ProjectInfo pinfo = it.value();
frameworkPaths += pinfo.frameworkPaths;
}
frameworkPaths.removeDuplicates();
return frameworkPaths;
}
QByteArray CppModelManager::updateDefinedMacros() const
QByteArray CppModelManager::internalDefinedMacros() const
{
QByteArray macros;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -527,8 +565,30 @@ QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
void CppModelManager::updateSourceFiles(const QStringList &sourceFiles)
{ (void) refreshSourceFiles(sourceFiles); }
CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Project *project)
{ return &m_projects[project]; }
QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const
{
QMutexLocker locker(&mutex);
return m_projects.values();
}
CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const
{
QMutexLocker locker(&mutex);
return m_projects.value(project, ProjectInfo(project));
}
void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
{
QMutexLocker locker(&mutex);
if (! pinfo.isValid())
return;
m_projects.insert(pinfo.project, pinfo);
m_dirty = true;
}
QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
{
@@ -683,7 +743,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
sel.cursor = c;
selections.append(sel);
}
ed->setExtraExtraSelections(selections);
ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections);
break;
}
}
@@ -691,13 +751,18 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
{
QMutexLocker locker(&mutex);
m_dirty = true;
}
void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
m_dirty = true;
m_projects.remove(project);
do {
QMutexLocker locker(&mutex);
m_dirty = true;
m_projects.remove(project);
} while (0);
GC();
}
@@ -705,8 +770,15 @@ void CppModelManager::onSessionUnloaded()
{
if (m_core->progressManager()) {
m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
m_dirty = true;
}
do {
QMutexLocker locker(&mutex);
m_projects.clear();
m_dirty = true;
} while (0);
GC();
}
void CppModelManager::parse(QFutureInterface<void> &future,

View File

@@ -40,6 +40,7 @@
#include <QMap>
#include <QFutureInterface>
#include <QMutex>
namespace Core {
class ICore;
@@ -70,9 +71,13 @@ public:
virtual ~CppModelManager();
virtual void updateSourceFiles(const QStringList &sourceFiles);
virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project);
virtual CPlusPlus::Document::Ptr document(const QString &fileName);
virtual DocumentTable documents();
virtual QList<ProjectInfo> projectInfos() const;
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
virtual void updateProjectInfo(const ProjectInfo &pinfo);
virtual CPlusPlus::Document::Ptr document(const QString &fileName) const;
virtual DocumentTable documents() const;
virtual void GC();
QFuture<void> refreshSourceFiles(const QStringList &sourceFiles);
@@ -127,21 +132,11 @@ private:
return m_definedMacros;
}
QStringList updateProjectFiles() const;
QStringList updateIncludePaths() const;
QStringList updateFrameworkPaths() const;
QByteArray updateDefinedMacros() const;
void ensureUpdated() {
if (! m_dirty)
return;
m_projectFiles = updateProjectFiles();
m_includePaths = updateIncludePaths();
m_frameworkPaths = updateFrameworkPaths();
m_definedMacros = updateDefinedMacros();
m_dirty = false;
}
void ensureUpdated();
QStringList internalProjectFiles() const;
QStringList internalIncludePaths() const;
QStringList internalFrameworkPaths() const;
QByteArray internalDefinedMacros() const;
static void parse(QFutureInterface<void> &future,
CppPreprocessor *preproc,
@@ -166,6 +161,8 @@ private:
// project integration
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
mutable QMutex mutex;
enum {
MAX_SELECTION_COUNT = 5
};

View File

@@ -38,6 +38,7 @@
#include <cplusplus/CppDocument.h>
#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QtCore/QPointer>
namespace ProjectExplorer {
class Project;
@@ -51,10 +52,29 @@ class CPPTOOLS_EXPORT CppModelManagerInterface
Q_OBJECT
public:
typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable;
typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable; // ### remove me
struct ProjectInfo
class ProjectInfo
{
public:
ProjectInfo()
{ }
ProjectInfo(QPointer<ProjectExplorer::Project> project)
: project(project)
{ }
operator bool() const
{ return ! project.isNull(); }
bool isValid() const
{ return ! project.isNull(); }
bool isNull() const
{ return project.isNull(); }
public: // attributes
QPointer<ProjectExplorer::Project> project;
QString projectPath;
QByteArray defines;
QStringList sourceFiles;
@@ -69,10 +89,12 @@ public:
virtual void GC() = 0;
virtual void updateSourceFiles(const QStringList &sourceFiles) = 0;
virtual CPlusPlus::Document::Ptr document(const QString &fileName) = 0;
virtual DocumentTable documents() = 0;
virtual CPlusPlus::Document::Ptr document(const QString &fileName) const = 0;
virtual DocumentTable documents() const = 0;
virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project) = 0;
virtual QList<ProjectInfo> projectInfos() const = 0;
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;
virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0;
};
} // namespace CppTools

View File

@@ -10,7 +10,7 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O3
INCLUDEPATH += .
DEFINES += CPPTOOLS_LIBRARY
CONFIG += help
include(rpp/rpp.pri)|error("Can't find RPP")
HEADERS += cpptools_global.h \
cppquickopenfilter.h \
cppclassesfilter.h \

View File

@@ -1,18 +0,0 @@
DEPENDPATH += $$PWD
INCLUDEPATH += $$PWD
HEADERS += $$PWD/pp-cctype.h \
$$PWD/pp-engine.h \
$$PWD/pp-environment.h \
$$PWD/pp-internal.h \
$$PWD/pp-macro-expander.h \
$$PWD/pp-macro.h \
$$PWD/pp-scanner.h \
$$PWD/pp.h \
$$PWD/pp-client.h
SOURCES += $$PWD/pp-engine.cpp \
$$PWD/pp-environment.cpp \
$$PWD/pp-macro-expander.cpp

View File

@@ -40,7 +40,8 @@ using namespace CPlusPlus;
using namespace CppTools::Internal;
SearchSymbols::SearchSymbols():
symbolsToSearchFor(Classes | Functions | Enums)
symbolsToSearchFor(Classes | Functions | Enums),
separateScope(false)
{
}
@@ -49,6 +50,11 @@ void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types)
symbolsToSearchFor = types;
}
void SearchSymbols::setSeparateScope(bool separateScope)
{
this->separateScope = separateScope;
}
QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
{
QString previousScope = switchScope(scope);
@@ -73,13 +79,12 @@ bool SearchSymbols::visit(Enum *symbol)
return false;
QString name = symbolName(symbol);
QString previousScope = switchScope(name);
QIcon icon = icons.iconForSymbol(symbol);
QString scopedName = scopedSymbolName(name);
QString previousScope = switchScope(scopedName);
appendItem(separateScope ? name : scopedName,
separateScope ? previousScope : QString(),
ModelItemInfo::Enum, symbol);
Scope *members = symbol->members();
items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
@@ -93,18 +98,18 @@ bool SearchSymbols::visit(Function *symbol)
return false;
QString name = symbolName(symbol);
QString type = overview.prettyType(symbol->type());
QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
QString scopedName = scopedSymbolName(name);
QString type = overview.prettyType(symbol->type(),
separateScope ? symbol->name() : 0);
appendItem(separateScope ? type : scopedName,
separateScope ? _scope : type,
ModelItemInfo::Method, symbol);
return false;
}
bool SearchSymbols::visit(Namespace *symbol)
{
QString name = symbolName(symbol);
QString name = findOrInsert(scopedSymbolName(symbol));
QString previousScope = switchScope(name);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
@@ -118,12 +123,9 @@ bool SearchSymbols::visit(Namespace *symbol)
bool SearchSymbols::visit(Declaration *symbol)
{
if (symbol->type()->isFunction()) {
QString name = symbolName(symbol);
QString name = scopedSymbolName(symbol);
QString type = overview.prettyType(symbol->type());
//QIcon icon = ...;
items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
QString::fromUtf8(symbol->fileName(), symbol->line()),
symbol->line()));
appendItems(name, type, ModelItemInfo::Method, symbol->fileName());
}
return false;
}
@@ -135,12 +137,11 @@ bool SearchSymbols::visit(Class *symbol)
return false;
QString name = symbolName(symbol);
QString previousScope = switchScope(name);
QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
QString scopedName = scopedSymbolName(name);
QString previousScope = switchScope(scopedName);
appendItem(separateScope ? name : scopedName,
separateScope ? previousScope : QString(),
ModelItemInfo::Class, symbol);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
@@ -149,11 +150,22 @@ bool SearchSymbols::visit(Class *symbol)
return false;
}
QString SearchSymbols::symbolName(const Symbol *symbol) const
QString SearchSymbols::scopedSymbolName(const QString &symbolName) const
{
QString name = _scope;
if (! name.isEmpty())
name += QLatin1String("::");
name += symbolName;
return name;
}
QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const
{
return scopedSymbolName(symbolName(symbol));
}
QString SearchSymbols::symbolName(const Symbol *symbol) const
{
QString symbolName = overview.prettyName(symbol->name());
if (symbolName.isEmpty()) {
QString type;
@@ -176,6 +188,17 @@ QString SearchSymbols::symbolName(const Symbol *symbol) const
symbolName += type;
symbolName += QLatin1String(">");
}
name += symbolName;
return name;
return symbolName;
}
void SearchSymbols::appendItem(const QString &name,
const QString &info,
ModelItemInfo::ItemType type,
const Symbol *symbol)
{
const QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, info, type,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
}

View File

@@ -44,6 +44,8 @@
#include <QMetaType>
#include <QString>
#include <functional>
namespace CppTools {
namespace Internal {
@@ -90,6 +92,7 @@ public:
SearchSymbols();
void setSymbolsToSearchFor(SymbolTypes types);
void setSeparateScope(bool separateScope);
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc)
{ return operator()(doc, QString()); }
@@ -111,14 +114,27 @@ protected:
virtual bool visit(CPlusPlus::Declaration *symbol);
#endif
virtual bool visit(CPlusPlus::Class *symbol);
QString scopedSymbolName(const QString &symbolName) const;
QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const;
QString symbolName(const CPlusPlus::Symbol *symbol) const;
void appendItem(const QString &name,
const QString &info,
ModelItemInfo::ItemType type,
const CPlusPlus::Symbol *symbol);
private:
QString findOrInsert(const QString &s)
{ return *strings.insert(s); }
QSet<QString> strings; // Used to avoid QString duplication
QString _scope;
CPlusPlus::Overview overview;
CPlusPlus::Icons icons;
QList<ModelItemInfo> items;
SymbolTypes symbolsToSearchFor;
bool separateScope;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes)

View File

@@ -62,6 +62,7 @@
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QTime>
#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QComboBox>
@@ -145,6 +146,7 @@ void DebuggerManager::init()
m_modulesHandler = 0;
m_registerHandler = 0;
m_statusLabel = new QLabel;
m_breakWindow = new BreakWindow;
m_disassemblerWindow = new DisassemblerWindow;
m_modulesWindow = new ModulesWindow;
@@ -157,6 +159,7 @@ void DebuggerManager::init()
//m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType);
//m_watchersWindow = new QTreeView;
m_tooltipWindow = new QTreeView;
m_statusTimer = new QTimer(this);
m_mainWindow = new QMainWindow;
m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
@@ -408,6 +411,8 @@ void DebuggerManager::init()
this, SLOT(saveSessionData()));
connect(m_dumpLogAction, SIGNAL(triggered()),
this, SLOT(dumpLog()));
connect(m_statusTimer, SIGNAL(timeout()),
this, SLOT(clearStatusMessage()));
connect(m_outputWindow, SIGNAL(commandExecutionRequested(QString)),
this, SLOT(executeDebuggerCommand(QString)));
@@ -553,24 +558,24 @@ QAbstractItemModel *DebuggerManager::threadsModel()
return qobject_cast<ThreadsWindow*>(m_threadsWindow)->model();
}
void DebuggerManager::clearStatusMessage()
{
m_statusLabel->setText(m_lastPermanentStatusMessage);
}
void DebuggerManager::showStatusMessage(const QString &msg, int timeout)
{
Q_UNUSED(timeout)
//qDebug() << "STATUS: " << msg;
showDebuggerOutput("status:", msg);
mainWindow()->statusBar()->showMessage(msg, timeout);
#if 0
QString currentTime = QTime::currentTime().toString("hh:mm:ss.zzz");
ICore *core = m_pm->getObject<Core::ICore>();
//qDebug() << qPrintable(currentTime) << "Setting status: " << msg;
if (msg.isEmpty())
core->messageManager()->displayStatusBarMessage(msg);
else if (timeout == -1)
core->messageManager()->displayStatusBarMessage(tr("Debugger: ") + msg);
else
core->messageManager()->displayStatusBarMessage(tr("Debugger: ") + msg, timeout);
#endif
m_statusLabel->setText(" " + msg);
if (timeout > 0) {
m_statusTimer->setSingleShot(true);
m_statusTimer->start(timeout);
} else {
m_lastPermanentStatusMessage = msg;
m_statusTimer->stop();
}
}
void DebuggerManager::notifyStartupFinished()

View File

@@ -44,9 +44,11 @@ QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
class QDockWidget;
class QLabel;
class QMainWindow;
class QModelIndex;
class QSplitter;
class QTimer;
class QWidget;
QT_END_NAMESPACE
@@ -190,7 +192,8 @@ public:
private:
friend class DebugMode;
virtual QWidget *threadsWindow() = 0;
virtual QWidget *threadsWindow() const = 0;
virtual QLabel *statusLabel() const = 0;
virtual QList<QDockWidget*> dockWidgets() const = 0;
virtual void createDockWidgets() = 0;
};
@@ -213,6 +216,7 @@ public:
IDebuggerManagerAccessForEngines *engineInterface();
IDebuggerManagerAccessForDebugMode *debugModeInterface();
QMainWindow *mainWindow() const { return m_mainWindow; }
QLabel *statusLabel() const { return m_statusLabel; }
enum StartMode { startInternal, startExternal, attachExternal };
enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
@@ -272,7 +276,7 @@ public slots:
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString &command);
void showStatusMessage(const QString &msg, int timeout); // -1 forever
void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
private slots:
void showDebuggerOutput(const QString &prefix, const QString &msg);
@@ -290,6 +294,7 @@ private slots:
void reloadRegisters();
void registerDockToggled(bool on);
void setStatus(int status);
void clearStatusMessage();
private:
//
@@ -322,7 +327,7 @@ private:
//
// Implementation of IDebuggerManagerAccessForDebugMode
//
QWidget *threadsWindow() { return m_threadsWindow; }
QWidget *threadsWindow() const { return m_threadsWindow; }
QList<QDockWidget*> dockWidgets() const { return m_dockWidgets; }
void createDockWidgets();
@@ -382,6 +387,7 @@ private:
/// Views
QMainWindow *m_mainWindow;
QLabel *m_statusLabel;
QDockWidget *m_breakDock;
QDockWidget *m_disassemblerDock;
QDockWidget *m_modulesDock;
@@ -440,6 +446,8 @@ private:
int m_status;
bool m_busy;
QTimer *m_statusTimer;
QString m_lastPermanentStatusMessage;
IDebuggerEngine *engine();
IDebuggerEngine *m_engine;

View File

@@ -285,6 +285,7 @@ void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &outp
void DebuggerOutputWindow::showInput(const QString &prefix, const QString &input)
{
Q_UNUSED(prefix);
m_inputText->append(input);
QTextCursor cursor = m_inputText->textCursor();
cursor.movePosition(QTextCursor::End);

View File

@@ -250,6 +250,12 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes
m_gdbRunningContext = uidm->uniqueIdentifier(Constants::GDBRUNNING);
m_breakpointMarginAction = new QAction(this);
m_breakpointMarginAction->setText("Toggle Breakpoint");
//m_breakpointMarginAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
connect(m_breakpointMarginAction, SIGNAL(triggered()),
this, SLOT(breakpointMarginActionTriggered()));
//Core::IActionContainer *mcppcontext =
// actionManager->actionContainer(CppEditor::Constants::M_CONTEXT);
@@ -502,6 +508,8 @@ void DebuggerPlugin::editorOpened(Core::IEditor *editor)
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
connect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
connect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
}
}
@@ -512,9 +520,27 @@ void DebuggerPlugin::editorAboutToClose(Core::IEditor *editor)
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
disconnect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
disconnect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
}
}
void DebuggerPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
int lineNumber, QMenu *menu)
{
m_breakpointMarginActionLineNumber = lineNumber;
m_breakpointMarginActionFileName = editor->file()->fileName();
menu->addAction(m_breakpointMarginAction);
}
void DebuggerPlugin::breakpointMarginActionTriggered()
{
m_manager->toggleBreakpoint(
m_breakpointMarginActionFileName,
m_breakpointMarginActionLineNumber
);
}
void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber)
{
m_manager->toggleBreakpoint(editor->file()->fileName(), lineNumber);

View File

@@ -84,10 +84,14 @@ private slots:
void setSessionValue(const QString &name, const QVariant &value);
void queryConfigValue(const QString &name, QVariant *value);
void setConfigValue(const QString &name, const QVariant &value);
void requestContextMenu(TextEditor::ITextEditor *editor,
int lineNumber, QMenu *menu);
void resetLocation();
void gotoLocation(const QString &fileName, int line, bool setMarker);
void breakpointMarginActionTriggered();
private:
friend class DebuggerManager;
friend class DebugMode; // FIXME: Just a hack now so that it can access the views
@@ -104,6 +108,10 @@ private:
QString m_previousMode;
LocationMark *m_locationMark;
int m_gdbRunningContext;
QAction *m_breakpointMarginAction;
int m_breakpointMarginActionLineNumber;
QString m_breakpointMarginActionFileName;
};
} // namespace Internal

View File

@@ -347,7 +347,7 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
"This is the default return value of error().");
}
q->showStatusMessage(msg, 5000);
q->showStatusMessage(msg);
QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
// act as if it was closed by the core
q->exitDebugger();
@@ -442,7 +442,8 @@ void GdbEngine::handleResponse()
break;
}
if (token == -1 && *from != '&' && *from != '~' && *from != '*') {
if (token == -1 && *from != '&' && *from != '~' && *from != '*'
&& *from != '=') {
// FIXME: On Linux the application's std::out is merged in here.
// High risk of falsely interpreting this as MI output.
// We assume that we _always_ use tokens, so not finding a token
@@ -470,7 +471,7 @@ void GdbEngine::handleResponse()
for (; from != to; ++from) {
const char c = *from;
if (!isNameChar(c))
break;
break;
asyncClass += *from;
}
//qDebug() << "ASYNCCLASS" << asyncClass;
@@ -710,7 +711,7 @@ void GdbEngine::sendCommand(const QString &command, int type,
bool temporarilyStopped = false;
if (needStop && q->status() == DebuggerInferiorRunning) {
q->showStatusMessage(tr("Temporarily stopped"), -1);
q->showStatusMessage(tr("Temporarily stopped"));
interruptInferior();
temporarilyStopped = true;
}
@@ -1055,7 +1056,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
// ~"242\t x *= 2;"
//109^done"
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Jumped. Stopped."), -1);
q->showStatusMessage(tr("Jumped. Stopped."));
QString output = record.data.findChild("logstreamoutput").data();
if (!output.isEmpty())
return;
@@ -1074,7 +1075,7 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record)
// func="foo",args=[{name="str",value="@0x7fff0f450460"}],
// file="main.cpp",fullname="/tmp/g/main.cpp",line="37"}
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Run to Function finished. Stopped."), -1);
q->showStatusMessage(tr("Run to Function finished. Stopped."));
GdbMi frame = record.data.findChild("frame");
QString file = frame.findChild("fullname").data();
int line = frame.findChild("line").data().toInt();
@@ -1212,7 +1213,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
}
} else {
// slow start requested.
q->showStatusMessage("Loading " + data.toString(), -1);
q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
continueInferior();
}
return;
@@ -1231,7 +1232,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
msg = "Program exited after receiving signal "
+ data.findChild("signal-name").toString();
}
q->showStatusMessage(msg, -1);
q->showStatusMessage(msg);
q->exitDebugger();
return;
}
@@ -1271,17 +1272,19 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
if (isStoppedReason(reason) || reason.isEmpty()) {
// Need another round trip
if (reason == "breakpoint-hit") {
q->showStatusMessage(tr("Stopped at breakpoint"));
GdbMi frame = data.findChild("frame");
//qDebug() << frame.toString();
m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%';
QApplication::alert(q->mainWindow(), 200);
QApplication::alert(q->mainWindow(), 3000);
sendCommand("-file-list-exec-source-files", GdbQuerySources);
sendCommand("-break-list", BreakList);
QVariant var = QVariant::fromValue<GdbMi>(data);
sendCommand("p 0", GdbAsyncOutput2, var); // dummy
} else {
q->showStatusMessage(tr("Stopped: \"%1\"").arg(reason));
handleAsyncOutput2(data);
}
return;
@@ -1303,7 +1306,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
// system="0.00136",start="1218810678.805432",end="1218810678.812011"}
q->resetLocation();
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Run to Function finished. Stopped."), -1);
q->showStatusMessage(tr("Run to Function finished. Stopped."));
GdbMi frame = data.findChild("frame");
QString file = frame.findChild("fullname").data();
int line = frame.findChild("line").data().toInt();
@@ -1376,8 +1379,9 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
if (response.resultClass == GdbResultDone) {
m_gdbVersion = 100;
QString msg = response.data.findChild("consolestreamoutput").data();
QRegExp supported("GNU gdb 6.[6789]");
if (msg.indexOf(supported) == -1) {
QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)\\.(\\d+)");
if (supported.indexIn(msg) == -1) {
qDebug() << "UNSUPPORTED GDB VERSION " << msg;
QStringList list = msg.split("\n");
while (list.size() > 2)
list.removeLast();
@@ -1394,11 +1398,11 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
#else
//QMessageBox::information(m_mainWindow, tr("Warning"), msg);
#endif
}
int pos = msg.indexOf("GNU gdb 6.");
if (pos != -1) {
m_gdbVersion = 600 + (msg.at(pos + 10).unicode() - '0') * 10;
//qDebug() << "GDB VERSION " << m_gdbVersion << msg;
} else {
m_gdbVersion = 10000 * supported.cap(2).toInt()
+ 100 * supported.cap(3).toInt()
+ 1 * supported.cap(4).toInt();
//qDebug() << "GDB VERSION " << m_gdbVersion;
}
}
}
@@ -1421,14 +1425,14 @@ void GdbEngine::handleExecRun(const GdbResultRecord &response)
{
if (response.resultClass == GdbResultRunning) {
qq->notifyInferiorRunning();
q->showStatusMessage(tr("Running..."), -1);
q->showStatusMessage(tr("Running..."));
//reloadModules();
} else if (response.resultClass == GdbResultError) {
QString msg = response.data.findChild("msg").data();
if (msg == "Cannot find bounds of current function") {
qq->notifyInferiorStopped();
//q->showStatusMessage(tr("No debug information available. "
// "Leaving function..."), -1);
// "Leaving function..."));
//stepOutExec();
} else {
QMessageBox::critical(q->mainWindow(), tr("Error"),
@@ -1556,7 +1560,7 @@ bool GdbEngine::startDebugger()
qDebug() << "ExeFile: " << q->m_executable;
#endif
q->showStatusMessage("Starting Debugger", -1);
q->showStatusMessage(tr("Starting Debugger"));
emit gdbInputAvailable(QString(), theGdbSettings().m_gdbCmd + ' ' + gdbArgs.join(" "));
m_gdbProc.start(theGdbSettings().m_gdbCmd, gdbArgs);
@@ -1565,7 +1569,7 @@ bool GdbEngine::startDebugger()
if (m_gdbProc.state() != QProcess::Running)
return false;
q->showStatusMessage(tr("Gdb Running"), -1);
q->showStatusMessage(tr("Gdb Running"));
sendCommand("show version", GdbShowVersion);
if (qq->useFastStart()) {
@@ -2335,8 +2339,8 @@ void GdbEngine::handleModulesList(const GdbResultRecord &record)
void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
{
Q_UNUSED(record);
qDebug("FIXME: StackHandler::handleOutput: SelectThread");
q->showStatusMessage(tr("Retrieving data for stack view..."), -1);
//qDebug("FIXME: StackHandler::handleOutput: SelectThread");
q->showStatusMessage(tr("Retrieving data for stack view..."), 3000);
sendCommand("-stack-list-frames", StackListFrames);
}
@@ -2430,7 +2434,7 @@ void GdbEngine::selectThread(int index)
QList<ThreadData> threads = threadsHandler->threads();
QWB_ASSERT(index < threads.size(), return);
int id = threads.at(index).id;
q->showStatusMessage(tr("Retrieving data for stack view..."), -1);
q->showStatusMessage(tr("Retrieving data for stack view..."), 10000);
sendCommand(QLatin1String("-thread-select ") + QString::number(id),
StackSelectThread);
}
@@ -2543,7 +2547,7 @@ bool GdbEngine::supportsThreads() const
{
// 6.3 crashes happily on -thread-list-ids. So don't use it.
// The test below is a semi-random pick, 6.8 works fine
return m_gdbVersion > 650;
return m_gdbVersion > 60500;
}
//////////////////////////////////////////////////////////////////////
@@ -3079,7 +3083,7 @@ void GdbEngine::runCustomDumper(const WatchData & data0, bool dumpChildren)
q->showStatusMessage(
tr("Retrieving data for watch view (%1 requests pending)...")
.arg(m_pendingRequests + 1), -1);
.arg(m_pendingRequests + 1), 10000);
// create response slot for socket data
QVariant var;
var.setValue(data);
@@ -3297,7 +3301,7 @@ void GdbEngine::updateWatchModel2()
PENDING_DEBUG("REBUILDING MODEL")
emit gdbInputAvailable(QString(),
"[" + currentTime() + "] <Rebuild Watchmodel>");
q->showStatusMessage(tr("Finished retrieving data."), -1);
q->showStatusMessage(tr("Finished retrieving data."), 400);
qq->watchHandler()->rebuildModel();
if (!m_toolTipExpression.isEmpty()) {
@@ -3311,9 +3315,6 @@ void GdbEngine::updateWatchModel2()
"Cannot evaluate expression: " + m_toolTipExpression);
}
}
//qDebug() << "INSERT DATA" << data0.toString();
//q->showStatusMessage(tr("Stopped."), 5000);
}
void GdbEngine::handleQueryDataDumper1(const GdbResultRecord &record)
@@ -3895,7 +3896,7 @@ void GdbEngine::handleToolTip(const GdbResultRecord &record,
if (isCustomValueDumperAvailable(m_toolTip.type))
runCustomDumper(m_toolTip, false);
else
q->showStatusMessage(tr("Retrieving data for tooltip..."), -1);
q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000);
sendCommand("-data-evaluate-expression " + m_toolTip.exp,
WatchToolTip, "evaluate");
//sendToolTipCommand("-var-evaluate-expression tooltip")
@@ -3970,7 +3971,7 @@ void GdbEngine::tryLoadCustomDumpers()
if (qq->useFastStart())
sendCommand("set stop-on-solib-events 0");
QString flag = QString::number(RTLD_NOW);
sendCommand("call dlopen(\"" + lib + "\", " + flag + ")");
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")");
sendCommand("sharedlibrary " + dotEscape(lib));
if (qq->useFastStart())
sendCommand("set stop-on-solib-events 1");

View File

@@ -169,6 +169,8 @@ QToolBar *DebugMode::createToolBar()
managerAccess->threadsWindow(), SIGNAL(threadSelected(int)));
debugToolBar->addWidget(threadBox);
debugToolBar->addWidget(managerAccess->statusLabel());
QWidget *stretch = new QWidget;
stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
debugToolBar->addWidget(stretch);

View File

@@ -320,6 +320,51 @@ static WatchData take(const QString &iname, QList<WatchData> *list)
}
static QList<WatchData> initialSet()
{
QList<WatchData> result;
WatchData root;
root.state = 0;
root.level = 0;
root.row = 0;
root.name = "Root";
root.parentIndex = -1;
root.childIndex.append(1);
root.childIndex.append(2);
root.childIndex.append(3);
result.append(root);
WatchData local;
local.iname = "local";
local.name = "Locals";
local.state = 0;
local.level = 1;
local.row = 0;
local.parentIndex = 0;
result.append(local);
WatchData tooltip;
tooltip.iname = "tooltip";
tooltip.name = "Tooltip";
tooltip.state = 0;
tooltip.level = 1;
tooltip.row = 1;
tooltip.parentIndex = 0;
result.append(tooltip);
WatchData watch;
watch.iname = "watch";
watch.name = "Watchers";
watch.state = 0;
watch.level = 1;
watch.row = 2;
watch.parentIndex = 0;
result.append(watch);
return result;
}
///////////////////////////////////////////////////////////////////////
//
// WatchHandler
@@ -332,7 +377,8 @@ WatchHandler::WatchHandler()
m_inFetchMore = false;
m_inChange = false;
cleanModel();
m_completeSet = initialSet();
m_incompleteSet.clear();
m_displaySet = m_completeSet;
}
@@ -380,6 +426,7 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
int node = idx.internalId();
if (node < 0)
return QVariant();
QWB_ASSERT(node < m_displaySet.size(), return QVariant());
const WatchData &data = m_displaySet.at(node);
@@ -441,6 +488,13 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
case VisualRole:
return m_displayedINames.contains(data.iname);
case ExpandedRole:
//qDebug() << " FETCHING: " << data.iname
// << m_expandedINames.contains(data.iname)
// << m_expandedINames;
// Level 0 and 1 are always expanded
return node < 4 || m_expandedINames.contains(data.iname);
default:
break;
}
@@ -558,10 +612,13 @@ void WatchHandler::rebuildModel()
MODEL_DEBUG("RECREATE MODEL, CURRENT SET:\n" << toString());
#endif
QHash<QString, int> oldTopINames;
QHash<QString, QString> oldValues;
for (int i = 0, n = m_oldSet.size(); i != n; ++i) {
WatchData &data = m_oldSet[i];
oldValues[data.iname] = data.value;
if (data.level == 2)
++oldTopINames[data.iname];
}
#ifdef DEBUG_PENDING
MODEL_DEBUG("OLD VALUES: " << oldValues);
@@ -575,6 +632,9 @@ void WatchHandler::rebuildModel()
qSort(m_completeSet.begin(), m_completeSet.end(), &iNameSorter);
// This helps to decide whether the view has completely changed or not.
QHash<QString, int> topINames;
QHash<QString, int> iname2idx;
for (int i = m_completeSet.size(); --i > 0; ) {
@@ -582,7 +642,10 @@ void WatchHandler::rebuildModel()
data.parentIndex = 0;
data.childIndex.clear();
iname2idx[data.iname] = i;
if (data.level == 2)
++topINames[data.iname];
}
//qDebug() << "TOPINAMES: " << topINames << "\nOLD: " << oldTopINames;
for (int i = 1; i < m_completeSet.size(); ++i) {
WatchData &data = m_completeSet[i];
@@ -603,7 +666,13 @@ void WatchHandler::rebuildModel()
&& data.value != strNotInScope;
}
//emit layoutAboutToBeChanged();
emit layoutAboutToBeChanged();
if (oldTopINames != topINames) {
m_displaySet = initialSet();
m_expandedINames.clear();
emit reset();
}
m_displaySet = m_completeSet;
@@ -668,11 +737,6 @@ void WatchHandler::rebuildModel()
emit reset();
//qDebug() << "WATCHHANDLER: RESET EMITTED";
m_inChange = false;
//emit layoutChanged();
//QSet<QString> einames = m_expandedINames;
//einames.insert("local");
//einames.insert("watch");
//emit expandedItems(einames);
#if DEBUG_MODEL
#if USE_MODEL_TEST
@@ -691,8 +755,11 @@ void WatchHandler::cleanup()
m_oldSet.clear();
m_expandedINames.clear();
m_displayedINames.clear();
cleanModel();
m_incompleteSet.clear();
m_completeSet = initialSet();
m_displaySet = m_completeSet;
#if 0
for (EditWindows::ConstIterator it = m_editWindows.begin();
it != m_editWindows.end(); ++it) {
@@ -707,7 +774,7 @@ void WatchHandler::cleanup()
void WatchHandler::collapseChildren(const QModelIndex &idx)
{
if (m_inChange || m_completeSet.isEmpty()) {
//qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
return;
}
QWB_ASSERT(checkIndex(idx.internalId()), return);
@@ -879,56 +946,10 @@ void WatchHandler::removeWatchExpression(const QString &iname)
emit watchModelUpdateRequested();
}
void WatchHandler::cleanModel()
{
// This uses data stored in m_oldSet to re-create a new set
// one-by-one
m_completeSet.clear();
m_incompleteSet.clear();
WatchData root;
root.state = 0;
root.level = 0;
root.row = 0;
root.name = "Root";
root.parentIndex = -1;
root.childIndex.append(1);
root.childIndex.append(2);
root.childIndex.append(3);
m_completeSet.append(root);
WatchData local;
local.iname = "local";
local.name = "Locals";
local.state = 0;
local.level = 1;
local.row = 0;
local.parentIndex = 0;
m_completeSet.append(local);
WatchData tooltip;
tooltip.iname = "tooltip";
tooltip.name = "Tooltip";
tooltip.state = 0;
tooltip.level = 1;
tooltip.row = 1;
tooltip.parentIndex = 0;
m_completeSet.append(tooltip);
WatchData watch;
watch.iname = "watch";
watch.name = "Watchers";
watch.state = 0;
watch.level = 1;
watch.row = 2;
watch.parentIndex = 0;
m_completeSet.append(watch);
}
void WatchHandler::reinitializeWatchers()
{
cleanModel();
m_completeSet = initialSet();
m_incompleteSet.clear();
// copy over all watchers and mark all watchers as incomplete
for (int i = 0, n = m_oldSet.size(); i < n; ++i) {

View File

@@ -135,7 +135,7 @@ public:
bool changed;
};
enum { INameRole = Qt::UserRole, VisualRole };
enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
class WatchHandler : public QAbstractItemModel
@@ -192,7 +192,6 @@ signals:
private:
WatchData takeData(const QString &iname);
QString toString() const;
void cleanModel();
bool m_expandPointers;
bool m_inChange;

View File

@@ -46,7 +46,7 @@
using namespace Debugger::Internal;
enum { INameRole = Qt::UserRole, VisualRole };
enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
/////////////////////////////////////////////////////////////////////
//
@@ -57,7 +57,6 @@ enum { INameRole = Qt::UserRole, VisualRole };
WatchWindow::WatchWindow(Type type, QWidget *parent)
: QTreeView(parent), m_type(type)
{
m_blocked = false;
setWindowTitle(tr("Locals and Watchers"));
setAlternatingRowColors(true);
setIndentation(indentation() * 9/10);
@@ -76,12 +75,6 @@ void WatchWindow::expandNode(const QModelIndex &idx)
//QModelIndex mi0 = idx.sibling(idx.row(), 0);
//QString iname = model()->data(mi0, INameRole).toString();
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
//qDebug() << "\n\nEXPAND NODE " // << iname << name
// << idx << (m_blocked ? "blocked" : "passed");
//if (isExpanded(idx))
// return;
//if (m_blocked)
// return;
emit requestExpandChildren(idx);
}
@@ -91,8 +84,6 @@ void WatchWindow::collapseNode(const QModelIndex &idx)
//QString iname = model()->data(mi0, INameRole).toString();
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
//qDebug() << "COLLAPSE NODE " << idx;
if (m_blocked)
return;
emit requestCollapseChildren(idx);
}
@@ -181,6 +172,7 @@ void WatchWindow::reset()
QTreeView::reset();
setRootIndex(model()->index(row, 0, model()->index(0, 0)));
//setRootIndex(model()->index(0, 0));
resetHelper(model()->index(0, 0));
}
void WatchWindow::setModel(QAbstractItemModel *model)
@@ -192,55 +184,15 @@ void WatchWindow::setModel(QAbstractItemModel *model)
header()->setResizeMode(QHeaderView::ResizeToContents);
if (m_type != LocalsType)
header()->hide();
connect(model, SIGNAL(modelAboutToBeReset()),
this, SLOT(modelAboutToBeReset()));
connect(model, SIGNAL(modelReset()),
this, SLOT(modelReset()));
}
void WatchWindow::modelAboutToBeReset()
void WatchWindow::resetHelper(const QModelIndex &idx)
{
m_blocked = true;
//qDebug() << "Model about to be reset";
m_expandedItems.clear();
m_expandedItems.insert("local");
m_expandedItems.insert("watch");
modelAboutToBeResetHelper(model()->index(0, 0));
//qDebug() << " expanded: " << m_expandedItems;
}
void WatchWindow::modelAboutToBeResetHelper(const QModelIndex &idx)
{
QString iname = model()->data(idx, INameRole).toString();
//qDebug() << "Model about to be reset helper" << iname << idx
// << isExpanded(idx);
if (isExpanded(idx))
m_expandedItems.insert(iname);
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
QModelIndex idx1 = model()->index(i, 0, idx);
modelAboutToBeResetHelper(idx1);
}
}
void WatchWindow::modelReset()
{
//qDebug() << "Model reset";
expand(model()->index(0, 0));
modelResetHelper(model()->index(0, 0));
m_blocked = false;
}
void WatchWindow::modelResetHelper(const QModelIndex &idx)
{
QString name = model()->data(idx, Qt::DisplayRole).toString();
QString iname = model()->data(idx, INameRole).toString();
//qDebug() << "Model reset helper" << iname << name;
if (m_expandedItems.contains(iname)) {
if (model()->data(idx, ExpandedRole).toBool()) {
expand(idx);
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
QModelIndex idx1 = model()->index(i, 0, idx);
modelResetHelper(idx1);
resetHelper(idx1);
}
}
}

View File

@@ -72,21 +72,16 @@ private slots:
void handleChangedItem(QWidget *);
void expandNode(const QModelIndex &index);
void collapseNode(const QModelIndex &index);
void modelAboutToBeReset();
void modelReset();
private:
void contextMenuEvent(QContextMenuEvent *ev);
void editItem(const QModelIndex &idx);
void reset(); /* reimpl */
void modelAboutToBeResetHelper(const QModelIndex &idx);
void modelResetHelper(const QModelIndex &idx);
void resetHelper(const QModelIndex &idx);
bool m_alwaysResizeColumnsToContents;
Type m_type;
bool m_blocked;
QSet<QString> m_expandedItems;
};

View File

@@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) :
m_ui->newClassWidget->setBaseClassInputVisible(false);
m_ui->newClassWidget->setNamespacesEnabled(true);
m_ui->newClassWidget->setAllowDirectories(true);
connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));

View File

@@ -1,4 +1,4 @@
<plugin name="ScmGit" version="0.1" compatVersion="0.1">
<plugin name="ScmGit" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>

View File

@@ -39,18 +39,20 @@
#include <QtGui/QFileDialog>
using namespace Perforce::Internal;
using namespace Core::Utils;
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
QWidget(parent)
{
m_ui.setupUi(this);
connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
m_ui.pathChooser->setPromptDialogTitle(tr("Perforce Command"));
m_ui.pathChooser->setExpectedKind(PathChooser::Command);
}
PerforceSettings SettingsPageWidget::settings() const
{
PerforceSettings rc;
rc.p4Command = m_ui.p4CmdLineEdit->text();
rc.p4Command = m_ui.pathChooser->path();
rc.defaultEnv = m_ui.defaultCheckBox->isChecked();
rc.p4Port = m_ui.portLineEdit->text();
rc.p4Client = m_ui.clientLineEdit->text();
@@ -60,21 +62,13 @@ PerforceSettings SettingsPageWidget::settings() const
void SettingsPageWidget::setSettings(const PerforceSettings &s)
{
m_ui.p4CmdLineEdit->setText(s.p4Command);
m_ui.pathChooser->setPath(s.p4Command);
m_ui.defaultCheckBox->setChecked(s.defaultEnv);
m_ui.portLineEdit->setText(s.p4Port);
m_ui.clientLineEdit->setText(s.p4Client);
m_ui.userLineEdit->setText(s.p4User);
}
void SettingsPageWidget::browseForCommand()
{
const QString cmd = QFileDialog::getOpenFileName(window(), tr("Perforce Command"));
if (!cmd.isEmpty())
m_ui.p4CmdLineEdit->setText(cmd);
}
SettingsPage::SettingsPage()
{
}

View File

@@ -54,9 +54,6 @@ public:
PerforceSettings settings() const;
void setSettings(const PerforceSettings &);
private slots:;
void browseForCommand();
private:
Ui::SettingsPage m_ui;
};

View File

@@ -36,14 +36,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="p4CmdLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="browseButton">
<property name="text">
<string>...</string>
</property>
</widget>
<widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
</item>
</layout>
</item>
@@ -120,11 +113,18 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>portLineEdit</tabstop>
<tabstop>clientLineEdit</tabstop>
<tabstop>userLineEdit</tabstop>
<tabstop>p4CmdLineEdit</tabstop>
</tabstops>
<resources/>
<connections>

View File

@@ -605,7 +605,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList & /*arguments*/, QStrin
}
}
connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(sessionManager()));
connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
#if 0
connect(m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
@@ -765,10 +765,10 @@ void ProjectExplorerPlugin::newProject()
updateActions();
}
void ProjectExplorerPlugin::sessionManager()
void ProjectExplorerPlugin::showSessionManager()
{
if (debug)
qDebug() << "ProjectExplorerPlugin::newSession";
qDebug() << "ProjectExplorerPlugin::showSessionManager";
if (m_session->isDefaultVirgin()) {
// do not save new virgin default sessions

View File

@@ -143,7 +143,7 @@ private slots:
void unloadProject();
void clearSession();
void newProject();
void sessionManager();
void showSessionManager();
void populateBuildConfigurationMenu();
void buildConfigurationMenuTriggered(QAction *);
void populateRunConfigurationMenu();

View File

@@ -104,8 +104,9 @@
<widget class="QLabel" name="filesLabel">
<property name="text">
<string>The following files will be added:
f1
f2
</string>
</property>
<property name="textInteractionFlags">

View File

@@ -709,7 +709,7 @@ void SessionManager::editDependencies()
dlg.exec();
}
QList<Project *> SessionManager::projects() const
const QList<Project *> &SessionManager::projects() const
{
return m_file->m_projects;
}
@@ -839,26 +839,26 @@ Project *SessionManager::projectForFile(const QString &fileName) const
if (debug)
qDebug() << "SessionManager::projectForFile(" << fileName << ")";
Project *project = 0;
const QList<Project *> &projectList = projects();
QList<Project *> projectList = projects();
// Check current project first
Project *currentProject = ProjectExplorerPlugin::instance()->currentProject();
if (currentProject && projectContainsFile(currentProject, fileName))
return currentProject;
// Always check current project first
if (Project *currentProject = ProjectExplorerPlugin::instance()->currentProject()) {
projectList.removeOne(currentProject);
projectList.insert(0, currentProject);
}
foreach (Project *p, projectList)
if (p != currentProject && projectContainsFile(p, fileName))
return p;
foreach (Project *p, projectList) {
if (!m_projectFileCache.contains(p)) {
m_projectFileCache.insert(p, p->files(Project::AllFiles));
}
if (m_projectFileCache.value(p).contains(fileName)) {
project = p;
break;
}
}
return project;
return 0;
}
bool SessionManager::projectContainsFile(Project *p, const QString &fileName) const
{
if (!m_projectFileCache.contains(p))
m_projectFileCache.insert(p, p->files(Project::AllFiles));
return m_projectFileCache.value(p).contains(fileName);
}
void SessionManager::setEditorCodec(Core::IEditor *editor, const QString &fileName)

View File

@@ -137,7 +137,7 @@ public:
Core::IFile *file() const;
Project *startupProject() const;
QList<Project *> projects() const;
const QList<Project *> &projects() const;
bool isDefaultVirgin() const;
bool isDefaultSession(const QString &session) const;
@@ -182,6 +182,7 @@ private:
bool loadImpl(const QString &fileName);
bool createImpl(const QString &fileName);
QString sessionNameToFileName(const QString &session);
bool projectContainsFile(Project *p, const QString &fileName) const;
bool recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const;
QStringList dependencies(const QString &proName) const;

View File

@@ -61,14 +61,6 @@ void ProFileReader::setQtVersion(QtVersion *qtVersion) {
bool ProFileReader::readProFile(const QString &fileName)
{
//disable caching -> list of include files is not updated otherwise
// ProFile *pro = proFileFromCache(fileName);
// if (!pro) {
// pro = new ProFile(fileName);
// if (!queryProFile(pro)) {
// delete pro;
// return false;
// }
// }
QString fn = QFileInfo(fileName).filePath();
ProFile *pro = new ProFile(fn);
if (!queryProFile(pro)) {
@@ -82,9 +74,6 @@ bool ProFileReader::readProFile(const QString &fileName)
ProFile *ProFileReader::parsedProFile(const QString &fileName)
{
// ProFile *pro = proFileFromCache(fileName);
// if (pro)
// return pro;
QString fn = QFileInfo(fileName).filePath();
ProFile *pro = ProFileEvaluator::parsedProFile(fn);
if (pro) {
@@ -99,16 +88,6 @@ void ProFileReader::releaseParsedProFile(ProFile *)
return;
}
ProFile *ProFileReader::proFileFromCache(const QString &fileName) const
{
QString fn = QFileInfo(fileName).filePath();
ProFile *pro = 0;
if (m_includeFiles.contains(fn))
pro = m_includeFiles.value(fn);
return pro;
}
QList<ProFile*> ProFileReader::includeFiles() const
{
QString qmakeMkSpecDir = propertyValue("QMAKE_MKSPECS");
@@ -196,3 +175,14 @@ void ProFileReader::errorMessage(const QString &message)
{
emit errorFound(message);
}
ProFile *ProFileReader::proFileFor(const QString &name)
{
qDebug()<<"Asking for "<<name;
qDebug()<<"in "<<m_includeFiles.keys();
QMap<QString, ProFile *>::const_iterator it = m_includeFiles.constFind(name);
if (it == m_includeFiles.constEnd())
return 0;
else
return it.value();
}

View File

@@ -63,7 +63,7 @@ public:
const QString &baseDirectory,
PathValuesMode mode,
const ProFile *pro = 0) const;
ProFile *proFileFromCache(const QString &fileName) const;
ProFile *proFileFor(const QString &name);
signals:
void errorFound(const QString &error);

View File

@@ -79,35 +79,22 @@ namespace {
Implements abstract ProjectNode class
*/
Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project,
const QString &filePath)
Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath)
: ProjectNode(filePath),
m_core(project->qt4ProjectManager()->core()),
m_project(project),
m_qt4ProFileNode(qt4ProFileNode),
m_projectFilePath(QDir::fromNativeSeparators(filePath)),
m_projectDir(QFileInfo(filePath).absolutePath()),
m_includeFile(0),
m_saveTimer(new QTimer(this)),
m_reader(0)
m_projectDir(QFileInfo(filePath).absolutePath())
{
Q_ASSERT(project);
setFolderName(QFileInfo(filePath).baseName());
setIcon(QIcon(":/qt4projectmanager/images/qt_project.png"));
// m_saveTimer is used for the delayed saving of the pro file
// so that multiple insert/remove calls in one event loop run
// trigger just one save call.
m_saveTimer->setSingleShot(true);
connect(m_saveTimer, SIGNAL(timeout()), this, SLOT(save()));
}
void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader)
{
Q_ASSERT(includeFile);
Q_ASSERT(reader);
m_reader = reader;
m_includeFile = includeFile;
// add project file node
if (m_fileNodes.isEmpty())
@@ -175,47 +162,42 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader)
QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions() const
{
QList<ProjectAction> actions;
if (m_includeFile) {
const FolderNode *folderNode = this;
const Qt4ProFileNode *proFileNode;
while (!(proFileNode = qobject_cast<const Qt4ProFileNode*>(folderNode)))
folderNode = folderNode->parentFolderNode();
Q_ASSERT(proFileNode);
switch (proFileNode->projectType()) {
case ApplicationTemplate:
case LibraryTemplate:
actions << AddFile << RemoveFile;
break;
case SubDirsTemplate:
actions << AddSubProject << RemoveSubProject;
break;
default:
break;
}
const FolderNode *folderNode = this;
const Qt4ProFileNode *proFileNode;
while (!(proFileNode = qobject_cast<const Qt4ProFileNode*>(folderNode)))
folderNode = folderNode->parentFolderNode();
Q_ASSERT(proFileNode);
switch (proFileNode->projectType()) {
case ApplicationTemplate:
case LibraryTemplate:
actions << AddFile << RemoveFile;
break;
case SubDirsTemplate:
actions << AddSubProject << RemoveSubProject;
break;
default:
break;
}
return actions;
}
bool Qt4PriFileNode::addSubProjects(const QStringList &proFilePaths)
{
if (!m_includeFile)
return false;
return changeIncludes(m_includeFile, proFilePaths, AddToProFile);
Q_UNUSED(proFilePaths);
return false; //changeIncludes(m_includeFile, proFilePaths, AddToProFile);
}
bool Qt4PriFileNode::removeSubProjects(const QStringList &proFilePaths)
{
if (!m_includeFile)
return false;
return changeIncludes(m_includeFile, proFilePaths, RemoveFromProFile);
Q_UNUSED(proFilePaths);
return false; //changeIncludes(m_includeFile, proFilePaths, RemoveFromProFile);
}
bool Qt4PriFileNode::addFiles(const FileType fileType, const QStringList &filePaths,
QStringList *notAdded)
{
if (!m_includeFile)
return false;
QStringList failedFiles;
changeFiles(fileType, filePaths, &failedFiles, AddToProFile);
@@ -227,8 +209,6 @@ bool Qt4PriFileNode::addFiles(const FileType fileType, const QStringList &filePa
bool Qt4PriFileNode::removeFiles(const FileType fileType, const QStringList &filePaths,
QStringList *notRemoved)
{
if (!m_includeFile)
return false;
QStringList failedFiles;
changeFiles(fileType, filePaths, &failedFiles, RemoveFromProFile);
if (notRemoved)
@@ -239,7 +219,7 @@ bool Qt4PriFileNode::removeFiles(const FileType fileType, const QStringList &fil
bool Qt4PriFileNode::renameFile(const FileType fileType, const QString &filePath,
const QString &newFilePath)
{
if (!m_includeFile || newFilePath.isEmpty())
if (newFilePath.isEmpty())
return false;
if (!QFile::rename(filePath, newFilePath))
@@ -268,18 +248,19 @@ bool Qt4PriFileNode::changeIncludes(ProFile *includeFile, const QStringList &pro
bool Qt4PriFileNode::priFileWritable(const QString &path)
{
const QString dir = QFileInfo(path).dir().path();
Core::IVersionControl *versionControl = m_core->vcsManager()->findVersionControlForDirectory(dir);
switch (Core::EditorManager::promptReadOnlyFile(path, versionControl, m_core->mainWindow(), false)) {
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
Core::IVersionControl *versionControl = core->vcsManager()->findVersionControlForDirectory(dir);
switch (Core::EditorManager::promptReadOnlyFile(path, versionControl, core->mainWindow(), false)) {
case Core::EditorManager::RO_OpenVCS:
if (!versionControl->vcsOpen(path)) {
QMessageBox::warning(m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC."));
QMessageBox::warning(core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC."));
return false;
}
break;
case Core::EditorManager::RO_MakeWriteable: {
const bool permsOk = QFile::setPermissions(path, QFile::permissions(path) | QFile::WriteUser);
if (!permsOk) {
QMessageBox::warning(m_core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable."));
QMessageBox::warning(core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable."));
return false;
}
break;
@@ -296,11 +277,13 @@ bool Qt4PriFileNode::saveModifiedEditors(const QString &path)
QList<Core::IFile*> allFileHandles;
QList<Core::IFile*> modifiedFileHandles;
foreach (Core::IFile *file, m_core->fileManager()->managedFiles(path)) {
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
foreach (Core::IFile *file, core->fileManager()->managedFiles(path)) {
allFileHandles << file;
}
foreach (Core::IEditor *editor, m_core->editorManager()->editorsForFileName(path)) {
foreach (Core::IEditor *editor, core->editorManager()->editorsForFileName(path)) {
if (Core::IFile *editorFile = editor->file()) {
if (editorFile->isModified())
modifiedFileHandles << editorFile;
@@ -309,7 +292,7 @@ bool Qt4PriFileNode::saveModifiedEditors(const QString &path)
if (!modifiedFileHandles.isEmpty()) {
bool cancelled;
m_core->fileManager()->saveModifiedFiles(modifiedFileHandles, &cancelled,
core->fileManager()->saveModifiedFiles(modifiedFileHandles, &cancelled,
tr("There are unsaved changes for project file %1.").arg(path));
if (cancelled)
return false;
@@ -330,6 +313,18 @@ void Qt4PriFileNode::changeFiles(const FileType fileType,
if (filePaths.isEmpty())
return;
ProFileReader *reader = m_qt4ProFileNode->createProFileReader();
if (!reader->readProFile(m_qt4ProFileNode->path())) {
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
delete reader;
return;
}
ProFile *includeFile = reader->proFileFor(m_projectFilePath);
if(!includeFile) {
m_project->proFileParseError(tr("Error while changing pro file %1.").arg(m_projectFilePath));
}
*notChanged = filePaths;
// Check for modified editors
@@ -338,7 +333,7 @@ void Qt4PriFileNode::changeFiles(const FileType fileType,
// Check if file is readonly
ProEditorModel proModel;
proModel.setProFiles(QList<ProFile*>() << m_includeFile);
proModel.setProFiles(QList<ProFile*>() << includeFile);
const QStringList vars = varNames(fileType);
QDir priFileDir = QDir(m_projectDir);
@@ -413,26 +408,27 @@ void Qt4PriFileNode::changeFiles(const FileType fileType,
}
// save file
if (!m_saveTimer->isActive())
m_saveTimer->start();
save(includeFile);
delete reader;
}
void Qt4PriFileNode::save()
void Qt4PriFileNode::save(ProFile *includeFile)
{
Core::FileManager *fileManager = m_core->fileManager();
QList<Core::IFile *> allFileHandles = fileManager->managedFiles(m_includeFile->fileName());
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
Core::FileManager *fileManager = core->fileManager();
QList<Core::IFile *> allFileHandles = fileManager->managedFiles(includeFile->fileName());
Core::IFile *modifiedFileHandle = 0;
foreach(Core::IFile *file, allFileHandles)
if (file->fileName() == m_includeFile->fileName())
if (file->fileName() == includeFile->fileName())
modifiedFileHandle = file;
if (modifiedFileHandle)
fileManager->blockFileChange(modifiedFileHandle);
ProWriter pw;
const bool ok = pw.write(m_includeFile, m_includeFile->fileName());
const bool ok = pw.write(includeFile, includeFile->fileName());
Q_UNUSED(ok)
m_includeFile->setModified(false);
m_project->qt4ProjectManager()->notifyChanged(m_includeFile->fileName());
includeFile->setModified(false);
m_project->qt4ProjectManager()->notifyChanged(includeFile->fileName());
if (modifiedFileHandle)
fileManager->unblockFileChange(modifiedFileHandle);
@@ -487,12 +483,11 @@ QStringList Qt4PriFileNode::varNames(FileType type)
Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
const QString &filePath,
QObject *parent)
: Qt4PriFileNode(project, filePath),
: Qt4PriFileNode(project, this, filePath),
// own stuff
m_projectType(InvalidProject),
m_isQBuildProject(false),
m_dirWatcher(new DirectoryWatcher(this)),
m_reader(0)
m_dirWatcher(new DirectoryWatcher(this))
{
if (parent)
setParent(parent);
@@ -507,7 +502,7 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
Qt4ProFileNode::~Qt4ProFileNode()
{
delete m_reader;
}
bool Qt4ProFileNode::hasTargets() const
@@ -527,11 +522,10 @@ QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
void Qt4ProFileNode::update()
{
delete m_reader;
m_reader = createProFileReader();
if (!m_reader->readProFile(m_projectFilePath)) {
ProFileReader *reader = createProFileReader();
if (!reader->readProFile(m_projectFilePath)) {
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
delete m_reader;
delete reader;
invalidate();
return;
}
@@ -546,7 +540,7 @@ void Qt4ProFileNode::update()
#endif
Qt4ProjectType projectType = InvalidProject;
switch (m_reader->templateType()) {
switch (reader->templateType()) {
case ProFileEvaluator::TT_Unknown:
case ProFileEvaluator::TT_Application: {
projectType = ApplicationTemplate;
@@ -585,11 +579,11 @@ void Qt4ProFileNode::update()
ProFile *fileForCurrentProject = 0;
{
if (projectType == SubDirsTemplate) {
foreach (const QString &subDirProject, subDirsPaths(m_reader))
foreach (const QString &subDirProject, subDirsPaths(reader))
newProjectFiles << subDirProject;
}
foreach (ProFile *includeFile, m_reader->includeFiles()) {
foreach (ProFile *includeFile, reader->includeFiles()) {
if (includeFile->fileName() == m_projectFilePath) { // this file
fileForCurrentProject = includeFile;
} else {
@@ -616,9 +610,9 @@ void Qt4ProFileNode::update()
} else if ((*existingNodeIter)->path() > *newProjectFileIter) {
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
Qt4PriFileNode *priFileNode
= new Qt4PriFileNode(m_project,
= new Qt4PriFileNode(m_project, this,
*newProjectFileIter);
priFileNode->update(file, m_reader);
priFileNode->update(file, reader);
toAdd << priFileNode;
} else {
toAdd << createSubProFileNode(*newProjectFileIter);
@@ -627,7 +621,7 @@ void Qt4ProFileNode::update()
} else { // *existingNodeIter->path() == *newProjectFileIter
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
Qt4PriFileNode *priFileNode = static_cast<Qt4PriFileNode*>(*existingNodeIter);
priFileNode->update(file, m_reader);
priFileNode->update(file, reader);
}
++existingNodeIter;
@@ -641,9 +635,9 @@ void Qt4ProFileNode::update()
while (newProjectFileIter != newProjectFiles.constEnd()) {
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
Qt4PriFileNode *priFileNode
= new Qt4PriFileNode(m_project,
= new Qt4PriFileNode(m_project, this,
*newProjectFileIter);
priFileNode->update(file, m_reader);
priFileNode->update(file, reader);
toAdd << priFileNode;
} else {
toAdd << createSubProFileNode(*newProjectFileIter);
@@ -656,15 +650,15 @@ void Qt4ProFileNode::update()
if (!toAdd.isEmpty())
addProjectNodes(toAdd);
Qt4PriFileNode::update(fileForCurrentProject, m_reader);
Qt4PriFileNode::update(fileForCurrentProject, reader);
// update other variables
QHash<Qt4Variable, QStringList> newVarValues;
newVarValues[CxxCompilerVar] << m_reader->value(QLatin1String("QMAKE_CXX"));
newVarValues[DefinesVar] = m_reader->values(QLatin1String("DEFINES"));
newVarValues[IncludePathVar] = includePaths(m_reader);
newVarValues[UiDirVar] = uiDirPaths(m_reader);
newVarValues[MocDirVar] = mocDirPaths(m_reader);
newVarValues[CxxCompilerVar] << reader->value(QLatin1String("QMAKE_CXX"));
newVarValues[DefinesVar] = reader->values(QLatin1String("DEFINES"));
newVarValues[IncludePathVar] = includePaths(reader);
newVarValues[UiDirVar] = uiDirPaths(reader);
newVarValues[MocDirVar] = mocDirPaths(reader);
if (m_varValues != newVarValues) {
m_varValues = newVarValues;
@@ -678,12 +672,14 @@ void Qt4ProFileNode::update()
foreach (NodesWatcher *watcher, watchers())
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
emit qt4Watcher->proFileUpdated(this);
delete reader;
}
void Qt4ProFileNode::fileChanged(const QString &filePath)
{
CppTools::CppModelManagerInterface *modelManager =
m_core->pluginManager()->getObject<CppTools::CppModelManagerInterface>();
ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
modelManager->updateSourceFiles(QStringList() << filePath);
}
@@ -789,7 +785,7 @@ void Qt4ProFileNode::updateGeneratedFiles()
}
}
ProFileReader *Qt4ProFileNode::createProFileReader() const
ProFileReader *Qt4PriFileNode::createProFileReader() const
{
ProFileReader *reader = new ProFileReader();
connect(reader, SIGNAL(errorFound(const QString &)),
@@ -801,7 +797,7 @@ ProFileReader *Qt4ProFileNode::createProFileReader() const
}
QHash<QString,QStringList> variables;
variables.insert(QLatin1String("OUT_PWD"), QStringList(buildDir()));
variables.insert(QLatin1String("OUT_PWD"), QStringList(m_qt4ProFileNode->buildDir()));
reader->addVariables(variables);
return reader;
@@ -916,7 +912,7 @@ QStringList Qt4ProFileNode::qBuildSubDirsPaths(const QString &scanDir) const
return subProjectPaths;
}
QString Qt4ProFileNode::buildDir() const
QString Qt4PriFileNode::buildDir() const
{
const QDir srcDirRoot = QFileInfo(m_project->rootProjectNode()->path()).absoluteDir();
const QString relativeDir = srcDirRoot.relativeFilePath(m_projectDir);
@@ -951,11 +947,6 @@ void Qt4ProFileNode::invalidate()
}
ProFile *Qt4ProFileNode::proFileFromCache(const QString &fileName)
{
return m_reader->proFileFromCache(fileName);
}
Qt4NodesWatcher::Qt4NodesWatcher(QObject *parent)
: NodesWatcher(parent)
{

View File

@@ -102,8 +102,7 @@ class Qt4PriFileNode : public ProjectExplorer::ProjectNode {
Q_OBJECT
Q_DISABLE_COPY(Qt4PriFileNode)
public:
Qt4PriFileNode(Qt4Project *project,
const QString &filePath);
Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath);
void update(ProFile *includeFile, ProFileReader *reader);
@@ -122,9 +121,6 @@ public:
bool renameFile(const FileType fileType,
const QString &filePath, const QString &newFilePath);
private slots:
void save();
protected:
void clear();
static QStringList varNames(FileType type);
@@ -142,18 +138,20 @@ protected:
const QStringList &filePaths,
QStringList *notChanged,
ChangeType change);
QString buildDir() const;
ProFileReader *createProFileReader() const;
private:
void save(ProFile *includeFile);
bool priFileWritable(const QString &path);
bool saveModifiedEditors(const QString &path);
Core::ICore *m_core;
Qt4Project *m_project;
Qt4ProFileNode *m_qt4ProFileNode;
QString m_projectFilePath;
QString m_projectDir;
ProFile *m_includeFile;
QTimer *m_saveTimer;
ProFileReader *m_reader;
// managed by Qt4ProFileNode
friend class Qt4ProFileNode;
@@ -174,7 +172,6 @@ public:
Qt4ProjectType projectType() const;
QStringList variableValue(const Qt4Variable var) const;
ProFile *proFileFromCache(const QString &fileName);
public slots:
void update();
@@ -185,7 +182,6 @@ private slots:
private:
void updateGeneratedFiles();
ProFileReader *createProFileReader() const;
Qt4ProFileNode *createSubProFileNode(const QString &path);
QStringList uiDirPaths(ProFileReader *reader) const;
@@ -194,7 +190,7 @@ private:
QStringList subDirsPaths(ProFileReader *reader) const;
QStringList qBuildSubDirsPaths(const QString &scanDir) const;
QString buildDir() const;
void invalidate();
@@ -203,7 +199,6 @@ private:
bool m_isQBuildProject;
DirectoryWatcher *m_dirWatcher;
ProFileReader *m_reader;
friend class Qt4NodeHierarchy;
};

View File

@@ -179,12 +179,8 @@ Qt4ProjectFile::Qt4ProjectFile(Qt4Project *project, const QString &filePath, QOb
bool Qt4ProjectFile::save(const QString &)
{
ProFile *file = m_project->proFileFromCache(m_filePath);
ProWriter pw;
bool ok = pw.write(file, file->fileName());
file->setModified(false);
m_project->qt4ProjectManager()->notifyChanged(file->fileName());
return ok;
// This is never used
return false;
}
QString Qt4ProjectFile::fileName() const
@@ -209,7 +205,7 @@ QString Qt4ProjectFile::mimeType() const
bool Qt4ProjectFile::isModified() const
{
return m_project->proFileFromCache(m_filePath)->isModified();
return false; // we save after changing anyway
}
bool Qt4ProjectFile::isReadOnly() const
@@ -478,29 +474,36 @@ void Qt4Project::updateCodeModel()
}
}
// Add mkspec directory
allIncludePaths.append(qtVersion(activeBuildConfiguration())->mkspecPath());
QStringList files;
files += m_projectFiles->files[HeaderType];
files += m_projectFiles->generatedFiles[HeaderType];
files += m_projectFiles->files[SourceType];
files += m_projectFiles->generatedFiles[SourceType];
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
if (pinfo->defines == predefinedMacros &&
pinfo->includePaths == allIncludePaths &&
pinfo->frameworkPaths == allFrameworkPaths &&
pinfo->sourceFiles == files) {
// Nothing to update...
if (pinfo.defines == predefinedMacros &&
pinfo.includePaths == allIncludePaths &&
pinfo.frameworkPaths == allFrameworkPaths &&
pinfo.sourceFiles == files) {
modelmanager->updateProjectInfo(pinfo);
} else {
pinfo->defines = predefinedMacros;
pinfo.defines = predefinedMacros;
// pinfo->defines += definedMacros; // ### FIXME: me
pinfo->includePaths = allIncludePaths;
pinfo->frameworkPaths = allFrameworkPaths;
pinfo->sourceFiles = files;
pinfo.includePaths = allIncludePaths;
pinfo.frameworkPaths = allFrameworkPaths;
pinfo.sourceFiles = files;
modelmanager->updateProjectInfo(pinfo);
modelmanager->GC();
modelmanager->updateSourceFiles(pinfo->sourceFiles);
modelmanager->updateSourceFiles(pinfo.sourceFiles);
}
// update info
}
@@ -895,16 +898,24 @@ MakeStep *Qt4Project::makeStep() const
return 0;
}
ProFile *Qt4Project::proFileFromCache(const QString &fileName)
bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
{
return rootProjectNode()->proFileFromCache(fileName);
if (root->path() == path)
return true;
foreach (FolderNode *fn, root->subFolderNodes()) {
if (qobject_cast<Qt4ProFileNode *>(fn)) {
// we aren't interested in pro file nodes
} else if(Qt4PriFileNode *qt4prifilenode = qobject_cast<Qt4PriFileNode *>(fn)) {
if (hasSubNode(qt4prifilenode, path))
return true;
}
}
return false;
}
void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
{
if (root->path() == fileName)
list.append(root);
else if (root->proFileFromCache(fileName))
if (hasSubNode(root, fileName))
list.append(root);
foreach (FolderNode *fn, root->subFolderNodes())
@@ -914,9 +925,10 @@ void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QLis
void Qt4Project::notifyChanged(const QString &name)
{
QList<Qt4ProFileNode *> list;
findProFile(name, rootProjectNode(), list);
foreach(Qt4ProFileNode *node, list)
node->update();
if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
QList<Qt4ProFileNode *> list;
findProFile(name, rootProjectNode(), list);
foreach(Qt4ProFileNode *node, list)
node->update();
}
}

View File

@@ -180,7 +180,6 @@ public:
QMakeStep *qmakeStep() const;
MakeStep *makeStep() const;
ProFile *proFileFromCache(const QString &fileName);
void notifyChanged(const QString &name);
public slots:
@@ -209,6 +208,7 @@ protected:
private:
static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list);
static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path);
QList<Internal::Qt4ProFileNode *> m_applicationProFileChange;
ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;

View File

@@ -728,6 +728,12 @@ QString QtVersion::mkspec() const
return m_mkspec;
}
QString QtVersion::mkspecPath() const
{
updateMkSpec();
return m_mkspecFullPath;
}
QHash<QString,QString> QtVersion::versionInfo() const
{
updateVersionInfo();
@@ -1023,25 +1029,25 @@ void QtVersion::updateMkSpec() const
//qDebug()<<"Finding mkspec for"<<path();
QString mkspec;
QFile f(path() + "/.qmake.cache");
if (f.exists() && f.open(QIODevice::ReadOnly)) {
while(!f.atEnd()) {
QByteArray line = f.readLine();
if(line.startsWith("QMAKESPEC")) {
const QList<QByteArray> &temp = line.split('=');
if(temp.size() == 2) {
mkspec = temp.at(1).trimmed();
if (mkspec.startsWith("$$QT_BUILD_TREE/mkspecs/"))
mkspec = mkspec.mid(QString("$$QT_BUILD_TREE/mkspecs/").length());
else if (mkspec.startsWith("$$QT_BUILD_TREE\\mkspecs\\"))
mkspec = mkspec.mid(QString("$$QT_BUILD_TREE\\mkspecs\\").length());
mkspec = QDir::fromNativeSeparators(mkspec);
}
break;
}
}
f.close();
} else {
// QFile f(path() + "/.qmake.cache");
// if (f.exists() && f.open(QIODevice::ReadOnly)) {
// while(!f.atEnd()) {
// QByteArray line = f.readLine();
// if(line.startsWith("QMAKESPEC")) {
// const QList<QByteArray> &temp = line.split('=');
// if(temp.size() == 2) {
// mkspec = temp.at(1).trimmed();
// if (mkspec.startsWith("$$QT_BUILD_TREE/mkspecs/"))
// mkspec = mkspec.mid(QString("$$QT_BUILD_TREE/mkspecs/").length());
// else if (mkspec.startsWith("$$QT_BUILD_TREE\\mkspecs\\"))
// mkspec = mkspec.mid(QString("$$QT_BUILD_TREE\\mkspecs\\").length());
// mkspec = QDir::fromNativeSeparators(mkspec);
// }
// break;
// }
// }
// f.close();
// } else {
// no .qmake.cache so look at the default mkspec
QString mkspecPath = versionInfo().value("QMAKE_MKSPECS");
if (mkspecPath.isEmpty())
@@ -1096,8 +1102,9 @@ void QtVersion::updateMkSpec() const
mkspec = f2.symLinkTarget();
}
#endif
}
// }
m_mkspecFullPath = mkspec;
int index = mkspec.lastIndexOf('/');
if(index == -1)
index = mkspec.lastIndexOf('\\');

View File

@@ -67,6 +67,7 @@ public:
QString path() const;
QString sourcePath() const;
QString mkspec() const;
QString mkspecPath() const;
QString makeCommand() const;
QString qmakeCommand() const;
// Returns the PREFIX, BINPREFIX, DOCPREFIX and similar information
@@ -107,6 +108,7 @@ private:
QString m_path;
QString m_sourcePath;
mutable QString m_mkspec; // updated lazily
mutable QString m_mkspecFullPath;
QString m_mingwDirectory;
QString m_prependPath;
QString m_msvcVersion;

View File

@@ -39,20 +39,24 @@
#include <extensionsystem/pluginmanager.h>
#include <QtGui/QFileDialog>
#include <utils/pathchooser.h>
using namespace Subversion::Internal;
using namespace Core::Utils;
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
QWidget(parent)
{
m_ui.setupUi(this);
connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
m_ui.pathChooser->setExpectedKind(PathChooser::Command);
m_ui.pathChooser->setPromptDialogTitle(tr("Subversion Command"));
}
SubversionSettings SettingsPageWidget::settings() const
{
SubversionSettings rc;
rc.svnCommand = m_ui.svnCmdLineEdit->text();
rc.svnCommand = m_ui.pathChooser->path();
rc.useAuthentication = m_ui.userGroupBox->isChecked();
rc.user = m_ui.usernameLineEdit->text();
rc.password = m_ui.passwordLineEdit->text();
@@ -63,19 +67,12 @@ SubversionSettings SettingsPageWidget::settings() const
void SettingsPageWidget::setSettings(const SubversionSettings &s)
{
m_ui.svnCmdLineEdit->setText(s.svnCommand);
m_ui.pathChooser->setPath(s.svnCommand);
m_ui.usernameLineEdit->setText(s.user);
m_ui.passwordLineEdit->setText(s.password);
m_ui.userGroupBox->setChecked(s.useAuthentication);
}
void SettingsPageWidget::browseForCommand()
{
QString cmd = QFileDialog::getOpenFileName(window(), tr("Subversion Command"));
if (!cmd.isEmpty())
m_ui.svnCmdLineEdit->setText(cmd);
}
SettingsPage::SettingsPage()
{
}

View File

@@ -59,9 +59,6 @@ public:
SubversionSettings settings() const;
void setSettings(const SubversionSettings &);
private slots:;
void browseForCommand();
private:
Ui::SettingsPage m_ui;
};

View File

@@ -32,14 +32,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="svnCmdLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="browseButton">
<property name="text">
<string>...</string>
</property>
</widget>
<widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
</item>
</layout>
</item>
@@ -109,9 +102,14 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>svnCmdLineEdit</tabstop>
</tabstops>
<customwidgets>
<customwidget>
<class>Core::Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -488,10 +488,6 @@ ITextEditable *BaseTextEditor::editableInterface() const
d->m_editable, SIGNAL(contentsChanged()));
connect(this, SIGNAL(changed()),
d->m_editable, SIGNAL(changed()));
connect(this,
SIGNAL(markRequested(TextEditor::ITextEditor *, int)),
d->m_editable,
SIGNAL(markRequested(TextEditor::ITextEditor *, int)));
}
return d->m_editable;
}
@@ -606,29 +602,44 @@ void BaseTextEditor::slotSelectionChanged()
void BaseTextEditor::gotoBlockStart()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false)) {
setTextCursor(cursor);
_q_matchParentheses();
}
}
void BaseTextEditor::gotoBlockEnd()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false)) {
setTextCursor(cursor);
_q_matchParentheses();
}
}
void BaseTextEditor::gotoBlockStartWithSelection()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true)) {
setTextCursor(cursor);
_q_matchParentheses();
}
}
void BaseTextEditor::gotoBlockEndWithSelection()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true)) {
setTextCursor(cursor);
_q_matchParentheses();
}
}
static QTextCursor flippedCursor(const QTextCursor &cursor) {
QTextCursor flipped = cursor;
flipped.clearSelection();
flipped.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
return flipped;
}
void BaseTextEditor::selectBlockUp()
@@ -644,7 +655,8 @@ void BaseTextEditor::selectBlockUp()
return;
if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
return;
setTextCursor(cursor);
setTextCursor(flippedCursor(cursor));
_q_matchParentheses();
}
void BaseTextEditor::selectBlockDown()
@@ -667,7 +679,8 @@ void BaseTextEditor::selectBlockDown()
if ( cursor != d->m_selectBlockAnchor)
TextBlockUserData::findNextClosingParenthesis(&cursor, true);
setTextCursor(cursor);
setTextCursor(flippedCursor(cursor));
_q_matchParentheses();
}
@@ -2434,9 +2447,10 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
}
} else if (e->button() == Qt::RightButton) {
QMenu * contextMenu = new QMenu(this);
emit lineContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu);
emit d->m_editable->markContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu);
if (!contextMenu->isEmpty())
contextMenu->exec(e->globalPos());
delete contextMenu;
}
} else if (d->extraAreaSelectionAnchorBlockNumber >= 0) {
QTextCursor selection = cursor;
@@ -2471,7 +2485,7 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
d->extraAreaToggleMarkBlockNumber = -1;
if (cursor.blockNumber() == n) {
int line = n + 1;
emit markRequested(editableInterface(), line);
emit d->m_editable->markRequested(editableInterface(), line);
}
}
}
@@ -2480,6 +2494,9 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
void BaseTextEditor::slotCursorPositionChanged()
{
QList<QTextEdit::ExtraSelection> extraSelections;
setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear
if (d->m_parenthesesMatchingEnabled)
d->m_parenthesesMatchingTimer->start(50);
if (d->m_highlightCurrentLine) {
QTextEdit::ExtraSelection sel;
@@ -2490,11 +2507,7 @@ void BaseTextEditor::slotCursorPositionChanged()
extraSelections.append(sel);
}
if (d->m_parenthesesMatchingEnabled)
d->m_parenthesesMatchingTimer->start(50);
d->m_extraSelections = extraSelections;
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
setExtraSelections(CurrentLineSelection, extraSelections);
}
QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block)
@@ -3136,7 +3149,7 @@ void BaseTextEditor::_q_matchParentheses()
if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch)
return;
QList<QTextEdit::ExtraSelection> extraSelections = d->m_extraSelections;
QList<QTextEdit::ExtraSelection> extraSelections;
if (backwardMatch.hasSelection()) {
QTextEdit::ExtraSelection sel;
@@ -3189,8 +3202,7 @@ void BaseTextEditor::_q_matchParentheses()
}
extraSelections.append(sel);
}
d->m_extraSelections = extraSelections;
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
setExtraSelections(ParenthesesMatchingSelection, extraSelections);
}
void BaseTextEditor::setActionHack(QObject *hack)
@@ -3237,15 +3249,21 @@ void BaseTextEditor::deleteLine()
cut();
}
void BaseTextEditor::setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
void BaseTextEditor::setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections)
{
d->m_extraExtraSelections = selections;
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
if (selections.isEmpty() && d->m_extraSelections[kind].isEmpty())
return;
d->m_extraSelections[kind] = selections;
QList<QTextEdit::ExtraSelection> all;
for (int i = 0; i < NExtraSelectionKinds; ++i)
all += d->m_extraSelections[i];
QPlainTextEdit::setExtraSelections(all);
}
QList<QTextEdit::ExtraSelection> BaseTextEditor::extraExtraSelections() const
QList<QTextEdit::ExtraSelection> BaseTextEditor::extraSelections(ExtraSelectionKind kind) const
{
return d->m_extraExtraSelections;
return d->m_extraSelections[kind];
}

View File

@@ -369,7 +369,6 @@ private:
Internal::BaseTextEditorPrivate *d;
friend class Internal::BaseTextEditorPrivate;
public:
QWidget *extraArea() const;
virtual int extraAreaWidth(int *markWidthPtr = 0) const;
@@ -385,8 +384,16 @@ public:
void ensureCursorVisible();
void setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
QList<QTextEdit::ExtraSelection> extraExtraSelections() const;
enum ExtraSelectionKind {
CurrentLineSelection,
ParenthesesMatchingSelection,
CodeWarningsSelection,
CodeSemanticsSelection,
OtherSelection,
NExtraSelectionKinds
};
void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections);
QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const;
struct BlockRange {
BlockRange():first(0), last(-1){}
@@ -431,8 +438,6 @@ protected slots:
signals:
void markRequested(TextEditor::ITextEditor *editor, int line);
void lineContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu);
void requestBlockUpdate(const QTextBlock &);
void requestAutoCompletion(ITextEditable *editor, bool forced);

View File

@@ -204,8 +204,7 @@ public:
QObject *m_actionHack;
QList<QTextEdit::ExtraSelection> m_extraSelections;
QList<QTextEdit::ExtraSelection> m_extraExtraSelections;
QList<QTextEdit::ExtraSelection> m_extraSelections[BaseTextEditor::NExtraSelectionKinds];
// block selection mode
bool m_inBlockSelectionMode;

View File

@@ -44,6 +44,7 @@
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
class QMenu;
class QTextBlock;
QT_END_NAMESPACE
@@ -124,6 +125,7 @@ public:
signals:
void contentsChanged();
void markRequested(TextEditor::ITextEditor *editor, int line);
void markContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu);
void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position);
void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position);
};

View File

@@ -225,23 +225,12 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e)
sel.format.setFontUnderline(true);
change = changeUnderCursor(cursor);
sel.format.setProperty(QTextFormat::UserProperty, change);
bool found = false;
foreach (QTextEdit::ExtraSelection es, extraSelections()) {
if (es.format.stringProperty(QTextFormat::UserProperty) == sel.format.stringProperty(QTextFormat::UserProperty)) {
found = true;
break;
}
}
if (!found) {
setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
viewport()->setCursor(Qt::PointingHandCursor);
}
} else {
if (!extraSelections().isEmpty()) {
setExtraSelections(QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
}
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
viewport()->setCursor(Qt::PointingHandCursor);
}
} else {
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
}
TextEditor::BaseTextEditor::mouseMoveEvent(e);
}

View File

@@ -1,16 +1,14 @@
IDE_SOURCE_TREE = $$PWD/../
isEmpty(TEST) {
CONFIG(debug, debug|release) {
isEmpty(TEST):CONFIG(debug, debug|release) {
!debug_and_release|build_pass {
TEST = 1
}
}
!isEmpty(TEST) {
equals(TEST, 1) {
QT +=testlib
DEFINES+=WITH_TESTS
}
equals(TEST, 1) {
QT +=testlib
DEFINES += WITH_TESTS
}
isEmpty(IDE_BUILD_TREE) {

View File

@@ -351,6 +351,23 @@ void testPlugin()
}
}
void testSet()
{
QSet<int> hgg0;
hgg0.insert(11);
hgg0.insert(22);
QSet<QString> hgg1;
hgg1.insert("22.0");
QObject ob;
QSet<QPointer<QObject> > hash;
QPointer<QObject> ptr(&ob);
//hash.insert(ptr);
//hash.insert(ptr);
//hash.insert(ptr);
}
void stringRefTest(const QString &refstring)
{
Q_UNUSED(refstring);
@@ -759,6 +776,7 @@ int main(int argc, char *argv[])
testImage();
testMap();
testString();
testSet();
testStringList();
testStruct();
//testThreads();
@@ -767,8 +785,13 @@ int main(int argc, char *argv[])
testVariant3();
testVector();
testVectorOfList();
*(int *)0 = 0;
testObject(argc, argv);
//QColor color(255,128,10);
//QFont font;