diff --git a/doc/doc.pri b/doc/doc.pri index e9e34fe733b561ee693ab897afa04be814003186..4207e364c766b53f2dc01a487c5d62bef801ec23 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -9,7 +9,11 @@ unix { QHP_FILE = $$OUT_PWD/doc/html/qtcreator.qhp QCH_FILE = $$OUT_PWD/doc/qtcreator.qch -html_docs.commands =$$QDOC $$PWD/qtcreator.qdocconf +unix { +html_docs.commands = $$QDOC $$PWD/qtcreator.qdocconf +} else { +html_docs.commands = \"$$QDOC $$PWD/qtcreator.qdocconf\" +} html_docs.depends += $$PWD/qtcreator.qdoc $$PWD/qtcreator.qdocconf html_docs.files = $$QHP_FILE diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index f4633fcd7351f7aa966d4067159963326265f28f..9dc93c0133d60349871c4a7ef28fae90786aacb7 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -186,6 +186,7 @@ MainWindow::MainWindow() : QCoreApplication::setOrganizationName(QLatin1String("Nokia")); QSettings::setDefaultFormat(QSettings::IniFormat); QString baseName = qApp->style()->objectName(); +#ifdef Q_WS_X11 if (baseName == "windows") { // Sometimes we get the standard windows 95 style as a fallback // e.g. if we are running on a KDE4 desktop @@ -195,6 +196,7 @@ MainWindow::MainWindow() : else baseName = "cleanlooks"; } +#endif qApp->setStyle(new ManhattanStyle(baseName)); statusBar()->setProperty("p_styled", true); } diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index c9256caaa5fc9ae7efe4d9ffdda918999f44131a..5a21d6a42d7a56248d4d2d0e1b21896f98a23985 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -26,7 +26,6 @@ HEADERS += attachexternaldialog.h \ disassemblerwindow.h \ gdbengine.h \ gdbmi.h \ - gdboptionpage.h \ idebuggerengine.h \ imports.h \ moduleshandler.h \ @@ -55,7 +54,6 @@ SOURCES += attachexternaldialog.cpp \ disassemblerwindow.cpp \ gdbengine.cpp \ gdbmi.cpp \ - gdboptionpage.cpp \ gdbengine.h \ moduleshandler.cpp \ moduleswindow.cpp \ diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f268fbb3dda787ac4341b42d0fde49cb762ade8d..ea0e6623b067aec04e98f8b272e476c426d3da36 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -86,6 +86,18 @@ using namespace Debugger::Constants; static const QString tooltipIName = "tooltip"; + +DebuggerSettings::DebuggerSettings() +{ + m_autoRun = false; + m_autoQuit = false; + m_skipKnownFrames = false; + m_debugDumpers = false; + m_useToolTips = false; + m_useToolTips = false; + m_useCustomDumpers = true; +} + /////////////////////////////////////////////////////////////////////// // // BreakByFunctionDialog @@ -322,56 +334,6 @@ void DebuggerManager::init() m_breakAtMainAction = new QAction(this); m_breakAtMainAction->setText(tr("Set Breakpoint at Function 'main'")); - m_debugDumpersAction = new QAction(this); - m_debugDumpersAction->setText(tr("Debug Custom Dumpers")); - m_debugDumpersAction->setToolTip(tr("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.")); - m_debugDumpersAction->setCheckable(true); - - m_skipKnownFramesAction = new QAction(this); - m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping")); - m_skipKnownFramesAction->setToolTip(tr("After checking this option" - "'Step Into' combines in certain situations several steps, " - "leading to 'less noisy' debugging. So will, e.g., the atomic " - "reference counting code be skipped, and a single 'Step Into' " - "for a signal emission will end up directly in the slot connected " - "to it")); - m_skipKnownFramesAction->setCheckable(true); - - m_useCustomDumpersAction = new QAction(this); - m_useCustomDumpersAction->setText(tr("Use Custom Display for Qt Objects")); - m_useCustomDumpersAction->setToolTip(tr("Checking this will make the debugger " - "try to use code to format certain data (QObject, QString, ...) nicely. ")); - m_useCustomDumpersAction->setCheckable(true); - m_useCustomDumpersAction->setChecked(true); - - m_useFastStartAction = new QAction(this); - m_useFastStartAction->setText(tr("Fast Debugger Start")); - m_useFastStartAction->setToolTip(tr("Checking this will make the debugger " - "start fast by loading only very few debug symbols on start up. This " - "might lead to situations where breakpoints can not be set properly. " - "So uncheck this option if you experience breakpoint related problems.")); - m_useFastStartAction->setCheckable(true); - m_useFastStartAction->setChecked(true); - - m_useToolTipsAction = new QAction(this); - m_useToolTipsAction->setText(tr("Use Tooltips While Debugging")); - m_useToolTipsAction->setToolTip(tr("Checking this will make enable " - "tooltips for variable values during debugging. Since this can slow " - "down debugging and does not provide reliable information as it does " - "not use scope information, it is switched off by default.")); - m_useToolTipsAction->setCheckable(true); - m_useToolTipsAction->setChecked(false); - - // FIXME - m_useFastStartAction->setChecked(false); - m_useFastStartAction->setEnabled(false); - - m_dumpLogAction = new QAction(this); - m_dumpLogAction->setText(tr("Dump Log File for Debugging Purposes")); - m_watchAction = new QAction(this); m_watchAction->setText(tr("Add to Watch Window")); @@ -416,14 +378,6 @@ void DebuggerManager::init() connect(m_breakAtMainAction, SIGNAL(triggered()), this, SLOT(breakAtMain())); - connect(m_useFastStartAction, SIGNAL(triggered()), - this, SLOT(saveSessionData())); - connect(m_useCustomDumpersAction, SIGNAL(triggered()), - this, SLOT(saveSessionData())); - connect(m_skipKnownFramesAction, SIGNAL(triggered()), - this, SLOT(saveSessionData())); - connect(m_dumpLogAction, SIGNAL(triggered()), - this, SLOT(dumpLog())); connect(m_statusTimer, SIGNAL(timeout()), this, SLOT(clearStatusMessage())); @@ -947,16 +901,6 @@ void DebuggerManager::loadSessionData() { m_breakHandler->loadSessionData(); m_watchHandler->loadSessionData(); - - QVariant value; - querySessionValue(QLatin1String("UseFastStart"), &value); - m_useFastStartAction->setChecked(value.toBool()); - querySessionValue(QLatin1String("UseToolTips"), &value); - m_useToolTipsAction->setChecked(value.toBool()); - querySessionValue(QLatin1String("UseCustomDumpers"), &value); - m_useCustomDumpersAction->setChecked(!value.isValid() || value.toBool()); - querySessionValue(QLatin1String("SkipKnownFrames"), &value); - m_skipKnownFramesAction->setChecked(value.toBool()); engine()->loadSessionData(); } @@ -964,15 +908,6 @@ void DebuggerManager::saveSessionData() { m_breakHandler->saveSessionData(); m_watchHandler->saveSessionData(); - - setSessionValue(QLatin1String("UseFastStart"), - m_useFastStartAction->isChecked()); - setSessionValue(QLatin1String("UseToolTips"), - m_useToolTipsAction->isChecked()); - setSessionValue(QLatin1String("UseCustomDumpers"), - m_useCustomDumpersAction->isChecked()); - setSessionValue(QLatin1String("SkipKnownFrames"), - m_skipKnownFramesAction->isChecked()); engine()->saveSessionData(); } @@ -1139,22 +1074,22 @@ void DebuggerManager::setBusyCursor(bool busy) bool DebuggerManager::skipKnownFrames() const { - return m_skipKnownFramesAction->isChecked(); + return m_settings.m_skipKnownFrames; } bool DebuggerManager::debugDumpers() const { - return m_debugDumpersAction->isChecked(); + return m_settings.m_debugDumpers; } bool DebuggerManager::useCustomDumpers() const { - return m_useCustomDumpersAction->isChecked(); + return m_settings.m_useCustomDumpers; } bool DebuggerManager::useFastStart() const { - return 0; // && m_useFastStartAction->isChecked(); + return 0; // && m_settings.m_useFastStart; } void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber, diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index bde8ce449b17d386beb670129bc487b5397a3bdf..9a5b5da37d3e2e55dc7dcf7054e7755aeecd6f27 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -167,8 +167,8 @@ private: virtual WatchHandler *watchHandler() = 0; virtual void showApplicationOutput(const QString &prefix, const QString &data) = 0; - virtual QAction *useCustomDumpersAction() const = 0; - virtual QAction *debugDumpersAction() const = 0; + //virtual QAction *useCustomDumpersAction() const = 0; + //virtual QAction *debugDumpersAction() const = 0; virtual bool skipKnownFrames() const = 0; virtual bool debugDumpers() const = 0; virtual bool useCustomDumpers() const = 0; @@ -180,6 +180,30 @@ private: }; +// +// DebuggerSettings +// + +class DebuggerSettings +{ +public: + DebuggerSettings(); + +public: + QString m_gdbCmd; + QString m_gdbEnv; + bool m_autoRun; + bool m_autoQuit; + + bool m_useCustomDumpers; + bool m_skipKnownFrames; + bool m_debugDumpers; + bool m_useFastStart; + bool m_useToolTips; + + QString m_scriptFile; +}; + // // DebuggerManager // @@ -196,6 +220,7 @@ public: IDebuggerManagerAccessForEngines *engineInterface(); QMainWindow *mainWindow() const { return m_mainWindow; } QLabel *statusLabel() const { return m_statusLabel; } + DebuggerSettings *settings() { return &m_settings; } enum StartMode { startInternal, startExternal, attachExternal }; enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger }; @@ -286,9 +311,9 @@ private: StackHandler *stackHandler() { return m_stackHandler; } ThreadsHandler *threadsHandler() { return m_threadsHandler; } WatchHandler *watchHandler() { return m_watchHandler; } - QAction *useCustomDumpersAction() const { return m_useCustomDumpersAction; } - QAction *useToolTipsAction() const { return m_useToolTipsAction; } - QAction *debugDumpersAction() const { return m_debugDumpersAction; } + //QAction *useCustomDumpersAction() const { return m_useCustomDumpersAction; } + //QAction *useToolTipsAction() const { return m_useToolTipsAction; } + //QAction *debugDumpersAction() const { return m_debugDumpersAction; } bool skipKnownFrames() const; bool debugDumpers() const; bool useCustomDumpers() const; @@ -342,7 +367,6 @@ signals: void setConfigValueRequested(const QString &name, const QVariant &value); void applicationOutputAvailable(const QString &prefix, const QString &msg); - public: // FIXME: make private QString m_executable; @@ -406,13 +430,6 @@ private: QAction *m_sepAction; QAction *m_stepIAction; QAction *m_nextIAction; - QAction *m_skipKnownFramesAction; - - QAction *m_debugDumpersAction; - QAction *m_useCustomDumpersAction; - QAction *m_useFastStartAction; - QAction *m_useToolTipsAction; - QAction *m_dumpLogAction; QWidget *m_breakWindow; QWidget *m_disassemblerWindow; @@ -432,9 +449,9 @@ private: IDebuggerEngine *engine(); IDebuggerEngine *m_engine; + DebuggerSettings m_settings; }; - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 80acb59b92f2036dffcb3ad6a8dfaa940a00cd45..3f12a02910611cb6a29c6d2e2768936b4bfb7d3a 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -36,12 +36,14 @@ #include "debuggerconstants.h" #include "debuggermanager.h" #include "debuggerrunner.h" -#include "gdboptionpage.h" #include "gdbengine.h" +#include "ui_gdboptionpage.h" + #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/basemode.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/findplaceholder.h> #include <coreplugin/icore.h> @@ -53,6 +55,8 @@ #include <coreplugin/rightpane.h> #include <coreplugin/uniqueidmanager.h> +#include <extensionsystem/pluginmanager.h> + #include <cplusplus/ExpressionUnderCursor.h> #include <cppeditor/cppeditorconstants.h> @@ -73,6 +77,7 @@ #include <QtCore/QSettings> #include <QtCore/QtPlugin> +#include <QtGui/QLineEdit> #include <QtGui/QDockWidget> #include <QtGui/QMainWindow> #include <QtGui/QPlainTextEdit> @@ -80,6 +85,8 @@ #include <QtGui/QTextCursor> +namespace ExtensionSystem { class PluginManager; } + using namespace Core; using namespace Debugger::Constants; using namespace Debugger::Internal; @@ -99,13 +106,7 @@ const char * const JUMP_TO_LINE = "Debugger.JumpToLine"; const char * const TOGGLE_BREAK = "Debugger.ToggleBreak"; const char * const BREAK_BY_FUNCTION = "Debugger.BreakByFunction"; const char * const BREAK_AT_MAIN = "Debugger.BreakAtMain"; -const char * const DEBUG_DUMPERS = "Debugger.DebugDumpers"; const char * const ADD_TO_WATCH = "Debugger.AddToWatch"; -const char * const USE_CUSTOM_DUMPERS = "Debugger.UseCustomDumpers"; -const char * const USE_FAST_START = "Debugger.UseFastStart"; -const char * const USE_TOOL_TIPS = "Debugger.UseToolTips"; -const char * const SKIP_KNOWN_FRAMES = "Debugger.SkipKnownFrames"; -const char * const DUMP_LOG = "Debugger.DumpLog"; #ifdef Q_OS_MAC const char * const INTERRUPT_KEY = "Shift+F5"; @@ -143,6 +144,12 @@ const char * const ADD_TO_WATCH_KEY = "Ctrl+Alt+Q"; } // namespace Debugger +/////////////////////////////////////////////////////////////////////// +// +// DebugMode +// +/////////////////////////////////////////////////////////////////////// + namespace Debugger { namespace Internal { @@ -159,9 +166,6 @@ public: void shutdown() {} }; -} // namespace Internal -} // namespace Debugger - DebugMode::DebugMode(QObject *parent) : BaseMode(parent) { @@ -177,6 +181,9 @@ DebugMode::~DebugMode() EditorManager::instance()->setParent(0); } +} // namespace Internal +} // namespace Debugger + /////////////////////////////////////////////////////////////////////// // @@ -184,8 +191,10 @@ DebugMode::~DebugMode() // /////////////////////////////////////////////////////////////////////// -class Debugger::Internal::LocationMark - : public TextEditor::BaseTextMark +namespace Debugger { +namespace Internal { + +class LocationMark : public TextEditor::BaseTextMark { Q_OBJECT @@ -212,6 +221,108 @@ QIcon LocationMark::icon() const return icon; } +} // namespace Internal +} // namespace Debugger + + +/////////////////////////////////////////////////////////////////////// +// +// GdbOptionPage +// +/////////////////////////////////////////////////////////////////////// + +namespace Debugger { +namespace Internal { + +class GdbOptionPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + GdbOptionPage(DebuggerPlugin *plugin) : m_plugin(plugin) {} + + // IOptionsPage + QString name() const { return tr("Gdb"); } + QString category() const { return "Debugger"; } + QString trCategory() const { return tr("Debugger"); } + + QWidget *createPage(QWidget *parent); + void apply(); + void finish() {} // automatically calls "apply" + +private: + Ui::GdbOptionPage m_ui; + + DebuggerSettings m_settings; + DebuggerPlugin *m_plugin; +}; + +QWidget *GdbOptionPage::createPage(QWidget *parent) +{ + QWidget *w = new QWidget(parent); + m_settings = *m_plugin->m_manager->settings(); + m_ui.setupUi(w); + m_ui.gdbLocationChooser->setExpectedKind(Core::Utils::PathChooser::Command); + m_ui.gdbLocationChooser->setPromptDialogTitle(tr("Choose Gdb Location")); + m_ui.gdbLocationChooser->setPath(m_settings.m_gdbCmd); + m_ui.scriptFileChooser->setExpectedKind(Core::Utils::PathChooser::File); + m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File")); + m_ui.scriptFileChooser->setPath(m_settings.m_scriptFile); + m_ui.environmentEdit->setText(m_settings.m_gdbEnv); + m_ui.autoStartBox->setChecked(m_settings.m_autoRun); + m_ui.autoQuitBox->setChecked(m_settings.m_autoQuit); + + m_ui.checkBoxSkipKnownFrames->setChecked(m_settings.m_skipKnownFrames); + m_ui.checkBoxDebugDumpers->setChecked(m_settings.m_debugDumpers); + m_ui.checkBoxUseCustomDumpers->setChecked(m_settings.m_useCustomDumpers); + m_ui.checkBoxFastStart->setChecked(m_settings.m_useFastStart); + m_ui.checkBoxUseToolTips->setChecked(m_settings.m_useToolTips); + +#ifndef QT_DEBUG +#if 0 + cmd = am->registerAction(m_manager->m_dumpLogAction, + Constants::DUMP_LOG, globalcontext); + //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L"))); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11"))); + mdebug->addAction(cmd); +#endif +#endif + + // FIXME + m_ui.autoStartBox->hide(); + m_ui.autoQuitBox->hide(); + m_ui.environmentEdit->hide(); + m_ui.labelEnvironment->hide(); + + m_ui.checkBoxFastStart->setChecked(false); + m_ui.checkBoxFastStart->hide(); + + //m_dumpLogAction = new QAction(this); + //m_dumpLogAction->setText(tr("Dump Log File for Debugging Purposes")); + return w; +} + +void GdbOptionPage::apply() +{ + m_settings.m_gdbCmd = m_ui.gdbLocationChooser->path(); + m_settings.m_gdbEnv = m_ui.environmentEdit->text(); + m_settings.m_autoRun = m_ui.autoStartBox->isChecked(); + m_settings.m_autoQuit = m_ui.autoQuitBox->isChecked(); + m_settings.m_scriptFile = m_ui.scriptFileChooser->path(); + + m_settings.m_skipKnownFrames = m_ui.checkBoxSkipKnownFrames->isChecked(); + m_settings.m_debugDumpers = m_ui.checkBoxDebugDumpers->isChecked(); + m_settings.m_useCustomDumpers = m_ui.checkBoxUseCustomDumpers->isChecked(); + m_settings.m_useFastStart = m_ui.checkBoxFastStart->isChecked(); + m_settings.m_useToolTips = m_ui.checkBoxUseToolTips->isChecked(); + + *m_plugin->m_manager->settings() = m_settings; + m_plugin->writeSettings(); +} + +} // namespace Internal +} // namespace Debugger + /////////////////////////////////////////////////////////////////////// // @@ -409,34 +520,6 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes cmd = am->registerAction(sep, QLatin1String("Debugger.Sep2"), globalcontext); mdebug->addAction(cmd); - cmd = am->registerAction(m_manager->m_skipKnownFramesAction, - Constants::SKIP_KNOWN_FRAMES, globalcontext); - mdebug->addAction(cmd); - - cmd = am->registerAction(m_manager->m_useCustomDumpersAction, - Constants::USE_CUSTOM_DUMPERS, globalcontext); - mdebug->addAction(cmd); - - cmd = am->registerAction(m_manager->m_useFastStartAction, - Constants::USE_FAST_START, globalcontext); - mdebug->addAction(cmd); - - cmd = am->registerAction(m_manager->m_useToolTipsAction, - Constants::USE_TOOL_TIPS, globalcontext); - mdebug->addAction(cmd); - -#ifdef QT_DEBUG - cmd = am->registerAction(m_manager->m_dumpLogAction, - Constants::DUMP_LOG, globalcontext); - //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L"))); - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11"))); - mdebug->addAction(cmd); - - cmd = am->registerAction(m_manager->m_debugDumpersAction, - Constants::DEBUG_DUMPERS, debuggercontext); - mdebug->addAction(cmd); -#endif - sep = new QAction(this); sep->setSeparator(true); cmd = am->registerAction(sep, QLatin1String("Debugger.Sep4"), globalcontext); @@ -479,7 +562,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes m_generalOptionPage = 0; // FIXME: - m_generalOptionPage = new GdbOptionPage(&theGdbSettings()); + m_generalOptionPage = new GdbOptionPage(this); addObject(m_generalOptionPage); m_locationMark = 0; @@ -711,7 +794,7 @@ void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber void DebuggerPlugin::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos) { - if (!m_manager->useToolTipsAction()->isChecked()) + if (!m_manager->settings()->m_useToolTips) return; QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget()); @@ -799,22 +882,57 @@ void DebuggerPlugin::changeStatus(int status) void DebuggerPlugin::writeSettings() const { - QSettings *s = settings(); QTC_ASSERT(m_manager, return); QTC_ASSERT(m_manager->mainWindow(), return); + + QSettings *s = settings(); + DebuggerSettings *m = m_manager->settings(); s->beginGroup(QLatin1String("DebugMode")); - s->setValue(QLatin1String("State"), m_manager->mainWindow()->saveState()); - s->setValue(QLatin1String("Locked"), m_toggleLockedAction->isChecked()); + s->setValue("State", m_manager->mainWindow()->saveState()); + s->setValue("Locked", m_toggleLockedAction->isChecked()); + s->setValue("Location", m->m_gdbCmd); + s->setValue("Environment", m->m_gdbEnv); + s->setValue("AutoRun", m->m_autoRun); + s->setValue("AutoQuit", m->m_autoQuit); + + s->setValue("UseFastStart", m->m_useFastStart); + s->setValue("UseToolTips", m->m_useToolTips); + s->setValue("UseCustomDumpers", m->m_useCustomDumpers); + s->setValue("SkipKnowFrames", m->m_skipKnownFrames); + s->setValue("DebugDumpers", m->m_debugDumpers); s->endGroup(); } void DebuggerPlugin::readSettings() { QSettings *s = settings(); + DebuggerSettings *m = &m_manager->m_settings; + + QString defaultCommand("gdb"); +#if defined(Q_OS_WIN32) + defaultCommand.append(".exe"); +#endif + Core::ICore *coreIFace = m_pm->getObject<Core::ICore>(); + QString defaultScript = coreIFace->resourcePath() + + QLatin1String("/gdb/qt4macros"); + s->beginGroup(QLatin1String("DebugMode")); - m_manager->mainWindow()->restoreState(s->value(QLatin1String("State"), QByteArray()).toByteArray()); - m_toggleLockedAction->setChecked(s->value(QLatin1String("Locked"), true).toBool()); + QByteArray ba = s->value("State", QByteArray()).toByteArray(); + m_toggleLockedAction->setChecked(s->value("Locked", true).toBool()); + m->m_gdbCmd = s->value("Location", defaultCommand).toString(); + m->m_scriptFile= s->value("ScriptFile", defaultScript).toString(); + m->m_gdbEnv = s->value("Environment", "").toString(); + m->m_autoRun = s->value("AutoRun", true).toBool(); + m->m_autoQuit = s->value("AutoQuit", true).toBool(); + + m->m_skipKnownFrames = s->value("SkipKnownFrames", false).toBool(); + m->m_debugDumpers = s->value("DebugDumpers", false).toBool(); + m->m_useCustomDumpers = s->value("UseCustomDupers", false).toBool(); + m->m_useFastStart = s->value("UseFastStart", false).toBool(); + m->m_useToolTips = s->value("UseToolTips", false).toBool(); s->endGroup(); + + m_manager->mainWindow()->restoreState(ba); } void DebuggerPlugin::focusCurrentEditor(IMode *mode) diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index 53f8490cfc3562084f168f95569f45e633a4d0e4..4ab9c5b89f8fd5a5eeec673a539468386686d76e 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -78,7 +78,6 @@ private slots: void changeStatus(int status); void requestMark(TextEditor::ITextEditor *editor, int lineNumber); void showToolTip(TextEditor::ITextEditor *editor, const QPoint &pnt, int pos); - void querySessionValue(const QString &name, QVariant *value); void setSessionValue(const QString &name, const QVariant &value); void queryConfigValue(const QString &name, QVariant *value); @@ -97,6 +96,7 @@ private: void writeSettings() const; friend class DebuggerManager; + friend class GdbOptionPage; friend class DebugMode; // FIXME: Just a hack now so that it can access the views ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const; diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 3190d1612a385fdd32b3ffdb300d5ddabfd4bd31..2370a55eed2ec637c359c595bfe95268495d3012 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -84,19 +84,6 @@ Q_DECLARE_METATYPE(Debugger::Internal::GdbMi); static const QString tooltipIName = "tooltip"; -/////////////////////////////////////////////////////////////////////// -// -// GdbSettings -// -/////////////////////////////////////////////////////////////////////// - -GdbSettings &Debugger::Internal::theGdbSettings() -{ - static GdbSettings settings; - return settings; -} - - /////////////////////////////////////////////////////////////////////// // // GdbCommandType @@ -265,7 +252,6 @@ void GdbEngine::init() m_pendingRequests = 0; m_gdbVersion = 100; m_shared = 0; - qq->debugDumpersAction()->setChecked(false); m_oldestAcceptableToken = -1; @@ -279,11 +265,6 @@ void GdbEngine::init() connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), q, SLOT(exitDebugger())); - connect(qq->debugDumpersAction(), SIGNAL(toggled(bool)), - this, SLOT(setDebugDumpers(bool))); - connect(qq->useCustomDumpersAction(), SIGNAL(toggled(bool)), - this, SLOT(setCustomDumpersWanted(bool))); - // Output connect(this, SIGNAL(gdbResponseAvailable()), this, SLOT(handleResponse()), Qt::QueuedConnection); @@ -306,7 +287,7 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error) case QProcess::FailedToStart: msg = QString(tr("The Gdb process failed to start. Either the " "invoked program '%1' is missing, or you may have insufficient " - "permissions to invoke the program.")).arg(theGdbSettings().m_gdbCmd); + "permissions to invoke the program.")).arg(q->settings()->m_gdbCmd); break; case QProcess::Crashed: msg = tr("The Gdb process crashed some time after starting " @@ -1503,7 +1484,7 @@ void GdbEngine::exitDebugger() m_varToType.clear(); m_dataDumperState = DataDumperUninitialized; m_shared = 0; - qq->debugDumpersAction()->setChecked(false); + //q->settings()->m_debugDumpers = false; } @@ -1535,7 +1516,7 @@ bool GdbEngine::startDebugger() m_gdbProc.setEnvironment(q->m_environment); #if 0 - qDebug() << "Command: " << theGdbSettings().m_gdbCmd; + qDebug() << "Command: " << q->settings()->m_gdbCmd; qDebug() << "WorkingDirectory: " << m_gdbProc.workingDirectory(); qDebug() << "Environment: " << m_gdbProc.environment(); qDebug() << "Arguments: " << gdbArgs; @@ -1544,9 +1525,9 @@ bool GdbEngine::startDebugger() #endif q->showStatusMessage(tr("Starting Debugger")); - emit gdbInputAvailable(QString(), theGdbSettings().m_gdbCmd + ' ' + gdbArgs.join(" ")); + emit gdbInputAvailable(QString(), q->settings()->m_gdbCmd + ' ' + gdbArgs.join(" ")); - m_gdbProc.start(theGdbSettings().m_gdbCmd, gdbArgs); + m_gdbProc.start(q->settings()->m_gdbCmd, gdbArgs); m_gdbProc.waitForStarted(); if (m_gdbProc.state() != QProcess::Running) @@ -2589,7 +2570,7 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0) return; } - if (qq->debugDumpersAction()->isChecked()) { + if (q->settings()->m_debugDumpers) { // minimize interference return; } @@ -2909,10 +2890,10 @@ void GdbEngine::setCustomDumpersWanted(bool on) bool GdbEngine::isCustomValueDumperAvailable(const QString &type) const { - if (!qq->useCustomDumpers()) + DebuggerSettings *s = q->settings(); + if (!s->m_useCustomDumpers) return false; - if (qq->debugDumpersAction()->isChecked() - && qq->stackHandler()->isDebuggingDumpers()) + if (s->m_debugDumpers && qq->stackHandler()->isDebuggingDumpers()) return false; if (m_dataDumperState != DataDumperAvailable) return false; @@ -3470,7 +3451,7 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record, //qDebug() << "CUSTOM DUMPER ERROR MESSAGE: " << msg; #ifdef QT_DEBUG // Make debugging of dumers easier - if (qq->debugDumpersAction()->isChecked() + if (q->settings()->m_debugDumpers && msg.startsWith("The program being debugged stopped while") && msg.contains("qDumpObjectData440")) { // Fake full stop diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index f5a7c658b762804edce91cf32cf5d87ccc54cb4e..e07e6a228c39950761b53c41542f7930d2b6e459 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -81,23 +81,6 @@ enum DataDumperState }; -class GdbSettings -{ -public: - GdbSettings() { m_autoRun = m_autoQuit = false; } - -public: - QString m_gdbCmd; - QString m_gdbEnv; - bool m_autoRun; - bool m_autoQuit; - - QString m_scriptFile; - QMap<QString, QVariant> m_typeMacros; -}; - -GdbSettings &theGdbSettings(); - class GdbEngine : public IDebuggerEngine { Q_OBJECT diff --git a/src/plugins/debugger/gdboptionpage.cpp b/src/plugins/debugger/gdboptionpage.cpp deleted file mode 100644 index 7c7a2700b6a560db0b854ce1f8e3eefc95e14ae2..0000000000000000000000000000000000000000 --- a/src/plugins/debugger/gdboptionpage.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.3, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ - -#include "gdboptionpage.h" - -#include "gdbengine.h" - -#include <extensionsystem/pluginmanager.h> -#include <coreplugin/icore.h> - -#include <QtCore/QSettings> -#include <QtGui/QLineEdit> -#include <QtGui/QFileDialog> - -using namespace Debugger::Internal; - -GdbOptionPage::GdbOptionPage(GdbSettings *settings) -{ - m_pm = ExtensionSystem::PluginManager::instance(); - m_settings = settings; - - Core::ICore *coreIFace = m_pm->getObject<Core::ICore>(); - if (!coreIFace || !coreIFace->settings()) - return; - QSettings *s = coreIFace->settings(); - s->beginGroup("GdbOptions"); - QString defaultCommand("gdb"); -#if defined(Q_OS_WIN32) - defaultCommand.append(".exe"); -#endif - QString defaultScript = coreIFace->resourcePath() + - QLatin1String("/gdb/qt4macros"); - - m_settings->m_gdbCmd = s->value("Location", defaultCommand).toString(); - m_settings->m_scriptFile= s->value("ScriptFile", defaultScript).toString(); - m_settings->m_gdbEnv = s->value("Environment", "").toString(); - m_settings->m_autoRun = s->value("AutoRun", true).toBool(); - m_settings->m_autoQuit = s->value("AutoQuit", true).toBool(); - s->endGroup(); -} - -QString GdbOptionPage::name() const -{ - return tr("Gdb"); -} - -QString GdbOptionPage::category() const -{ - return "Debugger"; -} - -QString GdbOptionPage::trCategory() const -{ - return tr("Debugger"); -} - -QWidget *GdbOptionPage::createPage(QWidget *parent) -{ - QWidget *w = new QWidget(parent); - m_ui.setupUi(w); - m_ui.gdbLocationChooser->setExpectedKind(Core::Utils::PathChooser::Command); - m_ui.gdbLocationChooser->setPromptDialogTitle(tr("Choose Gdb Location")); - m_ui.gdbLocationChooser->setPath(m_settings->m_gdbCmd); - m_ui.scriptFileChooser->setExpectedKind(Core::Utils::PathChooser::File); - m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File")); - m_ui.scriptFileChooser->setPath(m_settings->m_scriptFile); - m_ui.environmentEdit->setText(m_settings->m_gdbEnv); - m_ui.autoStartBox->setChecked(m_settings->m_autoRun); - m_ui.autoQuitBox->setChecked(m_settings->m_autoQuit); - - // FIXME - m_ui.autoStartBox->hide(); - m_ui.autoQuitBox->hide(); - m_ui.environmentEdit->hide(); - m_ui.labelEnvironment->hide(); - - connect(m_ui.gdbLocationChooser, SIGNAL(changed()), - this, SLOT(onGdbLocationChanged())); - connect(m_ui.scriptFileChooser, SIGNAL(changed()), - this, SLOT(onScriptFileChanged())); - - return w; -} - -void GdbOptionPage::onGdbLocationChanged() -{ - m_settings->m_gdbCmd = m_ui.gdbLocationChooser->path(); -} - -void GdbOptionPage::onScriptFileChanged() -{ - m_settings->m_scriptFile = m_ui.scriptFileChooser->path(); -} - -void GdbOptionPage::apply() -{ - m_settings->m_gdbCmd = m_ui.gdbLocationChooser->path(); - m_settings->m_gdbEnv = m_ui.environmentEdit->text(); - m_settings->m_autoRun = m_ui.autoStartBox->isChecked(); - m_settings->m_autoQuit = m_ui.autoQuitBox->isChecked(); - m_settings->m_scriptFile = m_ui.scriptFileChooser->path(); - - Core::ICore *coreIFace = m_pm->getObject<Core::ICore>(); - if (!coreIFace || !coreIFace->settings()) - return; - - QSettings *s = coreIFace->settings(); - - s->beginGroup("GdbOptions"); - s->setValue("Location", m_settings->m_gdbCmd); - s->setValue("Environment", m_settings->m_gdbEnv); - s->setValue("AutoRun", m_settings->m_autoRun); - s->setValue("AutoQuit", m_settings->m_autoQuit); - s->endGroup(); -} diff --git a/src/plugins/debugger/gdboptionpage.h b/src/plugins/debugger/gdboptionpage.h deleted file mode 100644 index c4c3ade9e31d60e881af9d2e6e091ad30decc674..0000000000000000000000000000000000000000 --- a/src/plugins/debugger/gdboptionpage.h +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.3, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ - -#ifndef GDBOPTIONPAGE_H -#define GDBOPTIONPAGE_H - -#include "ui_gdboptionpage.h" - -#include <coreplugin/dialogs/ioptionspage.h> - -#include <QtGui/QWidget> - -namespace ExtensionSystem { class PluginManager; } - -namespace Debugger { -namespace Internal { - -class GdbSettings; - -class GdbOptionPage : public Core::IOptionsPage -{ - Q_OBJECT - -public: - GdbOptionPage(GdbSettings *settings); - - QString name() const; - QString category() const; - QString trCategory() const; - - QWidget *createPage(QWidget *parent); - void apply(); - void finish() { } - -public slots: - void onGdbLocationChanged(); - void onScriptFileChanged(); - -private: - ExtensionSystem::PluginManager *m_pm; - Ui::GdbOptionPage m_ui; - - GdbSettings *m_settings; -}; - -#if 0 -class TypeMacroPage : public Core::IOptionsPage -{ - Q_OBJECT - -public: - TypeMacroPage(GdbSettings *settings); - - QString name() const; - QString category() const; - QString trCategory() const; - - QWidget *createPage(QWidget *parent); - void finished(bool accepted); - -private slots: - void onAddButton(); - void onDelButton(); - void currentItemChanged(QTreeWidgetItem *item); - void updateButtonState(); - -private: - ExtensionSystem::PluginManager *m_pm; - Ui::TypeMacroPage m_ui; - - GdbSettings *m_settings; - QWidget *m_widget; -}; -#endif - -} // namespace Internal -} // namespace Debugger - -#endif // GDBOPTIONPAGE_H diff --git a/src/plugins/debugger/gdboptionpage.ui b/src/plugins/debugger/gdboptionpage.ui index 580f13c0d660ebce063942c822c4d357ec9c6ed3..757ed1d70234a55c35e4f76bf4a9d26e67b480b7 100644 --- a/src/plugins/debugger/gdboptionpage.ui +++ b/src/plugins/debugger/gdboptionpage.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>433</width> - <height>233</height> + <width>465</width> + <height>372</height> </rect> </property> <property name="windowTitle"> @@ -36,7 +36,7 @@ <widget class="QLineEdit" name="environmentEdit"/> </item> <item row="0" column="0"> - <widget class="QLabel" name="labelGdbLocaltion"> + <widget class="QLabel" name="labelGdbLocation"> <property name="toolTip"> <string>This is either a full abolute path leading to the gdb binary you intend to use or the name of a gdb binary that wiull be searched in your PATH.</string> </property> @@ -74,6 +74,58 @@ </layout> </widget> </item> + <item> + <widget class="QCheckBox" name="checkBoxUseCustomDumpers"> + <property name="toolTip"> + <string>Checking this will make the debugger try to use code to format certain data (QObject, QString, std::string etc.) nicely.</string> + </property> + <property name="text"> + <string>Use custom display for Qt and Standard Library objects</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxFastStart"> + <property name="toolTip"> + <string>Checking this will make the debugger start fast by loading only very few debug symbols on start up. This might lead to situations where breakpoints can not be set properly. So uncheck this option if you experience breakpoint related problems.</string> + </property> + <property name="text"> + <string>Fast debugger start</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxSkipKnownFrames"> + <property name="toolTip"> + <string>fter checking this option 'Step Into' combines in certain situations several steps, leading to 'less noisy' debugging. So will, e.g., the atomic +reference counting code be skipped, and a single 'Step Into' for a signal emission will end up directly in the slot connected to it. +</string> + </property> + <property name="text"> + <string>Skip known frames when stepping</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxUseToolTips"> + <property name="toolTip"> + <string>Checking this will make enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default.</string> + </property> + <property name="text"> + <string>Use tooltips while debugging</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxDebugDumpers"> + <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> + </property> + <property name="text"> + <string>Debug Custom Dumpers</string> + </property> + </widget> + </item> <item> <widget class="QCheckBox" name="autoStartBox"> <property name="text"> diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 4a69ff97ea67da35e9c7cdf6ce011a52869a3155..72c68c1654deb39d8d48143959379e34d4319aa1 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -35,6 +35,10 @@ #include "fakevimconstants.h" +#include <coreplugin/filemanager.h> +#include <coreplugin/icore.h> +#include <texteditor/basetexteditor.h> + #include <QtCore/QDebug> #include <QtCore/QFile> #include <QtCore/QObject> @@ -220,6 +224,7 @@ public: bool m_wasReadOnly; // saves read-only state of document FakeVimHandler *q; + Core::ICore *m_core; Mode m_mode; SubMode m_submode; SubSubMode m_subsubmode; @@ -239,6 +244,7 @@ public: QString m_commandBuffer; QString m_currentFileName; + Core::IFile* m_currentFile; QString m_currentMessage; bool m_lastSearchForward; @@ -301,6 +307,8 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent) m_visualMode = NoVisualMode; m_desiredColumn = 0; + m_core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); + m_config[ConfigStartOfLine] = ConfigOn; m_config[ConfigTabStop] = "8"; m_config[ConfigSmartTab] = ConfigOff; @@ -1190,12 +1198,18 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0) bool exists = file.exists(); if (exists && !forced && !noArgs) { showRedMessage(tr("File '%1' exists (add ! to override)").arg(fileName)); - } else if (file.open(QIODevice::ReadWrite)) { - QTextCursor tc = selectRange(beginLine, endLine); - qDebug() << "ANCHOR: " << tc.position() << tc.anchor() - << tc.selection().toPlainText(); - { QTextStream ts(&file); ts << tc.selection().toPlainText(); } - file.close(); + } else if (m_currentFile || file.open(QIODevice::ReadWrite)) { + if(m_currentFile) { + m_core->fileManager()->blockFileChange(m_currentFile); + m_currentFile->save(fileName); + m_core->fileManager()->unblockFileChange(m_currentFile); + } else { + QTextCursor tc = selectRange(beginLine, endLine); + qDebug() << "ANCHOR: " << tc.position() << tc.anchor() + << tc.selection().toPlainText(); + { QTextStream ts(&file); ts << tc.selection().toPlainText(); } + file.close(); + } file.open(QIODevice::ReadOnly); QByteArray ba = file.readAll(); showBlackMessage(tr("\"%1\" %2 %3L, %4C written") @@ -1725,6 +1739,11 @@ void FakeVimHandler::Private::setWidget(QWidget *ob) { m_textedit = qobject_cast<QTextEdit *>(ob); m_plaintextedit = qobject_cast<QPlainTextEdit *>(ob); + TextEditor::BaseTextEditor* editor = qobject_cast<TextEditor::BaseTextEditor*>(ob); + if (editor) { + m_currentFile = editor->file(); + m_currentFileName = m_currentFile->fileName(); + } } /////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/projectexplorer/applicationlauncher_win.cpp b/src/plugins/projectexplorer/applicationlauncher_win.cpp index 09e0ee73c6c81e89bde73c83f6d182f83885158f..c6279b4c3cffd0b6da3508b1e44aa594b06808cd 100644 --- a/src/plugins/projectexplorer/applicationlauncher_win.cpp +++ b/src/plugins/projectexplorer/applicationlauncher_win.cpp @@ -34,7 +34,6 @@ #include "applicationlauncher.h" #include "consoleprocess.h" #include "winguiprocess.h" -#include <projectexplorer/ProjectExplorerInterfaces> #include <QDebug> diff --git a/src/plugins/projectexplorer/images/filtericon.png b/src/plugins/projectexplorer/images/filtericon.png index 7e46d2267581c60330a6b948a86d47ed8f9711a0..0915b5e5f6167dfb71799f637ac2ba67f3be7deb 100644 Binary files a/src/plugins/projectexplorer/images/filtericon.png and b/src/plugins/projectexplorer/images/filtericon.png differ diff --git a/src/plugins/qt4projectmanager/directorywatcher.cpp b/src/plugins/qt4projectmanager/directorywatcher.cpp index d20444098e0f1ae7084bc1a75d652fc5c615dee3..b054f1ff2913a891fe1a3d049d36b40540df4304 100644 --- a/src/plugins/qt4projectmanager/directorywatcher.cpp +++ b/src/plugins/qt4projectmanager/directorywatcher.cpp @@ -44,165 +44,6 @@ enum { debugWatcher = 0 }; namespace Qt4ProjectManager { namespace Internal { -int DirectoryWatcher::m_objectCount = 0; -QHash<QString,int> DirectoryWatcher::m_directoryCount; -QFileSystemWatcher *DirectoryWatcher::m_watcher = 0; - -/* - \class DirectoryWatcher - - A wrapper for QFileSystemWatcher that collects - consecutive changes to a registered directory and emits directoryChanged() and fileChanged(). - - Note that files added are only monitored if the parent directory is added, too. - - All instances of DirectoryWatcher share one QFileSystemWatcher object. - That's because every QFileSystemWatcher object consumes a file descriptor, - even if no files are watched. -*/ -DirectoryWatcher::DirectoryWatcher(QObject *parent) : - QObject(parent), - m_timer(0) -{ - if (!m_watcher) - m_watcher = new QFileSystemWatcher(); - ++m_objectCount; - connect(m_watcher, SIGNAL(directoryChanged(QString)), - this, SLOT(slotDirectoryChanged(QString))); -} - -DirectoryWatcher::~DirectoryWatcher() -{ - foreach (const QString &dir, m_directories) - removeDirectory(dir); - if (--m_objectCount == 0) { - delete m_watcher; - m_watcher = 0; - } -} - -QStringList DirectoryWatcher::directories() const -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << m_directories; - return m_directories; -} - -void DirectoryWatcher::addDirectory(const QString &dir) -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << dir; - if (m_directories.contains(dir)) - return; - m_directories += dir; - if (m_directoryCount[dir] == 0) - m_watcher->addPath(dir); - m_directoryCount[dir] += 1; -} - -void DirectoryWatcher::removeDirectory(const QString &dir) -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << dir; - m_directories.removeOne(dir); - m_directoryCount[dir] -= 1; - if (m_directoryCount[dir] == 0) - m_watcher->removePath(dir); -} - -QStringList DirectoryWatcher::files() const -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << m_files.keys(); - return m_files.keys(); -} - -void DirectoryWatcher::addFile(const QString &filePath) -{ - addFiles(QStringList() << filePath); -} - -void DirectoryWatcher::addFiles(const QStringList &filePaths) -{ - foreach (const QString filePath, filePaths) { - QFileInfo file(filePath); - m_files.insert(file.absoluteFilePath(),file.lastModified()); - } -} - -void DirectoryWatcher::removeFile(const QString &filePath) -{ - m_files.remove(filePath); -} - -void DirectoryWatcher::slotDirectoryChanged(const QString &path) -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << path; - if (!m_directories.contains(path) - || m_pendingDirectories.contains(path)) - return; - - if (!m_timer) { - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(500); // delay for 0.5 sec - connect(m_timer, SIGNAL(timeout()), this, SLOT(slotDelayedDirectoriesChanged())); - } - if (!m_timer->isActive()) - m_timer->start(); - m_pendingDirectories.push_back(path); -} - -void DirectoryWatcher::slotDelayedDirectoriesChanged() -{ - if (debugWatcher) - qDebug() << Q_FUNC_INFO << " emitting " << m_pendingDirectories; - const QStringList::const_iterator cend = m_pendingDirectories.constEnd(); - for (QStringList::const_iterator it = m_pendingDirectories.constBegin(); it != cend; ++it) { - const QString dir = *it; - if (!QFileInfo(dir).exists()) - removeDirectory(*it); - emit directoryChanged(*it); - updateFileList(*it); - } - m_pendingDirectories.clear(); -} - -void DirectoryWatcher::updateFileList(const QString &dir) -{ - const QStringList monitoredFiles = m_files.keys(); - QStringList removedFiles = monitoredFiles; - if (QFileInfo(dir).exists()) { - // Compare directory contents and emit signals - QFileInfoList entryInfoList - = QDir(dir).entryInfoList(QDir::Files|QDir::CaseSensitive); - // Loop over directory creating the new map of file->time, removing - // the existing entries from the old map - const QFileInfoList::const_iterator cend = entryInfoList.constEnd(); - for (QFileInfoList::const_iterator filIt = entryInfoList.constBegin(); - filIt != cend; ++filIt) { - const QString path = filIt->absoluteFilePath(); - FileModificationTimeMap::iterator mapIt = m_files.find(path); - if (mapIt != m_files.end()) { - const QDateTime lastModified = filIt->lastModified(); - if (lastModified > mapIt.value()) { - if (debugWatcher) - qDebug() << Q_FUNC_INFO << "emitting file changed" << path; - emit fileChanged(path); - m_files[path] = lastModified; - } - removedFiles.removeOne(path); - } - } - } - - if (!removedFiles.isEmpty()) { - foreach (const QString &file, removedFiles) - removeFile(file); - } -} - int FileWatcher::m_objectCount = 0; QHash<QString,int> FileWatcher::m_fileCount; QFileSystemWatcher *FileWatcher::m_watcher = 0; @@ -256,7 +97,5 @@ void FileWatcher::removeFile(const QString &file) m_watcher->removePath(file); } - - } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/directorywatcher.h b/src/plugins/qt4projectmanager/directorywatcher.h index 57f015330a1d764e9333f7e42e657721866e9437..35ceaed91e1af7610f3347724c5b8be509c4c460 100644 --- a/src/plugins/qt4projectmanager/directorywatcher.h +++ b/src/plugins/qt4projectmanager/directorywatcher.h @@ -47,46 +47,6 @@ QT_END_NAMESPACE namespace Qt4ProjectManager { namespace Internal { -class DirectoryWatcher : public QObject -{ - Q_DISABLE_COPY(DirectoryWatcher) - Q_OBJECT -public: - explicit DirectoryWatcher(QObject *parent = 0); - virtual ~DirectoryWatcher(); - - QStringList directories() const; - void addDirectory(const QString &dir); - void removeDirectory(const QString &dir); - - QStringList files() const; - void addFile(const QString &filePath); - void addFiles(const QStringList &filePaths); - void removeFile(const QString &filePath); - -signals: - void directoryChanged(const QString &path); - void fileChanged(const QString &path); - -private slots: - void slotDirectoryChanged(const QString &); - void slotDelayedDirectoriesChanged(); - -private: - void updateFileList(const QString &dir); - - static int m_objectCount; - static QHash<QString,int> m_directoryCount; - static QFileSystemWatcher *m_watcher; - - QTimer *m_timer; - QStringList m_directories; - QStringList m_pendingDirectories; - - typedef QHash<QString, QDateTime> FileModificationTimeMap; - FileModificationTimeMap m_files; -}; - class FileWatcher : public QObject { Q_DISABLE_COPY(FileWatcher) diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 8f836f649826dbb3e70a1c34880b3fc4427d8359..14fb56a38e951e040bc2e3bdc527a38e391605cb 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -49,6 +49,7 @@ #include <coreplugin/vcsmanager.h> #include <cpptools/cppmodelmanagerinterface.h> +#include <cplusplus/CppDocument.h> #include <utils/qtcassert.h> @@ -488,6 +489,9 @@ QStringList Qt4PriFileNode::varNames(FileType type) return vars; } +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/buildmanager.h> + /*! \class Qt4ProFileNode Implements abstract ProjectNode class @@ -498,8 +502,7 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project, : Qt4PriFileNode(project, this, filePath), // own stuff m_projectType(InvalidProject), - m_isQBuildProject(false), - m_dirWatcher(new DirectoryWatcher(this)) + m_isQBuildProject(false) { if (parent) setParent(parent); @@ -507,14 +510,13 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project, m_updateTimer.setInterval(100); m_updateTimer.setSingleShot(true); - connect(m_dirWatcher, SIGNAL(directoryChanged(const QString&)), - this, SLOT(updateGeneratedFiles())); - connect(m_dirWatcher, SIGNAL(fileChanged(const QString&)), - this, SLOT(fileChanged(const QString&))); connect(m_project, SIGNAL(activeBuildConfigurationChanged()), this, SLOT(update())); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(update())); + + connect(ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(), SIGNAL(buildStateChanged(ProjectExplorer::Project*)), + this, SLOT(buildStateChanged(ProjectExplorer::Project*))); } Qt4ProFileNode::~Qt4ProFileNode() @@ -522,6 +524,12 @@ Qt4ProFileNode::~Qt4ProFileNode() } +void Qt4ProFileNode::buildStateChanged(ProjectExplorer::Project *project) +{ + if (project == m_project && !ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager()->isBuilding(m_project)) + updateUiFiles(); +} + bool Qt4ProFileNode::hasTargets() const { return (projectType() == ApplicationTemplate) || (projectType() == LibraryTemplate); @@ -689,7 +697,7 @@ void Qt4ProFileNode::update() emit qt4Watcher->variablesChanged(this, m_varValues, newVarValues); } - updateGeneratedFiles(); + updateUiFiles(); foreach (NodesWatcher *watcher, watchers()) if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher)) @@ -698,15 +706,6 @@ void Qt4ProFileNode::update() delete reader; } -void Qt4ProFileNode::fileChanged(const QString &filePath) -{ - CppTools::CppModelManagerInterface *modelManager = - ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); - - // TODO compress - modelManager->updateSourceFiles(QStringList() << filePath); -} - namespace { // find all ui files in project class FindUiFileNodesVisitor : public ProjectExplorer::NodesVisitor { @@ -726,53 +725,54 @@ namespace { }; } -/* - Adds ui_xxx.h files to tree and monitors them / the UI_DIR directory for changes - */ -void Qt4ProFileNode::updateGeneratedFiles() +// This function is triggered after a build, and updates the state ui files +// That is it adds files that didn't exist yet to the project tree, and calls +// updateSourceFiles() for files that changed +// 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 configuration changes +// since the build directory could change, and thus the generated files that are present +// TODO check that it works +void Qt4ProFileNode::updateUiFiles() { + // Only those two project types can have ui files for us if (m_projectType != ApplicationTemplate && m_projectType != LibraryTemplate) return; + // Find all ui files FindUiFileNodesVisitor uiFilesVisitor; this->accept(&uiFilesVisitor); const QList<FileNode*> uiFiles = uiFilesVisitor.uiFileNodes; - // monitor uic dir (only if there are .ui files) + // Find the UiDir, there can only ever be one + QString uiDir; // We should default to the build directory + QStringList tmp = m_varValues[UiDirVar]; + if (tmp.size() != 0) + uiDir = tmp.first(); - QSet<QString> oldUiDirs = m_dirWatcher->directories().toSet(); - QSet<QString> newUiDirs = - (!uiFiles.isEmpty()) ? m_varValues[UiDirVar].toSet() : QSet<QString>(); - foreach (const QString &uiDir, oldUiDirs - newUiDirs) - m_dirWatcher->removeDirectory(uiDir); - foreach (const QString &uiDir, newUiDirs - oldUiDirs) - m_dirWatcher->addDirectory(uiDir); - - // update generated files - - // Already existing FileNodes + // Collect all existing generated files QList<FileNode*> existingFileNodes; foreach (FileNode *file, fileNodes()) { if (file->isGenerated()) existingFileNodes << file; } - // Convert uiFile to uiHeaderFilePath, find all headers that correspond - // and try to find them in uicDirs + // and try to find them in uiDir QStringList newFilePaths; - foreach (const QString &uicDir, m_varValues[UiDirVar]) { - foreach (FileNode *uiFile, uiFiles) { - const QString uiHeaderFilePath - = QString("%1/ui_%2.h").arg(uicDir, QFileInfo(uiFile->path()).baseName()); - if (QFileInfo(uiHeaderFilePath).exists()) - newFilePaths << uiHeaderFilePath; - } + foreach (FileNode *uiFile, uiFiles) { + const QString uiHeaderFilePath + = QString("%1/ui_%2.h").arg(uiDir, QFileInfo(uiFile->path()).baseName()); + if (QFileInfo(uiHeaderFilePath).exists()) + newFilePaths << uiHeaderFilePath; } + // Create a diff between those lists QList<FileNode*> toRemove; QList<FileNode*> toAdd; + // The list of files for which we call updateSourceFile + QStringList toUpdate; qSort(newFilePaths); qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath); @@ -788,6 +788,13 @@ void Qt4ProFileNode::updateGeneratedFiles() toAdd << new FileNode(*newPathIter, ProjectExplorer::HeaderType, true); ++newPathIter; } else { // *existingNodeIter->path() == *newPathIter + QString fileName = (*existingNodeIter)->path(); + QMap<QString, QDateTime>::const_iterator it = m_uitimestamps.find(fileName); + QDateTime lastModified = QFileInfo(fileName).lastModified(); + if (it == m_uitimestamps.constEnd() || it.value() < lastModified) { + toUpdate << fileName; + m_uitimestamps[fileName] = lastModified; + } ++existingNodeIter; ++newPathIter; } @@ -801,16 +808,33 @@ void Qt4ProFileNode::updateGeneratedFiles() ++newPathIter; } + // Update project tree if (!toRemove.isEmpty()) { foreach (FileNode *file, toRemove) - m_dirWatcher->removeFile(file->path()); + m_uitimestamps.remove(file->path()); removeFileNodes(toRemove, this); } + + CppTools::CppModelManagerInterface *modelManager = + ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); + if (!toAdd.isEmpty()) { - foreach (FileNode *file, toAdd) - m_dirWatcher->addFile(file->path()); + foreach (FileNode *file, toAdd) { + m_uitimestamps.insert(file->path(), QFileInfo(file->path()).lastModified()); + toUpdate << file->path(); + + // Also adding files depending on that. + QString fileName = QFileInfo(file->path()).fileName(); + foreach (CPlusPlus::Document::Ptr doc, modelManager->snapshot()) { + if (doc->includedFiles().contains(fileName)) { + if (!toUpdate.contains(doc->fileName())) + toUpdate << doc->fileName(); + } + } + } addFileNodes(toAdd, this); } + modelManager->updateSourceFiles(toUpdate); } ProFileReader *Qt4PriFileNode::createProFileReader() const @@ -824,9 +848,7 @@ ProFileReader *Qt4PriFileNode::createProFileReader() const reader->setQtVersion(version); } - QHash<QString,QStringList> variables; - variables.insert(QLatin1String("OUT_PWD"), QStringList(m_qt4ProFileNode->buildDir())); - reader->addVariables(variables); + reader->setOutputDir(m_qt4ProFileNode->buildDir()); return reader; } @@ -957,13 +979,6 @@ void Qt4ProFileNode::invalidate() clear(); - // remove monitored files/directories - foreach (const QString &file, m_dirWatcher->files()) - m_dirWatcher->removeFile(file); - foreach (const QString &dir, m_dirWatcher->directories()) - m_dirWatcher->removeDirectory(dir); - - // change project type Qt4ProjectType oldType = m_projectType; m_projectType = InvalidProject; diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index 9ea6b07c71cf1f3ac6dc2fcba405a216c1a99d90..5d428cc67202c94882de7061cf419cb37b8f6772 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -35,10 +35,13 @@ #define QT4NODES_H #include <projectexplorer/projectnodes.h> +#include <projectexplorer/project.h> #include <QtCore/QHash> #include <QtCore/QStringList> #include <QtCore/QTimer> +#include <QtCore/QDateTime> +#include <QtCore/QMap> // defined in proitems.h QT_BEGIN_NAMESPACE @@ -184,8 +187,8 @@ public slots: void scheduleUpdate(); void update(); private slots: - void fileChanged(const QString &filePath); - void updateGeneratedFiles(); + void updateUiFiles(); + void buildStateChanged(ProjectExplorer::Project*); private: Qt4ProFileNode *createSubProFileNode(const QString &path); @@ -205,7 +208,7 @@ private: bool m_isQBuildProject; QTimer m_updateTimer; - DirectoryWatcher *m_dirWatcher; + QMap<QString, QDateTime> m_uitimestamps; friend class Qt4NodeHierarchy; }; diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp index 99c19e3a7e9957aae6216fdadacb9a6f47123096..64961844996e1fab4f255dc3154917960634688e 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp @@ -306,14 +306,10 @@ QString Qt4RunConfiguration::qmakeBuildConfigFromBuildConfiguration(const QStrin QVariant qmakeBuildConfiguration = qs->value(buildConfigurationName, "buildConfiguration"); if (qmakeBuildConfiguration.isValid()) { QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(qmakeBuildConfiguration.toInt()); - if (projectBuildConfiguration & QtVersion::BuildAll) { - if (projectBuildConfiguration & QtVersion::DebugBuild) - return "debug"; - else - return "release"; - } else { - return ""; - } + if (projectBuildConfiguration & QtVersion::DebugBuild) + return "debug"; + else + return "release"; } else { // Old sytle always CONFIG+=debug_and_release if (qobject_cast<Qt4Project *>(project())->qtVersion(buildConfigurationName)->defaultBuildConfig() & QtVersion::DebugBuild)