Commit e84d4ae7 authored by mae's avatar mae

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

parents 173ae4d6 0a91e21f
#!/bin/sh
bindir=$(dirname "$0")
bindir=$(dirname $(readlink -nf $0))
if test "$(uname -m)" = "x86_64" ; then
libdir=$(cd ${bindir}/../lib64 ; pwd)
else
......
......@@ -13,11 +13,9 @@ General
* Completely reworked editor split mechanism.
Editing
* Completion for constructors in variable initialization.
* Some support for Obj-C++ //TODO: what does that mean more concrete?
* Some support for doxygen style comments //TODO: what does that mean more concrete?
* More intelligent adding of braces.
* Improved function argument completion.
* Added support for JavaScript.
* Added syntax highlighting and code completion for qdoc and doxygen tags.
* Improved function argument hint.
* More checkpoints in editor history.
* Ctrl-click for jumping to a symbol definition.
* Context help for form editor widgets.
......@@ -26,19 +24,26 @@ Editing
* Improved open documents view (sorted, single-click, close buttons).
* Copying text from the context help browser and output windows didn't work.
Building, Running and Debugging
Building and Running
* Experimental support for generic Makefile based projects.
* Improved .pro file parsing, handling scopes and $$system directive.
* Support subdir.file in .pro files.
* Experimental cdb debugger.
* Option to start application in external terminal.
Debugging
* Possibility to attach debugger to core files.
* Debugger understands std::set now.
* Changed approach to dumper loading: Build once per used Qt version,
no dumper buildstep anymore.
* New dumper for std::set. Improved QString, QVariant, std::wstring
* Make strategy to load shared objects configurable (auto-solib-add).
* Maximum stack depth configurable.
* Improved interaction in the Locals&Watchers view.
Wizards
* It is now possible to choose file suffixes in the options dialog.
* Code of language change event is now generated correctly (added call
to base class).
* Generated header guards now adapt to file extension.
Designer
* Added signal/slot editor.
......
......@@ -223,14 +223,13 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
continue;
if (q->nameCount() > 1) {
Name *classOrNamespaceName = 0;
if (q->nameCount() == 1)
classOrNamespaceName = q->nameAt(0);
else
classOrNamespaceName = control()->qualifiedNameId(q->names(),
q->nameCount() - 1);
Name *classOrNamespaceName = control()->qualifiedNameId(q->names(),
q->nameCount() - 1);
if (Identifier *classOrNamespaceNameId = identifier(classOrNamespaceName)) {
if (classOrNamespaceNameId->isEqualTo(id))
continue;
}
const QList<Symbol *> resolvedClassOrNamespace =
resolveClassOrNamespace(classOrNamespaceName, visibleScopes);
......@@ -455,7 +454,7 @@ void LookupContext::expandFunction(Scope *scope,
expandedScopes->append(function->arguments());
if (QualifiedNameId *q = function->name()->asQualifiedNameId()) {
Name *nestedNameSpec = 0;
if (q->nameCount() == 1 && q->isGlobal())
if (q->nameCount() == 1)
nestedNameSpec = q->nameAt(0);
else
nestedNameSpec = control()->qualifiedNameId(q->names(), q->nameCount() - 1,
......
......@@ -42,7 +42,8 @@
#include <QtDebug>
#ifdef Q_OS_LINUX
# define USE_UNPATCHED_QPLUGINLOADER 0
// Using the patched version breaks on Fedora 10, KDE4.2.2/Qt4.5.
# define USE_UNPATCHED_QPLUGINLOADER 1
#else
# define USE_UNPATCHED_QPLUGINLOADER 1
#endif
......
......@@ -24,3 +24,5 @@ unix {
LIBS += -lshell32
}
target.path = /bin
INSTALLS += target
......@@ -169,8 +169,8 @@ InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
QLabel *label = new QLabel(this);
label->setWordWrap(true);
label->setText(tr("Qt Creator has detected an in source build. "
"This prevents out of souce builds, Qt Creator won't allow you to change the build directory. "
"If you want a out of source build, clean your source directory and open the project again"));
"This prevents shadow builds, Qt Creator won't allow you to change the build directory. "
"If you want a shadow build, clean your source directory and open the project again."));
layout()->addWidget(label);
}
......@@ -181,8 +181,8 @@ XmlFileUpToDatePage::XmlFileUpToDatePage(CMakeOpenProjectWizard *cmakeWizard)
setLayout(new QVBoxLayout);
QLabel *label = new QLabel(this);
label->setWordWrap(true);
label->setText(tr("Qt Creator has found a recent cbp file, which Qt Creator parses to gather information about the project. "
"You can change the command line arguments used to create this file, in the project mode. "
label->setText(tr("Qt Creator has found a recent cbp file, which Qt Creator will parse to gather information about the project. "
"You can change the command line arguments used to create this file in the project mode. "
"Click finish to load the project"));
layout()->addWidget(label);
}
......@@ -239,13 +239,19 @@ void CMakeRunPage::initWidgets()
fl->addRow(m_descriptionLabel);
m_argumentsLineEdit = new QLineEdit(this);
fl->addRow(tr("Arguments:"), m_argumentsLineEdit);
//fl->addRow(tr("Arguments:"), m_argumentsLineEdit);
m_runCMake = new QPushButton(this);
m_runCMake->setText("Run CMake");
m_runCMake->setText(tr("Run CMake"));
connect(m_runCMake, SIGNAL(clicked()), this, SLOT(runCMake()));
fl->addWidget(m_runCMake);
//fl->addWidget(m_runCMake);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(m_argumentsLineEdit);
hbox->addWidget(m_runCMake);
fl->addRow(tr("Arguments"), hbox);
m_output = new QPlainTextEdit(this);
m_output->setReadOnly(true);
......@@ -257,22 +263,23 @@ void CMakeRunPage::initializePage()
if (m_presetBuildDirectory.isEmpty()) {
m_buildDirectory = m_cmakeWizard->buildDirectory();
m_descriptionLabel->setText(
tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file, by running cmake. "
tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running cmake. "
"Some projects require command line arguments to the initial cmake call.").arg(m_buildDirectory));
} else {
m_buildDirectory = m_presetBuildDirectory;
// TODO tell the user more?
if (m_update)
m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt "
"Creator needs to update this file by running cmake. "
"If you want to add additional command line arguments, "
"add them in the below.").arg(m_buildDirectory));
"add them in the below. Note, that cmake remembers command "
"line arguments from the former runs.").arg(m_buildDirectory));
else
m_descriptionLabel->setText(tr("The directory %1, specified in a buildconfiguration, "
m_descriptionLabel->setText(tr("The directory %1 specified in a buildconfiguration, "
"does not contain a cbp file. Qt Creator needs to "
"recreate this file, by running cmake. "
"Some projects require command line arguments to "
"the initial cmake call.").arg(m_buildDirectory));
"the initial cmake call. Note, that cmake remembers command "
"line arguments from the former runs.").arg(m_buildDirectory));
}
}
......
......@@ -207,30 +207,30 @@ void CMakeProject::parseCMakeLists()
// Create run configurations for m_targets
//qDebug()<<"Create run configurations of m_targets";
QMap<QString, QSharedPointer<CMakeRunConfiguration> > existingRunConfigurations;
QMultiMap<QString, QSharedPointer<CMakeRunConfiguration> > existingRunConfigurations;
foreach(QSharedPointer<ProjectExplorer::RunConfiguration> cmakeRunConfiguration, runConfigurations()) {
if (QSharedPointer<CMakeRunConfiguration> rc = cmakeRunConfiguration.dynamicCast<CMakeRunConfiguration>()) {
existingRunConfigurations.insert(rc->title(), rc);
}
}
bool setActive = false;
bool setActive = existingRunConfigurations.isEmpty();
foreach(const CMakeTarget &ct, m_targets) {
if (ct.executable.isEmpty())
continue;
if (ct.title.endsWith("/fast"))
continue;
QMap<QString, QSharedPointer<CMakeRunConfiguration> >::iterator it =
existingRunConfigurations.find(ct.title);
if (it != existingRunConfigurations.end()) {
QList<QSharedPointer<CMakeRunConfiguration> > list = existingRunConfigurations.values(ct.title);
if (!list.isEmpty()) {
// Already exists, so override the settings...
QSharedPointer<CMakeRunConfiguration> rc = it.value();
//qDebug()<<"Updating Run Configuration with title"<<ct.title;
//qDebug()<<" Executable new:"<<ct.executable<< "old:"<<rc->executable();
//qDebug()<<" WD new:"<<ct.workingDirectory<<"old:"<<rc->workingDirectory();
rc->setExecutable(ct.executable);
rc->setWorkingDirectory(ct.workingDirectory);
existingRunConfigurations.erase(it);
foreach (QSharedPointer<CMakeRunConfiguration> rc, list) {
//qDebug()<<"Updating Run Configuration with title"<<ct.title;
//qDebug()<<" Executable new:"<<ct.executable<< "old:"<<rc->executable();
//qDebug()<<" WD new:"<<ct.workingDirectory<<"old:"<<rc->workingDirectory();
rc->setExecutable(ct.executable);
rc->setWorkingDirectory(ct.workingDirectory);
}
existingRunConfigurations.remove(ct.title);
} else {
// Does not exist yet
//qDebug()<<"Adding new run configuration with title"<<ct.title;
......@@ -238,13 +238,13 @@ void CMakeProject::parseCMakeLists()
QSharedPointer<ProjectExplorer::RunConfiguration> rc(new CMakeRunConfiguration(this, ct.executable, ct.workingDirectory, ct.title));
addRunConfiguration(rc);
// The first one gets the honour of beeing the active one
if (!setActive) {
if (setActive) {
setActiveRunConfiguration(rc);
setActive = true;
setActive = false;
}
}
}
QMap<QString, QSharedPointer<CMakeRunConfiguration> >::const_iterator it =
QMultiMap<QString, QSharedPointer<CMakeRunConfiguration> >::const_iterator it =
existingRunConfigurations.constBegin();
for( ; it != existingRunConfigurations.constEnd(); ++it) {
QSharedPointer<CMakeRunConfiguration> rc = it.value();
......@@ -282,8 +282,13 @@ QString CMakeProject::buildParser(const QString &buildConfiguration) const
QStringList CMakeProject::targets() const
{
QStringList results;
foreach (const CMakeTarget &ct, m_targets)
foreach (const CMakeTarget &ct, m_targets) {
if (ct.executable.isEmpty())
continue;
if (ct.title.endsWith("/fast"))
continue;
results << ct.title;
}
return results;
}
......@@ -501,6 +506,10 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
if (!copw.buildDirectory().isEmpty())
setValue("all", "buildDirectory", copw.buildDirectory());
//TODO save arguments somewhere copw.arguments()
MakeStep *cleanMakeStep = new MakeStep(this);
insertCleanStep(0, cleanMakeStep);
cleanMakeStep->setValue("clean", true);
} else {
// We have a user file, but we could still be missing the cbp file
// TODO check that we have a cbp file and if not, open up a dialog ?
......@@ -526,6 +535,14 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
parseCMakeLists(); // Gets the directory from the active buildconfiguration
}
CMakeTarget CMakeProject::targetForTitle(const QString &title)
{
foreach(const CMakeTarget &ct, m_targets)
if (ct.title == title)
return ct;
return CMakeTarget();
}
CMakeFile::CMakeFile(CMakeProject *parent, QString fileName)
: Core::IFile(parent), m_project(parent), m_fileName(fileName)
{
......
......@@ -101,6 +101,7 @@ public:
MakeStep *makeStep() const;
QStringList targets() const;
QString buildParser(const QString &buildConfiguration) const;
CMakeTarget targetForTitle(const QString &title);
protected:
virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
......
......@@ -168,8 +168,11 @@ QStringList CMakeRunConfigurationFactory::canCreate(ProjectExplorer::Project *pr
CMakeProject *pro = qobject_cast<CMakeProject *>(project);
if (!pro)
return QStringList();
// TODO gather all targets and return them here
return QStringList();
QStringList allTargets = pro->targets();
for (int i=0; i<allTargets.size(); ++i) {
allTargets[i] = Constants::CMAKERUNCONFIGURATION + allTargets[i];
}
return allTargets;
}
// used to translate the types to names to display to the user
......@@ -193,9 +196,9 @@ QSharedPointer<ProjectExplorer::RunConfiguration> CMakeRunConfigurationFactory::
return rc;
} else {
// Adding new
// TODO extract target from type
QString file = type.mid(QString(Constants::CMAKERUNCONFIGURATION).length());
QSharedPointer<ProjectExplorer::RunConfiguration> rc(new CMakeRunConfiguration(pro, file, QString::null, QString::null));
const QString title = type.mid(QString(Constants::CMAKERUNCONFIGURATION).length());
const CMakeTarget &ct = pro->targetForTitle(title);
QSharedPointer<ProjectExplorer::RunConfiguration> rc(new CMakeRunConfiguration(pro, ct.executable, ct.workingDirectory, ct.title));
return rc;
}
}
......@@ -50,6 +50,7 @@ using namespace CMakeProjectManager::Internal;
MakeStep::MakeStep(CMakeProject *pro)
: AbstractProcessStep(pro), m_pro(pro), m_buildParser(0)
{
m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
}
MakeStep::~MakeStep()
......@@ -98,16 +99,23 @@ bool MakeStep::init(const QString &buildConfiguration)
setCommand(buildConfiguration, "make"); // TODO give full path here?
#endif // Q_OS_WIN
QStringList arguments = value(buildConfiguration, "buildTargets").toStringList();
arguments << additionalArguments(buildConfiguration);
setArguments(buildConfiguration, arguments); // TODO
setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
if (value("clean").isValid() && value("clean").toBool()) {
setArguments(buildConfiguration, QStringList() << "clean");
} else {
QStringList arguments = value(buildConfiguration, "buildTargets").toStringList();
arguments << additionalArguments(buildConfiguration);
setArguments(buildConfiguration, arguments); // TODO
setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
}
return AbstractProcessStep::init(buildConfiguration);
}
void MakeStep::run(QFutureInterface<bool> &fi)
{
m_futureInterface = &fi;
m_futureInterface->setProgressRange(0, 100);
AbstractProcessStep::run(fi);
m_futureInterface = 0;
}
QString MakeStep::name()
......@@ -134,6 +142,12 @@ void MakeStep::stdOut(const QString &line)
{
if (m_buildParser)
m_buildParser->stdOutput(line);
if (m_percentProgress.indexIn(line) != -1) {
bool ok = false;
int percent = m_percentProgress.cap(1).toInt(&ok);;
if (ok)
m_futureInterface->setProgressValue(percent);
}
AbstractProcessStep::stdOut(line);
}
......
......@@ -73,6 +73,8 @@ private:
CMakeProject *m_pro;
ProjectExplorer::BuildParserInterface *m_buildParser;
QSet<QString> m_openDirectories;
QRegExp m_percentProgress;
QFutureInterface<bool> *m_futureInterface;
};
class MakeStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget
......
......@@ -1336,13 +1336,16 @@ void EditorManager::updateActions()
m_d->m_revertToSavedAction->setEnabled(curEditor != 0
&& !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified());
m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(fName));
m_d->m_saveAction->setText(tr("&Save %1").arg(fName));
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(fName));
QString quotedName;
if (!fName.isEmpty())
quotedName = '"' + fName + '"';
m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName));
m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName));
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName));
m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0);
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(fName));
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName));
m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0);
m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorHistory.count() > 0);
......
......@@ -419,11 +419,11 @@ EditorView::EditorView(EditorModel *model, QWidget *parent) :
m_statusWidgetButton->setText(tr("Placeholder"));
hbox->addWidget(m_statusWidgetButton);
m_statusHLine->setVisible(false);
m_statusWidget->setVisible(false);
tl->addWidget(m_statusHLine);
tl->addWidget(m_statusWidget);
}
}
EditorView::~EditorView()
......
......@@ -63,6 +63,7 @@
#include "editormanager/ieditorfactory.h"
#include "baseview.h"
#include "basefilewizard.h"
#include "ioutputpane.h"
#include <coreplugin/findplaceholder.h>
#include <utils/pathchooser.h>
......@@ -302,6 +303,9 @@ bool MainWindow::init(QString *errorMessage)
outputModeWidget->layout()->addWidget(new Core::FindToolBarPlaceHolder(m_outputMode));
outputModeWidget->setFocusProxy(oph);
connect(m_modeManager, SIGNAL(currentModeChanged(Core::IMode*)),
this, SLOT(modeChanged(Core::IMode*)), Qt::QueuedConnection);
m_outputMode->setContext(m_globalContext);
pm->addObject(m_outputMode);
pm->addObject(m_generalSettings);
......@@ -317,6 +321,16 @@ bool MainWindow::init(QString *errorMessage)
return true;
}
void MainWindow::modeChanged(Core::IMode *mode)
{
if (mode == m_outputMode) {
int idx = OutputPaneManager::instance()->m_widgetComboBox->itemData(OutputPaneManager::instance()->m_widgetComboBox->currentIndex()).toInt();
IOutputPane *out = OutputPaneManager::instance()->m_pageMap.value(idx);
if (out && out->canFocus())
out->setFocus();
}
}
void MainWindow::extensionsInitialized()
{
m_editorManager->init();
......
......@@ -64,6 +64,7 @@ class UniqueIDManager;
class VariableManager;
class VCSManager;
class ViewManagerInterface;
class IMode;
namespace Internal {
......@@ -153,6 +154,7 @@ private slots:
void updateFocusWidget(QWidget *old, QWidget *now);
void setSidebarVisible(bool visible);
void destroyVersionDialog();
void modeChanged(Core::IMode *mode);
private:
void updateContextObject(IContext *context);
......
......@@ -233,10 +233,13 @@ void WelcomeMode::updateWelcomePage(const WelcomePageData &welcomePageData)
{
QString projects;
QTextStream str(&projects);
foreach (const QString &s, welcomePageData.projectList) {
const QFileInfo fi(s);
str << "<li><p><a href=\"gh-project:" << s << "\" title=\""
<< fi.absolutePath() << "\">" << fi.fileName() << "</a></p></li>\n";
QList<QPair<QString, QString> >::const_iterator it, end;
end = welcomePageData.projectList.constEnd();
for( it = welcomePageData.projectList.constBegin(); it != end; ++it) {
const QFileInfo fi((*it).first);
str << "<li><p><a href=\"gh-project:" << (*it).first << "\" title=\""
<< fi.absolutePath() << "\">" << (*it).second << "</a></p></li>\n";
}
projectHtml.replace(QLatin1String("<!-- RECENT PROJECTS LIST -->"), projects);
}
......
......@@ -33,6 +33,7 @@
#include <coreplugin/imode.h>
#include <QtCore/QObject>
#include <QtCore/QPair>
QT_BEGIN_NAMESPACE
class QWidget;
......@@ -59,7 +60,7 @@ public:
QString previousSession;
QString activeSession;
QStringList sessionList;
QStringList projectList;
QList<QPair<QString, QString> > projectList; // pair of filename, displayname
};
void updateWelcomePage(const WelcomePageData &welcomePageData);
......
......@@ -602,22 +602,6 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
if (!doc)
return link;
// Handle include directives
const unsigned lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineno && incl.resolved()) {
link.fileName = incl.fileName();
link.pos = cursor.block().position();
link.length = cursor.block().length();
return link;
}
}
// Find the last symbol up to the cursor position
Symbol *lastSymbol = doc->findSymbolAt(line, column);
if (!lastSymbol)
return link;
QTextCursor tc = cursor;
static TokenUnderCursor tokenUnderCursor;
......@@ -625,20 +609,33 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
QTextBlock block;
const SimpleToken tk = tokenUnderCursor(tc, &block);
if (tk.isLiteral() || tk.isComment()) {
// Drop out if we're at a number, string or comment
return link;
// Handle include directives
if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
const unsigned lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineno && incl.resolved()) {
link.fileName = incl.fileName();
link.pos = cursor.block().position() + tk.position() + 1;
link.length = tk.length() - 2;
return link;
}
}
}
if (tk.isNot(T_IDENTIFIER))
return link;
// Find the last symbol up to the cursor position
Symbol *lastSymbol = doc->findSymbolAt(line, column);
if (!lastSymbol)
return link;
const int nameStart = tk.position();
const int nameLength = tk.length();
const int endOfName = nameStart + nameLength;
const int endOfName = block.position() + nameStart + nameLength;
const QString name = block.text().mid(nameStart, nameLength);
tc.setPosition(block.position() + endOfName);
tc.setPosition(endOfName);
// Evaluate the type of the expression under the cursor
ExpressionUnderCursor expressionUnderCursor;
......@@ -668,7 +665,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
def = findDefinition(symbol);
link = linkToSymbol(def ? def : symbol);
link.pos = nameStart;
link.pos = block.position() + nameStart;
link.length = nameLength;
return link;
......
......@@ -383,9 +383,9 @@ void FunctionArgumentWidget::updateHintText()
const QDesktopWidget *desktop = QApplication::desktop();
#ifdef Q_OS_MAC
const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_popupFrame));
const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_editor->widget()));
#else
const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_popupFrame));
const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_editor->widget()));
#endif
const QSize sz = m_popupFrame->sizeHint();
......@@ -508,14 +508,11 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
return start;
}
bool CppCodeCompletion::isValid(TextEditor::ITextEditable *editor)
bool CppCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
{ return m_manager->isCppEditor(editor); }
bool CppCodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
{
if (! m_manager->isCppEditor(editor)) // ### remove me
return false;
const int pos = editor->position();
if (startOfOperator(editor, pos, /*token =*/ 0,
/*want function call=*/ true) != pos)
......
......@@ -58,7 +58,7 @@ class CppCodeCompletion : public TextEditor::ICompletionCollector