forked from qt-creator/qt-creator
Merge branch '1.1' of git@scm.dev.nokia.troll.no:creator/mainline into 1.1
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
bindir=$(dirname "$0")
|
||||
bindir=$(dirname $(readlink -nf $0))
|
||||
if test "$(uname -m)" = "x86_64" ; then
|
||||
libdir=$(cd ${bindir}/../lib64 ; pwd)
|
||||
else
|
||||
|
||||
Vendored
+13
-8
@@ -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
|
||||
public:
|
||||
explicit CppCodeCompletion(CppModelManager *manager);
|
||||
|
||||
bool isValid(TextEditor::ITextEditable *editor);
|
||||
bool supportsEditor(TextEditor::ITextEditable *editor);
|
||||
bool triggersCompletion(TextEditor::ITextEditable *editor);
|
||||
int startCompletion(TextEditor::ITextEditable *editor);
|
||||
void completions(QList<TextEditor::CompletionItem> *completions);
|
||||
|
||||
@@ -161,35 +161,35 @@ DebuggerSettings *theDebuggerSettings()
|
||||
item->setText(QObject::tr("Collapse item"));
|
||||
|
||||
//
|
||||
// Dumpers
|
||||
// DebuggingHelper
|
||||
//
|
||||
item = new SavedAction(instance);
|
||||
instance->insertItem(UseDumpers, item);
|
||||
instance->insertItem(UseDebuggingHelpers, item);
|
||||
item->setDefaultValue(true);
|
||||
item->setSettingsKey("DebugMode", "UseDumpers");
|
||||
item->setText(QObject::tr("Use data dumpers"));
|
||||
item->setSettingsKey("DebugMode", "UseDebuggingHelper");
|
||||
item->setText(QObject::tr("Use Debugging Helper"));
|
||||
item->setCheckable(true);
|
||||
item->setDefaultValue(true);
|
||||
|
||||
item = new SavedAction(instance);
|
||||
instance->insertItem(UseCustomDumperLocation, item);
|
||||
item->setSettingsKey("DebugMode", "CustomDumperLocation");
|
||||
instance->insertItem(UseCustomDebuggingHelperLocation, item);
|
||||
item->setSettingsKey("DebugMode", "CustomDebuggingHelperLocation");
|
||||
item->setCheckable(true);
|
||||
|
||||
item = new SavedAction(instance);
|
||||
instance->insertItem(CustomDumperLocation, item);
|
||||
item->setSettingsKey("DebugMode", "CustomDumperLocation");
|
||||
instance->insertItem(CustomDebuggingHelperLocation, item);
|
||||
item->setSettingsKey("DebugMode", "CustomDebuggingHelperLocation");
|
||||
|
||||
item = new SavedAction(instance);
|
||||
instance->insertItem(DebugDumpers, item);
|
||||
item->setSettingsKey("DebugMode", "DebugDumpers");
|
||||
item->setText(QObject::tr("Debug data dumpers"));
|
||||
instance->insertItem(DebugDebuggingHelpers, item);
|
||||
item->setSettingsKey("DebugMode", "DebugDebuggingHelpers");
|
||||
item->setText(QObject::tr("Debug debugging helper"));
|
||||
item->setCheckable(true);
|
||||
|
||||
|
||||
item = new SavedAction(instance);
|
||||
item->setText(QObject::tr("Recheck custom dumper availability"));
|
||||
instance->insertItem(RecheckDumpers, item);
|
||||
item->setText(QObject::tr("Recheck debugging helper availability"));
|
||||
instance->insertItem(RecheckDebuggingHelpers, item);
|
||||
|
||||
//
|
||||
// Breakpoints
|
||||
@@ -314,6 +314,14 @@ DebuggerSettings *theDebuggerSettings()
|
||||
item->setDefaultValue(20);
|
||||
instance->insertItem(MaximalStackDepth, item);
|
||||
|
||||
item = new SavedAction(instance);
|
||||
item->setText(QObject::tr("Reload full stack"));
|
||||
instance->insertItem(ExpandStack, item);
|
||||
|
||||
item = new SavedAction(instance);
|
||||
item->setText(QObject::tr("Execute line"));
|
||||
instance->insertItem(ExecuteCommand, item);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,9 +75,11 @@ enum DebuggerActionCode
|
||||
GdbLocation,
|
||||
GdbEnvironment,
|
||||
GdbScriptFile,
|
||||
ExecuteCommand,
|
||||
|
||||
// Stack
|
||||
MaximalStackDepth,
|
||||
ExpandStack,
|
||||
|
||||
// Watchers & Locals
|
||||
WatchExpression,
|
||||
@@ -90,11 +92,11 @@ enum DebuggerActionCode
|
||||
ExpandItem,
|
||||
CollapseItem,
|
||||
|
||||
RecheckDumpers,
|
||||
UseDumpers,
|
||||
UseCustomDumperLocation,
|
||||
CustomDumperLocation,
|
||||
DebugDumpers,
|
||||
RecheckDebuggingHelpers,
|
||||
UseDebuggingHelpers,
|
||||
UseCustomDebuggingHelperLocation,
|
||||
CustomDebuggingHelperLocation,
|
||||
DebugDebuggingHelpers,
|
||||
|
||||
// Source List
|
||||
ListSourceFiles,
|
||||
|
||||
@@ -148,8 +148,7 @@ extern IDebuggerEngine *createWinEngine(DebuggerManager *)
|
||||
#endif
|
||||
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
||||
|
||||
DebuggerManager::DebuggerManager() :
|
||||
m_attachCoreAction(0)
|
||||
DebuggerManager::DebuggerManager()
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -279,7 +278,7 @@ void DebuggerManager::init()
|
||||
connect(m_watchHandler, SIGNAL(setSessionValueRequested(QString,QVariant)),
|
||||
this, SIGNAL(setSessionValueRequested(QString,QVariant)));
|
||||
connect(theDebuggerAction(AssignValue), SIGNAL(triggered()),
|
||||
this, SLOT(assignValueInDebugger()));
|
||||
this, SLOT(assignValueInDebugger()), Qt::QueuedConnection);
|
||||
|
||||
// Tooltip
|
||||
QTreeView *tooltipView = qobject_cast<QTreeView *>(m_tooltipWindow);
|
||||
@@ -294,11 +293,9 @@ void DebuggerManager::init()
|
||||
m_attachExternalAction = new QAction(this);
|
||||
m_attachExternalAction->setText(tr("Attach to Running External Application..."));
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
m_attachCoreAction = new QAction(this);
|
||||
m_attachCoreAction->setText(tr("Attach to Core..."));
|
||||
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
|
||||
#endif
|
||||
|
||||
m_continueAction = new QAction(this);
|
||||
m_continueAction->setText(tr("Continue"));
|
||||
@@ -358,9 +355,6 @@ void DebuggerManager::init()
|
||||
m_watchAction->setText(tr("Add to Watch Window"));
|
||||
|
||||
// For usuage hints oin focus{In,Out}
|
||||
//connect(m_outputWindow, SIGNAL(statusMessageRequested(QString,int)),
|
||||
// this, SLOT(showStatusMessage(QString,int)));
|
||||
|
||||
connect(m_continueAction, SIGNAL(triggered()),
|
||||
this, SLOT(continueExec()));
|
||||
|
||||
@@ -401,8 +395,8 @@ void DebuggerManager::init()
|
||||
connect(m_statusTimer, SIGNAL(timeout()),
|
||||
this, SLOT(clearStatusMessage()));
|
||||
|
||||
connect(m_outputWindow, SIGNAL(commandExecutionRequested(QString)),
|
||||
this, SLOT(executeDebuggerCommand(QString)));
|
||||
connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
|
||||
this, SLOT(executeDebuggerCommand()));
|
||||
|
||||
|
||||
m_breakDock = createDockForWidget(m_breakWindow);
|
||||
@@ -971,6 +965,7 @@ void DebuggerManager::assignValueInDebugger()
|
||||
assignValueInDebugger(str.left(i), str.mid(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerManager::assignValueInDebugger(const QString &expr, const QString &value)
|
||||
{
|
||||
QTC_ASSERT(m_engine, return);
|
||||
@@ -1036,6 +1031,12 @@ void DebuggerManager::nextIExec()
|
||||
m_engine->nextIExec();
|
||||
}
|
||||
|
||||
void DebuggerManager::executeDebuggerCommand()
|
||||
{
|
||||
if (QAction *action = qobject_cast<QAction *>(sender()))
|
||||
executeDebuggerCommand(action->data().toString());
|
||||
}
|
||||
|
||||
void DebuggerManager::executeDebuggerCommand(const QString &command)
|
||||
{
|
||||
if (Debugger::Constants::Internal::debug)
|
||||
@@ -1168,7 +1169,7 @@ void DebuggerManager::setStatus(int status)
|
||||
if (status == m_status)
|
||||
return;
|
||||
|
||||
if (!isAllowedTransition(m_status, status)) {
|
||||
if (0 && !isAllowedTransition(m_status, status)) {
|
||||
const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3").
|
||||
arg(QLatin1String(Q_FUNC_INFO), QLatin1String(stateName(m_status)), QLatin1String(stateName(status)));
|
||||
qWarning("%s", qPrintable(msg));
|
||||
@@ -1189,8 +1190,11 @@ void DebuggerManager::setStatus(int status)
|
||||
|
||||
m_startExternalAction->setEnabled(!started && !starting);
|
||||
m_attachExternalAction->setEnabled(!started && !starting);
|
||||
if (m_attachCoreAction)
|
||||
m_attachCoreAction->setEnabled(!started && !starting);
|
||||
#ifdef Q_OS_WIN
|
||||
m_attachCoreAction->setEnabled(false);
|
||||
#else
|
||||
m_attachCoreAction->setEnabled(!started && !starting);
|
||||
#endif
|
||||
m_watchAction->setEnabled(ready);
|
||||
m_breakAction->setEnabled(true);
|
||||
|
||||
@@ -1368,7 +1372,7 @@ void DebuggerManager::disassemblerDockToggled(bool on)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sourec files specific stuff
|
||||
// Source files specific stuff
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1445,4 +1449,19 @@ void DebuggerManager::reloadRegisters()
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Testing
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DebuggerManager::runTest(const QString &fileName)
|
||||
{
|
||||
m_executable = fileName;
|
||||
m_processArgs = QStringList() << "--run-debuggee";
|
||||
m_workingDir = QString();
|
||||
if (!startNewDebugger(StartInternal))
|
||||
emit debuggingFinished();
|
||||
}
|
||||
|
||||
#include "debuggermanager.moc"
|
||||
|
||||
@@ -238,6 +238,8 @@ public slots:
|
||||
|
||||
void assignValueInDebugger();
|
||||
void assignValueInDebugger(const QString &expr, const QString &value);
|
||||
|
||||
void executeDebuggerCommand();
|
||||
void executeDebuggerCommand(const QString &command);
|
||||
|
||||
void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
|
||||
@@ -339,6 +341,7 @@ public:
|
||||
private:
|
||||
void init();
|
||||
void setDebuggerType(DebuggerType type);
|
||||
void runTest(const QString &fileName);
|
||||
QDockWidget *createDockForWidget(QWidget *widget);
|
||||
Q_SLOT void createNewDock(QWidget *widget);
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ public:
|
||||
menu->addAction(m_clearContentsAction);
|
||||
//menu->addAction(m_saveContentsAction);
|
||||
addContextActions(menu);
|
||||
theDebuggerAction(ExecuteCommand)->setData(textCursor().block().text());
|
||||
menu->addAction(theDebuggerAction(ExecuteCommand));
|
||||
menu->addSeparator();
|
||||
menu->addAction(theDebuggerAction(SettingsDialog));
|
||||
menu->exec(ev->globalPos());
|
||||
@@ -101,35 +103,20 @@ class InputPane : public DebuggerPane
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InputPane(QWidget *parent) : DebuggerPane(parent)
|
||||
{
|
||||
m_commandExecutionAction = new QAction(this);
|
||||
m_commandExecutionAction->setText("Execute line");
|
||||
m_commandExecutionAction->setEnabled(true);
|
||||
//m_commandExecutionAction->setShortcut
|
||||
// (Qt::ControlModifier + Qt::Key_Return);
|
||||
|
||||
connect(m_commandExecutionAction, SIGNAL(triggered(bool)),
|
||||
this, SLOT(executeCommand()));
|
||||
}
|
||||
InputPane(QWidget *parent)
|
||||
: DebuggerPane(parent)
|
||||
{}
|
||||
|
||||
signals:
|
||||
void commandExecutionRequested(const QString &);
|
||||
void clearContentsRequested();
|
||||
void statusMessageRequested(const QString &, int);
|
||||
void commandSelected(int);
|
||||
|
||||
private slots:
|
||||
void executeCommand()
|
||||
{
|
||||
emit commandExecutionRequested(textCursor().block().text());
|
||||
}
|
||||
|
||||
private:
|
||||
void keyPressEvent(QKeyEvent *ev)
|
||||
{
|
||||
if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return)
|
||||
emit commandExecutionRequested(textCursor().block().text());
|
||||
theDebuggerAction(ExecuteCommand)->trigger(textCursor().block().text());
|
||||
else if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_R)
|
||||
emit clearContentsRequested();
|
||||
else
|
||||
@@ -157,7 +144,7 @@ private:
|
||||
|
||||
void addContextActions(QMenu *menu)
|
||||
{
|
||||
menu->addAction(m_commandExecutionAction);
|
||||
menu->addAction(theDebuggerAction(ExecuteCommand));
|
||||
}
|
||||
|
||||
void focusInEvent(QFocusEvent *ev)
|
||||
@@ -171,8 +158,6 @@ private:
|
||||
emit statusMessageRequested(QString(), -1);
|
||||
QPlainTextEdit::focusOutEvent(ev);
|
||||
}
|
||||
|
||||
QAction *m_commandExecutionAction;
|
||||
};
|
||||
|
||||
|
||||
@@ -252,19 +237,12 @@ DebuggerOutputWindow::DebuggerOutputWindow(QWidget *parent)
|
||||
aggregate->add(new BaseTextFind(m_inputText));
|
||||
#endif
|
||||
|
||||
connect(m_inputText, SIGNAL(commandExecutionRequested(QString)),
|
||||
this, SIGNAL(commandExecutionRequested(QString)));
|
||||
connect(m_inputText, SIGNAL(statusMessageRequested(QString,int)),
|
||||
this, SIGNAL(statusMessageRequested(QString,int)));
|
||||
connect(m_inputText, SIGNAL(commandSelected(int)),
|
||||
m_combinedText, SLOT(gotoResult(int)));
|
||||
};
|
||||
|
||||
void DebuggerOutputWindow::onReturnPressed()
|
||||
{
|
||||
emit commandExecutionRequested(m_commandEdit->text());
|
||||
}
|
||||
|
||||
void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &output)
|
||||
{
|
||||
if (output.isEmpty())
|
||||
|
||||
@@ -65,10 +65,6 @@ public slots:
|
||||
signals:
|
||||
void showPage();
|
||||
void statusMessageRequested(const QString &msg, int);
|
||||
void commandExecutionRequested(const QString &cmd);
|
||||
|
||||
private slots:
|
||||
void onReturnPressed();
|
||||
|
||||
private:
|
||||
QPlainTextEdit *m_combinedText; // combined input/output
|
||||
|
||||
@@ -321,23 +321,23 @@ QWidget *GdbOptionPage::createPage(QWidget *parent)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DumperOptionPage
|
||||
// DebuggingHelperOptionPage
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class DumperOptionPage : public Core::IOptionsPage
|
||||
class DebuggingHelperOptionPage : public Core::IOptionsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DumperOptionPage() {}
|
||||
DebuggingHelperOptionPage() {}
|
||||
|
||||
// IOptionsPage
|
||||
QString id() const { return QLatin1String("DataDumper"); }
|
||||
QString trName() const { return tr("Data Dumper"); }
|
||||
QString id() const { return QLatin1String("DebuggingHelper"); }
|
||||
QString trName() const { return tr("Debugging Helper"); }
|
||||
QString category() const { return QLatin1String("Debugger"); }
|
||||
QString trCategory() const { return tr("Debugger"); }
|
||||
|
||||
@@ -349,39 +349,39 @@ private:
|
||||
Q_SLOT void updateState();
|
||||
|
||||
friend class DebuggerPlugin;
|
||||
Ui::DumperOptionPage m_ui;
|
||||
Ui::DebuggingHelperOptionPage m_ui;
|
||||
|
||||
Core::Utils::SavedActionSet m_group;
|
||||
};
|
||||
|
||||
QWidget *DumperOptionPage::createPage(QWidget *parent)
|
||||
QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
|
||||
{
|
||||
QWidget *w = new QWidget(parent);
|
||||
m_ui.setupUi(w);
|
||||
|
||||
m_ui.dumperLocationChooser->setExpectedKind(Core::Utils::PathChooser::Command);
|
||||
m_ui.dumperLocationChooser->setPromptDialogTitle(tr("Choose Dumper Location"));
|
||||
m_ui.dumperLocationChooser->setPromptDialogTitle(tr("Choose DebuggingHelper Location"));
|
||||
m_ui.dumperLocationChooser->setInitialBrowsePathBackup(
|
||||
Core::ICore::instance()->resourcePath() + "../../lib");
|
||||
|
||||
connect(m_ui.checkBoxUseDumpers, SIGNAL(toggled(bool)),
|
||||
connect(m_ui.checkBoxUseDebuggingHelpers, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateState()));
|
||||
connect(m_ui.checkBoxUseCustomDumperLocation, SIGNAL(toggled(bool)),
|
||||
connect(m_ui.checkBoxUseCustomDebuggingHelperLocation, SIGNAL(toggled(bool)),
|
||||
this, SLOT(updateState()));
|
||||
|
||||
m_group.clear();
|
||||
m_group.insert(theDebuggerAction(UseDumpers),
|
||||
m_ui.checkBoxUseDumpers);
|
||||
m_group.insert(theDebuggerAction(UseCustomDumperLocation),
|
||||
m_ui.checkBoxUseCustomDumperLocation);
|
||||
m_group.insert(theDebuggerAction(CustomDumperLocation),
|
||||
m_group.insert(theDebuggerAction(UseDebuggingHelpers),
|
||||
m_ui.checkBoxUseDebuggingHelpers);
|
||||
m_group.insert(theDebuggerAction(UseCustomDebuggingHelperLocation),
|
||||
m_ui.checkBoxUseCustomDebuggingHelperLocation);
|
||||
m_group.insert(theDebuggerAction(CustomDebuggingHelperLocation),
|
||||
m_ui.dumperLocationChooser);
|
||||
|
||||
m_group.insert(theDebuggerAction(DebugDumpers),
|
||||
m_ui.checkBoxDebugDumpers);
|
||||
m_group.insert(theDebuggerAction(DebugDebuggingHelpers),
|
||||
m_ui.checkBoxDebugDebuggingHelpers);
|
||||
|
||||
m_ui.dumperLocationChooser->
|
||||
setEnabled(theDebuggerAction(UseCustomDumperLocation)->value().toBool());
|
||||
setEnabled(theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool());
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
#if 0
|
||||
@@ -396,13 +396,13 @@ QWidget *DumperOptionPage::createPage(QWidget *parent)
|
||||
return w;
|
||||
}
|
||||
|
||||
void DumperOptionPage::updateState()
|
||||
void DebuggingHelperOptionPage::updateState()
|
||||
{
|
||||
m_ui.checkBoxUseCustomDumperLocation->setEnabled(
|
||||
m_ui.checkBoxUseDumpers->isChecked());
|
||||
m_ui.checkBoxUseCustomDebuggingHelperLocation->setEnabled(
|
||||
m_ui.checkBoxUseDebuggingHelpers->isChecked());
|
||||
m_ui.dumperLocationChooser->setEnabled(
|
||||
m_ui.checkBoxUseDumpers->isChecked()
|
||||
&& m_ui.checkBoxUseCustomDumperLocation->isChecked());
|
||||
m_ui.checkBoxUseDebuggingHelpers->isChecked()
|
||||
&& m_ui.checkBoxUseCustomDebuggingHelperLocation->isChecked());
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
@@ -652,7 +652,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
// FIXME:
|
||||
m_generalOptionPage = new GdbOptionPage;
|
||||
addObject(m_generalOptionPage);
|
||||
m_dumperOptionPage = new DumperOptionPage;
|
||||
m_dumperOptionPage = new DebuggingHelperOptionPage;
|
||||
addObject(m_dumperOptionPage);
|
||||
|
||||
m_locationMark = 0;
|
||||
@@ -796,6 +796,11 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
|
||||
void DebuggerPlugin::extensionsInitialized()
|
||||
{
|
||||
// time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
|
||||
QByteArray env = qgetenv("QTC_DEBUGGER_TEST");
|
||||
//qDebug() << "EXTENSIONS INITIALIZED:" << env;
|
||||
if (!env.isEmpty())
|
||||
m_manager->runTest(QString::fromLocal8Bit(env));
|
||||
}
|
||||
|
||||
/*! Activates the previous mode when the current mode is the debug mode. */
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Internal {
|
||||
class DebuggerManager;
|
||||
class DebugMode;
|
||||
class GdbOptionPage;
|
||||
class DumperOptionPage;
|
||||
class DebuggingHelperOptionPage;
|
||||
class LocationMark;
|
||||
|
||||
class DebuggerPlugin : public ExtensionSystem::IPlugin
|
||||
@@ -102,14 +102,14 @@ private:
|
||||
|
||||
friend class DebuggerManager;
|
||||
friend class GdbOptionPage;
|
||||
friend class DumperOptionPage;
|
||||
friend class DebuggingHelperOptionPage;
|
||||
friend class DebugMode; // FIXME: Just a hack now so that it can access the views
|
||||
|
||||
DebuggerManager *m_manager;
|
||||
DebugMode *m_debugMode;
|
||||
|
||||
GdbOptionPage *m_generalOptionPage;
|
||||
DumperOptionPage *m_dumperOptionPage;
|
||||
DebuggingHelperOptionPage *m_dumperOptionPage;
|
||||
|
||||
QString m_previousMode;
|
||||
LocationMark *m_locationMark;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = Dumper
|
||||
TARGET = DebuggingHelper
|
||||
CONFIG += shared
|
||||
DESTDIR = ../../../bin
|
||||
include(../../qworkbenchlibrary.pri)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DumperOptionPage</class>
|
||||
<widget class="QWidget" name="DumperOptionPage">
|
||||
<class>DebuggingHelperOptionPage</class>
|
||||
<widget class="QWidget" name="DebuggingHelperOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@@ -15,12 +15,12 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxUseDumpers">
|
||||
<widget class="QCheckBox" name="checkBoxUseDebuggingHelpers">
|
||||
<property name="toolTip">
|
||||
<string>This will enable nice display of Qt and Standard Library objects in the Locals&Watchers view</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use data dumpers</string>
|
||||
<string>Use debugging helper</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -43,12 +43,12 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxUseCustomDumperLocation">
|
||||
<widget class="QCheckBox" name="checkBoxUseCustomDebuggingHelperLocation">
|
||||
<property name="toolTip">
|
||||
<string>This will load a dumper library</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use dumpers from custom location</string>
|
||||
<string>Use debugging helper from custom location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -73,7 +73,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelDumperLocation">
|
||||
<widget class="QLabel" name="labelDebuggingHelperLocation">
|
||||
<property name="text">
|
||||
<string>Location: </string>
|
||||
</property>
|
||||
@@ -85,12 +85,12 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxDebugDumpers">
|
||||
<widget class="QCheckBox" name="checkBoxDebugDebuggingHelpers">
|
||||
<property name="toolTip">
|
||||
<string notr="true">This is an internal tool to make debugging the Custom Data Dumper code easier. Using this action is in general not needed unless you want do debug Qt Creator itself.</string>
|
||||
<string notr="true">This is an internal tool to make debugging the debugging helper code easier. Using this action is in general not needed unless you want do debug Qt Creator itself.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Debug custom dumpers</string>
|
||||
<string>Debug debugging helper</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -108,13 +108,8 @@
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>checkBoxDebugDumpers</zorder>
|
||||
<zorder>checkBoxUseDumpers</zorder>
|
||||
<zorder>checkBoxUseDefaultDumperLocation</zorder>
|
||||
<zorder>horizontalSpacer</zorder>
|
||||
<zorder>labelDumperLocation</zorder>
|
||||
<zorder>horizontalSpacer_2</zorder>
|
||||
<zorder>labelDumperLocation</zorder>
|
||||
<zorder>checkBoxDebugDebuggingHelpers</zorder>
|
||||
<zorder>checkBoxUseDebuggingHelpers</zorder>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
+125
-124
@@ -115,7 +115,7 @@ enum GdbCommandType
|
||||
GdbInfoShared,
|
||||
GdbInfoProc,
|
||||
GdbInfoThreads,
|
||||
GdbQueryDataDumper,
|
||||
GdbQueryDebuggingHelper,
|
||||
GdbTemporaryContinue,
|
||||
GdbTargetCore,
|
||||
|
||||
@@ -147,11 +147,11 @@ enum GdbCommandType
|
||||
WatchVarCreate,
|
||||
WatchEvaluateExpression,
|
||||
WatchToolTip,
|
||||
WatchDumpCustomSetup,
|
||||
WatchDumpCustomValue1, // waiting for gdb ack
|
||||
WatchDumpCustomValue2, // waiting for actual data
|
||||
WatchDumpCustomValue3, // macro based
|
||||
WatchDumpCustomEditValue,
|
||||
WatchDebuggingHelperSetup,
|
||||
WatchDebuggingHelperValue1, // waiting for gdb ack
|
||||
WatchDebuggingHelperValue2, // waiting for actual data
|
||||
WatchDebuggingHelperValue3, // macro based
|
||||
WatchDebuggingHelperEditValue,
|
||||
};
|
||||
|
||||
static int ¤tToken()
|
||||
@@ -211,12 +211,12 @@ void GdbEngine::initializeConnections()
|
||||
q, SLOT(showApplicationOutput(QString)),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(theDebuggerAction(UseDumpers), SIGNAL(valueChanged(QVariant)),
|
||||
this, SLOT(setUseDumpers(QVariant)));
|
||||
connect(theDebuggerAction(DebugDumpers), SIGNAL(valueChanged(QVariant)),
|
||||
this, SLOT(setDebugDumpers(QVariant)));
|
||||
connect(theDebuggerAction(RecheckDumpers), SIGNAL(triggered()),
|
||||
this, SLOT(recheckCustomDumperAvailability()));
|
||||
connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
|
||||
this, SLOT(setUseDebuggingHelpers(QVariant)));
|
||||
connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
|
||||
this, SLOT(setDebugDebuggingHelpers(QVariant)));
|
||||
connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()),
|
||||
this, SLOT(recheckDebuggingHelperAvailability()));
|
||||
|
||||
connect(theDebuggerAction(FormatHexadecimal), SIGNAL(triggered()),
|
||||
this, SLOT(reloadRegisters()));
|
||||
@@ -230,11 +230,14 @@ void GdbEngine::initializeConnections()
|
||||
this, SLOT(reloadRegisters()));
|
||||
connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()),
|
||||
this, SLOT(reloadRegisters()));
|
||||
|
||||
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
|
||||
this, SLOT(reloadFullStack()));
|
||||
}
|
||||
|
||||
void GdbEngine::initializeVariables()
|
||||
{
|
||||
m_dataDumperState = DataDumperUninitialized;
|
||||
m_debuggingHelperState = DebuggingHelperUninitialized;
|
||||
m_gdbVersion = 100;
|
||||
m_gdbBuildVersion = -1;
|
||||
|
||||
@@ -373,12 +376,14 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
|
||||
GdbMi record;
|
||||
while (from != to) {
|
||||
GdbMi data;
|
||||
if (*from != ',') {
|
||||
qDebug() << "MALFORMED ASYNC OUTPUT" << from;
|
||||
return;
|
||||
// happens on archer where we get
|
||||
// 23^running <NL> *running,thread-id="all" <NL> (gdb)
|
||||
record.m_type = GdbMi::Tuple;
|
||||
break;
|
||||
}
|
||||
++from; // skip ','
|
||||
GdbMi data;
|
||||
data.parseResultOrValue(from, to);
|
||||
if (data.isValid()) {
|
||||
//qDebug() << "parsed response: " << data.toString();
|
||||
@@ -395,6 +400,10 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
// target-name="/usr/lib/libdrm.so.2",
|
||||
// host-name="/usr/lib/libdrm.so.2",
|
||||
// symbols-loaded="0"
|
||||
} else if (asyncClass == "library-unloaded") {
|
||||
// Archer has 'id="/usr/lib/libdrm.so.2",
|
||||
// target-name="/usr/lib/libdrm.so.2",
|
||||
// host-name="/usr/lib/libdrm.so.2"
|
||||
} else if (asyncClass == "thread-group-created") {
|
||||
// Archer has "{id="28902"}"
|
||||
} else if (asyncClass == "thread-created") {
|
||||
@@ -403,6 +412,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
// Archer has "{id="28902"}"
|
||||
} else if (asyncClass == "thread-exited") {
|
||||
//"{id="1",group-id="28902"}"
|
||||
} else if (asyncClass == "thread-selected") {
|
||||
//"{id="2"}"
|
||||
#ifdef Q_OS_MAC
|
||||
} else if (asyncClass == "shlibs-updated") {
|
||||
// MAC announces updated libs
|
||||
@@ -473,14 +484,16 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
|
||||
from = inner;
|
||||
if (from != to) {
|
||||
if (*from != ',') {
|
||||
qDebug() << "MALFORMED RESULT OUTPUT" << from;
|
||||
return;
|
||||
if (*from == ',') {
|
||||
++from;
|
||||
record.data.parseTuple_helper(from, to);
|
||||
record.data.m_type = GdbMi::Tuple;
|
||||
record.data.m_name = "data";
|
||||
} else {
|
||||
// Archer has this
|
||||
record.data.m_type = GdbMi::Tuple;
|
||||
record.data.m_name = "data";
|
||||
}
|
||||
++from;
|
||||
record.data.parseTuple_helper(from, to);
|
||||
record.data.m_type = GdbMi::Tuple;
|
||||
record.data.m_name = "data";
|
||||
}
|
||||
|
||||
//qDebug() << "\nLOG STREAM:" + m_pendingLogStreamOutput;
|
||||
@@ -753,8 +766,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
case GdbInfoShared:
|
||||
handleInfoShared(record);
|
||||
break;
|
||||
case GdbQueryDataDumper:
|
||||
handleQueryDataDumper(record);
|
||||
case GdbQueryDebuggingHelper:
|
||||
handleQueryDebuggingHelper(record);
|
||||
break;
|
||||
case GdbTemporaryContinue:
|
||||
continueInferior();
|
||||
@@ -803,7 +816,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
break;
|
||||
|
||||
case StackListFrames:
|
||||
handleStackListFrames(record);
|
||||
handleStackListFrames(record, cookie.toBool());
|
||||
break;
|
||||
case StackListThreads:
|
||||
handleStackListThreads(record, cookie.toInt());
|
||||
@@ -833,19 +846,19 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
case WatchToolTip:
|
||||
handleToolTip(record, cookie.toString());
|
||||
break;
|
||||
case WatchDumpCustomValue1:
|
||||
handleDumpCustomValue1(record, cookie.value<WatchData>());
|
||||
case WatchDebuggingHelperValue1:
|
||||
handleDebuggingHelperValue1(record, cookie.value<WatchData>());
|
||||
break;
|
||||
case WatchDumpCustomValue2:
|
||||
handleDumpCustomValue2(record, cookie.value<WatchData>());
|
||||
case WatchDebuggingHelperValue2:
|
||||
handleDebuggingHelperValue2(record, cookie.value<WatchData>());
|
||||
break;
|
||||
|
||||
case WatchDumpCustomValue3:
|
||||
handleDumpCustomValue3(record, cookie.value<WatchData>());
|
||||
case WatchDebuggingHelperValue3:
|
||||
handleDebuggingHelperValue3(record, cookie.value<WatchData>());
|
||||
break;
|
||||
|
||||
case WatchDumpCustomSetup:
|
||||
handleDumpCustomSetup(record);
|
||||
case WatchDebuggingHelperSetup:
|
||||
handleDebuggingHelperSetup(record);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -857,7 +870,6 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
|
||||
void GdbEngine::executeDebuggerCommand(const QString &command)
|
||||
{
|
||||
//createGdbProcessIfNeeded();
|
||||
if (m_gdbProc.state() == QProcess::NotRunning) {
|
||||
debugMessage("NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: " + command);
|
||||
return;
|
||||
@@ -867,7 +879,6 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
|
||||
cmd.command = command;
|
||||
cmd.type = -1;
|
||||
|
||||
emit gdbInputAvailable(QString(), cmd.command);
|
||||
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
|
||||
}
|
||||
|
||||
@@ -902,7 +913,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record)
|
||||
//
|
||||
qq->reloadRegisters();
|
||||
|
||||
// Gdb-Macro based Dumpers
|
||||
// Gdb-Macro based DebuggingHelpers
|
||||
sendCommand(
|
||||
"define qdumpqstring\n"
|
||||
"set $i = 0\n"
|
||||
@@ -1093,10 +1104,10 @@ void GdbEngine::handleAqcuiredInferior()
|
||||
#endif
|
||||
if (theDebuggerBoolSetting(ListSourceFiles))
|
||||
reloadSourceFiles();
|
||||
tryLoadCustomDumpers();
|
||||
tryLoadDebuggingHelpers();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
// intentionally after tryLoadCustomDumpers(),
|
||||
// intentionally after tryLoadDebuggingHelpers(),
|
||||
// otherwise we'd interupt solib loading.
|
||||
if (theDebuggerBoolSetting(AllPluginBreakpoints)) {
|
||||
sendCommand("set auto-solib-add on");
|
||||
@@ -1205,7 +1216,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
return;
|
||||
}
|
||||
|
||||
//tryLoadCustomDumpers();
|
||||
//tryLoadDebuggingHelpers();
|
||||
|
||||
// jump over well-known frames
|
||||
static int stepCounter = 0;
|
||||
@@ -1303,12 +1314,18 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
#endif
|
||||
}
|
||||
|
||||
void GdbEngine::reloadFullStack()
|
||||
{
|
||||
QString cmd = "-stack-list-frames";
|
||||
sendSynchronizedCommand(cmd, StackListFrames, true);
|
||||
}
|
||||
|
||||
void GdbEngine::reloadStack()
|
||||
{
|
||||
QString cmd = "-stack-list-frames";
|
||||
if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt())
|
||||
cmd += " 0 " + QString::number(stackDepth);
|
||||
sendSynchronizedCommand(cmd, StackListFrames);
|
||||
sendSynchronizedCommand(cmd, StackListFrames, false);
|
||||
}
|
||||
|
||||
void GdbEngine::handleAsyncOutput2(const GdbMi &data)
|
||||
@@ -1506,7 +1523,7 @@ void GdbEngine::exitDebugger()
|
||||
|
||||
m_outputCollector.shutdown();
|
||||
initializeVariables();
|
||||
//q->settings()->m_debugDumpers = false;
|
||||
//q->settings()->m_debugDebuggingHelpers = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1614,7 +1631,7 @@ bool GdbEngine::startDebugger()
|
||||
// otherwise program doesn't know.
|
||||
// Pass and Stop may be combined.
|
||||
// We need "print" as otherwise we would get no feedback whatsoever
|
||||
// Custom Dumper crashs which happen regularily for when accessing
|
||||
// Custom DebuggingHelper crashs which happen regularily for when accessing
|
||||
// uninitialized variables.
|
||||
sendCommand("handle SIGSEGV nopass stop print");
|
||||
|
||||
@@ -1738,7 +1755,7 @@ void GdbEngine::handleAttach()
|
||||
handleAqcuiredInferior();
|
||||
|
||||
q->resetLocation();
|
||||
recheckCustomDumperAvailability();
|
||||
recheckDebuggingHelperAvailability();
|
||||
|
||||
//
|
||||
// Stack
|
||||
@@ -1855,7 +1872,7 @@ void GdbEngine::setTokenBarrier()
|
||||
m_oldestAcceptableToken = currentToken();
|
||||
}
|
||||
|
||||
void GdbEngine::setDebugDumpers(const QVariant &on)
|
||||
void GdbEngine::setDebugDebuggingHelpers(const QVariant &on)
|
||||
{
|
||||
if (on.toBool()) {
|
||||
debugMessage("SWITCHING ON DUMPER DEBUGGING");
|
||||
@@ -2452,7 +2469,7 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
|
||||
}
|
||||
|
||||
|
||||
void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
|
||||
void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull)
|
||||
{
|
||||
QList<StackFrame> stackFrames;
|
||||
|
||||
@@ -2503,30 +2520,11 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
|
||||
topFrame = i;
|
||||
}
|
||||
|
||||
if (n >= theDebuggerAction(MaximalStackDepth)->value().toInt()) {
|
||||
StackFrame frame(n);
|
||||
frame.file = "...";
|
||||
frame.function = "...";
|
||||
frame.from = "...";
|
||||
frame.line = 0;
|
||||
frame.address = "...";
|
||||
stackFrames.append(frame);
|
||||
}
|
||||
bool canExpand = !isFull
|
||||
&& (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
|
||||
theDebuggerAction(ExpandStack)->setEnabled(canExpand);
|
||||
qq->stackHandler()->setFrames(stackFrames, canExpand);
|
||||
|
||||
qq->stackHandler()->setFrames(stackFrames);
|
||||
|
||||
#if 0
|
||||
if (0 && topFrame != -1) {
|
||||
// updates of locals already triggered early
|
||||
const StackFrame &frame = qq->stackHandler()->currentFrame();
|
||||
if (frame.isUsable())
|
||||
q->gotoLocation(frame.file, frame.line, true);
|
||||
else
|
||||
qDebug() << "FULL NAME NOT USABLE 0: " << frame.file;
|
||||
} else {
|
||||
activateFrame(topFrame);
|
||||
}
|
||||
#else
|
||||
if (topFrame != -1) {
|
||||
// updates of locals already triggered early
|
||||
const StackFrame &frame = qq->stackHandler()->currentFrame();
|
||||
@@ -2535,7 +2533,6 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
|
||||
else
|
||||
qDebug() << "FULL NAME NOT USABLE 0: " << frame.file << topFrame;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GdbEngine::selectThread(int index)
|
||||
@@ -2564,6 +2561,10 @@ void GdbEngine::activateFrame(int frameIndex)
|
||||
//qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
|
||||
// << stackHandler->currentIndex();
|
||||
|
||||
if (frameIndex == stackHandler->stackSize()) {
|
||||
reloadFullStack();
|
||||
return;
|
||||
}
|
||||
QTC_ASSERT(frameIndex < stackHandler->stackSize(), return);
|
||||
|
||||
if (oldIndex != frameIndex) {
|
||||
@@ -2697,7 +2698,7 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (theDebuggerBoolSetting(DebugDumpers)) {
|
||||
if (theDebuggerBoolSetting(DebugDebuggingHelpers)) {
|
||||
// minimize interference
|
||||
return;
|
||||
}
|
||||
@@ -2900,7 +2901,7 @@ static void setWatchDataSAddress(WatchData &data, const GdbMi &mi)
|
||||
data.saddr = mi.data();
|
||||
}
|
||||
|
||||
void GdbEngine::setUseDumpers(const QVariant &on)
|
||||
void GdbEngine::setUseDebuggingHelpers(const QVariant &on)
|
||||
{
|
||||
qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
|
||||
// FIXME: a bit too harsh, but otherwise the treeview sometimes look funny
|
||||
@@ -2909,9 +2910,9 @@ void GdbEngine::setUseDumpers(const QVariant &on)
|
||||
updateLocals();
|
||||
}
|
||||
|
||||
bool GdbEngine::isCustomValueDumperAvailable(const QString &type) const
|
||||
bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
|
||||
{
|
||||
if (!theDebuggerBoolSetting(UseDumpers))
|
||||
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
|
||||
return false;
|
||||
|
||||
if (q->startMode() == AttachCore) {
|
||||
@@ -2920,15 +2921,15 @@ bool GdbEngine::isCustomValueDumperAvailable(const QString &type) const
|
||||
|| type == "QStringList" || type.endsWith("::QStringList");
|
||||
}
|
||||
|
||||
if (theDebuggerBoolSetting(DebugDumpers)
|
||||
&& qq->stackHandler()->isDebuggingDumpers())
|
||||
if (theDebuggerBoolSetting(DebugDebuggingHelpers)
|
||||
&& qq->stackHandler()->isDebuggingDebuggingHelpers())
|
||||
return false;
|
||||
|
||||
if (m_dataDumperState != DataDumperAvailable)
|
||||
if (m_debuggingHelperState != DebuggingHelperAvailable)
|
||||
return false;
|
||||
|
||||
// simple types
|
||||
if (m_availableSimpleDumpers.contains(type))
|
||||
if (m_availableSimpleDebuggingHelpers.contains(type))
|
||||
return true;
|
||||
|
||||
// templates
|
||||
@@ -2936,10 +2937,10 @@ bool GdbEngine::isCustomValueDumperAvailable(const QString &type) const
|
||||
QString inner;
|
||||
if (!extractTemplate(type, &tmplate, &inner))
|
||||
return false;
|
||||
return m_availableSimpleDumpers.contains(tmplate);
|
||||
return m_availableSimpleDebuggingHelpers.contains(tmplate);
|
||||
}
|
||||
|
||||
void GdbEngine::runDirectDumper(const WatchData &data, bool dumpChildren)
|
||||
void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildren)
|
||||
{
|
||||
Q_UNUSED(dumpChildren);
|
||||
QString type = data.type;
|
||||
@@ -2952,17 +2953,17 @@ void GdbEngine::runDirectDumper(const WatchData &data, bool dumpChildren)
|
||||
|
||||
QVariant var;
|
||||
var.setValue(data);
|
||||
sendSynchronizedCommand(cmd, WatchDumpCustomValue3, var);
|
||||
sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var);
|
||||
|
||||
q->showStatusMessage(
|
||||
tr("Retrieving data for watch view (%1 requests pending)...")
|
||||
.arg(m_pendingRequests + 1), 10000);
|
||||
}
|
||||
|
||||
void GdbEngine::runCustomDumper(const WatchData &data0, bool dumpChildren)
|
||||
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
|
||||
{
|
||||
if (q->startMode() == AttachCore) {
|
||||
runDirectDumper(data0, dumpChildren);
|
||||
runDirectDebuggingHelper(data0, dumpChildren);
|
||||
return;
|
||||
}
|
||||
WatchData data = data0;
|
||||
@@ -3111,14 +3112,14 @@ void GdbEngine::runCustomDumper(const WatchData &data0, bool dumpChildren)
|
||||
|
||||
QVariant var;
|
||||
var.setValue(data);
|
||||
sendSynchronizedCommand(cmd, WatchDumpCustomValue1, var);
|
||||
sendSynchronizedCommand(cmd, WatchDebuggingHelperValue1, var);
|
||||
|
||||
q->showStatusMessage(
|
||||
tr("Retrieving data for watch view (%1 requests pending)...")
|
||||
.arg(m_pendingRequests + 1), 10000);
|
||||
|
||||
// retrieve response
|
||||
sendSynchronizedCommand("p (char*)qDumpOutBuffer", WatchDumpCustomValue2, var);
|
||||
sendSynchronizedCommand("p (char*)qDumpOutBuffer", WatchDebuggingHelperValue2, var);
|
||||
}
|
||||
|
||||
void GdbEngine::createGdbVariable(const WatchData &data)
|
||||
@@ -3170,7 +3171,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
|
||||
// a common case that can be easily solved
|
||||
if (data.isChildrenNeeded() && isPointerType(data.type)
|
||||
&& !isCustomValueDumperAvailable(data.type)) {
|
||||
&& !hasDebuggingHelperForType(data.type)) {
|
||||
// We sometimes know what kind of children pointers have
|
||||
#if DEBUG_SUBITEM
|
||||
qDebug() << "IT'S A POINTER";
|
||||
@@ -3188,11 +3189,11 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.isValueNeeded() && isCustomValueDumperAvailable(data.type)) {
|
||||
if (data.isValueNeeded() && hasDebuggingHelperForType(data.type)) {
|
||||
#if DEBUG_SUBITEM
|
||||
qDebug() << "UPDATE SUBITEM: CUSTOMVALUE";
|
||||
#endif
|
||||
runCustomDumper(data, qq->watchHandler()->isExpandedIName(data.iname));
|
||||
runDebuggingHelper(data, qq->watchHandler()->isExpandedIName(data.iname));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3228,11 +3229,11 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.isChildrenNeeded() && isCustomValueDumperAvailable(data.type)) {
|
||||
if (data.isChildrenNeeded() && hasDebuggingHelperForType(data.type)) {
|
||||
#if DEBUG_SUBITEM
|
||||
qDebug() << "UPDATE SUBITEM: CUSTOMVALUE WITH CHILDREN";
|
||||
#endif
|
||||
runCustomDumper(data, true);
|
||||
runDebuggingHelper(data, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3253,11 +3254,11 @@ void GdbEngine::updateSubItem(const WatchData &data0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.isChildCountNeeded() && isCustomValueDumperAvailable(data.type)) {
|
||||
if (data.isChildCountNeeded() && hasDebuggingHelperForType(data.type)) {
|
||||
#if DEBUG_SUBITEM
|
||||
qDebug() << "UPDATE SUBITEM: CUSTOMVALUE WITH CHILDREN";
|
||||
#endif
|
||||
runCustomDumper(data, qq->watchHandler()->isExpandedIName(data.iname));
|
||||
runDebuggingHelper(data, qq->watchHandler()->isExpandedIName(data.iname));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3338,7 +3339,7 @@ void GdbEngine::updateWatchModel2()
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleQueryDataDumper(const GdbResultRecord &record)
|
||||
void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record)
|
||||
{
|
||||
//qDebug() << "DATA DUMPER TRIAL:" << record.toString();
|
||||
GdbMi output = record.data.findChild("consolestreamoutput");
|
||||
@@ -3366,11 +3367,11 @@ void GdbEngine::handleQueryDataDumper(const GdbResultRecord &record)
|
||||
|
||||
//qDebug() << "CONTENTS: " << contents.toString();
|
||||
//qDebug() << "SIMPLE DUMPERS: " << simple.toString();
|
||||
m_availableSimpleDumpers.clear();
|
||||
m_availableSimpleDebuggingHelpers.clear();
|
||||
foreach (const GdbMi &item, simple.children())
|
||||
m_availableSimpleDumpers.append(item.data());
|
||||
if (m_availableSimpleDumpers.isEmpty()) {
|
||||
m_dataDumperState = DataDumperUnavailable;
|
||||
m_availableSimpleDebuggingHelpers.append(item.data());
|
||||
if (m_availableSimpleDebuggingHelpers.isEmpty()) {
|
||||
m_debuggingHelperState = DebuggingHelperUnavailable;
|
||||
QMessageBox::warning(q->mainWindow(),
|
||||
tr("Cannot find special data dumpers"),
|
||||
tr("The debugged binary does not contain information needed for "
|
||||
@@ -3380,11 +3381,11 @@ void GdbEngine::handleQueryDataDumper(const GdbResultRecord &record)
|
||||
"into your project directly.")
|
||||
);
|
||||
} else {
|
||||
m_dataDumperState = DataDumperAvailable;
|
||||
m_debuggingHelperState = DebuggingHelperAvailable;
|
||||
q->showStatusMessage(tr("%1 custom dumpers found.")
|
||||
.arg(m_availableSimpleDumpers.size()));
|
||||
.arg(m_availableSimpleDebuggingHelpers.size()));
|
||||
}
|
||||
//qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDumpers;
|
||||
//qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDebuggingHelpers;
|
||||
}
|
||||
|
||||
void GdbEngine::sendWatchParameters(const QByteArray ¶ms0)
|
||||
@@ -3435,7 +3436,7 @@ void GdbEngine::handleVarCreate(const GdbResultRecord &record,
|
||||
if (record.resultClass == GdbResultDone) {
|
||||
data.variable = data.iname;
|
||||
setWatchDataType(data, record.data.findChild("type"));
|
||||
if (isCustomValueDumperAvailable(data.type)) {
|
||||
if (hasDebuggingHelperForType(data.type)) {
|
||||
// we do not trust gdb if we have a custom dumper
|
||||
if (record.data.findChild("children").isValid())
|
||||
data.setChildrenUnneeded();
|
||||
@@ -3483,7 +3484,7 @@ void GdbEngine::handleEvaluateExpression(const GdbResultRecord &record,
|
||||
//updateWatchModel2();
|
||||
}
|
||||
|
||||
void GdbEngine::handleDumpCustomSetup(const GdbResultRecord &record)
|
||||
void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record)
|
||||
{
|
||||
//qDebug() << "CUSTOM SETUP RESULT: " << record.toString();
|
||||
if (record.resultClass == GdbResultDone) {
|
||||
@@ -3494,7 +3495,7 @@ void GdbEngine::handleDumpCustomSetup(const GdbResultRecord &record)
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
|
||||
void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
|
||||
const WatchData &data0)
|
||||
{
|
||||
WatchData data = data0;
|
||||
@@ -3509,7 +3510,7 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
|
||||
//qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg;
|
||||
#ifdef QT_DEBUG
|
||||
// Make debugging of dumpers easier
|
||||
if (theDebuggerBoolSetting(DebugDumpers)
|
||||
if (theDebuggerBoolSetting(DebugDebuggingHelpers)
|
||||
&& msg.startsWith("The program being debugged stopped while")
|
||||
&& msg.contains("qDumpObjectData440")) {
|
||||
// Fake full stop
|
||||
@@ -3526,7 +3527,7 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleDumpCustomValue2(const GdbResultRecord &record,
|
||||
void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
|
||||
const WatchData &data0)
|
||||
{
|
||||
WatchData data = data0;
|
||||
@@ -3626,7 +3627,7 @@ void GdbEngine::handleDumpCustomValue2(const GdbResultRecord &record,
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleDumpCustomValue3(const GdbResultRecord &record,
|
||||
void GdbEngine::handleDebuggingHelperValue3(const GdbResultRecord &record,
|
||||
const WatchData &data0)
|
||||
{
|
||||
WatchData data = data0;
|
||||
@@ -3667,7 +3668,7 @@ void GdbEngine::handleDumpCustomValue3(const GdbResultRecord &record,
|
||||
QString cmd = "qdumpqstring (" + data1.exp + ")";
|
||||
QVariant var;
|
||||
var.setValue(data1);
|
||||
sendSynchronizedCommand(cmd, WatchDumpCustomValue3, var);
|
||||
sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var);
|
||||
}
|
||||
} else {
|
||||
data.setValue("<unavailable>");
|
||||
@@ -3931,7 +3932,7 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
|
||||
data.exp = parent.exp + '.' + exp;
|
||||
}
|
||||
|
||||
if (isCustomValueDumperAvailable(data.type)) {
|
||||
if (hasDebuggingHelperForType(data.type)) {
|
||||
// we do not trust gdb if we have a custom dumper
|
||||
data.setValueNeeded();
|
||||
data.setChildCountNeeded();
|
||||
@@ -3989,8 +3990,8 @@ void GdbEngine::handleToolTip(const GdbResultRecord &record,
|
||||
if (what == "create") {
|
||||
setWatchDataType(m_toolTip, record.data.findChild("type"));
|
||||
setWatchDataChildCount(m_toolTip, record.data.findChild("numchild"));
|
||||
if (isCustomValueDumperAvailable(m_toolTip.type))
|
||||
runCustomDumper(m_toolTip, false);
|
||||
if (hasDebuggingHelperForType(m_toolTip.type))
|
||||
runDebuggingHelper(m_toolTip, false);
|
||||
else
|
||||
q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000);
|
||||
sendCommand("-data-evaluate-expression " + m_toolTip.exp,
|
||||
@@ -4040,18 +4041,18 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
|
||||
|
||||
QString GdbEngine::dumperLibraryName() const
|
||||
{
|
||||
if (theDebuggerAction(UseCustomDumperLocation)->value().toBool())
|
||||
return theDebuggerAction(CustomDumperLocation)->value().toString();
|
||||
if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
|
||||
return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
|
||||
return q->m_dumperLib;
|
||||
}
|
||||
|
||||
void GdbEngine::tryLoadCustomDumpers()
|
||||
void GdbEngine::tryLoadDebuggingHelpers()
|
||||
{
|
||||
if (m_dataDumperState != DataDumperUninitialized)
|
||||
if (m_debuggingHelperState != DebuggingHelperUninitialized)
|
||||
return;
|
||||
|
||||
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
|
||||
m_dataDumperState = DataDumperUnavailable;
|
||||
m_debuggingHelperState = DebuggingHelperUnavailable;
|
||||
QString lib = dumperLibraryName();
|
||||
//qDebug() << "DUMPERLIB: " << lib;
|
||||
|
||||
@@ -4063,44 +4064,44 @@ void GdbEngine::tryLoadCustomDumpers()
|
||||
return;
|
||||
}
|
||||
|
||||
m_dataDumperState = DataDumperLoadTried;
|
||||
m_debuggingHelperState = DebuggingHelperLoadTried;
|
||||
#if defined(Q_OS_WIN)
|
||||
sendCommand("sharedlibrary .*"); // for LoadLibraryA
|
||||
//sendCommand("handle SIGSEGV pass stop print");
|
||||
//sendCommand("set unwindonsignal off");
|
||||
sendCommand("call LoadLibraryA(\"" + lib + "\")",
|
||||
WatchDumpCustomSetup);
|
||||
WatchDebuggingHelperSetup);
|
||||
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||
#elif defined(Q_OS_MAC)
|
||||
//sendCommand("sharedlibrary libc"); // for malloc
|
||||
//sendCommand("sharedlibrary libdl"); // for dlopen
|
||||
QString flag = QString::number(RTLD_NOW);
|
||||
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
||||
WatchDumpCustomSetup);
|
||||
WatchDebuggingHelperSetup);
|
||||
//sendCommand("sharedlibrary " + dotEscape(lib));
|
||||
m_dataDumperState = DataDumperLoadTried;
|
||||
m_debuggingHelperState = DebuggingHelperLoadTried;
|
||||
#else
|
||||
//sendCommand("p dlopen");
|
||||
QString flag = QString::number(RTLD_NOW);
|
||||
sendCommand("sharedlibrary libc"); // for malloc
|
||||
sendCommand("sharedlibrary libdl"); // for dlopen
|
||||
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
||||
WatchDumpCustomSetup);
|
||||
WatchDebuggingHelperSetup);
|
||||
// some older systems like CentOS 4.6 prefer this:
|
||||
sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")",
|
||||
WatchDumpCustomSetup);
|
||||
WatchDebuggingHelperSetup);
|
||||
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||
#endif
|
||||
// retreive list of dumpable classes
|
||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper);
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDebuggingHelper);
|
||||
}
|
||||
|
||||
void GdbEngine::recheckCustomDumperAvailability()
|
||||
void GdbEngine::recheckDebuggingHelperAvailability()
|
||||
{
|
||||
// retreive list of dumpable classes
|
||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper);
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDebuggingHelper);
|
||||
}
|
||||
|
||||
IDebuggerEngine *createGdbEngine(DebuggerManager *parent)
|
||||
|
||||
@@ -72,12 +72,12 @@ struct GdbCookie
|
||||
QVariant cookie;
|
||||
};
|
||||
|
||||
enum DataDumperState
|
||||
enum DebuggingHelperState
|
||||
{
|
||||
DataDumperUninitialized,
|
||||
DataDumperLoadTried,
|
||||
DataDumperAvailable,
|
||||
DataDumperUnavailable,
|
||||
DebuggingHelperUninitialized,
|
||||
DebuggingHelperLoadTried,
|
||||
DebuggingHelperAvailable,
|
||||
DebuggingHelperUnavailable,
|
||||
};
|
||||
|
||||
|
||||
@@ -130,8 +130,8 @@ private:
|
||||
void loadSymbols(const QString &moduleName);
|
||||
void loadAllSymbols();
|
||||
|
||||
Q_SLOT void setDebugDumpers(const QVariant &on);
|
||||
Q_SLOT void setUseDumpers(const QVariant &on);
|
||||
Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
|
||||
Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
|
||||
|
||||
//
|
||||
// Own stuff
|
||||
@@ -277,10 +277,11 @@ private:
|
||||
//
|
||||
// Stack specific stuff
|
||||
//
|
||||
void handleStackListFrames(const GdbResultRecord &record);
|
||||
void handleStackListFrames(const GdbResultRecord &record, bool isFull);
|
||||
void handleStackSelectThread(const GdbResultRecord &record, int cookie);
|
||||
void handleStackListThreads(const GdbResultRecord &record, int cookie);
|
||||
void reloadStack();
|
||||
Q_SLOT void reloadStack();
|
||||
Q_SLOT void reloadFullStack();
|
||||
|
||||
|
||||
//
|
||||
@@ -305,11 +306,11 @@ private:
|
||||
void handleTypeContents(const QString &output);
|
||||
void maybeHandleInferiorPidChanged(const QString &pid);
|
||||
|
||||
void tryLoadCustomDumpers();
|
||||
Q_SLOT void recheckCustomDumperAvailability();
|
||||
void runCustomDumper(const WatchData &data, bool dumpChildren);
|
||||
void runDirectDumper(const WatchData &data, bool dumpChildren);
|
||||
bool isCustomValueDumperAvailable(const QString &type) const;
|
||||
void tryLoadDebuggingHelpers();
|
||||
Q_SLOT void recheckDebuggingHelperAvailability();
|
||||
void runDebuggingHelper(const WatchData &data, bool dumpChildren);
|
||||
void runDirectDebuggingHelper(const WatchData &data, bool dumpChildren);
|
||||
bool hasDebuggingHelperForType(const QString &type) const;
|
||||
|
||||
void handleVarListChildren(const GdbResultRecord &record,
|
||||
const WatchData &cookie);
|
||||
@@ -320,15 +321,15 @@ private:
|
||||
const WatchData &cookie);
|
||||
void handleToolTip(const GdbResultRecord &record,
|
||||
const QString &cookie);
|
||||
void handleQueryDataDumper(const GdbResultRecord &record);
|
||||
void handleDumpCustomValue1(const GdbResultRecord &record,
|
||||
void handleQueryDebuggingHelper(const GdbResultRecord &record);
|
||||
void handleDebuggingHelperValue1(const GdbResultRecord &record,
|
||||
const WatchData &cookie);
|
||||
void handleDumpCustomValue2(const GdbResultRecord &record,
|
||||
void handleDebuggingHelperValue2(const GdbResultRecord &record,
|
||||
const WatchData &cookie);
|
||||
void handleDumpCustomValue3(const GdbResultRecord &record,
|
||||
void handleDebuggingHelperValue3(const GdbResultRecord &record,
|
||||
const WatchData &cookie);
|
||||
void handleDumpCustomEditValue(const GdbResultRecord &record);
|
||||
void handleDumpCustomSetup(const GdbResultRecord &record);
|
||||
void handleDebuggingHelperEditValue(const GdbResultRecord &record);
|
||||
void handleDebuggingHelperSetup(const GdbResultRecord &record);
|
||||
void handleStackListLocals(const GdbResultRecord &record);
|
||||
void handleStackListArguments(const GdbResultRecord &record);
|
||||
void handleVarListChildrenHelper(const GdbMi &child,
|
||||
@@ -339,11 +340,11 @@ private:
|
||||
QString m_editedData;
|
||||
int m_pendingRequests;
|
||||
|
||||
QStringList m_availableSimpleDumpers;
|
||||
QStringList m_availableSimpleDebuggingHelpers;
|
||||
QString m_namespace; // namespace used in "namespaced Qt";
|
||||
int m_qtVersion; // Qt version used in the debugged program
|
||||
|
||||
DataDumperState m_dataDumperState; // state of qt creator dumpers
|
||||
DebuggingHelperState m_debuggingHelperState;
|
||||
QList<GdbMi> m_currentFunctionArgs;
|
||||
QString m_currentFrame;
|
||||
QMap<QString, QString> m_varToType;
|
||||
|
||||
+55
-201
@@ -115,18 +115,18 @@ void GdbMi::parseValue(const char *&from, const char *to)
|
||||
{
|
||||
//qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from);
|
||||
switch (*from) {
|
||||
case '{':
|
||||
parseTuple(from, to);
|
||||
break;
|
||||
case '[':
|
||||
parseList(from, to);
|
||||
break;
|
||||
case '"':
|
||||
m_type = Const;
|
||||
m_data = parseCString(from, to);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case '{':
|
||||
parseTuple(from, to);
|
||||
break;
|
||||
case '[':
|
||||
parseList(from, to);
|
||||
break;
|
||||
case '"':
|
||||
m_type = Const;
|
||||
m_data = parseCString(from, to);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,52 +211,53 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
|
||||
}
|
||||
}
|
||||
|
||||
static QByteArray escaped(QByteArray ba)
|
||||
{
|
||||
ba.replace("\"", "\\\"");
|
||||
return ba;
|
||||
}
|
||||
|
||||
QByteArray GdbMi::toString(bool multiline, int indent) const
|
||||
{
|
||||
QByteArray result;
|
||||
switch (m_type) {
|
||||
case Invalid:
|
||||
if (multiline) {
|
||||
result += ind(indent) + "Invalid\n";
|
||||
} else {
|
||||
result += "Invalid";
|
||||
}
|
||||
break;
|
||||
case Const:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
if (multiline) {
|
||||
result += "\"" + m_data + "\"";
|
||||
} else {
|
||||
result += "\"" + m_data + "\"";
|
||||
}
|
||||
break;
|
||||
case Tuple:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
if (multiline) {
|
||||
result += "{\n";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += '\n' + ind(indent) + "}";
|
||||
} else {
|
||||
result += "{";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += "}";
|
||||
}
|
||||
break;
|
||||
case List:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
if (multiline) {
|
||||
result += "[\n";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += "]";
|
||||
} else {
|
||||
result += "[";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += '\n' + ind(indent) + "]";
|
||||
}
|
||||
break;
|
||||
case Invalid:
|
||||
if (multiline)
|
||||
result += ind(indent) + "Invalid\n";
|
||||
else
|
||||
result += "Invalid";
|
||||
break;
|
||||
case Const:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
result += "\"" + escaped(m_data) + "\"";
|
||||
break;
|
||||
case Tuple:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
if (multiline) {
|
||||
result += "{\n";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += '\n' + ind(indent) + "}";
|
||||
} else {
|
||||
result += "{";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += "}";
|
||||
}
|
||||
break;
|
||||
case List:
|
||||
if (!m_name.isEmpty())
|
||||
result += m_name + "=";
|
||||
if (multiline) {
|
||||
result += "[\n";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += '\n' + ind(indent) + "]";
|
||||
} else {
|
||||
result += "[";
|
||||
dumpChildren(&result, multiline, indent + 1);
|
||||
result += "]";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -319,152 +320,5 @@ QByteArray GdbResultRecord::toString() const
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GdbStreamOutput
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
|
||||
static const char test1[] =
|
||||
"1^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
|
||||
"func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test2[] =
|
||||
"2^done,stack=[frame={level=\"0\",addr=\"0x00002ac058675840\","
|
||||
"func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\","
|
||||
"fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"},"
|
||||
"frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test3[] =
|
||||
"3^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
|
||||
"func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test4[] =
|
||||
"&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\"\n"
|
||||
"4^done\n"
|
||||
"(gdb)\n";
|
||||
|
||||
|
||||
static const char test5[] =
|
||||
"1*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\","
|
||||
"frame={addr=\"0x0000000000405738\",func=\"main\","
|
||||
"args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}],"
|
||||
"file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\","
|
||||
"line=\"209\"}\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test6[] =
|
||||
"{u = {u = 2048, v = 16788279, w = -689265400}, a = 1, b = -689265424, c = 11063, s = {static null = {<No data fields>}, static shared_null = {ref = {value = 2}, alloc = 0, size = 0, data = 0x6098da, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, static shared_empty = {ref = {value = 1}, alloc = 0, size = 0, data = 0x2b37d84f8fba, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, d = 0x6098c0, static codecForCStrings = 0x0}}";
|
||||
|
||||
static const char test8[] =
|
||||
"8^done,data={locals={{name=\"a\"},{name=\"w\"}}}\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test9[] =
|
||||
"9^done,data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}\n"
|
||||
"(gdb)\n";
|
||||
|
||||
|
||||
static const char test10[] =
|
||||
"16^done,name=\"urgs\",numchild=\"1\",type=\"Urgs\"\n"
|
||||
"(gdb)\n"
|
||||
"17^done,name=\"purgs\",numchild=\"1\",type=\"Urgs *\"\n"
|
||||
"(gdb)\n"
|
||||
"18^done,name=\"bar\",numchild=\"0\",type=\"int\"\n"
|
||||
"(gdb)\n"
|
||||
"19^done,name=\"z\",numchild=\"0\",type=\"int\"\n"
|
||||
"(gdb)\n";
|
||||
|
||||
static const char test11[] =
|
||||
"[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"},"
|
||||
"{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
|
||||
|
||||
static const char test12[] =
|
||||
"{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\",numchild=\"0\"}";
|
||||
|
||||
static struct Tester {
|
||||
|
||||
Tester() {
|
||||
//test(test10);
|
||||
test2(test12);
|
||||
//test(test4);
|
||||
//apple();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void test(const char* input)
|
||||
{
|
||||
//qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
|
||||
//qPrintable(GdbResponse(input).toString()));
|
||||
}
|
||||
|
||||
void test2(const char* input)
|
||||
{
|
||||
GdbMi mi(input);
|
||||
qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
|
||||
qPrintable(mi.toString()));
|
||||
}
|
||||
|
||||
void apple()
|
||||
{
|
||||
QByteArray input(test9);
|
||||
/*
|
||||
qDebug() << "input: " << input;
|
||||
input = input.replace("{{","[");
|
||||
input = input.replace("},{",",");
|
||||
input = input.replace("}}","]");
|
||||
qDebug() << "input: " << input;
|
||||
GdbResponse response(input);
|
||||
qDebug() << "read: " << response.toString();
|
||||
GdbMi list = response.results[0].data.findChild("data").findChild("locals");
|
||||
QByteArrayList locals;
|
||||
foreach (const GdbMi &item, list.children())
|
||||
locals.append(item.string());
|
||||
qDebug() << "Locals (new): " << locals;
|
||||
*/
|
||||
}
|
||||
void parse(const QByteArray &str)
|
||||
{
|
||||
QByteArray result;
|
||||
result += "\n ";
|
||||
int indent = 0;
|
||||
int from = 0;
|
||||
int to = str.size();
|
||||
if (str.size() && str[0] == '{' /*'}'*/) {
|
||||
++from;
|
||||
--to;
|
||||
}
|
||||
for (int i = from; i < to; ++i) {
|
||||
if (str[i] == '{')
|
||||
result += "{\n" + QByteArray(2*++indent + 1, ' ');
|
||||
else if (str[i] == '}') {
|
||||
if (!result.isEmpty() && result[result.size() - 1] != '\n')
|
||||
result += "\n";
|
||||
result += QByteArray(2*--indent + 1, ' ') + "}\n";
|
||||
}
|
||||
else if (str[i] == ',') {
|
||||
if (true || !result.isEmpty() && result[result.size() - 1] != '\n')
|
||||
result += "\n";
|
||||
result += QByteArray(2*indent, ' ');
|
||||
}
|
||||
else
|
||||
result += str[i];
|
||||
}
|
||||
qDebug() << "result:\n" << result;
|
||||
}
|
||||
|
||||
} dummy;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
@@ -63,6 +63,13 @@ using namespace Debugger;
|
||||
using namespace Debugger::Internal;
|
||||
using namespace Debugger::Constants;
|
||||
|
||||
//#define DEBUG_SCRIPT 1
|
||||
#if DEBUG_SCRIPT
|
||||
# define SDEBUG(s) qDebug() << s
|
||||
#else
|
||||
# define SDEBUG(s)
|
||||
#endif
|
||||
# define XSDEBUG(s) qDebug() << s
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -100,24 +107,29 @@ ScriptAgent::ScriptAgent(ScriptEngine *debugger, QScriptEngine *script)
|
||||
|
||||
void ScriptAgent::contextPop()
|
||||
{
|
||||
qDebug() << "ScriptAgent::contextPop: ";
|
||||
SDEBUG("ScriptAgent::contextPop: ");
|
||||
}
|
||||
|
||||
void ScriptAgent::contextPush()
|
||||
{
|
||||
qDebug() << "ScriptAgent::contextPush: ";
|
||||
SDEBUG("ScriptAgent::contextPush: ");
|
||||
}
|
||||
|
||||
void ScriptAgent::exceptionCatch(qint64 scriptId, const QScriptValue & exception)
|
||||
{
|
||||
qDebug() << "ScriptAgent::exceptionCatch: " << scriptId << &exception;
|
||||
Q_UNUSED(scriptId);
|
||||
Q_UNUSED(exception);
|
||||
SDEBUG("ScriptAgent::exceptionCatch: " << scriptId << &exception);
|
||||
}
|
||||
|
||||
void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception,
|
||||
bool hasHandler)
|
||||
{
|
||||
qDebug() << "ScriptAgent::exceptionThrow: " << scriptId << &exception
|
||||
<< hasHandler;
|
||||
Q_UNUSED(scriptId);
|
||||
Q_UNUSED(exception);
|
||||
Q_UNUSED(hasHandler);
|
||||
SDEBUG("ScriptAgent::exceptionThrow: " << scriptId << &exception
|
||||
<< hasHandler);
|
||||
}
|
||||
|
||||
void ScriptAgent::functionEntry(qint64 scriptId)
|
||||
@@ -128,12 +140,14 @@ void ScriptAgent::functionEntry(qint64 scriptId)
|
||||
|
||||
void ScriptAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue)
|
||||
{
|
||||
qDebug() << "ScriptAgent::functionExit: " << scriptId << &returnValue;
|
||||
Q_UNUSED(scriptId);
|
||||
Q_UNUSED(returnValue);
|
||||
SDEBUG("ScriptAgent::functionExit: " << scriptId << &returnValue);
|
||||
}
|
||||
|
||||
void ScriptAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber)
|
||||
{
|
||||
//qDebug() << "ScriptAgent::position: " << lineNumber;
|
||||
SDEBUG("ScriptAgent::position: " << lineNumber);
|
||||
Q_UNUSED(scriptId);
|
||||
Q_UNUSED(lineNumber);
|
||||
Q_UNUSED(columnNumber);
|
||||
@@ -147,14 +161,14 @@ void ScriptAgent::scriptLoad(qint64 scriptId, const QString &program,
|
||||
Q_UNUSED(program);
|
||||
Q_UNUSED(fileName);
|
||||
Q_UNUSED(baseLineNumber);
|
||||
//qDebug() << "ScriptAgent::scriptLoad: " << program << fileName
|
||||
// << baseLineNumber;
|
||||
SDEBUG("ScriptAgent::scriptLoad: " << program << fileName
|
||||
<< baseLineNumber);
|
||||
}
|
||||
|
||||
void ScriptAgent::scriptUnload(qint64 scriptId)
|
||||
{
|
||||
Q_UNUSED(scriptId);
|
||||
//qDebug() << "ScriptAgent::scriptUnload: " << scriptId;
|
||||
SDEBUG("ScriptAgent::scriptUnload: " << scriptId);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +195,7 @@ ScriptEngine::~ScriptEngine()
|
||||
void ScriptEngine::executeDebuggerCommand(const QString &command)
|
||||
{
|
||||
Q_UNUSED(command);
|
||||
qDebug() << "FIXME: ScriptEngine::executeDebuggerCommand()";
|
||||
XSDEBUG("FIXME: ScriptEngine::executeDebuggerCommand()");
|
||||
}
|
||||
|
||||
void ScriptEngine::shutdown()
|
||||
@@ -191,7 +205,7 @@ void ScriptEngine::shutdown()
|
||||
|
||||
void ScriptEngine::exitDebugger()
|
||||
{
|
||||
//qDebug() << " ScriptEngine::exitDebugger()";
|
||||
SDEBUG("ScriptEngine::exitDebugger()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = false;
|
||||
m_scriptEngine->abortEvaluation();
|
||||
@@ -212,19 +226,69 @@ bool ScriptEngine::startDebugger()
|
||||
m_scriptContents = stream.readAll();
|
||||
scriptFile.close();
|
||||
attemptBreakpointSynchronization();
|
||||
qq->notifyInferiorRunningRequested();
|
||||
QTimer::singleShot(0, this, SLOT(runInferior()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEngine::continueInferior()
|
||||
{
|
||||
//qDebug() << "ScriptEngine::continueInferior()";
|
||||
SDEBUG("ScriptEngine::continueInferior()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = false;
|
||||
}
|
||||
|
||||
void ScriptEngine::runInferior()
|
||||
{
|
||||
//qDebug() << "ScriptEngine::runInferior()";
|
||||
//QDir dir(QApplication::applicationDirPath());
|
||||
//if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release"))
|
||||
// dir.cdUp();
|
||||
//dir.cdUp();
|
||||
//dir.cdUp();
|
||||
QDir dir("/home/apoenitz/dev/qtscriptgenerator");
|
||||
if (!dir.cd("plugins")) {
|
||||
fprintf(stderr, "plugins folder does not exist -- did you build the bindings?\n");
|
||||
return;
|
||||
}
|
||||
QStringList paths = qApp->libraryPaths();
|
||||
paths << dir.absolutePath();
|
||||
qApp->setLibraryPaths(paths);
|
||||
|
||||
SDEBUG("ScriptEngine::runInferior()");
|
||||
QStringList extensions;
|
||||
extensions << "qt.core"
|
||||
<< "qt.gui"
|
||||
<< "qt.xml"
|
||||
<< "qt.svg"
|
||||
<< "qt.network"
|
||||
<< "qt.sql"
|
||||
<< "qt.opengl"
|
||||
<< "qt.webkit"
|
||||
<< "qt.xmlpatterns"
|
||||
<< "qt.uitools";
|
||||
QStringList failExtensions;
|
||||
foreach (const QString &ext, extensions) {
|
||||
QScriptValue ret = m_scriptEngine->importExtension(ext);
|
||||
if (ret.isError())
|
||||
failExtensions.append(ext);
|
||||
}
|
||||
if (!failExtensions.isEmpty()) {
|
||||
if (failExtensions.size() == extensions.size()) {
|
||||
qWarning("Failed to import Qt bindings!\n"
|
||||
"Plugins directory searched: %s/script\n"
|
||||
"Make sure that the bindings have been built, "
|
||||
"and that this executable and the plugins are "
|
||||
"using compatible Qt libraries.", qPrintable(dir.absolutePath()));
|
||||
} else {
|
||||
qWarning("Failed to import some Qt bindings: %s\n"
|
||||
"Plugins directory searched: %s/script\n"
|
||||
"Make sure that the bindings have been built, "
|
||||
"and that this executable and the plugins are "
|
||||
"using compatible Qt libraries.",
|
||||
qPrintable(failExtensions.join(", ")), qPrintable(dir.absolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName);
|
||||
}
|
||||
|
||||
@@ -232,40 +296,40 @@ void ScriptEngine::interruptInferior()
|
||||
{
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
qDebug() << "FIXME: ScriptEngine::interruptInferior()";
|
||||
XSDEBUG("ScriptEngine::interruptInferior()");
|
||||
}
|
||||
|
||||
void ScriptEngine::stepExec()
|
||||
{
|
||||
//qDebug() << "FIXME: ScriptEngine::stepExec()";
|
||||
//SDEBUG("ScriptEngine::stepExec()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
}
|
||||
|
||||
void ScriptEngine::stepIExec()
|
||||
{
|
||||
//qDebug() << "FIXME: ScriptEngine::stepIExec()";
|
||||
//SDEBUG("ScriptEngine::stepIExec()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
}
|
||||
|
||||
void ScriptEngine::stepOutExec()
|
||||
{
|
||||
//qDebug() << "FIXME: ScriptEngine::stepOutExec()";
|
||||
//SDEBUG("ScriptEngine::stepOutExec()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
}
|
||||
|
||||
void ScriptEngine::nextExec()
|
||||
{
|
||||
//qDebug() << "FIXME: ScriptEngine::nextExec()";
|
||||
//SDEBUG("ScriptEngine::nextExec()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
}
|
||||
|
||||
void ScriptEngine::nextIExec()
|
||||
{
|
||||
//qDebug() << "FIXME: ScriptEngine::nextIExec()";
|
||||
//SDEBUG("ScriptEngine::nextIExec()");
|
||||
m_stopped = false;
|
||||
m_stopOnNextLine = true;
|
||||
}
|
||||
@@ -274,20 +338,20 @@ void ScriptEngine::runToLineExec(const QString &fileName, int lineNumber)
|
||||
{
|
||||
Q_UNUSED(fileName);
|
||||
Q_UNUSED(lineNumber);
|
||||
qDebug() << "FIXME: ScriptEngine::runToLineExec()";
|
||||
SDEBUG("FIXME: ScriptEngine::runToLineExec()");
|
||||
}
|
||||
|
||||
void ScriptEngine::runToFunctionExec(const QString &functionName)
|
||||
{
|
||||
Q_UNUSED(functionName);
|
||||
qDebug() << "FIXME: ScriptEngine::runToFunctionExec()";
|
||||
XSDEBUG("FIXME: ScriptEngine::runToFunctionExec()");
|
||||
}
|
||||
|
||||
void ScriptEngine::jumpToLineExec(const QString &fileName, int lineNumber)
|
||||
{
|
||||
Q_UNUSED(fileName);
|
||||
Q_UNUSED(lineNumber);
|
||||
qDebug() << "FIXME: ScriptEngine::jumpToLineExec()";
|
||||
XSDEBUG("FIXME: ScriptEngine::jumpToLineExec()");
|
||||
}
|
||||
|
||||
void ScriptEngine::activateFrame(int index)
|
||||
@@ -381,7 +445,7 @@ void ScriptEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
|
||||
Q_UNUSED(exp0);
|
||||
|
||||
if (q->status() != DebuggerInferiorStopped) {
|
||||
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED";
|
||||
//SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -453,8 +517,9 @@ void ScriptEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
|
||||
void ScriptEngine::assignValueInDebugger(const QString &expression,
|
||||
const QString &value)
|
||||
{
|
||||
Q_UNUSED(expression);
|
||||
Q_UNUSED(value);
|
||||
XSDEBUG("ASSIGNING: " << expression + '=' + value);
|
||||
m_scriptEngine->evaluate(expression + '=' + value);
|
||||
updateLocals();
|
||||
}
|
||||
|
||||
void ScriptEngine::maybeBreakNow(bool byFunction)
|
||||
@@ -493,7 +558,7 @@ void ScriptEngine::maybeBreakNow(bool byFunction)
|
||||
return;
|
||||
|
||||
// we just run into a breakpoint
|
||||
//qDebug() << "RESOLVING BREAKPOINT AT " << fileName << lineNumber;
|
||||
//SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber);
|
||||
BreakpointData *data = handler->at(index);
|
||||
data->bpLineNumber = QString::number(lineNumber);
|
||||
data->bpFileName = fileName;
|
||||
@@ -506,9 +571,14 @@ void ScriptEngine::maybeBreakNow(bool byFunction)
|
||||
|
||||
qq->notifyInferiorStopped();
|
||||
q->gotoLocation(fileName, lineNumber, true);
|
||||
updateLocals();
|
||||
}
|
||||
|
||||
void ScriptEngine::updateLocals()
|
||||
{
|
||||
QScriptContext *context = m_scriptEngine->currentContext();
|
||||
qq->watchHandler()->reinitializeWatchers();
|
||||
//qDebug() << "UPDATE LOCALS";
|
||||
//SDEBUG("UPDATE LOCALS");
|
||||
|
||||
//
|
||||
// Build stack
|
||||
@@ -545,10 +615,10 @@ void ScriptEngine::maybeBreakNow(bool byFunction)
|
||||
// FIXME: Use an extra thread. This here is evil
|
||||
m_stopped = true;
|
||||
while (m_stopped) {
|
||||
//qDebug() << "LOOPING";
|
||||
//SDEBUG("LOOPING");
|
||||
QApplication::processEvents();
|
||||
}
|
||||
//qDebug() << "RUNNING AGAIN";
|
||||
//SDEBUG("RUNNING AGAIN");
|
||||
}
|
||||
|
||||
void ScriptEngine::updateWatchModel()
|
||||
@@ -567,7 +637,7 @@ void ScriptEngine::updateWatchModel()
|
||||
void ScriptEngine::updateSubItem(const WatchData &data0)
|
||||
{
|
||||
WatchData data = data0;
|
||||
//qDebug() << "\nUPDATE SUBITEM: " << data.toString();
|
||||
//SDEBUG("\nUPDATE SUBITEM: " << data.toString());
|
||||
QTC_ASSERT(data.isValid(), return);
|
||||
|
||||
if (data.isTypeNeeded() || data.isValueNeeded()) {
|
||||
@@ -632,6 +702,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
|
||||
it.next();
|
||||
WatchData data1;
|
||||
data1.iname = data.iname + "." + it.name();
|
||||
data1.exp = it.name();
|
||||
data1.name = it.name();
|
||||
data1.scriptValue = it.value();
|
||||
if (qq->watchHandler()->isExpandedIName(data1.iname))
|
||||
@@ -641,7 +712,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
|
||||
qq->watchHandler()->insertData(data1);
|
||||
++numChild;
|
||||
}
|
||||
//qDebug() << " ... CHILDREN: " << numChild;
|
||||
//SDEBUG(" ... CHILDREN: " << numChild);
|
||||
data.setChildCount(numChild);
|
||||
data.setChildrenUnneeded();
|
||||
qq->watchHandler()->insertData(data);
|
||||
@@ -656,7 +727,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
|
||||
++numChild;
|
||||
}
|
||||
data.setChildCount(numChild);
|
||||
//qDebug() << " ... CHILDCOUNT: " << numChild;
|
||||
//SDEBUG(" ... CHILDCOUNT: " << numChild);
|
||||
qq->watchHandler()->insertData(data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
void exitDebugger();
|
||||
|
||||
void continueInferior();
|
||||
void runInferior();
|
||||
Q_SLOT void runInferior();
|
||||
void interruptInferior();
|
||||
|
||||
void runToLineExec(const QString &fileName, int lineNumber);
|
||||
@@ -110,6 +110,7 @@ private:
|
||||
bool supportsThreads() const { return true; }
|
||||
void maybeBreakNow(bool byFunction);
|
||||
void updateWatchModel();
|
||||
void updateLocals();
|
||||
void updateSubItem(const WatchData &data0);
|
||||
|
||||
private:
|
||||
|
||||
@@ -57,12 +57,13 @@ StackHandler::StackHandler(QObject *parent)
|
||||
{
|
||||
m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg");
|
||||
m_positionIcon = QIcon(":/gdbdebugger/images/location.svg");
|
||||
m_canExpand = false;
|
||||
}
|
||||
|
||||
int StackHandler::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// Since the stack is not a tree, row count is 0 for any valid parent
|
||||
return parent.isValid() ? 0 : m_stackFrames.size();
|
||||
return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand);
|
||||
}
|
||||
|
||||
int StackHandler::columnCount(const QModelIndex &parent) const
|
||||
@@ -72,9 +73,15 @@ int StackHandler::columnCount(const QModelIndex &parent) const
|
||||
|
||||
QVariant StackHandler::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= m_stackFrames.size())
|
||||
if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
|
||||
return QVariant();
|
||||
|
||||
if (index.row() == m_stackFrames.size()) {
|
||||
if (role == Qt::DisplayRole && index.column() == 0)
|
||||
return "<...>";
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const StackFrame &frame = m_stackFrames.at(index.row());
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
@@ -123,10 +130,12 @@ QVariant StackHandler::headerData(int section, Qt::Orientation orientation, int
|
||||
|
||||
Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (index.row() >= m_stackFrames.size())
|
||||
if (index.row() >= m_stackFrames.size() + m_canExpand)
|
||||
return 0;
|
||||
if (index.row() == m_stackFrames.size())
|
||||
return QAbstractTableModel::flags(index);
|
||||
const StackFrame &frame = m_stackFrames.at(index.row());
|
||||
const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
|
||||
const bool isValid = (!frame.file.isEmpty() && !frame.function.isEmpty());
|
||||
return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);
|
||||
}
|
||||
|
||||
@@ -160,8 +169,9 @@ void StackHandler::removeAll()
|
||||
reset();
|
||||
}
|
||||
|
||||
void StackHandler::setFrames(const QList<StackFrame> &frames)
|
||||
void StackHandler::setFrames(const QList<StackFrame> &frames, bool canExpand)
|
||||
{
|
||||
m_canExpand = canExpand;
|
||||
m_stackFrames = frames;
|
||||
if (m_currentIndex >= m_stackFrames.size())
|
||||
m_currentIndex = m_stackFrames.size() - 1;
|
||||
@@ -173,7 +183,7 @@ QList<StackFrame> StackHandler::frames() const
|
||||
return m_stackFrames;
|
||||
}
|
||||
|
||||
bool StackHandler::isDebuggingDumpers() const
|
||||
bool StackHandler::isDebuggingDebuggingHelpers() const
|
||||
{
|
||||
for (int i = m_stackFrames.size(); --i >= 0; )
|
||||
if (m_stackFrames.at(i).function.startsWith("qDumpObjectData"))
|
||||
|
||||
@@ -64,7 +64,7 @@ class StackHandler : public QAbstractTableModel
|
||||
public:
|
||||
StackHandler(QObject *parent = 0);
|
||||
|
||||
void setFrames(const QList<StackFrame> &frames);
|
||||
void setFrames(const QList<StackFrame> &frames, bool canExpand = false);
|
||||
QList<StackFrame> frames() const;
|
||||
void setCurrentIndex(int index);
|
||||
int currentIndex() const { return m_currentIndex; }
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
// Called from StackHandler after a new stack list has been received
|
||||
void removeAll();
|
||||
QAbstractItemModel *stackModel() { return this; }
|
||||
bool isDebuggingDumpers() const;
|
||||
bool isDebuggingDebuggingHelpers() const;
|
||||
|
||||
private:
|
||||
// QAbstractTableModel
|
||||
@@ -88,6 +88,7 @@ private:
|
||||
int m_currentIndex;
|
||||
QIcon m_positionIcon;
|
||||
QIcon m_emptyIcon;
|
||||
bool m_canExpand;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
act2->setCheckable(true);
|
||||
act2->setChecked(m_alwaysResizeColumnsToContents);
|
||||
|
||||
menu.addAction(theDebuggerAction(ExpandStack));
|
||||
menu.addAction(act0);
|
||||
menu.addSeparator();
|
||||
menu.addAction(act1);
|
||||
|
||||
@@ -493,6 +493,14 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool WatchHandler::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(role);
|
||||
Q_UNUSED(value);
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags WatchHandler::flags(const QModelIndex &idx) const
|
||||
{
|
||||
using namespace Qt;
|
||||
@@ -871,10 +879,11 @@ void WatchHandler::watchExpression(const QString &exp)
|
||||
{
|
||||
// FIXME: 'exp' can contain illegal characters
|
||||
//MODEL_DEBUG("WATCH: " << exp);
|
||||
static int counter = 0;
|
||||
WatchData data;
|
||||
data.exp = exp;
|
||||
data.name = exp;
|
||||
data.iname = QLatin1String("watch.") + exp;
|
||||
data.iname = QLatin1String("watch.") + QString::number(counter++);
|
||||
insertData(data);
|
||||
m_watchers.append(exp);
|
||||
saveWatchers();
|
||||
@@ -993,7 +1002,6 @@ void WatchHandler::reinitializeWatchersHelper()
|
||||
data.variable.clear();
|
||||
data.setAllNeeded();
|
||||
data.valuedisabled = false;
|
||||
data.iname = QLatin1String("watch.") + QString::number(i);
|
||||
data.name = exp;
|
||||
data.exp = exp;
|
||||
insertData(data);
|
||||
|
||||
@@ -149,6 +149,7 @@ public:
|
||||
// QAbstractItemModel
|
||||
//
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
QModelIndex index(int, int, const QModelIndex &idx) const;
|
||||
QModelIndex parent(const QModelIndex &idx) const;
|
||||
int rowCount(const QModelIndex &idx) const;
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
|
||||
const QModelIndex &) const
|
||||
{
|
||||
qDebug() << "CREATE EDITOR";
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
|
||||
@@ -77,13 +78,15 @@ public:
|
||||
lineEdit->setText(index.model()->data(index, ExpressionRole).toString());
|
||||
}
|
||||
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *,
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
//qDebug() << "SET MODEL DATA";
|
||||
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
|
||||
QTC_ASSERT(lineEdit, return);
|
||||
QString value = lineEdit->text();
|
||||
QString exp = index.model()->data(index, ExpressionRole).toString();
|
||||
QString exp = model->data(index, ExpressionRole).toString();
|
||||
model->setData(index, value, Qt::EditRole);
|
||||
if (index.column() == 1) {
|
||||
// the value column
|
||||
theDebuggerAction(AssignValue)->trigger(exp + '=' + value);
|
||||
@@ -147,7 +150,9 @@ void WatchWindow::keyPressEvent(QKeyEvent *ev)
|
||||
QModelIndex idx1 = idx.sibling(idx.row(), 0);
|
||||
QString exp = model()->data(idx1).toString();
|
||||
theDebuggerAction(RemoveWatchExpression)->trigger(exp);
|
||||
} else if (ev->key() == Qt::Key_Return && m_type == LocalsType) {
|
||||
} else if (ev->key() == Qt::Key_Return
|
||||
&& ev->modifiers() == Qt::ControlModifier
|
||||
&& m_type == LocalsType) {
|
||||
QModelIndex idx = currentIndex();
|
||||
QModelIndex idx1 = idx.sibling(idx.row(), 0);
|
||||
QString exp = model()->data(idx1).toString();
|
||||
@@ -184,8 +189,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
menu.addAction(act3);
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(theDebuggerAction(RecheckDumpers));
|
||||
menu.addAction(theDebuggerAction(UseDumpers));
|
||||
menu.addAction(theDebuggerAction(RecheckDebuggingHelpers));
|
||||
menu.addAction(theDebuggerAction(UseDebuggingHelpers));
|
||||
menu.addSeparator();
|
||||
menu.addAction(theDebuggerAction(SettingsDialog));
|
||||
|
||||
@@ -264,4 +269,3 @@ void WatchWindow::resetHelper(const QModelIndex &idx)
|
||||
collapse(idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,15 +125,16 @@ enum Mode
|
||||
enum SubMode
|
||||
{
|
||||
NoSubMode,
|
||||
RegisterSubMode, // used for "
|
||||
ChangeSubMode, // used for c
|
||||
DeleteSubMode, // used for d
|
||||
FilterSubMode, // used for !
|
||||
IndentSubMode, // used for =
|
||||
RegisterSubMode, // used for "
|
||||
ReplaceSubMode, // used for R and r
|
||||
YankSubMode, // used for y
|
||||
ShiftLeftSubMode, // used for <
|
||||
ShiftRightSubMode, // used for >
|
||||
IndentSubMode, // used for =
|
||||
WindowSubMode, // used for Ctrl-w
|
||||
YankSubMode, // used for y
|
||||
ZSubMode,
|
||||
};
|
||||
|
||||
@@ -212,6 +213,7 @@ public:
|
||||
|
||||
EventResult handleEvent(QKeyEvent *ev);
|
||||
bool wantsOverride(QKeyEvent *ev);
|
||||
void handleCommand(const QString &cmd); // sets m_tc + handleExCommand
|
||||
void handleExCommand(const QString &cmd);
|
||||
|
||||
void installEventFilter();
|
||||
@@ -265,7 +267,8 @@ public:
|
||||
void shiftRegionRight(int repeat = 1);
|
||||
|
||||
void moveToFirstNonBlankOnLine();
|
||||
void moveToDesiredColumn();
|
||||
void moveToTargetColumn();
|
||||
void setTargetColumn() { m_targetColumn = leftDist(); }
|
||||
void moveToNextWord(bool simple);
|
||||
void moveToMatchingParanthesis();
|
||||
void moveToWordBoundary(bool simple, bool forward);
|
||||
@@ -315,6 +318,7 @@ public:
|
||||
int m_subsubdata;
|
||||
QString m_input;
|
||||
QTextCursor m_tc;
|
||||
QTextCursor m_oldTc; // copy from last event to check for external changes
|
||||
int m_anchor;
|
||||
QHash<int, QString> m_registers;
|
||||
int m_register;
|
||||
@@ -347,6 +351,7 @@ public:
|
||||
bool m_needMoreUndo;
|
||||
|
||||
// extra data for '.'
|
||||
void replay(const QString &text);
|
||||
QString m_dotCommand;
|
||||
bool m_inReplay; // true if we are executing a '.'
|
||||
|
||||
@@ -381,7 +386,7 @@ public:
|
||||
|
||||
// for restoring cursor position
|
||||
int m_savedYankPosition;
|
||||
int m_desiredColumn;
|
||||
int m_targetColumn;
|
||||
|
||||
int m_cursorWidth;
|
||||
|
||||
@@ -390,6 +395,7 @@ public:
|
||||
bool removeAutomaticIndentation(); // true if something removed
|
||||
// number of autoindented characters
|
||||
int m_justAutoIndented;
|
||||
void handleStartOfLine();
|
||||
|
||||
void recordJump();
|
||||
void recordNewUndo();
|
||||
@@ -418,7 +424,7 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
||||
m_register = '"';
|
||||
m_gflag = false;
|
||||
m_visualMode = NoVisualMode;
|
||||
m_desiredColumn = 0;
|
||||
m_targetColumn = 0;
|
||||
m_moveType = MoveInclusive;
|
||||
m_anchor = 0;
|
||||
m_savedYankPosition = 0;
|
||||
@@ -485,8 +491,12 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
|
||||
|
||||
// Fake "End of line"
|
||||
m_tc = EDITOR(textCursor());
|
||||
m_tc.setVisualNavigation(true);
|
||||
|
||||
if (m_tc.position() != m_oldTc.position())
|
||||
setTargetColumn();
|
||||
|
||||
m_tc.setVisualNavigation(true);
|
||||
|
||||
if (m_fakeEnd)
|
||||
moveRight();
|
||||
|
||||
@@ -511,6 +521,7 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
|
||||
if (m_fakeEnd)
|
||||
moveLeft();
|
||||
|
||||
m_oldTc = m_tc;
|
||||
EDITOR(setTextCursor(m_tc));
|
||||
return result;
|
||||
}
|
||||
@@ -654,6 +665,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
updateMiniBuffer();
|
||||
}
|
||||
|
||||
moveToTargetColumn();
|
||||
|
||||
m_moveType = MoveInclusive;
|
||||
m_mvcount.clear();
|
||||
m_opcount.clear();
|
||||
@@ -663,7 +676,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
|
||||
updateSelection();
|
||||
updateMiniBuffer();
|
||||
m_desiredColumn = leftDist();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::updateSelection()
|
||||
@@ -800,7 +812,10 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
{
|
||||
EventResult handled = EventHandled;
|
||||
|
||||
if (m_submode == RegisterSubMode) {
|
||||
if (m_submode == WindowSubMode) {
|
||||
emit q->windowCommandRequested(key);
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == RegisterSubMode) {
|
||||
m_register = key;
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == ChangeSubMode && key == 'c') {
|
||||
@@ -984,7 +999,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
m_moveType = MoveExclusive;
|
||||
finishMovement("$");
|
||||
if (submode == NoSubMode)
|
||||
m_desiredColumn = -1;
|
||||
m_targetColumn = -1;
|
||||
} else if (key == ',') {
|
||||
// FIXME: use some other mechanism
|
||||
//m_passing = true;
|
||||
@@ -994,11 +1009,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
qDebug() << "REPEATING" << m_dotCommand;
|
||||
QString savedCommand = m_dotCommand;
|
||||
m_dotCommand.clear();
|
||||
m_inReplay = true;
|
||||
for (int i = count(); --i >= 0; )
|
||||
foreach (QChar c, savedCommand)
|
||||
handleKey(c.unicode(), c.unicode(), QString(c));
|
||||
m_inReplay = false;
|
||||
replay(savedCommand);
|
||||
enterCommandMode();
|
||||
m_dotCommand = savedCommand;
|
||||
} else if (key == '<' && m_visualMode == NoVisualMode) {
|
||||
@@ -1079,7 +1090,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
int sline = cursorLineOnScreen();
|
||||
// FIXME: this should use the "scroll" option, and "count"
|
||||
moveDown(linesOnScreen() / 2);
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
scrollToLineInDocument(cursorLineInDocument() - sline);
|
||||
finishMovement();
|
||||
} else if (key == 'e') {
|
||||
@@ -1108,8 +1119,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
if (m_gflag) {
|
||||
m_gflag = false;
|
||||
m_tc.setPosition(firstPositionInLine(1), KeepAnchor);
|
||||
if (hasConfig(ConfigStartOfLine))
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else {
|
||||
m_gflag = true;
|
||||
@@ -1117,8 +1127,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == 'G') {
|
||||
int n = m_mvcount.isEmpty() ? linesInDocument() : count();
|
||||
m_tc.setPosition(firstPositionInLine(n), KeepAnchor);
|
||||
if (hasConfig(ConfigStartOfLine))
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == 'h' || key == Key_Left
|
||||
|| key == Key_Backspace || key == control('h')) {
|
||||
@@ -1126,11 +1135,12 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
if (m_fakeEnd && m_tc.block().length() > 1)
|
||||
++n;
|
||||
moveLeft(n);
|
||||
setTargetColumn();
|
||||
finishMovement("h");
|
||||
} else if (key == 'H') {
|
||||
m_tc = EDITOR(cursorForPosition(QPoint(0, 0)));
|
||||
moveDown(qMax(count() - 1, 0));
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == 'i') {
|
||||
m_dotCommand = "i"; //QString("%1i").arg(count());
|
||||
@@ -1152,12 +1162,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
setPosition(m_jumpListRedo.takeLast());
|
||||
}
|
||||
} else if (key == 'j' || key == Key_Down) {
|
||||
//qDebug() << "DESIRED COLUMN" << m_desiredColumn;
|
||||
int savedColumn = m_desiredColumn;
|
||||
if (m_submode == NoSubMode || m_submode == ZSubMode
|
||||
|| m_submode == RegisterSubMode) {
|
||||
moveDown(count());
|
||||
moveToDesiredColumn();
|
||||
} else {
|
||||
m_moveType = MoveLineWise;
|
||||
moveToStartOfLine();
|
||||
@@ -1165,7 +1172,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveDown(count() + 1);
|
||||
}
|
||||
finishMovement("j");
|
||||
m_desiredColumn = savedColumn;
|
||||
} else if (key == 'J') {
|
||||
if (m_submode == NoSubMode) {
|
||||
for (int i = qMax(count(), 2) - 1; --i >= 0; ) {
|
||||
@@ -1182,11 +1188,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveLeft();
|
||||
}
|
||||
} else if (key == 'k' || key == Key_Up) {
|
||||
int savedColumn = m_desiredColumn;
|
||||
if (m_submode == NoSubMode || m_submode == ZSubMode
|
||||
|| m_submode == RegisterSubMode) {
|
||||
moveUp(count());
|
||||
moveToDesiredColumn();
|
||||
} else {
|
||||
m_moveType = MoveLineWise;
|
||||
moveToStartOfLine();
|
||||
@@ -1195,15 +1199,15 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveUp(count() + 1);
|
||||
}
|
||||
finishMovement("k");
|
||||
m_desiredColumn = savedColumn;
|
||||
} else if (key == 'l' || key == Key_Right || key == ' ') {
|
||||
m_moveType = MoveExclusive;
|
||||
moveRight(qMin(count(), rightDist()));
|
||||
setTargetColumn();
|
||||
finishMovement("l");
|
||||
} else if (key == 'L') {
|
||||
m_tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()))));
|
||||
moveUp(qMax(count(), 1));
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == control('l')) {
|
||||
// screen redraw. should not be needed
|
||||
@@ -1211,7 +1215,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
m_subsubmode = MarkSubSubMode;
|
||||
} else if (key == 'M') {
|
||||
m_tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2)));
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == 'n') {
|
||||
search(lastSearchString(), m_lastSearchForward);
|
||||
@@ -1240,7 +1244,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
//qDebug() << "LINES: " << n << text << m_register;
|
||||
if (n > 0) {
|
||||
moveToStartOfLine();
|
||||
m_desiredColumn = 0;
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (key == 'p')
|
||||
moveDown();
|
||||
@@ -1249,7 +1253,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
}
|
||||
moveToFirstNonBlankOnLine();
|
||||
} else {
|
||||
m_desiredColumn = 0;
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (key == 'p')
|
||||
moveRight();
|
||||
@@ -1295,7 +1299,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
int sline = cursorLineOnScreen();
|
||||
// FIXME: this should use the "scroll" option, and "count"
|
||||
moveUp(linesOnScreen() / 2);
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
scrollToLineInDocument(cursorLineInDocument() - sline);
|
||||
finishMovement();
|
||||
} else if (key == 'v') {
|
||||
@@ -1324,6 +1328,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
m_moveType = MoveExclusive;
|
||||
}
|
||||
finishMovement("W");
|
||||
} else if (key == control('w')) {
|
||||
m_submode = WindowSubMode;
|
||||
} else if (key == 'x' && m_visualMode == NoVisualMode) { // = "dl"
|
||||
m_moveType = MoveExclusive;
|
||||
if (atEndOfLine())
|
||||
@@ -1375,12 +1381,12 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == Key_PageDown || key == control('f')) {
|
||||
moveDown(count() * (linesOnScreen() - 2) - cursorLineOnScreen());
|
||||
scrollToLineInDocument(cursorLineInDocument());
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == Key_PageUp || key == control('b')) {
|
||||
moveUp(count() * (linesOnScreen() - 2) + cursorLineOnScreen());
|
||||
scrollToLineInDocument(cursorLineInDocument() + linesOnScreen() - 2);
|
||||
moveToFirstNonBlankOnLine();
|
||||
handleStartOfLine();
|
||||
finishMovement();
|
||||
} else if (key == Key_Delete) {
|
||||
setAnchor();
|
||||
@@ -1415,6 +1421,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int,
|
||||
data += m_lastInsertion;
|
||||
}
|
||||
moveLeft(qMin(1, leftDist()));
|
||||
setTargetColumn();
|
||||
m_dotCommand += m_lastInsertion;
|
||||
m_dotCommand += QChar(27);
|
||||
recordNewUndo();
|
||||
@@ -1634,6 +1641,13 @@ void FakeVimHandler::Private::selectRange(int beginLine, int endLine)
|
||||
setPosition(firstPositionInLine(endLine + 1));
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::handleCommand(const QString &cmd)
|
||||
{
|
||||
m_tc = EDITOR(textCursor());
|
||||
handleExCommand(cmd);
|
||||
EDITOR(setTextCursor(m_tc));
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
{
|
||||
QString cmd = cmd0;
|
||||
@@ -1656,10 +1670,11 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
|
||||
//qDebug() << "RANGE: " << beginLine << endLine << cmd << cmd0 << m_marks;
|
||||
|
||||
static QRegExp reWrite("^w!?( (.*))?$");
|
||||
static QRegExp reDelete("^d( (.*))?$");
|
||||
static QRegExp reSet("^set?( (.*))?$");
|
||||
static QRegExp reHistory("^his(tory)?( (.*))?$");
|
||||
static QRegExp reNormal("^norm(al)?( (.*))?$");
|
||||
static QRegExp reSet("^set?( (.*))?$");
|
||||
static QRegExp reWrite("^w!?( (.*))?$");
|
||||
|
||||
if (cmd.isEmpty()) {
|
||||
setPosition(firstPositionInLine(beginLine));
|
||||
@@ -1760,6 +1775,9 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
redo();
|
||||
enterCommandMode();
|
||||
updateMiniBuffer();
|
||||
} else if (reNormal.indexIn(cmd) != -1) { // :normal
|
||||
enterCommandMode();
|
||||
replay(reNormal.cap(3));
|
||||
} else if (reSet.indexIn(cmd) != -1) { // :set
|
||||
showBlackMessage(QString());
|
||||
QString arg = reSet.cap(2);
|
||||
@@ -1989,12 +2007,12 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
|
||||
m_dotCommand = QString("%1<<").arg(endLine - beginLine + 1);
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::moveToDesiredColumn()
|
||||
void FakeVimHandler::Private::moveToTargetColumn()
|
||||
{
|
||||
if (m_desiredColumn == -1 || m_tc.block().length() <= m_desiredColumn)
|
||||
m_tc.movePosition(EndOfLine, KeepAnchor);
|
||||
else
|
||||
m_tc.setPosition(m_tc.block().position() + m_desiredColumn, KeepAnchor);
|
||||
if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn)
|
||||
m_tc.movePosition(EndOfLine, KeepAnchor);
|
||||
else
|
||||
m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor);
|
||||
}
|
||||
|
||||
static int charClass(QChar c, bool simple)
|
||||
@@ -2326,6 +2344,21 @@ bool FakeVimHandler::Private::removeAutomaticIndentation()
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::handleStartOfLine()
|
||||
{
|
||||
if (hasConfig(ConfigStartOfLine))
|
||||
moveToFirstNonBlankOnLine();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::replay(const QString &command)
|
||||
{
|
||||
//qDebug() << "REPLAY: " << command;
|
||||
m_inReplay = true;
|
||||
for (int i = count(); --i >= 0; )
|
||||
foreach (QChar c, command)
|
||||
handleKey(c.unicode(), c.unicode(), QString(c));
|
||||
m_inReplay = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -2388,7 +2421,7 @@ void FakeVimHandler::restoreWidget()
|
||||
|
||||
void FakeVimHandler::handleCommand(const QString &cmd)
|
||||
{
|
||||
d->handleExCommand(cmd);
|
||||
d->handleCommand(cmd);
|
||||
}
|
||||
|
||||
void FakeVimHandler::setCurrentFileName(const QString &fileName)
|
||||
|
||||
@@ -72,6 +72,7 @@ signals:
|
||||
void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
|
||||
void indentRegion(int *amount, int beginLine, int endLine, QChar typedChar);
|
||||
void completionRequested();
|
||||
void windowCommandRequested(int key);
|
||||
|
||||
public:
|
||||
class Private;
|
||||
|
||||
@@ -231,6 +231,7 @@ private slots:
|
||||
void setUseFakeVim(const QVariant &value);
|
||||
void quitFakeVim();
|
||||
void triggerCompletions();
|
||||
void windowCommand(int key);
|
||||
void showSettingsDialog();
|
||||
|
||||
void showCommandBuffer(const QString &contents);
|
||||
@@ -309,6 +310,46 @@ void FakeVimPluginPrivate::showSettingsDialog()
|
||||
Core::ICore::instance()->showOptionsDialog("FakeVim", "General");
|
||||
}
|
||||
|
||||
void FakeVimPluginPrivate::windowCommand(int key)
|
||||
{
|
||||
#define control(n) (256 + n)
|
||||
QString code;
|
||||
switch (key) {
|
||||
case 'c': case 'C': case control('c'):
|
||||
code = Core::Constants::CLOSE;
|
||||
break;
|
||||
case 'n': case 'N': case control('n'):
|
||||
code = Core::Constants::GOTONEXT;
|
||||
break;
|
||||
case 'o': case 'O': case control('o'):
|
||||
code = Core::Constants::REMOVE_ALL_SPLITS;
|
||||
code = Core::Constants::REMOVE_CURRENT_SPLIT;
|
||||
break;
|
||||
case 'p': case 'P': case control('p'):
|
||||
code = Core::Constants::GOTOPREV;
|
||||
break;
|
||||
case 's': case 'S': case control('s'):
|
||||
code = Core::Constants::SPLIT;
|
||||
break;
|
||||
case 'w': case 'W': case control('w'):
|
||||
code = Core::Constants::GOTO_OTHER_SPLIT;
|
||||
break;
|
||||
}
|
||||
#undef control
|
||||
qDebug() << "RUNNING WINDOW COMMAND: " << key << code;
|
||||
if (code.isEmpty()) {
|
||||
qDebug() << "UNKNOWN WINDOWS COMMAND: " << key;
|
||||
return;
|
||||
}
|
||||
Core::ActionManager *am = Core::ICore::instance()->actionManager();
|
||||
QTC_ASSERT(am, return);
|
||||
Core::Command *cmd = am->command(code);
|
||||
QTC_ASSERT(cmd, return);
|
||||
QAction *action = cmd->action();
|
||||
QTC_ASSERT(action, return);
|
||||
action->trigger();
|
||||
}
|
||||
|
||||
void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
|
||||
{
|
||||
if (!editor)
|
||||
@@ -344,6 +385,8 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
|
||||
this, SLOT(indentRegion(int*,int,int,QChar)));
|
||||
connect(handler, SIGNAL(completionRequested()),
|
||||
this, SLOT(triggerCompletions()));
|
||||
connect(handler, SIGNAL(windowCommandRequested(int)),
|
||||
this, SLOT(windowCommand(int)));
|
||||
|
||||
handler->setCurrentFileName(editor->file()->fileName());
|
||||
handler->installEventFilter();
|
||||
|
||||
@@ -40,14 +40,15 @@ using namespace Find::Internal;
|
||||
FindToolWindow::FindToolWindow(FindPlugin *plugin)
|
||||
: QDialog(Core::ICore::instance()->mainWindow()),
|
||||
m_plugin(plugin),
|
||||
m_findCompleter(new QCompleter(this))
|
||||
m_findCompleter(new QCompleter(this)),
|
||||
m_currentFilter(0)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
connect(m_ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(m_ui.searchButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
connect(m_ui.matchCase, SIGNAL(toggled(bool)), m_plugin, SLOT(setCaseSensitive(bool)));
|
||||
connect(m_ui.wholeWords, SIGNAL(toggled(bool)), m_plugin, SLOT(setWholeWord(bool)));
|
||||
connect(m_ui.filterList, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentFilter(int)));
|
||||
connect(m_ui.filterList, SIGNAL(activated(int)), this, SLOT(setCurrentFilter(int)));
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(search()));
|
||||
m_findCompleter->setModel(m_plugin->findCompletionModel());
|
||||
m_ui.searchTerm->setCompleter(m_findCompleter);
|
||||
@@ -74,6 +75,8 @@ void FindToolWindow::setFindFilters(const QList<IFindFilter *> &filters)
|
||||
m_configWidgets.append(filter->createConfigWidget());
|
||||
}
|
||||
m_ui.filterList->addItems(names);
|
||||
if (m_filters.size() > 0)
|
||||
setCurrentFilter(0);
|
||||
}
|
||||
|
||||
void FindToolWindow::setFindText(const QString &text)
|
||||
@@ -83,9 +86,11 @@ void FindToolWindow::setFindText(const QString &text)
|
||||
|
||||
void FindToolWindow::open(IFindFilter *filter)
|
||||
{
|
||||
if (!filter)
|
||||
filter = m_currentFilter;
|
||||
int index = m_filters.indexOf(filter);
|
||||
if (index >= 0) {
|
||||
m_ui.filterList->setCurrentIndex(index);
|
||||
setCurrentFilter(index);
|
||||
}
|
||||
m_ui.matchCase->setChecked(m_plugin->findFlags() & QTextDocument::FindCaseSensitively);
|
||||
m_ui.wholeWords->setChecked(m_plugin->findFlags() & QTextDocument::FindWholeWords);
|
||||
@@ -96,6 +101,7 @@ void FindToolWindow::open(IFindFilter *filter)
|
||||
|
||||
void FindToolWindow::setCurrentFilter(int index)
|
||||
{
|
||||
m_ui.filterList->setCurrentIndex(index);
|
||||
for (int i = 0; i < m_configWidgets.size(); ++i) {
|
||||
QWidget *configWidget = m_configWidgets.at(i);
|
||||
if (!configWidget)
|
||||
@@ -112,6 +118,7 @@ void FindToolWindow::setCurrentFilter(int index)
|
||||
configWidget->setParent(0);
|
||||
}
|
||||
}
|
||||
m_currentFilter = m_filters.at(index);
|
||||
}
|
||||
|
||||
void FindToolWindow::search()
|
||||
@@ -129,6 +136,7 @@ void FindToolWindow::writeSettings()
|
||||
{
|
||||
QSettings *settings = Core::ICore::instance()->settings();
|
||||
settings->beginGroup("Find");
|
||||
settings->setValue("CurrentFilter", m_currentFilter->id());
|
||||
foreach (IFindFilter *filter, m_filters)
|
||||
filter->writeSettings(settings);
|
||||
settings->endGroup();
|
||||
@@ -138,7 +146,13 @@ void FindToolWindow::readSettings()
|
||||
{
|
||||
QSettings *settings = Core::ICore::instance()->settings();
|
||||
settings->beginGroup("Find");
|
||||
foreach (IFindFilter *filter, m_filters)
|
||||
const QString currentFilter = settings->value("CurrentFilter").toString();
|
||||
for (int i = 0; i < m_filters.size(); ++i) {
|
||||
IFindFilter *filter = m_filters.at(i);
|
||||
filter->readSettings(settings);
|
||||
if (filter->id() == currentFilter) {
|
||||
setCurrentFilter(i);
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ private:
|
||||
QList<IFindFilter *> m_filters;
|
||||
QCompleter *m_findCompleter;
|
||||
QList<QWidget *> m_configWidgets;
|
||||
IFindFilter *m_currentFilter;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
|
||||
virtual ~IFindFilter() {}
|
||||
|
||||
virtual QString id() const = 0;
|
||||
virtual QString name() const = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual QKeySequence defaultShortcut() const = 0;
|
||||
|
||||
@@ -84,7 +84,7 @@ public slots:
|
||||
private slots:
|
||||
void handleExpandCollapseToolButton(bool checked);
|
||||
void handleJumpToSearchResult(int index, const QString &fileName, int lineNumber,
|
||||
int searchTermStart, int searchTermLength);
|
||||
int searchTermStart, int searchTermLength);
|
||||
|
||||
private:
|
||||
void readSettings();
|
||||
|
||||
@@ -544,9 +544,11 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
|
||||
process.setEnvironment(environment.toStringList());
|
||||
|
||||
process.start(m_binaryPath, arguments);
|
||||
|
||||
if (!process.waitForFinished()) {
|
||||
if (errorText)
|
||||
*errorText = "Error: Git timed out";
|
||||
process.kill();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ AllProjectsFind::AllProjectsFind(ProjectExplorerPlugin *plugin, SearchResultWind
|
||||
connect(m_plugin, SIGNAL(fileListChanged()), this, SIGNAL(changed()));
|
||||
}
|
||||
|
||||
QString AllProjectsFind::id() const
|
||||
{
|
||||
return "All Projects";
|
||||
}
|
||||
|
||||
QString AllProjectsFind::name() const
|
||||
{
|
||||
return tr("All Projects");
|
||||
|
||||
@@ -50,6 +50,7 @@ class AllProjectsFind : public TextEditor::BaseFileFind
|
||||
public:
|
||||
AllProjectsFind(ProjectExplorerPlugin *plugin, Find::SearchResultWindow *resultWindow);
|
||||
|
||||
QString id() const;
|
||||
QString name() const;
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
@@ -65,6 +65,11 @@ BuildManager::BuildManager(ProjectExplorerPlugin *parent)
|
||||
connect(&m_watcher, SIGNAL(finished()),
|
||||
this, SLOT(nextBuildQueue()));
|
||||
|
||||
connect(&m_watcher, SIGNAL(progressValueChanged(int)),
|
||||
this, SLOT(progressChanged()));
|
||||
connect(&m_watcher, SIGNAL(progressRangeChanged(int, int)),
|
||||
this, SLOT(progressChanged()));
|
||||
|
||||
m_outputWindow = new CompileOutputWindow(this);
|
||||
pm->addObject(m_outputWindow);
|
||||
|
||||
@@ -115,7 +120,7 @@ void BuildManager::cancel()
|
||||
this, SLOT(addToOutputWindow(QString)));
|
||||
decrementActiveBuildSteps(m_currentBuildStep->project());
|
||||
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress, "Build canceled"); //TODO NBS fix in qtconcurrent
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress*100, "Build canceled"); //TODO NBS fix in qtconcurrent
|
||||
clearBuildQueue();
|
||||
}
|
||||
return;
|
||||
@@ -184,7 +189,7 @@ void BuildManager::startBuildQueue()
|
||||
connect(progress, SIGNAL(clicked()), this, SLOT(showBuildResults()));
|
||||
progress->setWidget(new BuildProgress(m_taskWindow));
|
||||
m_progress = 0;
|
||||
m_progressFutureInterface->setProgressRange(0, m_maxProgress);
|
||||
m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);
|
||||
|
||||
m_running = true;
|
||||
m_canceling = false;
|
||||
@@ -194,9 +199,9 @@ void BuildManager::startBuildQueue()
|
||||
nextStep();
|
||||
} else {
|
||||
// Already running
|
||||
m_progressFutureInterface->setProgressRange(0, m_maxProgress);
|
||||
m_progressFutureInterface->setProgressRange(0, m_maxProgress * 100);
|
||||
const QString &progressText = tr("Finished %1 of %2 build steps").arg(m_progress).arg(m_maxProgress);
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress, progressText);
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress*100, progressText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +236,7 @@ void BuildManager::nextBuildQueue()
|
||||
|
||||
++m_progress;
|
||||
const QString &progressText = tr("Finished %1 of %2 build steps").arg(m_progress).arg(m_maxProgress);
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress, progressText);
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress*100, progressText);
|
||||
|
||||
bool result = m_watcher.result();
|
||||
if (!result) {
|
||||
@@ -239,7 +244,7 @@ void BuildManager::nextBuildQueue()
|
||||
addToOutputWindow(tr("<font color=\"#ff0000\">Error while building project %1</font>").arg(m_currentBuildStep->project()->name()));
|
||||
addToOutputWindow(tr("<font color=\"#ff0000\">When executing build step '%1'</font>").arg(m_currentBuildStep->displayName()));
|
||||
// NBS TODO fix in qtconcurrent
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress, tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
|
||||
m_progressFutureInterface->setProgressValueAndText(m_progress*100, tr("Error while building project %1").arg(m_currentBuildStep->project()->name()));
|
||||
}
|
||||
|
||||
decrementActiveBuildSteps(m_currentBuildStep->project());
|
||||
@@ -249,6 +254,17 @@ void BuildManager::nextBuildQueue()
|
||||
clearBuildQueue();
|
||||
}
|
||||
|
||||
void BuildManager::progressChanged()
|
||||
{
|
||||
if (!m_progressFutureInterface)
|
||||
return;
|
||||
int range = m_watcher.progressMaximum() - m_watcher.progressMinimum();
|
||||
if (range != 0) {
|
||||
int percent = (m_watcher.progressValue() - m_watcher.progressMinimum()) * 100 / range;
|
||||
m_progressFutureInterface->setProgressValue(m_progress * 100 + percent);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildManager::nextStep()
|
||||
{
|
||||
if (!m_buildQueue.empty()) {
|
||||
@@ -279,8 +295,9 @@ void BuildManager::nextStep()
|
||||
m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep));
|
||||
} else {
|
||||
m_running = false;
|
||||
m_previousBuildStepProject = 0;
|
||||
m_previousBuildStepProject = 0;
|
||||
m_progressFutureInterface->reportFinished();
|
||||
m_progressWatcher.setFuture(QFuture<void>());
|
||||
delete m_progressFutureInterface;
|
||||
m_progressFutureInterface = 0;
|
||||
m_maxProgress = 0;
|
||||
|
||||
@@ -97,6 +97,7 @@ private slots:
|
||||
void addToOutputWindow(const QString &string);
|
||||
|
||||
void nextBuildQueue();
|
||||
void progressChanged();
|
||||
void emitCancelMessage();
|
||||
void showBuildResults();
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ CurrentProjectFind::CurrentProjectFind(ProjectExplorerPlugin *plugin, SearchResu
|
||||
this, SIGNAL(changed()));
|
||||
}
|
||||
|
||||
QString CurrentProjectFind::id() const
|
||||
{
|
||||
return "Current Project";
|
||||
}
|
||||
|
||||
QString CurrentProjectFind::name() const
|
||||
{
|
||||
return tr("Current Project");
|
||||
|
||||
@@ -48,6 +48,7 @@ class CurrentProjectFind : public TextEditor::BaseFileFind
|
||||
public:
|
||||
CurrentProjectFind(ProjectExplorerPlugin *plugin, Find::SearchResultWindow *resultWindow);
|
||||
|
||||
QString id() const;
|
||||
QString name() const;
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
@@ -602,16 +602,34 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
||||
addAutoReleasedObject(new ProjectTreeWidgetFactory);
|
||||
addAutoReleasedObject(new FolderNavigationWidgetFactory);
|
||||
|
||||
QStringList oldRecentProjects;
|
||||
if (QSettings *s = core->settings())
|
||||
m_recentProjects = s->value("ProjectExplorer/RecentProjects/Files", QStringList()).toStringList();
|
||||
for (QStringList::iterator it = m_recentProjects.begin(); it != m_recentProjects.end(); ) {
|
||||
oldRecentProjects = s->value("ProjectExplorer/RecentProjects/Files", QStringList()).toStringList();
|
||||
for (QStringList::iterator it = oldRecentProjects.begin(); it != oldRecentProjects.end(); ) {
|
||||
if (QFileInfo(*it).isFile()) {
|
||||
++it;
|
||||
} else {
|
||||
it = m_recentProjects.erase(it);
|
||||
it = oldRecentProjects.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(const QString &s, oldRecentProjects) {
|
||||
m_recentProjects.append(qMakePair(s, QFileInfo(s).fileName()));
|
||||
}
|
||||
|
||||
// TODO restore recentProjects
|
||||
if (QSettings *s = core->settings()) {
|
||||
const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
|
||||
const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
|
||||
if (fileNames.size() == displayNames.size()) {
|
||||
for (int i = 0; i < fileNames.size(); ++i) {
|
||||
m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
|
||||
connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
|
||||
#if 0
|
||||
@@ -726,7 +744,7 @@ void ProjectExplorerPlugin::unloadProject()
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
addToRecentProjects(fi->fileName());
|
||||
addToRecentProjects(fi->fileName(), m_currentProject->name());
|
||||
m_session->removeProject(m_currentProject);
|
||||
updateActions();
|
||||
}
|
||||
@@ -822,7 +840,19 @@ void ProjectExplorerPlugin::savePersistentSettings()
|
||||
QSettings *s = Core::ICore::instance()->settings();
|
||||
if (s) {
|
||||
s->setValue("ProjectExplorer/StartupSession", m_session->file()->fileName());
|
||||
s->setValue("ProjectExplorer/RecentProjects/Files", m_recentProjects);
|
||||
s->remove("ProjectExplorer/RecentProjects/Files");
|
||||
|
||||
QStringList fileNames;
|
||||
QStringList displayNames;
|
||||
QList<QPair<QString, QString> >::const_iterator it, end;
|
||||
end = m_recentProjects.constEnd();
|
||||
for (it = m_recentProjects.constBegin(); it != end; ++it) {
|
||||
fileNames << (*it).first;
|
||||
displayNames << (*it).second;
|
||||
}
|
||||
|
||||
s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
|
||||
s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,14 +861,15 @@ bool ProjectExplorerPlugin::openProject(const QString &fileName)
|
||||
if (debug)
|
||||
qDebug() << "ProjectExplorerPlugin::openProject";
|
||||
|
||||
if (openProjects(QStringList() << fileName)) {
|
||||
addToRecentProjects(fileName);
|
||||
QList<Project *> list = openProjects(QStringList() << fileName);
|
||||
if (!list.isEmpty()) {
|
||||
addToRecentProjects(fileName, list.first()->name());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
|
||||
QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
|
||||
@@ -866,7 +897,7 @@ bool ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
|
||||
if (debug)
|
||||
qDebug() << "ProjectExplorerPlugin - Could not open any projects!";
|
||||
QApplication::restoreOverrideCursor();
|
||||
return false;
|
||||
return QList<Project *>();
|
||||
}
|
||||
|
||||
foreach (Project *pro, openedPro) {
|
||||
@@ -886,7 +917,7 @@ bool ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
|
||||
Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
return true;
|
||||
return openedPro;
|
||||
}
|
||||
|
||||
Project *ProjectExplorerPlugin::currentProject() const
|
||||
@@ -1477,7 +1508,7 @@ void ProjectExplorerPlugin::cancelBuild()
|
||||
m_buildManager->cancel();
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName)
|
||||
void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";
|
||||
@@ -1485,10 +1516,17 @@ void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName)
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
QString prettyFileName(QDir::toNativeSeparators(fileName));
|
||||
m_recentProjects.removeAll(prettyFileName);
|
||||
|
||||
QList<QPair<QString, QString> >::iterator it;
|
||||
for(it = m_recentProjects.begin(); it != m_recentProjects.end();)
|
||||
if ((*it).first == prettyFileName)
|
||||
it = m_recentProjects.erase(it);
|
||||
else
|
||||
++it;
|
||||
|
||||
if (m_recentProjects.count() > m_maxRecentProjects)
|
||||
m_recentProjects.removeLast();
|
||||
m_recentProjects.prepend(prettyFileName);
|
||||
m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
|
||||
QFileInfo fi(prettyFileName);
|
||||
m_lastOpenDirectory = fi.absolutePath();
|
||||
}
|
||||
@@ -1506,11 +1544,15 @@ void ProjectExplorerPlugin::updateRecentProjectMenu()
|
||||
menu->setEnabled(!m_recentProjects.isEmpty());
|
||||
|
||||
//projects (ignore sessions, they used to be in this list)
|
||||
foreach (const QString &s, m_recentProjects) {
|
||||
if (s.endsWith(".qws"))
|
||||
|
||||
QList<QPair<QString, QString> >::const_iterator it, end;
|
||||
end = m_recentProjects.constEnd();
|
||||
for (it = m_recentProjects.constBegin(); it != end; ++it) {
|
||||
const QPair<QString, QString> &s = *it;
|
||||
if (s.first.endsWith(".qws"))
|
||||
continue;
|
||||
QAction *action = menu->addAction(s);
|
||||
action->setData(s);
|
||||
QAction *action = menu->addAction(s.second);
|
||||
action->setData(s.first);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
static ProjectExplorerPlugin *instance();
|
||||
|
||||
bool openProject(const QString &fileName);
|
||||
bool openProjects(const QStringList &fileNames);
|
||||
QList<Project *> openProjects(const QStringList &fileNames);
|
||||
|
||||
SessionManager *session() const;
|
||||
|
||||
@@ -192,7 +192,7 @@ private:
|
||||
IRunConfigurationRunner *findRunner(QSharedPointer<RunConfiguration> config, const QString &mode);
|
||||
|
||||
void updateActions();
|
||||
void addToRecentProjects(const QString &fileName);
|
||||
void addToRecentProjects(const QString &fileName, const QString &displayName);
|
||||
void updateWelcomePage(Core::Internal::WelcomeMode *welcomeMode);
|
||||
Internal::ProjectFileFactory *findProjectFileFactory(const QString &filename) const;
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
QStringList m_profileMimeTypes;
|
||||
Internal::OutputPane *m_outputPane;
|
||||
|
||||
QStringList m_recentProjects;
|
||||
QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
|
||||
static const int m_maxRecentProjects = 7;
|
||||
|
||||
QString m_lastOpenDirectory;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
using namespace Qt4ProjectManager::Internal;
|
||||
|
||||
#define MAX_VARIABLES 48
|
||||
#define MAX_VARIABLES 49
|
||||
const char *const variables[MAX_VARIABLES] = {
|
||||
"CONFIG",
|
||||
"DEFINES",
|
||||
@@ -56,6 +56,7 @@ const char *const variables[MAX_VARIABLES] = {
|
||||
"OBJECTS",
|
||||
"OBJECTS_DIR",
|
||||
"OBJMOC",
|
||||
"PKGCONFIG",
|
||||
"POST_TARGETDEPS",
|
||||
"PRECOMPILED_HEADER",
|
||||
"PRE_TARGETDEPS",
|
||||
|
||||
@@ -536,7 +536,7 @@ Qt4ProFileNode::~Qt4ProFileNode()
|
||||
void Qt4ProFileNode::buildStateChanged(ProjectExplorer::Project *project)
|
||||
{
|
||||
if (project == m_project && !ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager()->isBuilding(m_project))
|
||||
updateUiFiles(m_project->buildDirectory(m_project->activeBuildConfiguration()));
|
||||
updateUiFiles();
|
||||
}
|
||||
|
||||
bool Qt4ProFileNode::hasTargets() const
|
||||
@@ -707,7 +707,7 @@ void Qt4ProFileNode::update()
|
||||
emit qt4Watcher->variablesChanged(this, m_varValues, newVarValues);
|
||||
}
|
||||
|
||||
updateUiFiles(m_project->buildDirectory(m_project->activeBuildConfiguration()));
|
||||
updateUiFiles();
|
||||
|
||||
foreach (NodesWatcher *watcher, watchers())
|
||||
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
|
||||
@@ -741,7 +741,7 @@ namespace {
|
||||
// It does so by storing a modification time for each ui file we know about.
|
||||
|
||||
// TODO this function should also be called if the build directory is changed
|
||||
void Qt4ProFileNode::updateUiFiles(const QString &buildDirectory)
|
||||
void Qt4ProFileNode::updateUiFiles()
|
||||
{
|
||||
// Only those two project types can have ui files for us
|
||||
if (m_projectType != ApplicationTemplate
|
||||
|
||||
@@ -186,10 +186,10 @@ public slots:
|
||||
void scheduleUpdate();
|
||||
void update();
|
||||
private slots:
|
||||
void updateUiFiles(const QString& buildConfiguration);
|
||||
void buildStateChanged(ProjectExplorer::Project*);
|
||||
|
||||
private:
|
||||
void updateUiFiles();
|
||||
Qt4ProFileNode *createSubProFileNode(const QString &path);
|
||||
|
||||
QStringList uiDirPaths(ProFileReader *reader) const;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/variablemanager.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -225,8 +226,9 @@ QWidget *Qt4RunConfiguration::configurationWidget()
|
||||
|
||||
void Qt4RunConfiguration::save(PersistentSettingsWriter &writer) const
|
||||
{
|
||||
QDir projectDir(QFileInfo(project()->file()->fileName()).absoluteDir());
|
||||
writer.saveValue("CommandLineArguments", m_commandLineArguments);
|
||||
writer.saveValue("ProFile", m_proFilePath);
|
||||
writer.saveValue("ProFile", projectDir.relativeFilePath(m_proFilePath));
|
||||
writer.saveValue("UserSetName", m_userSetName);
|
||||
writer.saveValue("UseTerminal", m_runMode == Console);
|
||||
writer.saveValue("UseDyldImageSuffix", m_isUsingDyldImageSuffix);
|
||||
@@ -234,10 +236,11 @@ void Qt4RunConfiguration::save(PersistentSettingsWriter &writer) const
|
||||
}
|
||||
|
||||
void Qt4RunConfiguration::restore(const PersistentSettingsReader &reader)
|
||||
{
|
||||
{
|
||||
ApplicationRunConfiguration::restore(reader);
|
||||
QDir projectDir(QFileInfo(project()->file()->fileName()).absoluteDir());
|
||||
m_commandLineArguments = reader.restoreValue("CommandLineArguments").toStringList();
|
||||
m_proFilePath = reader.restoreValue("ProFile").toString();
|
||||
m_proFilePath = projectDir.filePath(reader.restoreValue("ProFile").toString());
|
||||
m_userSetName = reader.restoreValue("UserSetName").toBool();
|
||||
m_runMode = reader.restoreValue("UseTerminal").toBool() ? Console : Gui;
|
||||
m_isUsingDyldImageSuffix = reader.restoreValue("UseDyldImageSuffix").toBool();
|
||||
|
||||
@@ -64,44 +64,6 @@ static const char *QtVersionsSectionName = "QtVersions";
|
||||
static const char *defaultQtVersionKey = "DefaultQtVersion";
|
||||
static const char *newQtVersionsKey = "NewQtVersions";
|
||||
|
||||
DebuggingHelperWidget::DebuggingHelperWidget()
|
||||
{
|
||||
setLayout(new QHBoxLayout());
|
||||
m_statusLabel = new QLabel(this);
|
||||
|
||||
layout()->addWidget(m_statusLabel);
|
||||
|
||||
m_showLog = new QPushButton(this);
|
||||
m_showLog->setText("Show Log");
|
||||
layout()->addWidget(m_showLog);
|
||||
|
||||
m_rebuild = new QPushButton(this);
|
||||
m_rebuild->setText("Rebuild");
|
||||
layout()->addWidget(m_rebuild);
|
||||
|
||||
connect(m_showLog, SIGNAL(clicked()), this, SIGNAL(showLogClicked()));
|
||||
connect(m_rebuild, SIGNAL(clicked()), this, SIGNAL(rebuildClicked()));
|
||||
}
|
||||
|
||||
void DebuggingHelperWidget::setState(State s)
|
||||
{
|
||||
if (s & InvalidQt) {
|
||||
m_statusLabel->setVisible(false);
|
||||
m_showLog->setVisible(false);
|
||||
m_rebuild->setVisible(false);
|
||||
return;
|
||||
} else {
|
||||
m_statusLabel->setVisible(true);
|
||||
m_statusLabel->setText("");
|
||||
m_showLog->setVisible(true);
|
||||
m_rebuild->setVisible(true);
|
||||
if (s & Error)
|
||||
m_statusLabel->setPixmap(QPixmap(":/extensionsystem/images/error.png"));
|
||||
else
|
||||
m_statusLabel->setPixmap(QPixmap(":/extensionsystem/images/ok.png"));
|
||||
m_showLog->setVisible(s & ShowLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QtVersionManager::QtVersionManager()
|
||||
@@ -445,20 +407,15 @@ QtDirWidget::QtDirWidget(QWidget *parent, QList<QtVersion *> versions, int defau
|
||||
item->setText(1, version->path());
|
||||
item->setData(0, Qt::UserRole, version->uniqueId());
|
||||
|
||||
DebuggingHelperWidget *dhw = new DebuggingHelperWidget();
|
||||
m_ui.qtdirList->setItemWidget(item, 2, dhw);
|
||||
if (version->isValid()) {
|
||||
if (version->hasDebuggingHelper())
|
||||
dhw->setState(DebuggingHelperWidget::Ok);
|
||||
item->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/ok.png"));
|
||||
else
|
||||
dhw->setState(DebuggingHelperWidget::Error);
|
||||
item->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/error.png"));
|
||||
} else {
|
||||
dhw->setState(DebuggingHelperWidget::InvalidQt);
|
||||
item->setData(2, Qt::DecorationRole, QIcon());
|
||||
}
|
||||
|
||||
connect(dhw, SIGNAL(rebuildClicked()), this, SLOT(buildDebuggingHelper()));
|
||||
connect(dhw, SIGNAL(showLogClicked()), this, SLOT(showDebuggingBuildLog()));
|
||||
|
||||
m_ui.defaultCombo->addItem(version->name());
|
||||
if (i == m_defaultVersion)
|
||||
m_ui.defaultCombo->setCurrentIndex(i);
|
||||
@@ -491,6 +448,11 @@ QtDirWidget::QtDirWidget(QWidget *parent, QList<QtVersion *> versions, int defau
|
||||
connect(m_ui.msvcComboBox, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(msvcVersionChanged()));
|
||||
|
||||
connect(m_ui.rebuildButton, SIGNAL(clicked()),
|
||||
this, SLOT(buildDebuggingHelper()));
|
||||
connect(m_ui.showLogButton, SIGNAL(clicked()),
|
||||
this, SLOT(showDebuggingBuildLog()));
|
||||
|
||||
showEnvironmentPage(0);
|
||||
updateState();
|
||||
}
|
||||
@@ -498,47 +460,37 @@ QtDirWidget::QtDirWidget(QWidget *parent, QList<QtVersion *> versions, int defau
|
||||
void QtDirWidget::buildDebuggingHelper()
|
||||
{
|
||||
// Find the qt version for this button..
|
||||
int index = indexForWidget(qobject_cast<QWidget *>(sender()));
|
||||
if (index == -1)
|
||||
QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem();
|
||||
if (!currentItem)
|
||||
return;
|
||||
|
||||
QString result = m_versions.at(index)->buildDebuggingHelperLibrary();
|
||||
int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem);
|
||||
QtVersion *version = m_versions[currentItemIndex];
|
||||
|
||||
QTreeWidgetItem *item = m_ui.qtdirList->topLevelItem(index);
|
||||
item->setData(2, Qt::UserRole, result);
|
||||
DebuggingHelperWidget *dhw =
|
||||
qobject_cast<DebuggingHelperWidget *>(m_ui.qtdirList->itemWidget(item, 2));
|
||||
if (dhw) {
|
||||
QString result = m_versions.at(currentItemIndex)->buildDebuggingHelperLibrary();
|
||||
currentItem->setData(2, Qt::UserRole, result);
|
||||
|
||||
if (m_versions.at(index)->hasDebuggingHelper())
|
||||
dhw->setState(DebuggingHelperWidget::State(DebuggingHelperWidget::Ok | DebuggingHelperWidget::ShowLog));
|
||||
else
|
||||
dhw->setState(DebuggingHelperWidget::State(DebuggingHelperWidget::Error | DebuggingHelperWidget::ShowLog));
|
||||
if (version->hasDebuggingHelper()) {
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/ok.png"));
|
||||
currentItem->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/ok.png"));
|
||||
} else {
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/error.png"));
|
||||
currentItem->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/error.png"));
|
||||
}
|
||||
}
|
||||
|
||||
int QtDirWidget::indexForWidget(QWidget *widget) const
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < m_ui.qtdirList->topLevelItemCount(); ++i) {
|
||||
if (m_ui.qtdirList->itemWidget(m_ui.qtdirList->topLevelItem(i), 2) == widget) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
m_ui.showLogButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void QtDirWidget::showDebuggingBuildLog()
|
||||
{
|
||||
int index = indexForWidget(qobject_cast<QWidget *>(sender()));
|
||||
if (index == -1)
|
||||
QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem();
|
||||
if (!currentItem)
|
||||
return;
|
||||
|
||||
int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem);
|
||||
QDialog dlg;
|
||||
Ui_ShowBuildLog ui;
|
||||
ui.setupUi(&dlg);
|
||||
ui.log->setPlainText(m_ui.qtdirList->topLevelItem(index)->data(2, Qt::UserRole).toString());
|
||||
ui.log->setPlainText(m_ui.qtdirList->topLevelItem(currentItemIndex)->data(2, Qt::UserRole).toString());
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
@@ -556,16 +508,7 @@ void QtDirWidget::addQtDir()
|
||||
item->setText(0, newVersion->name());
|
||||
item->setText(1, newVersion->path());
|
||||
item->setData(0, Qt::UserRole, newVersion->uniqueId());
|
||||
|
||||
DebuggingHelperWidget *dhw = new DebuggingHelperWidget();
|
||||
m_ui.qtdirList->setItemWidget(item, 2, dhw);
|
||||
if (newVersion->hasDebuggingHelper())
|
||||
dhw->setState(DebuggingHelperWidget::Ok);
|
||||
else
|
||||
dhw->setState(DebuggingHelperWidget::Error);
|
||||
connect(dhw, SIGNAL(rebuildClicked()), this, SLOT(buildDebuggingHelper()));
|
||||
connect(dhw, SIGNAL(showLogClicked()), this, SLOT(showDebuggingBuildLog()));
|
||||
m_ui.qtdirList->setItemWidget(item, 2, dhw);
|
||||
item->setData(2, Qt::DecorationRole, QIcon());
|
||||
|
||||
m_ui.qtdirList->setCurrentItem(item);
|
||||
|
||||
@@ -579,8 +522,6 @@ void QtDirWidget::addQtDir()
|
||||
void QtDirWidget::removeQtDir()
|
||||
{
|
||||
QTreeWidgetItem *item = m_ui.qtdirList->currentItem();
|
||||
|
||||
|
||||
int index = m_ui.qtdirList->indexOfTopLevelItem(item);
|
||||
if (index < 0)
|
||||
return;
|
||||
@@ -607,8 +548,24 @@ void QtDirWidget::updateState()
|
||||
m_ui.nameEdit->setEnabled(enabled && !isSystemVersion);
|
||||
m_ui.qtPath->setEnabled(enabled && !isSystemVersion);
|
||||
m_ui.mingwPath->setEnabled(enabled);
|
||||
}
|
||||
|
||||
bool hasLog = enabled && !m_ui.qtdirList->currentItem()->data(2, Qt::UserRole).toString().isEmpty();
|
||||
m_ui.showLogButton->setEnabled(hasLog);
|
||||
|
||||
QtVersion *version = 0;
|
||||
if (enabled)
|
||||
version = m_versions.at(m_ui.qtdirList->indexOfTopLevelItem(m_ui.qtdirList->currentItem()));
|
||||
if (version) {
|
||||
m_ui.rebuildButton->setEnabled(version->isValid());
|
||||
if (version->hasDebuggingHelper())
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/ok.png"));
|
||||
else
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/error.png"));
|
||||
} else {
|
||||
m_ui.rebuildButton->setEnabled(false);
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap());
|
||||
}
|
||||
}
|
||||
void QtDirWidget::makeMingwVisible(bool visible)
|
||||
{
|
||||
m_ui.mingwLabel->setVisible(visible);
|
||||
@@ -781,16 +738,20 @@ void QtDirWidget::updateCurrentQtPath()
|
||||
|
||||
showEnvironmentPage(currentItem);
|
||||
|
||||
DebuggingHelperWidget *dhw = qobject_cast<DebuggingHelperWidget *>(m_ui.qtdirList->itemWidget(currentItem, 2));
|
||||
if (m_versions[currentItemIndex]->isValid()) {
|
||||
DebuggingHelperWidget::State s = DebuggingHelperWidget::Ok;
|
||||
if (!m_versions[currentItemIndex]->hasDebuggingHelper())
|
||||
s = DebuggingHelperWidget::State(s | DebuggingHelperWidget::Error);
|
||||
if (!currentItem->data(2, Qt::UserRole).toString().isEmpty())
|
||||
s = DebuggingHelperWidget::State(s | DebuggingHelperWidget::ShowLog);
|
||||
dhw->setState(s);
|
||||
bool hasLog = !currentItem->data(2, Qt::UserRole).toString().isEmpty();
|
||||
bool hasHelper = m_versions[currentItemIndex]->hasDebuggingHelper();
|
||||
if (hasHelper) {
|
||||
currentItem->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/ok.png"));
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/ok.png"));
|
||||
} else {
|
||||
currentItem->setData(2, Qt::DecorationRole, QIcon(":/extensionsystem/images/error.png"));
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap(":/extensionsystem/images/error.png"));
|
||||
}
|
||||
m_ui.showLogButton->setEnabled(hasLog);
|
||||
} else {
|
||||
dhw->setState(DebuggingHelperWidget::InvalidQt);
|
||||
currentItem->setData(2, Qt::DecorationRole, QIcon());
|
||||
m_ui.debuggingHelperStateLabel->setPixmap(QPixmap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1463,7 +1424,7 @@ QString QtVersion::buildDebuggingHelperLibrary()
|
||||
qmake.setWorkingDirectory(directory);
|
||||
qmake.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
qmake.start(qmakeCommand(), QStringList()<<"-spec"<<"default"<<"gdbmacros.pro");
|
||||
qmake.start(qmakeCommand(), QStringList()<<"-spec"<< mkspec() <<"gdbmacros.pro");
|
||||
qmake.waitForFinished();
|
||||
|
||||
output += qmake.readAll();
|
||||
|
||||
@@ -223,27 +223,6 @@ private:
|
||||
int m_idcount;
|
||||
};
|
||||
|
||||
class DebuggingHelperWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DebuggingHelperWidget();
|
||||
enum State {
|
||||
Ok = 0,
|
||||
Error = 1,
|
||||
ShowLog = 2,
|
||||
InvalidQt = 4
|
||||
};
|
||||
void setState(State s);
|
||||
signals:
|
||||
void rebuildClicked();
|
||||
void showLogClicked();
|
||||
private:
|
||||
QLabel *m_statusLabel;
|
||||
QPushButton *m_showLog;
|
||||
QPushButton *m_rebuild;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qt4ProjectManager
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>823</width>
|
||||
<height>929</height>
|
||||
<width>811</width>
|
||||
<height>505</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -61,7 +61,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>10</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -137,6 +137,38 @@
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="Core::Utils::PathChooser" name="mingwPath" native="true"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Debugging Helper:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="debuggingHelperStateLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="showLogButton">
|
||||
<property name="text">
|
||||
<string>Show &Log</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rebuildButton">
|
||||
<property name="text">
|
||||
<string>&Rebuild</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "javascriptengine_p.h"
|
||||
#include "javascriptnodepool_p.h"
|
||||
#include "javascriptvalue.h"
|
||||
@@ -10,17 +39,17 @@ namespace JavaScript {
|
||||
|
||||
int Ecma::RegExp::flagFromChar(const QChar &ch)
|
||||
{
|
||||
static QHash<QChar, int> flagsHash;
|
||||
if (flagsHash.isEmpty()) {
|
||||
flagsHash[QLatin1Char('g')] = Global;
|
||||
flagsHash[QLatin1Char('i')] = IgnoreCase;
|
||||
flagsHash[QLatin1Char('m')] = Multiline;
|
||||
}
|
||||
QHash<QChar, int>::const_iterator it;
|
||||
it = flagsHash.constFind(ch);
|
||||
if (it == flagsHash.constEnd())
|
||||
return 0;
|
||||
return it.value();
|
||||
static QHash<QChar, int> flagsHash;
|
||||
if (flagsHash.isEmpty()) {
|
||||
flagsHash[QLatin1Char('g')] = Global;
|
||||
flagsHash[QLatin1Char('i')] = IgnoreCase;
|
||||
flagsHash[QLatin1Char('m')] = Multiline;
|
||||
}
|
||||
QHash<QChar, int>::const_iterator it;
|
||||
it = flagsHash.constFind(ch);
|
||||
if (it == flagsHash.constEnd())
|
||||
return 0;
|
||||
return it.value();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +64,8 @@ NodePool::~NodePool()
|
||||
|
||||
Code *NodePool::createCompiledCode(AST::Node *, CompilationUnit &)
|
||||
{
|
||||
Q_ASSERT(0);
|
||||
return 0;
|
||||
Q_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toDigit(char c)
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef JAVASCRIPTENGINE_P_H
|
||||
#define JAVASCRIPTENGINE_P_H
|
||||
|
||||
@@ -42,24 +71,24 @@ public:
|
||||
|
||||
class JavaScriptNameIdImpl
|
||||
{
|
||||
QString _text;
|
||||
QString _text;
|
||||
|
||||
public:
|
||||
JavaScriptNameIdImpl(const QChar *u, int s)
|
||||
: _text(u, s)
|
||||
{ }
|
||||
JavaScriptNameIdImpl(const QChar *u, int s)
|
||||
: _text(u, s)
|
||||
{ }
|
||||
|
||||
const QString asString() const
|
||||
{ return _text; }
|
||||
const QString asString() const
|
||||
{ return _text; }
|
||||
|
||||
bool operator == (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text == other._text; }
|
||||
bool operator == (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text == other._text; }
|
||||
|
||||
bool operator != (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text != other._text; }
|
||||
bool operator != (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text != other._text; }
|
||||
|
||||
bool operator < (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text < other._text; }
|
||||
bool operator < (const JavaScriptNameIdImpl &other) const
|
||||
{ return _text < other._text; }
|
||||
};
|
||||
|
||||
inline uint qHash(const JavaScriptNameIdImpl &id)
|
||||
@@ -67,43 +96,43 @@ inline uint qHash(const JavaScriptNameIdImpl &id)
|
||||
|
||||
class JavaScriptEnginePrivate
|
||||
{
|
||||
JavaScript::Lexer *_lexer;
|
||||
JavaScript::NodePool *_nodePool;
|
||||
JavaScript::AST::Node *_ast;
|
||||
QSet<JavaScriptNameIdImpl> _literals;
|
||||
JavaScript::Lexer *_lexer;
|
||||
JavaScript::NodePool *_nodePool;
|
||||
JavaScript::AST::Node *_ast;
|
||||
QSet<JavaScriptNameIdImpl> _literals;
|
||||
|
||||
public:
|
||||
JavaScriptEnginePrivate()
|
||||
: _lexer(0), _nodePool(0), _ast(0)
|
||||
{ }
|
||||
JavaScriptEnginePrivate()
|
||||
: _lexer(0), _nodePool(0), _ast(0)
|
||||
{ }
|
||||
|
||||
QSet<JavaScriptNameIdImpl> literals() const
|
||||
{ return _literals; }
|
||||
QSet<JavaScriptNameIdImpl> literals() const
|
||||
{ return _literals; }
|
||||
|
||||
JavaScriptNameIdImpl *intern(const QChar *u, int s)
|
||||
{ return const_cast<JavaScriptNameIdImpl *>(&*_literals.insert(JavaScriptNameIdImpl(u, s))); }
|
||||
JavaScriptNameIdImpl *intern(const QChar *u, int s)
|
||||
{ return const_cast<JavaScriptNameIdImpl *>(&*_literals.insert(JavaScriptNameIdImpl(u, s))); }
|
||||
|
||||
JavaScript::Lexer *lexer() const
|
||||
{ return _lexer; }
|
||||
JavaScript::Lexer *lexer() const
|
||||
{ return _lexer; }
|
||||
|
||||
void setLexer(JavaScript::Lexer *lexer)
|
||||
{ _lexer = lexer; }
|
||||
void setLexer(JavaScript::Lexer *lexer)
|
||||
{ _lexer = lexer; }
|
||||
|
||||
JavaScript::NodePool *nodePool() const
|
||||
{ return _nodePool; }
|
||||
JavaScript::NodePool *nodePool() const
|
||||
{ return _nodePool; }
|
||||
|
||||
void setNodePool(JavaScript::NodePool *nodePool)
|
||||
{ _nodePool = nodePool; }
|
||||
void setNodePool(JavaScript::NodePool *nodePool)
|
||||
{ _nodePool = nodePool; }
|
||||
|
||||
JavaScript::AST::Node *ast() const
|
||||
{ return _ast; }
|
||||
JavaScript::AST::Node *ast() const
|
||||
{ return _ast; }
|
||||
|
||||
JavaScript::AST::Node *changeAbstractSyntaxTree(JavaScript::AST::Node *node)
|
||||
{
|
||||
JavaScript::AST::Node *previousAST = _ast;
|
||||
_ast = node;
|
||||
return previousAST;
|
||||
}
|
||||
JavaScript::AST::Node *changeAbstractSyntaxTree(JavaScript::AST::Node *node)
|
||||
{
|
||||
JavaScript::AST::Node *previousAST = _ast;
|
||||
_ast = node;
|
||||
return previousAST;
|
||||
}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -22,7 +22,7 @@ Qt::CaseSensitivity QtScriptCodeCompletion::caseSensitivity() const
|
||||
void QtScriptCodeCompletion::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
|
||||
{ m_caseSensitivity = caseSensitivity; }
|
||||
|
||||
bool QtScriptCodeCompletion::isValid(TextEditor::ITextEditable *editor)
|
||||
bool QtScriptCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
|
||||
{
|
||||
if (qobject_cast<ScriptEditor *>(editor->widget()))
|
||||
return true;
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
Qt::CaseSensitivity caseSensitivity() const;
|
||||
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
|
||||
|
||||
virtual bool isValid(TextEditor::ITextEditable *editor);
|
||||
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
|
||||
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
|
||||
virtual int startCompletion(TextEditor::ITextEditable *editor);
|
||||
virtual void completions(QList<TextEditor::CompletionItem> *completions);
|
||||
|
||||
@@ -240,7 +240,7 @@ void ScriptEditor::updateDocumentNow()
|
||||
errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
|
||||
|
||||
QTextCharFormat warningFormat;
|
||||
warningFormat.setUnderlineColor(Qt::yellow);
|
||||
warningFormat.setUnderlineColor(Qt::darkYellow);
|
||||
warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
|
||||
|
||||
QTextEdit::ExtraSelection sel;
|
||||
|
||||
@@ -74,14 +74,14 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
|
||||
QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
|
||||
foreach (const QString &dir, dirs) {
|
||||
if (dir != "." && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) {
|
||||
FilterEntry entry(this, dir, directory + "/" + dir);
|
||||
FilterEntry entry(this, dir, dirInfo.filePath(dir));
|
||||
entry.resolveFileIcon = true;
|
||||
value.append(entry);
|
||||
}
|
||||
}
|
||||
foreach (const QString &file, files) {
|
||||
if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) {
|
||||
const QString fullPath = directory + "/" + file;
|
||||
const QString fullPath = dirInfo.filePath(file);
|
||||
FilterEntry entry(this, file, fullPath);
|
||||
entry.resolveFileIcon = true;
|
||||
value.append(entry);
|
||||
|
||||
@@ -94,7 +94,7 @@ void CompletionSupport::autoComplete(ITextEditable *editor, bool forced)
|
||||
m_completionCollector = 0;
|
||||
|
||||
foreach (ICompletionCollector *collector, m_completionCollectors) {
|
||||
if (collector->isValid(editor)) {
|
||||
if (collector->supportsEditor(editor)) {
|
||||
m_completionCollector = collector;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,11 @@ FindInFiles::FindInFiles(SearchResultWindow *resultWindow)
|
||||
{
|
||||
}
|
||||
|
||||
QString FindInFiles::id() const
|
||||
{
|
||||
return "Files on Disk";
|
||||
}
|
||||
|
||||
QString FindInFiles::name() const
|
||||
{
|
||||
return tr("Files on Disk");
|
||||
|
||||
@@ -51,6 +51,7 @@ class FindInFiles : public BaseFileFind
|
||||
public:
|
||||
explicit FindInFiles(Find::SearchResultWindow *resultWindow);
|
||||
|
||||
QString id() const;
|
||||
QString name() const;
|
||||
QKeySequence defaultShortcut() const;
|
||||
void findAll(const QString &txt, QTextDocument::FindFlags findFlags);
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
/*
|
||||
* Returns true if this completion collector can be used with the given editor.
|
||||
*/
|
||||
virtual bool isValid(ITextEditable *editor) = 0;
|
||||
virtual bool supportsEditor(ITextEditable *editor) = 0;
|
||||
|
||||
/* This method should return whether the cursor is at a position which could
|
||||
* trigger an autocomplete. It will be called each time a character is typed in
|
||||
|
||||
@@ -224,15 +224,15 @@ public:
|
||||
ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
|
||||
: q(q_)
|
||||
{
|
||||
// Global parser state
|
||||
m_prevLineNo = 0;
|
||||
m_prevProFile = 0;
|
||||
|
||||
// Configuration, more or less
|
||||
m_verbose = true;
|
||||
m_block = 0;
|
||||
m_commentItem = 0;
|
||||
m_syntaxError = 0;
|
||||
m_lineNo = 0;
|
||||
m_contNextLine = false;
|
||||
m_cumulative = true;
|
||||
|
||||
// Evaluator state
|
||||
m_updateCondition = false;
|
||||
m_condition = ConditionFalse;
|
||||
m_invertNext = false;
|
||||
@@ -248,8 +248,13 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parser state
|
||||
m_block = 0;
|
||||
m_commentItem = 0;
|
||||
m_contNextLine = false;
|
||||
m_syntaxError = false;
|
||||
m_lineNo = 1;
|
||||
m_blockstack.clear();
|
||||
m_blockstack.push(pro);
|
||||
|
||||
QTextStream ts(&file);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
QT = core testlib
|
||||
|
||||
DEBUGGERDIR = ../../../src/plugins/debugger
|
||||
UTILSDIR = ../../../src/libs
|
||||
|
||||
SOURCES += \
|
||||
$$DEBUGGERDIR/gdbmi.cpp \
|
||||
main.cpp \
|
||||
|
||||
INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
#include "gdbmi.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtTest/QtTest>
|
||||
//#include <QtTest/qtest_gui.h>
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
static const char test1[] =
|
||||
"[frame={level=\"0\",addr=\"0x00000000004061ca\","
|
||||
"func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]";
|
||||
|
||||
static const char test2[] =
|
||||
"[frame={level=\"0\",addr=\"0x00002ac058675840\","
|
||||
"func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\","
|
||||
"fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"},"
|
||||
"frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]";
|
||||
|
||||
static const char test3[] =
|
||||
"[stack={frame={level=\"0\",addr=\"0x00000000004061ca\","
|
||||
"func=\"main\",file=\"test1.cpp\","
|
||||
"fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}}]";
|
||||
|
||||
static const char test4[] =
|
||||
"&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\""
|
||||
"4^done\n";
|
||||
|
||||
static const char test5[] =
|
||||
"[reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\","
|
||||
"frame={addr=\"0x0000000000405738\",func=\"main\","
|
||||
"args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}],"
|
||||
"file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\","
|
||||
"line=\"209\"}]";
|
||||
|
||||
static const char test8[] =
|
||||
"[data={locals={{name=\"a\"},{name=\"w\"}}}]";
|
||||
|
||||
static const char test9[] =
|
||||
"[data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}]";
|
||||
|
||||
static const char test10[] =
|
||||
"[name=\"urgs\",numchild=\"1\",type=\"Urgs\"]";
|
||||
|
||||
static const char test11[] =
|
||||
"[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"},"
|
||||
"{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
|
||||
|
||||
static const char test12[] =
|
||||
"[{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\","
|
||||
"numchild=\"0\"}]";
|
||||
|
||||
class tst_Debugger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_Debugger() {}
|
||||
|
||||
void testMi(const char* input)
|
||||
{
|
||||
QCOMPARE('\n' + QString::fromLatin1(GdbMi(input).toString(false)),
|
||||
'\n' + QString(input));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void mi1() { testMi(test1); }
|
||||
void mi2() { testMi(test2); }
|
||||
void mi3() { testMi(test3); }
|
||||
//void mi4() { testMi(test4); }
|
||||
void mi5() { testMi(test5); }
|
||||
void mi8() { testMi(test8); }
|
||||
void mi9() { testMi(test9); }
|
||||
void mi10() { testMi(test10); }
|
||||
void mi11() { testMi(test11); }
|
||||
void mi12() { testMi(test12); }
|
||||
void runQtc();
|
||||
|
||||
public slots:
|
||||
void readStandardOutput();
|
||||
void readStandardError();
|
||||
|
||||
private:
|
||||
QProcess m_proc; // the Qt Creator process
|
||||
};
|
||||
|
||||
static QByteArray stripped(QByteArray ba)
|
||||
{
|
||||
for (int i = ba.size(); --i >= 0; ) {
|
||||
if (ba.at(i) == '\n' || ba.at(i) == ' ')
|
||||
ba.chop(1);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return ba;
|
||||
}
|
||||
|
||||
void tst_Debugger::readStandardOutput()
|
||||
{
|
||||
qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput());
|
||||
}
|
||||
|
||||
void tst_Debugger::readStandardError()
|
||||
{
|
||||
qDebug() << "qtcreator-err: " << stripped(m_proc.readAllStandardError());
|
||||
}
|
||||
|
||||
void tst_Debugger::runQtc()
|
||||
{
|
||||
QString test = QFileInfo(qApp->arguments().at(0)).absoluteFilePath();
|
||||
QString qtc = QFileInfo(test).absolutePath() + "/../../../bin/qtcreator.bin";
|
||||
qtc = QFileInfo(qtc).absoluteFilePath();
|
||||
QStringList env = QProcess::systemEnvironment();
|
||||
env.append("QTC_DEBUGGER_TEST=" + test);
|
||||
m_proc.setEnvironment(env);
|
||||
connect(&m_proc, SIGNAL(readyReadStandardOutput()),
|
||||
this, SLOT(readStandardOutput()));
|
||||
connect(&m_proc, SIGNAL(readyReadStandardError()),
|
||||
this, SLOT(readStandardError()));
|
||||
m_proc.start(qtc);
|
||||
m_proc.waitForStarted();
|
||||
QCOMPARE(m_proc.state(), QProcess::Running);
|
||||
m_proc.waitForFinished();
|
||||
QCOMPARE(m_proc.state(), QProcess::NotRunning);
|
||||
}
|
||||
|
||||
void runDebuggee()
|
||||
{
|
||||
qDebug() << "RUNNING DEBUGGEE";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QStringList args = app.arguments();
|
||||
|
||||
|
||||
if (args.size() == 2 && args.at(1) == "--run-debuggee") {
|
||||
runDebuggee();
|
||||
return 0;
|
||||
}
|
||||
|
||||
tst_Debugger test;
|
||||
return QTest::qExec(&test, argc, argv);
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
|
||||
QT += testlib
|
||||
|
||||
FAKEVIMSOURCE = ../../../src/plugins/fakevim
|
||||
|
||||
INCLUDEPATH += $$FAKEVIMSOURCE
|
||||
FAKEVIMDIR = ../../../src/plugins/fakevim
|
||||
UTILSDIR = ../../../src/libs
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
$$FAKEVIMSOURCE/handler.cpp
|
||||
$$FAKEVIMDIR/fakevimhandler.cpp \
|
||||
$$FAKEVIMDIR/fakevimactions.cpp \
|
||||
$$UTILSDIR/utils/savedaction.cpp \
|
||||
$$UTILSDIR/utils/pathchooser.cpp \
|
||||
$$UTILSDIR/utils/basevalidatinglineedit.cpp \
|
||||
|
||||
HEADERS += \
|
||||
$$FAKEVIMSOURCE/handler.h
|
||||
$$FAKEVIMDIR/fakevimhandler.h \
|
||||
$$FAKEVIMDIR/fakevimactions.h \
|
||||
$$UTILSDIR/utils/savedaction.h \
|
||||
$$UTILSDIR/utils/pathchooser.h \
|
||||
$$UTILSDIR/utils/basevalidatinglineedit.h \
|
||||
|
||||
INCLUDEPATH += $$FAKEVIMDIR $$UTILSDIR
|
||||
|
||||
|
||||
+151
-2
@@ -27,18 +27,167 @@
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "handler.h"
|
||||
#include "fakevimhandler.h"
|
||||
|
||||
#include <QtCore/QSet>
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QSet>
|
||||
|
||||
using namespace FakeVim;
|
||||
using namespace FakeVim::Internal;
|
||||
|
||||
|
||||
class tst_FakeVim : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_FakeVim();
|
||||
|
||||
void setup();
|
||||
void send(const QString &command); // send a normal command
|
||||
void sendEx(const QString &command); // send an ex command
|
||||
|
||||
QString cleaned(QString wanted) { wanted.remove('$'); return wanted; }
|
||||
|
||||
public slots:
|
||||
void changeStatusData(const QString &info) { m_statusData = info; }
|
||||
void changeStatusMessage(const QString &info) { m_statusMessage = info; }
|
||||
void changeExtraInformation(const QString &info) { m_infoMessage = info; }
|
||||
|
||||
public:
|
||||
QString m_statusMessage;
|
||||
QString m_statusData;
|
||||
QString m_infoMessage;
|
||||
|
||||
private slots:
|
||||
void commandI();
|
||||
void commandDollar();
|
||||
|
||||
private:
|
||||
QPlainTextEdit m_editor;
|
||||
FakeVimHandler m_handler;
|
||||
QList<QTextEdit::ExtraSelection> m_selection;
|
||||
|
||||
static const QString lines;
|
||||
static const QString escape;
|
||||
};
|
||||
|
||||
const QString tst_FakeVim::lines =
|
||||
"\n"
|
||||
"#include <QtCore>\n"
|
||||
"#include <QtGui>\n"
|
||||
"\n"
|
||||
"int main(int argc, char *argv[])\n"
|
||||
"{\n"
|
||||
" QApplication app(argc, argv);\n"
|
||||
"\n"
|
||||
" return app.exec();\n"
|
||||
"}\n";
|
||||
|
||||
const QString tst_FakeVim::escape = QChar(27);
|
||||
|
||||
tst_FakeVim::tst_FakeVim()
|
||||
: m_handler(&m_editor, this)
|
||||
{
|
||||
|
||||
QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)),
|
||||
this, SLOT(changeStatusMessage(QString)));
|
||||
QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)),
|
||||
this, SLOT(changeExtraInformation(QString)));
|
||||
QObject::connect(&m_handler, SIGNAL(statusDataChanged(QString)),
|
||||
this, SLOT(changeStatusData(QString)));
|
||||
}
|
||||
|
||||
void tst_FakeVim::setup()
|
||||
{
|
||||
m_statusMessage.clear();
|
||||
m_statusData.clear();
|
||||
m_infoMessage.clear();
|
||||
m_editor.setPlainText(lines);
|
||||
QCOMPARE(m_editor.toPlainText(), lines);
|
||||
}
|
||||
|
||||
void tst_FakeVim::send(const QString &command)
|
||||
{
|
||||
m_handler.handleCommand("normal " + command);
|
||||
}
|
||||
|
||||
void tst_FakeVim::sendEx(const QString &command)
|
||||
{
|
||||
m_handler.handleCommand(command);
|
||||
}
|
||||
|
||||
#define checkContents(wanted) \
|
||||
do { QString want = cleaned(wanted); \
|
||||
QString got = m_editor.toPlainText(); \
|
||||
QStringList wantlist = want.split('\n'); \
|
||||
QStringList gotlist = got.split('\n'); \
|
||||
QCOMPARE(gotlist.size(), wantlist.size()); \
|
||||
for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) { \
|
||||
QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i)); \
|
||||
QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); \
|
||||
QCOMPARE(g, w); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define checkText(cmd, wanted) \
|
||||
do { \
|
||||
send(cmd); \
|
||||
checkContents(wanted); \
|
||||
int p = (wanted).indexOf('$'); \
|
||||
QCOMPARE(m_editor.textCursor().position(), p); \
|
||||
} while (0)
|
||||
|
||||
#define checkTextEx(cmd, wanted) \
|
||||
do { \
|
||||
sendEx(cmd); \
|
||||
checkContents(wanted); \
|
||||
int p = (wanted).indexOf('$'); \
|
||||
QCOMPARE(m_editor.textCursor().position(), p); \
|
||||
} while (0)
|
||||
|
||||
#define checkPosition(cmd, pos) \
|
||||
do { \
|
||||
send(cmd); \
|
||||
QCOMPARE(m_editor.textCursor().position(), pos); \
|
||||
} while (0)
|
||||
|
||||
void tst_FakeVim::commandI()
|
||||
{
|
||||
setup();
|
||||
|
||||
// empty insertion at start of document
|
||||
checkText("i" + escape, "$" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
|
||||
// small insertion at start of document
|
||||
checkText("ix" + escape, "$x" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
|
||||
// small insertion at start of document
|
||||
checkText("ixxx" + escape, "xx$x" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
|
||||
// combine insertions
|
||||
checkText("ia" + escape, "$a" + lines);
|
||||
checkText("ibx" + escape, "b$xa" + lines);
|
||||
checkText("icyy" + escape, "bcy$yxa" + lines);
|
||||
checkText("u", "b$xa" + lines);
|
||||
checkText("u", "$a" + lines); // undo broken
|
||||
checkTextEx("redo", "b$xa" + lines);
|
||||
checkText("u", "$a" + lines);
|
||||
checkText("u", "$" + lines);
|
||||
}
|
||||
|
||||
void tst_FakeVim::commandDollar()
|
||||
{
|
||||
setup();
|
||||
checkPosition("$", 0);
|
||||
checkPosition("j", 2);
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_FakeVim)
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
|
||||
function cube(a)
|
||||
{
|
||||
return a * a * a;
|
||||
var x = a * a * a;
|
||||
x = x + 1;
|
||||
x = x - 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
var a = cube(3);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QSharedPointer>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QAction>
|
||||
@@ -493,6 +494,11 @@ void testQSet()
|
||||
//hash.insert(ptr);
|
||||
}
|
||||
|
||||
|
||||
void testQSharedPointer()
|
||||
{
|
||||
}
|
||||
|
||||
void stringRefTest(const QString &refstring)
|
||||
{
|
||||
Q_UNUSED(refstring);
|
||||
@@ -1078,7 +1084,8 @@ struct QMetaTypeId<QHostAddress>
|
||||
{
|
||||
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||
if (!metatype_id)
|
||||
metatype_id = qRegisterMetaType<QHostAddress>("myns::QHostAddress");
|
||||
metatype_id = qRegisterMetaType<QHostAddress>
|
||||
("myns::QHostAddress");
|
||||
return metatype_id; \
|
||||
} \
|
||||
};
|
||||
@@ -1091,7 +1098,8 @@ struct QMetaTypeId< QMap<uint, QStringList> >
|
||||
{
|
||||
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||
if (!metatype_id)
|
||||
metatype_id = qRegisterMetaType< QMap<uint, QStringList> >("myns::QMap<uint, myns::QStringList>");
|
||||
metatype_id = qRegisterMetaType< QMap<uint, QStringList> >
|
||||
("myns::QMap<uint, myns::QStringList>");
|
||||
return metatype_id; \
|
||||
} \
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user