From d0159d7c7c0b2f59d1d3b5c6f2909be3f6a237c0 Mon Sep 17 00:00:00 2001 From: dt Date: Wed, 15 Apr 2009 16:22:55 +0200 Subject: [PATCH 01/22] Small tweaks to the cmake open project wizard. Note: The use is now forced to run cmake. This is rather suboptimal, but currently cancel doesn't do the correct thing so we prevent that. --- src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp | 7 +++++++ src/plugins/cmakeprojectmanager/cmakeproject.cpp | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index fcfef28f997..51d57b9e09b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -75,6 +75,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const setPage(CMakeRunPageId, new CMakeRunPage(this)); setStartId(startid); + setOption(QWizard::NoCancelButton); + setOption(QWizard::NoBackButtonOnStartPage); } CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, @@ -87,6 +89,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const addPage(new CMakeRunPage(this, buildDirectory, false)); foreach(const QString &buildDirectory, needToUpdate) addPage(new CMakeRunPage(this, buildDirectory, true)); + setOption(QWizard::NoCancelButton); + setOption(QWizard::NoBackButtonOnStartPage); } CMakeManager *CMakeOpenProjectWizard::cmakeManager() const @@ -255,6 +259,9 @@ void CMakeRunPage::initWidgets() m_output = new QPlainTextEdit(this); m_output->setReadOnly(true); + QSizePolicy pl = m_output->sizePolicy(); + pl.setVerticalStretch(1); + m_output->setSizePolicy(pl); fl->addRow(m_output); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index d1fe107412d..ffd333d23fa 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -512,7 +512,6 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader 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 ? // or simply run createXml with the saved settings QFileInfo sourceFileInfo(m_fileName); QStringList needToCreate; From 655d39a9d7968502620231170019a439451f8066 Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 16 Apr 2009 11:22:18 +0200 Subject: [PATCH 02/22] nicer visual session switching --- src/plugins/coreplugin/editormanager/editormanager.cpp | 1 + src/plugins/coreplugin/editormanager/editormanager.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index f9b2cde57b2..7edd516cafe 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1538,6 +1538,7 @@ QByteArray EditorManager::saveState() const bool EditorManager::restoreState(const QByteArray &state) { closeAllEditors(true); + removeAllSplits(); QDataStream stream(state); QByteArray version; diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index fa4b05740e7..81a1025a4ee 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -208,6 +208,8 @@ private slots: void goBackInNavigationHistory(); void goForwardInNavigationHistory(); void makeCurrentEditorWritable(); + +public slots: void split(Qt::Orientation orientation); void split(); void splitSideBySide(); From c172e9b1a44507dd39955bd5a9b5334115905176 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 09:18:09 +0200 Subject: [PATCH 03/22] fakevim: autotests for 'e', 'dd', 'w', 'cc' --- src/plugins/fakevim/README | 14 ++ src/plugins/fakevim/fakevimhandler.cpp | 130 +++++++++++------- tests/auto/fakevim/main.cpp | 183 ++++++++++++++++++------- 3 files changed, 224 insertions(+), 103 deletions(-) create mode 100644 src/plugins/fakevim/README diff --git a/src/plugins/fakevim/README b/src/plugins/fakevim/README new file mode 100644 index 00000000000..f901e5984a0 --- /dev/null +++ b/src/plugins/fakevim/README @@ -0,0 +1,14 @@ + + +fakevim is based on eventFilters installed on a QTextEdit or a QPlainTextEdit. +It basically catches all keystrokes and modifies some internal state that +make the resulting text in the editor look like it was using vim. + +There are only a few files in here: + + fakevimplugin.{h,cpp} - interaction with the rest of Creator + fakevimactions.{h,cpp} - settings + fakevimhandler.{h,cpp} - the "real" event + +There are some more hints for developers in fakevimhandler.cpp + diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 50385d9c6ac..ce04adfa6a9 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -29,28 +29,33 @@ #include "fakevimhandler.h" -// Please do not add any direct dependencies to other Qt Creator code here. -// Instead emit signals and let the FakeVimPlugin channel the information to -// Qt Creator. The idea is to keep this file here in a "clean" state that -// allows easy reuse with any QTextEdit or QPlainTextEdit derived class. - - -// Some conventions: // -// Use 1 based line numbers and 0 based column numbers. Even though -// the 1 based line are not nice it matches vim's and QTextEdit's 'line' -// concepts. +// ATTENTION: // -// Do not pass QTextCursor etc around unless really needed. Convert -// early to line/column. +// 1 Please do not add any direct dependencies to other Qt Creator code here. +// Instead emit signals and let the FakeVimPlugin channel the information to +// Qt Creator. The idea is to keep this file here in a "clean" state that +// allows easy reuse with any QTextEdit or QPlainTextEdit derived class. // -// There is always a "current" cursor (m_tc). A current "region of interest" -// spans between m_anchor (== anchor()) and m_tc.position() (== position()) -// The value of m_tc.anchor() is not used. +// 2 There are a few auto tests located in ../../../tests/auto/fakevim. +// Commands that are covered there are marked as "// tested" below. +// +// 3 Some conventions: +// +// Use 1 based line numbers and 0 based column numbers. Even though +// the 1 based line are not nice it matches vim's and QTextEdit's 'line' +// concepts. +// +// Do not pass QTextCursor etc around unless really needed. Convert +// early to line/column. +// +// There is always a "current" cursor (m_tc). A current "region of interest" +// spans between m_anchor (== anchor()) and m_tc.position() (== position()) +// The value of m_tc.anchor() is not used. +// #include - #include #include #include @@ -278,7 +283,7 @@ public: typedef QTextCursor::MoveOperation MoveOperation; typedef QTextCursor::MoveMode MoveMode; void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); } - void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); } + void moveToStartOfLine(); void moveToEndOfLine(); void moveUp(int n = 1) { moveDown(-n); } void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); } @@ -353,6 +358,8 @@ public: // extra data for '.' void replay(const QString &text, int count); + void setDotCommand(const QString &cmd) { m_dotCommand = cmd; } + void setDotCommand(const QString &cmd, int n) { m_dotCommand = cmd.arg(n); } QString m_dotCommand; bool m_inReplay; // true if we are executing a '.' @@ -632,6 +639,17 @@ void FakeVimHandler::Private::moveToEndOfLine() #endif } +void FakeVimHandler::Private::moveToStartOfLine() +{ +#if 0 + // does not work for "hidden" documents like in the autotests + m_tc.movePosition(StartOfLine, MoveAnchor); +#else + const QTextBlock &block = m_tc.block(); + setPosition(block.position()); +#endif +} + void FakeVimHandler::Private::finishMovement(const QString &dotCommand) { //qDebug() << "ANCHOR: " << position() << anchor(); @@ -656,7 +674,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) if (anchor() >= position()) m_anchor++; if (!dotCommand.isEmpty()) - m_dotCommand = "c" + dotCommand; + setDotCommand("c" + dotCommand); QString text = removeSelectedText(); //qDebug() << "CHANGING TO INSERT MODE" << text; m_registers[m_register] = text; @@ -668,7 +686,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) if (anchor() >= position()) m_anchor++; if (!dotCommand.isEmpty()) - m_dotCommand = "d" + dotCommand; + setDotCommand("d" + dotCommand); m_registers[m_register] = removeSelectedText(); m_submode = NoSubMode; if (atEndOfLine()) @@ -694,8 +712,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) updateMiniBuffer(); } - moveToTargetColumn(); - m_moveType = MoveInclusive; m_mvcount.clear(); m_opcount.clear(); @@ -847,13 +863,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, } else if (m_submode == RegisterSubMode) { m_register = key; m_submode = NoSubMode; - } else if (m_submode == ChangeSubMode && key == 'c') { - moveToStartOfLine(); + } else if (m_submode == ChangeSubMode && key == 'c') { // tested + moveDown(count() - 1); + moveToEndOfLine(); + moveLeft(); setAnchor(); - moveDown(count()); + moveToStartOfLine(); + setTargetColumn(); + moveUp(count() - 1); m_moveType = MoveLineWise; - finishMovement("c"); - } else if (m_submode == DeleteSubMode && key == 'd') { + m_lastInsertion.clear(); + setDotCommand("%1cc", count()); + finishMovement(); + } else if (m_submode == DeleteSubMode && key == 'd') { // tested moveToStartOfLine(); setAnchor(); moveDown(count()); @@ -869,19 +891,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, setAnchor(); moveDown(count() - 1); m_moveType = MoveLineWise; - m_dotCommand = QString("%1<<").arg(count()); + setDotCommand("%1<<", count()); finishMovement(); } else if (m_submode == ShiftRightSubMode && key == '>') { setAnchor(); moveDown(count() - 1); m_moveType = MoveLineWise; - m_dotCommand = QString("%1>>").arg(count()); + setDotCommand("%1>>", count()); finishMovement(); } else if (m_submode == IndentSubMode && key == '=') { setAnchor(); moveDown(count() - 1); m_moveType = MoveLineWise; - m_dotCommand = QString("%1>>").arg(count()); + setDotCommand("%1>>", count()); finishMovement(); } else if (m_submode == ZSubMode) { //qDebug() << "Z_MODE " << cursorLineInDocument() << linesOnScreen(); @@ -928,7 +950,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, m_tc.insertText(QString(count(), text.at(0))); m_moveType = MoveExclusive; m_submode = NoSubMode; - m_dotCommand = QString("%1r%2").arg(count()).arg(text); + setDotCommand("%1r" + text, count()); finishMovement(); } else { m_submode = NoSubMode; @@ -1125,7 +1147,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, handleStartOfLine(); scrollToLineInDocument(cursorLineInDocument() - sline); finishMovement(); - } else if (key == 'e') { + } else if (key == 'e') { // tested m_moveType = MoveInclusive; moveToWordBoundary(false, true); finishMovement(); @@ -1175,13 +1197,13 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, handleStartOfLine(); finishMovement(); } else if (key == 'i') { - m_dotCommand = "i"; //QString("%1i").arg(count()); + setDotCommand("i"); // setDotCommand("%1i", count()); enterInsertMode(); updateMiniBuffer(); if (atEndOfLine()) moveLeft(); } else if (key == 'I') { - m_dotCommand = "I"; //QString("%1I").arg(count()); + setDotCommand("I"); // setDotCommand("%1I", count()); enterInsertMode(); if (m_gflag) moveToStartOfLine(); @@ -1256,7 +1278,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, search(lastSearchString(), !m_lastSearchForward); recordJump(); } else if (key == 'o' || key == 'O') { - m_dotCommand = QString("%1o").arg(count()); + setDotCommand("%1o", count()); enterInsertMode(); moveToFirstNonBlankOnLine(); if (key == 'O') @@ -1293,18 +1315,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, moveLeft(); } } - m_dotCommand = QString("%1p").arg(count()); + setDotCommand("%1p", count()); finishMovement(); } else if (key == 'r') { m_submode = ReplaceSubMode; - m_dotCommand = "r"; + setDotCommand("r"); } else if (key == 'R') { // FIXME: right now we repeat the insertion count() times, // but not the deletion m_lastInsertion.clear(); m_mode = InsertMode; m_submode = ReplaceSubMode; - m_dotCommand = "R"; + setDotCommand("R"); } else if (key == control('r')) { redo(); } else if (key == 's') { @@ -1313,7 +1335,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, setAnchor(); moveRight(qMin(count(), rightDist())); m_registers[m_register] = removeSelectedText(); - m_dotCommand = "s"; //QString("%1s").arg(count()); + setDotCommand("s"); // setDotCommand("%1s", count()); m_opcount.clear(); m_mvcount.clear(); enterInsertMode(); @@ -1340,7 +1362,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, enterVisualMode(VisualLineMode); } else if (key == control('v')) { enterVisualMode(VisualBlockMode); - } else if (key == 'w') { + } else if (key == 'w') { // tested // Special case: "cw" and "cW" work the same as "ce" and "cE" if the // cursor is on a non-blank. if (m_submode == ChangeSubMode) { @@ -1369,7 +1391,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, setAnchor(); m_submode = DeleteSubMode; moveRight(qMin(count(), rightDist())); - m_dotCommand = QString("%1x").arg(count()); + setDotCommand("%1x", count()); finishMovement(); } else if (key == 'X') { if (leftDist() > 0) { @@ -1957,16 +1979,16 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle0) void FakeVimHandler::Private::moveToFirstNonBlankOnLine() { - QTextBlock block = m_tc.block(); QTextDocument *doc = m_tc.document(); - m_tc.movePosition(StartOfLine, KeepAnchor); - int firstPos = m_tc.position(); + const QTextBlock &block = m_tc.block(); + int firstPos = block.position(); for (int i = firstPos, n = firstPos + block.length(); i < n; ++i) { if (!doc->characterAt(i).isSpace()) { - m_tc.setPosition(i, KeepAnchor); + setPosition(i); return; } } + setPosition(block.position()); } void FakeVimHandler::Private::indentRegion(QChar typedChar) @@ -1978,7 +2000,7 @@ void FakeVimHandler::Private::indentRegion(QChar typedChar) qSwap(beginLine, endLine); int amount = 0; emit q->indentRegion(&amount, beginLine, endLine, typedChar); - m_dotCommand = QString("%1==").arg(endLine - beginLine + 1); + setDotCommand("%1==", endLine - beginLine + 1); } void FakeVimHandler::Private::shiftRegionRight(int repeat) @@ -2000,7 +2022,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) setPosition(firstPos); moveToFirstNonBlankOnLine(); - m_dotCommand = QString("%1>>").arg(endLine - beginLine + 1); + setDotCommand("%1>>", endLine - beginLine + 1); } void FakeVimHandler::Private::shiftRegionLeft(int repeat) @@ -2037,17 +2059,20 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat) setPosition(firstPos); moveToFirstNonBlankOnLine(); - m_dotCommand = QString("%1<<").arg(endLine - beginLine + 1); + setDotCommand("%1<<", endLine - beginLine + 1); } void FakeVimHandler::Private::moveToTargetColumn() { - if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) { - const QTextBlock &block = m_tc.block(); + const QTextBlock &block = m_tc.block(); + int col = m_tc.position() - m_tc.block().position(); + if (col == m_targetColumn) + return; + //qDebug() << "CORRECTING COLUMN FROM: " << col << "TO" << m_targetColumn; + if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) m_tc.setPosition(block.position() + block.length() - 1, KeepAnchor); - } else { + else m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor); - } } /* if simple is given: @@ -2075,7 +2100,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward) int lastClass = -1; while (true) { QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1)); - qDebug() << "EXAMINING: " << c << " AT " << position(); + //qDebug() << "EXAMINING: " << c << " AT " << position(); int thisClass = charClass(c, simple); if (thisClass != lastClass && lastClass != 0) --repeat; @@ -2319,6 +2344,7 @@ QString FakeVimHandler::Private::removeSelectedText() m_tc.setPosition(pos, KeepAnchor); QString from = m_tc.selection().toPlainText(); m_tc.removeSelectedText(); + setAnchor(); return from; } diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp index a1ac3be7826..df4b6d691a2 100644 --- a/tests/auto/fakevim/main.cpp +++ b/tests/auto/fakevim/main.cpp @@ -55,13 +55,17 @@ public slots: void changeExtraInformation(const QString &info) { m_infoMessage = info; } private slots: - void commandDollar(); - void commandDown(); - void commandLeft(); - void commandRight(); - void commandI(); - void commandUp(); - void commandW(); + // command mode + void command_cc(); + void command_dd(); + void command_dollar(); + void command_down(); + void command_e(); + void command_i(); + void command_left(); + void command_right(); + void command_up(); + void command_w(); private: void setup(); @@ -73,6 +77,9 @@ private: const char* file, int line); QString insertCursor(const QString &needle0); + QString lmid(int i, int n = -1) const + { return QStringList(l.mid(i, n)).join("\n"); } + QTextEdit *m_textedit; QPlainTextEdit *m_plaintextedit; FakeVimHandler *m_handler; @@ -82,6 +89,8 @@ private: QString m_statusData; QString m_infoMessage; + // the individual lines + static const QStringList l; // identifier intentionally kept short static const QString lines; static const QString escape; }; @@ -100,8 +109,11 @@ const QString tst_FakeVim::lines = " return app.exec();\n" "}\n"; +const QStringList tst_FakeVim::l = tst_FakeVim::lines.split('\n'); + const QString tst_FakeVim::escape = QChar(27); + tst_FakeVim::tst_FakeVim(bool usePlainTextEdit) { if (usePlainTextEdit) { @@ -170,16 +182,16 @@ bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line) QStringList wantlist = want.split('\n'); QStringList gotlist = got.split('\n'); if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) { - qDebug() << "WANT: " << want; - qDebug() << "GOT: " << got; + qDebug() << "0 WANT: " << want; + qDebug() << "0 GOT: " << got; return false; } 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)); if (!QTest::qCompare(g, w, "", "", file, line)) { - qDebug() << "WANT: " << want; - qDebug() << "GOT: " << got; + qDebug() << "1 WANT: " << want; + qDebug() << "1 GOT: " << got; return false; } } @@ -222,11 +234,77 @@ QString tst_FakeVim::insertCursor(const QString &needle0) needle.remove('@'); QString lines0 = lines; int pos = lines0.indexOf(needle); + if (pos == -1) + qDebug() << "Cannot find: \n----\n" + needle + "\n----\n"; lines0.replace(pos, needle.size(), needle0); return lines0; } -void tst_FakeVim::commandI() + +////////////////////////////////////////////////////////////////////////// +// +// Command mode +// +////////////////////////////////////////////////////////////////////////// + +void tst_FakeVim::command_cc() +{ + setup(); + move("j", "@" + l[1]); + check("ccabc" + escape, l[0] + "\nab@c\n" + lmid(2)); + check("ccabc" + escape, l[0] + "\nab@c\n" + lmid(2)); + check(".", l[0] + "\nab@c\n" + lmid(2)); + check("j", l[0] + "\nabc\n#i@nclude \n" + lmid(3)); + check("3ccxyz" + escape, l[0] + "\nabc\nxy@z\n" + lmid(5)); +} + +void tst_FakeVim::command_dd() +{ + setup(); + move("j", "@" + l[1]); + check("dd", l[0] + "\n@" + lmid(2)); + check(".", l[0] + "\n@" + lmid(3)); + check("3dd", l[0] + "\n@" + lmid(6)); +} + +void tst_FakeVim::command_dollar() +{ + setup(); + move("j$", "@"); + move("j$", "@"); + move("2j", ")@"); +} + +void tst_FakeVim::command_down() +{ + setup(); + move("j", "@" + l[1]); + move("3j", "@int main"); + move("4j", "@ return app.exec()"); +} + +void tst_FakeVim::command_e() +{ + setup(); + move("e", "@#include @"); - move("j$", "@"); - move("2j", ")@"); -} - -void tst_FakeVim::commandDown() -{ - setup(); - move("j", "@#include @@ -321,6 +394,14 @@ int main(int argc, char *argv[]) } */ + + +////////////////////////////////////////////////////////////////////////// +// +// Main +// +////////////////////////////////////////////////////////////////////////// + int main(int argc, char *argv[]) \ { int res = 0; From 5076be59e340a232142d9ac951518ee57797c0f6 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 11:52:58 +0200 Subject: [PATCH 04/22] fakevim: fix cursor position for j or k and end or begin of document --- src/plugins/fakevim/fakevimhandler.cpp | 5 +++-- tests/auto/fakevim/main.cpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index ce04adfa6a9..e18599d7072 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -620,8 +620,9 @@ void FakeVimHandler::Private::moveDown(int n) m_tc.movePosition(Down, MoveAnchor, n); #else const int col = m_tc.position() - m_tc.block().position(); - const int line = m_tc.block().blockNumber(); - const QTextBlock &block = m_tc.document()->findBlockByNumber(line + n); + const int lastLine = m_tc.document()->lastBlock().blockNumber(); + const int targetLine = qMax(0, qMin(lastLine, m_tc.block().blockNumber() + n)); + const QTextBlock &block = m_tc.document()->findBlockByNumber(targetLine); const int pos = block.position(); setPosition(pos + qMin(block.length() - 1, col)); moveToTargetColumn(); diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp index df4b6d691a2..fd5b06f0931 100644 --- a/tests/auto/fakevim/main.cpp +++ b/tests/auto/fakevim/main.cpp @@ -302,6 +302,7 @@ void tst_FakeVim::command_e() move("e", "int main(int argc, char *arg@v[])"); move("e", "int main(int argc, char *argv[]@)"); move("e", "@{"); + move("10k","@\n"); // home. } void tst_FakeVim::command_i() From 1f458da6bb2ffd7739217e361543970d8e7270dc Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 12:17:01 +0200 Subject: [PATCH 05/22] debugger: add a destructor in the manual test --- tests/manual/gdbdebugger/simple/app.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp index 427cbf452fe..76b35c9ce77 100644 --- a/tests/manual/gdbdebugger/simple/app.cpp +++ b/tests/manual/gdbdebugger/simple/app.cpp @@ -87,6 +87,12 @@ public: b = 2 + s + t; a += 1; } + + ~Foo() + { + a = 5; + } + void doit() { static QObject ob; From 40700c9dd74a354f86d128800d3c5080818061c3 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 12:52:29 +0200 Subject: [PATCH 06/22] debugger: add an autotest for the regexp used for paring 'info break' output --- src/plugins/debugger/gdbengine.cpp | 5 ++++ tests/auto/debugger/main.cpp | 38 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index c2d2c4b4c3f..709324378d6 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -2210,6 +2210,11 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData * // within namespaces. // Sometimes the path is relative too. + // 2 breakpoint keep y 0x0040168e + // 2.1 y 0x0040168e in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 + // 2.2 y 0x00401792 in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 + + QRegExp re("MULTIPLE.*(0x[0-9a-f]+) in (.*)\\s+at (.*):([\\d]+)([^\\d]|$)"); re.setMinimal(true); diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index 13ece24e546..4e7eeeeb61f 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -79,6 +79,9 @@ private slots: void mi10() { testMi(test10); } void mi11() { testMi(test11); } void mi12() { testMi(test12); } + + void infoBreak(); + void runQtc(); public slots: @@ -100,6 +103,41 @@ static QByteArray stripped(QByteArray ba) return ba; } + +void tst_Debugger::infoBreak() +{ + // This tests the regular expression used in GdbEngine::extractDataFromInfoBreak + // to discover breakpoints in constructors. + + // Copied from gdbengine.cpp: + + QRegExp re("MULTIPLE.*(0x[0-9a-f]+) in (.*)\\s+at (.*):([\\d]+)([^\\d]|$)"); + re.setMinimal(true); + + QCOMPARE(re.indexIn( + "2 breakpoint keep y 0x0040168e\n" + "2.1 y 0x0040168e " + "in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7\n" + "2.2 y 0x00401792 " + "in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7\n"), 33); + QCOMPARE(re.cap(1), QString("0x0040168e")); + QCOMPARE(re.cap(2).trimmed(), QString("MainWindow::MainWindow(QWidget*)")); + QCOMPARE(re.cap(3), QString("mainwindow.cpp")); + QCOMPARE(re.cap(4), QString("7")); + + + QCOMPARE(re.indexIn( + "Num Type Disp Enb Address What" + "4 breakpoint keep y 0x00000000004066ad" + "4.1 y 0x00000000004066ad in CTorTester" + " at /main/tests/manual/gdbdebugger/simple/app.cpp:124"), 88); + + QCOMPARE(re.cap(1), QString("0x00000000004066ad")); + QCOMPARE(re.cap(2).trimmed(), QString("CTorTester")); + QCOMPARE(re.cap(3), QString("/main/tests/manual/gdbdebugger/simple/app.cpp")); + QCOMPARE(re.cap(4), QString("124")); +} + void tst_Debugger::readStandardOutput() { qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput()); From 98c87839bdf09c3afa05cb1395b653ff4570383b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Thu, 16 Apr 2009 13:59:19 +0200 Subject: [PATCH 07/22] Updated files to be patched to new Qt version --- src/tools/qpatch/files-to-patch-linux | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/tools/qpatch/files-to-patch-linux b/src/tools/qpatch/files-to-patch-linux index 8fa0394d0b3..da166075843 100644 --- a/src/tools/qpatch/files-to-patch-linux +++ b/src/tools/qpatch/files-to-patch-linux @@ -235,26 +235,26 @@ examples/xml/xmlstreamlint/xmlstreamlint examples/xmlpatterns/filetree/filetree examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel examples/xmlpatterns/recipes/recipes -lib/libQt3Support.so.4.5.0 -lib/libQtAssistantClient.so.4.5.0 -lib/libQtCLucene.so.4.5.0 -lib/libQtCore.so.4.5.0 -lib/libQtDBus.so.4.5.0 -lib/libQtDesigner.so.4.5.0 -lib/libQtDesignerComponents.so.4.5.0 -lib/libQtGui.so.4.5.0 -lib/libQtHelp.so.4.5.0 -lib/libQtNetwork.so.4.5.0 -lib/libQtOpenGL.so.4.5.0 -lib/libQtScript.so.4.5.0 -lib/libQtScriptTools.so.4.5.0 -lib/libQtSql.so.4.5.0 -lib/libQtSvg.so.4.5.0 -lib/libQtTest.so.4.5.0 +lib/libQt3Support.so.4.5.1 +lib/libQtAssistantClient.so.4.5.1 +lib/libQtCLucene.so.4.5.1 +lib/libQtCore.so.4.5.1 +lib/libQtDBus.so.4.5.1 +lib/libQtDesigner.so.4.5.1 +lib/libQtDesignerComponents.so.4.5.1 +lib/libQtGui.so.4.5.1 +lib/libQtHelp.so.4.5.1 +lib/libQtNetwork.so.4.5.1 +lib/libQtOpenGL.so.4.5.1 +lib/libQtScript.so.4.5.1 +lib/libQtScriptTools.so.4.5.1 +lib/libQtSql.so.4.5.1 +lib/libQtSvg.so.4.5.1 +lib/libQtTest.so.4.5.1 lib/libQtUiTools.a -lib/libQtWebKit.so.4.5.0 -lib/libQtXml.so.4.5.0 -lib/libQtXmlPatterns.so.4.5.0 +lib/libQtWebKit.so.4.5.1 +lib/libQtXml.so.4.5.1 +lib/libQtXmlPatterns.so.4.5.1 plugins/accessible/libqtaccessiblecompatwidgets.so plugins/accessible/libqtaccessiblewidgets.so plugins/codecs/libqcncodecs.so From e2ef47bcffbab2cabed2ff80f317dddfebfd59a2 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 13:54:34 +0200 Subject: [PATCH 08/22] debugger: prevent endless loop when contructor breakpoints are located in inaccessible files --- src/plugins/debugger/gdbengine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 709324378d6..64d0314a30b 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -2214,7 +2214,7 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData * // 2.1 y 0x0040168e in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 // 2.2 y 0x00401792 in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 - + // tested in ../../../tests/auto/debugger/ QRegExp re("MULTIPLE.*(0x[0-9a-f]+) in (.*)\\s+at (.*):([\\d]+)([^\\d]|$)"); re.setMinimal(true); @@ -2223,6 +2223,10 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData * data->bpFuncName = re.cap(2).trimmed(); data->bpLineNumber = re.cap(4); QString full = fullName(re.cap(3)); + if (full.isEmpty()) { + qDebug() << "NO FULL NAME KNOWN FOR" << re.cap(3); + full = re.cap(3); // FIXME: wrong, but prevents recursion + } data->markerLineNumber = data->bpLineNumber.toInt(); data->markerFileName = full; data->bpFileName = full; From 544aea1a2ee5d2476938ab43ee681d90e4cde4ae Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 14:42:19 +0200 Subject: [PATCH 09/22] debugger: watcher creation revisited --- src/plugins/debugger/debuggeractions.cpp | 2 +- src/plugins/debugger/watchhandler.cpp | 1 - src/plugins/debugger/watchwindow.cpp | 4 +--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 43dc44ce7a1..d0a620c16d2 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -158,7 +158,7 @@ DebuggerSettings *DebuggerSettings::instance() instance->insertItem(UseDebuggingHelpers, item); item->setDefaultValue(true); item->setSettingsKey("DebugMode", "UseDebuggingHelper"); - item->setText(tr("Use Debugging Helper")); + item->setText(tr("Use debugging helper")); item->setCheckable(true); item->setDefaultValue(true); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 42e42f5f0b6..eea64c4bca0 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -932,7 +932,6 @@ QString WatchHandler::watcherName(const QString &exp) void WatchHandler::watchExpression(const QString &exp) { // FIXME: 'exp' can contain illegal characters - //MODEL_DEBUG("WATCH: " << exp); m_watchers[exp] = watcherCounter++; WatchData data; data.exp = exp; diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index f6e2fd01cb8..71ac3bb1e6c 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -96,7 +96,7 @@ public: } else if (index.column() == 0) { // the watcher name column theDebuggerAction(RemoveWatchExpression)->trigger(exp); - theDebuggerAction(WatchExpression)->trigger(lineEdit->text()); + theDebuggerAction(WatchExpression)->trigger(value); } } @@ -175,8 +175,6 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) QModelIndex idx = indexAt(ev->pos()); QModelIndex mi0 = idx.sibling(idx.row(), 0); QString exp = model()->data(mi0).toString(); - QModelIndex mi1 = idx.sibling(idx.row(), 0); - QString value = model()->data(mi1).toString(); menu.addSeparator(); int type = (m_type == LocalsType) ? WatchExpression : RemoveWatchExpression; From 39bf47f7ae7aba13dd4186e1aabcd2d6b7c93dac Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Apr 2009 15:06:31 +0200 Subject: [PATCH 10/22] debugger: fix message on debugger exit --- src/plugins/debugger/gdbengine.cpp | 31 ++++++++++++++++++++---------- src/plugins/debugger/gdbengine.h | 1 + 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 64d0314a30b..391890c40eb 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -103,6 +103,7 @@ enum GdbCommandType GdbQuerySources, GdbAsyncOutput2, GdbStart, + GdbExit, GdbAttached, GdbStubAttached, GdbExecRun, @@ -755,6 +756,9 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, case GdbInfoThreads: handleInfoThreads(record); break; + case GdbExit: + handleExit(record); + break; case GdbShowVersion: handleShowVersion(record); @@ -1167,7 +1171,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) + data.findChild("signal-name").toString(); } q->showStatusMessage(msg); - sendCommand("-gdb-exit"); + sendCommand("-gdb-exit", GdbExit); return; } @@ -1525,7 +1529,7 @@ void GdbEngine::exitDebugger() sendCommand("detach"); else sendCommand("kill"); - sendCommand("-gdb-exit"); + sendCommand("-gdb-exit", GdbExit); // 20s can easily happen when loading webkit debug information m_gdbProc.waitForFinished(20000); if (m_gdbProc.state() != QProcess::Running) { @@ -1797,6 +1801,12 @@ void GdbEngine::handleAttach() qq->reloadRegisters(); } +void GdbEngine::handleExit(const GdbResultRecord &response) +{ + Q_UNUSED(response); + q->showStatusMessage(tr("Debugger exited.")); +} + void GdbEngine::stepExec() { setTokenBarrier(); @@ -3409,14 +3419,15 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record) 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 " - "nice display of Qt data types.\n\n" - "You might want to try including the file\n\n" - ".../share/qtcreator/gdbmacros/gdbmacros.cpp\n\n" - "into your project directly.") - ); + q->showStatusMessage(tr("Debugging helpers not found.")); + //QMessageBox::warning(q->mainWindow(), + // tr("Cannot find special data dumpers"), + // tr("The debugged binary does not contain information needed for " + // "nice display of Qt data types.\n\n" + // "You might want to try including the file\n\n" + // ".../share/qtcreator/gdbmacros/gdbmacros.cpp\n\n" + // "into your project directly.") + // ); } else { m_debuggingHelperState = DebuggingHelperAvailable; q->showStatusMessage(tr("%1 custom dumpers found.") diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index aebb5da6373..44afa4e73a1 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -199,6 +199,7 @@ private: void handleQueryPwd(const GdbResultRecord &response); void handleQuerySources(const GdbResultRecord &response); void handleTargetCore(const GdbResultRecord &response); + void handleExit(const GdbResultRecord &response); void debugMessage(const QString &msg); QString dumperLibraryName() const; From c95b3eef3757c7e6c1aa6dd6832eacd50e843ef3 Mon Sep 17 00:00:00 2001 From: dt Date: Thu, 16 Apr 2009 15:27:50 +0200 Subject: [PATCH 11/22] Fixes make install not installing the wrapper Patch by Fathi Boudra. --- src/app/app.pro | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/app.pro b/src/app/app.pro index 69f677dacb7..0894b2a7261 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -43,10 +43,12 @@ unix:!macx { QMAKE_POST_LINK += $${QMAKE_COPY_FILE} $${COPYSRC} $${COPYDEST} $$SEPARATOR } - target.files += $$OUT_PWD/$$DESTDIR/$$IDE_APP_WRAPPER - target.files += $$OUT_PWD/$$DESTDIR/$$IDE_APP_TARGET + wrapper.files = $$OUT_PWD/$$DESTDIR/$$IDE_APP_WRAPPER + wrapper.path = /bin + target.path = /bin - INSTALLS += target + + INSTALLS += target wrapper } From 1356d8c20a753e4fd66cdefc0e63fd6d7d8da585 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Apr 2009 15:34:06 +0200 Subject: [PATCH 12/22] whoops newlines are like whitespace, so items don't run together --- src/shared/proparser/profileevaluator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 1313f7c0306..0aea2bcbc07 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -346,6 +346,7 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0) m_contNextLine = escaped; if (escaped) { m_proitem.chop(1); + updateItem(); return true; } else { if (!m_syntaxError) { From 923db1ce6d99c73fdce402f80840226dbf21b08b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Apr 2009 15:35:54 +0200 Subject: [PATCH 13/22] less convoluted --- src/shared/proparser/profileevaluator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 0aea2bcbc07..95bd578d9fc 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -351,10 +351,10 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0) } else { if (!m_syntaxError) { updateItem(); - if (!m_contNextLine) - finalizeBlock(); + finalizeBlock(); + return true; } - return !m_syntaxError; + return false; } } From 8f78e79b98cd0cbcba94e214327f1dddce48929a Mon Sep 17 00:00:00 2001 From: dt Date: Thu, 16 Apr 2009 16:24:38 +0200 Subject: [PATCH 14/22] Correct and add some notes about the debugging helper library. --- doc/qtcreator.qdoc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index c2129ea57ab..4f31d54407a 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -347,15 +347,6 @@ \bold{Build Settings} page. Qt Creator will run the make command using the correct Qt version. - \note The \bold{Gdb Macros Build} step builds a small library along with your - project that is used for the custom display of Qt and STL objects in the - integrated debugger. The library is created and built in a "qtc-gdbmacros" - subfolder of your project's main directory, and loaded dynamically into your - application if you run it in the debugger. If the - debugging helper seems to break your build or your application, you can - remove the build step. You will still be able to debug applications, but the - contents of Qt and STL data types will not be displayed properly. - \section1 Dependencies If you have multiple projects loaded in your session, you can configure @@ -1179,6 +1170,18 @@ registers. Both views are useful for low-level commands such as \gui{Step Single Instruction} and \gui{Step Over Single Instruction}. + \section1 Debugging Helper Library + + While debugging Qt Creator dynamically loads a helper library into + your program. This helper library enables Qt Creator to pretty print + Qt and STL types. The Qt SDK package already contains a prebuilt + debugging helper library. To create a debugging helper library + select the \{Options} from the \gui{Tools} menu, and go to the + \gui{Qt/Qt Versions} pane. As the internal layout of qt can + change between versions, the debugging helper library is build + per Qt Version. + + \section1 A Walkthrough for the Debugger Frontend In our \l{Writing a Simple Program with Qt Creator}{TextFinder} example, we From c8a2423627e8ca3e411bf65e581ea6f24abbf222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Thu, 16 Apr 2009 16:48:13 +0200 Subject: [PATCH 15/22] Don't disable the frame around QSpinBox in debugger options --- src/plugins/debugger/gdboptionpage.ui | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/debugger/gdboptionpage.ui b/src/plugins/debugger/gdboptionpage.ui index baf91e4667d..7c7c20b957c 100644 --- a/src/plugins/debugger/gdboptionpage.ui +++ b/src/plugins/debugger/gdboptionpage.ui @@ -182,9 +182,6 @@ Qt::LeftToRight - - false - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter From ceca662ec5477ad53ea763636c05a2b0448f4c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Thu, 16 Apr 2009 17:01:25 +0200 Subject: [PATCH 16/22] Updated known issues related to .pro file parsing Reviewed-by: Oswald Buddenhagen --- doc/qtcreator.qdoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index 4f31d54407a..9ae007d3bd2 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -1571,8 +1571,11 @@ \o Loading KDE4 designer plugins breaks the style in KDE < 4.2.1 due to a bug in KDE. - \o Scopes in \c{.pro} files are ignored, and environment variables not - expanded. + \o The DEFINES and INCLUDES set in \c{.pro} files are not dealt with + on a file-specific level. Because of this, handling of DEFINES has + been disabled completely. Also the \c{.qmake.cache} is not being + parsed. In general, the \c{.pro} file parser is incomplete and + problems are still to be expected. \o Code completion for generated UI header files is updated only after a build. From dec4acdbf2c5f9013c2ab74ea6e28a6a72a2ed78 Mon Sep 17 00:00:00 2001 From: dt Date: Thu, 16 Apr 2009 17:12:19 +0200 Subject: [PATCH 17/22] Run make clean on clicking rebuild for the debugging helper library. --- .../qt4projectmanager/qtversionmanager.cpp | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index fe4e3d48770..e612ace6f9c 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -1424,17 +1424,13 @@ QString QtVersion::buildDebuggingHelperLibrary() if (!success) continue; - output += QString("Building debugging helper library in %1\n").arg(directory); - output += "\n"; - output += QString("Runinng %1 ...\n").arg(qmakeCommand()); + // Setup process + QProcess proc; - QProcess qmake; ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); addToEnvironment(env); - // TODO this is a hack to get, to be removed and rewritten for 1.2 - // - // For MSVC and MINGW, we need a toolchain to get the right environment + // For MSVC and MINGW, we need a toolchain to get the right environment ProjectExplorer::ToolChain *toolChain = 0; ProjectExplorer::ToolChain::ToolChainType t = toolchainType(); if (t == ProjectExplorer::ToolChain::MinGW) @@ -1447,23 +1443,20 @@ QString QtVersion::buildDebuggingHelperLibrary() toolChain = 0; } - qmake.setEnvironment(env.toStringList()); - qmake.setWorkingDirectory(directory); - qmake.setProcessChannelMode(QProcess::MergedChannels); + proc.setEnvironment(env.toStringList()); + proc.setWorkingDirectory(directory); + proc.setProcessChannelMode(QProcess::MergedChannels); - qmake.start(qmakeCommand(), QStringList()<<"-spec"<< mkspec() <<"gdbmacros.pro"); - qmake.waitForFinished(); - - output += qmake.readAll(); + output += QString("Building debugging helper library in %1\n").arg(directory); + output += "\n"; + QString make; // TODO this is butt ugly // only qt4projects have a toolchain() method. (Reason mostly, that in order to create // the toolchain, we need to have the path to gcc // which might depend on environment settings of the project // so we hardcode the toolchainType to make conversation here // and think about how to fix that later - - QString make; if (t == ProjectExplorer::ToolChain::MinGW) make = "mingw32-make.exe"; else if(t == ProjectExplorer::ToolChain::MSVC || t == ProjectExplorer::ToolChain::WINCE) @@ -1472,12 +1465,29 @@ QString QtVersion::buildDebuggingHelperLibrary() make = "make"; QString makeFullPath = env.searchInPath(make); + if (!makeFullPath.isEmpty()) { + output += QString("Running %1 clean...\n").arg(makeFullPath); + proc.start(makeFullPath, QStringList() << "clean"); + proc.waitForFinished(); + output += proc.readAll(); + } else { + output += QString("%1 not found in PATH\n").arg(make); + break; + } + + output += QString("\nRuninng %1 ...\n").arg(qmakeCommand()); + + proc.start(qmakeCommand(), QStringList()<<"-spec"<< mkspec() <<"gdbmacros.pro"); + proc.waitForFinished(); + + output += proc.readAll(); + output += "\n"; if (!makeFullPath.isEmpty()) { output += QString("Running %1 ...\n").arg(makeFullPath); - qmake.start(makeFullPath, QStringList()); - qmake.waitForFinished(); - output += qmake.readAll(); + proc.start(makeFullPath, QStringList()); + proc.waitForFinished(); + output += proc.readAll(); } else { output += QString("%1 not found in PATH\n").arg(make); } From dd67f0857d0ee466c533854b487837164b2308b7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 17 Apr 2009 11:48:50 +0200 Subject: [PATCH 18/22] Prevent non-existing projects from showing on the welcome page. Reviewed-by: dt --- src/plugins/projectexplorer/projectexplorer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 56058e782b5..06bf33a3e3f 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -602,6 +602,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new ProjectTreeWidgetFactory); addAutoReleasedObject(new FolderNavigationWidgetFactory); + // > -- Creator 1.0 compatibility code QStringList oldRecentProjects; if (QSettings *s = core->settings()) oldRecentProjects = s->value("ProjectExplorer/RecentProjects/Files", QStringList()).toStringList(); @@ -616,6 +617,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er foreach(const QString &s, oldRecentProjects) { m_recentProjects.append(qMakePair(s, QFileInfo(s).fileName())); } + // < -- Creator 1.0 compatibility code // TODO restore recentProjects if (QSettings *s = core->settings()) { @@ -623,7 +625,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er 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))); + if (QFileInfo(fileNames.at(i)).isFile()) + m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i))); } } } From ad1047925b33617540f42ec0169bbb8e095a1380 Mon Sep 17 00:00:00 2001 From: dt Date: Fri, 17 Apr 2009 12:27:04 +0200 Subject: [PATCH 19/22] Fix the directories the cmakelugin checks for the debugger plugin I need to refactor that code for 1.2. --- .../cmakeprojectmanager.cpp | 23 ++++++++++++------- .../cmakeprojectmanager/cmakeprojectmanager.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 4629aa3d5fc..0ed79cfc489 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -155,7 +155,10 @@ QString CMakeManager::qtVersionForQMake(const QString &qmakePath) return QString(); } -QString CMakeManager::findQtDir(const ProjectExplorer::Environment &env) +// this is mostly a copy from qt4versionmanager +// TODO refactor this code +// returns QPair< QTDIR, QT_INSTALL_DATA > +QPair CMakeManager::findQtDir(const ProjectExplorer::Environment &env) { QStringList possibleCommands; // On windows noone has renamed qmake, right? @@ -171,21 +174,23 @@ QString CMakeManager::findQtDir(const ProjectExplorer::Environment &env) QFileInfo qmake(path + "/" + possibleCommand); if (qmake.exists()) { if (!qtVersionForQMake(qmake.absoluteFilePath()).isNull()) { + QDir qtDir = qmake.absoluteDir(); + qtDir.cdUp(); QProcess proc; proc.start(qmake.absoluteFilePath(), QStringList() << "-query" << "QT_INSTALL_DATA"); if (proc.waitForFinished()) { - return proc.readAll().trimmed(); + return qMakePair(qtDir.absolutePath(), QString(proc.readAll().trimmed())); } else { proc.kill(); QDir dir(qmake.absoluteDir()); dir.cdUp(); - return dir.absolutePath(); + return qMakePair(qtDir.absolutePath(), dir.absolutePath()); } } } } } - return QString(); + return qMakePair(QString(), QString()); } // This code is more or less duplicated in qtversionmanager @@ -195,14 +200,16 @@ QString CMakeManager::findDumperLibrary(const ProjectExplorer::Environment &env) static QString lastpath; if (lastenv == env) return lastpath; - QString qtdir = findQtDir(env); - if (qtdir.isEmpty()) + + QPair pair = findQtDir(env); + QString qtInstallDataDir = pair.second; + if (qtInstallDataDir.isEmpty()) return QString(); - uint hash = qHash(qtdir); + uint hash = qHash(pair.first); QStringList directories; directories - << (qtdir + "/qtc-debugging-helper/") + << (qtInstallDataDir + "/qtc-debugging-helper/") << (QApplication::applicationDirPath() + "/../qtc-debugging-helper/" + QString::number(hash)) + "/" << (QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/qtc-debugging-helper/" + QString::number(hash)) + "/"; foreach(const QString &directory, directories) { diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h index f8c734c0114..49c5f4576ba 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h @@ -65,7 +65,7 @@ public: static QString findDumperLibrary(const ProjectExplorer::Environment &env); private: static QString qtVersionForQMake(const QString &qmakePath); - static QString findQtDir(const ProjectExplorer::Environment &env); + static QPair findQtDir(const ProjectExplorer::Environment &env); int m_projectContext; int m_projectLanguage; CMakeSettingsPage *m_settingsPage; From 85f340e27fabe739c93ecc8f562f3bb0bc48a104 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Apr 2009 14:20:41 +0200 Subject: [PATCH 20/22] debugger: fix dumper building on 'release' Qts --- share/qtcreator/gdbmacros/gdbmacros.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/qtcreator/gdbmacros/gdbmacros.pro b/share/qtcreator/gdbmacros/gdbmacros.pro index bd1c07b9686..00c7b2403c8 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.pro +++ b/share/qtcreator/gdbmacros/gdbmacros.pro @@ -1,3 +1,7 @@ TEMPLATE = lib CONFIG += shared +linux-* { +CONFIG -= release +CONFIG += debug +} SOURCES=gdbmacros.cpp From 02d0ede3ec06b6c20597c682514a300ef06b2e42 Mon Sep 17 00:00:00 2001 From: con Date: Fri, 17 Apr 2009 14:25:45 +0200 Subject: [PATCH 21/22] Two-keystroke menu shortcuts do not work on Mac. --- src/plugins/coreplugin/editormanager/editormanager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 7edd516cafe..ee0c58e0a4c 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -334,31 +334,41 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) : m_d->m_splitAction = new QAction(tr("Split"), this); cmd = am->registerAction(m_d->m_splitAction, Constants::SPLIT, editManagerContext); +#ifndef Q_OS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,2"))); +#endif mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(m_d->m_splitAction, SIGNAL(triggered()), this, SLOT(split())); m_d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this); cmd = am->registerAction(m_d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext); +#ifndef Q_OS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,3"))); +#endif mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(m_d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide())); m_d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this); cmd = am->registerAction(m_d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext); +#ifndef Q_OS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,0"))); +#endif mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(m_d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit())); m_d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this); cmd = am->registerAction(m_d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext); +#ifndef Q_OS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,1"))); +#endif mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(m_d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); m_d->m_gotoOtherSplitAction = new QAction(tr("Goto Other Split"), this); cmd = am->registerAction(m_d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); +#ifndef Q_OS_MAC cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+E,o"))); +#endif mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(m_d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit())); From 6f85959d06ea2585cd43df1446c967c4b58c0b01 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Apr 2009 14:58:01 +0200 Subject: [PATCH 22/22] fakevim: eat Ctrl-A to prevent the global "select all" shortcut to trigger --- src/plugins/fakevim/fakevimhandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index e18599d7072..4ecf1290678 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1096,6 +1096,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, m_mode = InsertMode; moveToEndOfLine(); m_lastInsertion.clear(); + } else if (key == control('a')) { + // FIXME: eat it to prevent the global "select all" shortcut to trigger } else if (key == 'b') { m_moveType = MoveExclusive; moveToWordBoundary(false, false);