From a2b518412307a03addcd63ccd6b9bce4eacdd4a7 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 13:45:01 +0100 Subject: [PATCH 1/9] Activate the completion only when the canonical symbol has a valid name. --- src/plugins/cppeditor/cppeditor.cpp | 13 ++++++++----- src/plugins/cpptools/cppfindreferences.cpp | 3 +++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index d96a3f50087..e323ff0651a 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -762,10 +762,6 @@ void CPPEditor::findUsages() void CPPEditor::renameUsages() { - Core::EditorManager::instance()->showEditorInfoBar(QLatin1String("CppEditor.Rename"), - tr("This change cannot be undone."), - tr("Yes, I know what I am doing."), - this, SLOT(hideRenameNotification())); renameUsagesNow(); } @@ -777,7 +773,14 @@ void CPPEditor::hideRenameNotification() void CPPEditor::renameUsagesNow() { if (Symbol *canonicalSymbol = markSymbols()) { - m_modelManager->renameUsages(canonicalSymbol); + if (canonicalSymbol->identifier() != 0) { + Core::EditorManager::instance()->showEditorInfoBar(QLatin1String("CppEditor.Rename"), + tr("This change cannot be undone."), + tr("Yes, I know what I am doing."), + this, SLOT(hideRenameNotification())); + + m_modelManager->renameUsages(canonicalSymbol); + } } } diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index eb90a186786..06ae9790602 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -656,6 +656,9 @@ void CppFindReferences::renameUsages(Symbol *symbol) void CppFindReferences::findAll_helper(Symbol *symbol) { + if (! (symbol && symbol->identifier())) + return; + _resultWindow->popup(true); const Snapshot snapshot = _modelManager->snapshot(); From 485dec6d2b3347b87b307f21597a0f4dbd5c930f Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 14:40:36 +0100 Subject: [PATCH 2/9] Link with cplusplus library. --- tests/auto/cplusplus/ast/ast.pro | 2 +- tests/auto/cplusplus/lookup/lookup.pro | 6 ++---- tests/auto/cplusplus/preprocessor/preprocessor.pro | 6 ++---- tests/auto/cplusplus/semantic/semantic.pro | 2 +- tests/auto/cplusplus/shared/shared.pri | 1 + tests/auto/cplusplus/shared/shared.pro | 6 +++--- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/auto/cplusplus/ast/ast.pro b/tests/auto/cplusplus/ast/ast.pro index 2f5a0a33eae..05435839c6c 100644 --- a/tests/auto/cplusplus/ast/ast.pro +++ b/tests/auto/cplusplus/ast/ast.pro @@ -1,6 +1,6 @@ TEMPLATE = app CONFIG += qt warn_on console depend_includepath -QT = core testlib +QT += testlib include(../shared/shared.pri) SOURCES += tst_ast.cpp TARGET=tst_$$TARGET diff --git a/tests/auto/cplusplus/lookup/lookup.pro b/tests/auto/cplusplus/lookup/lookup.pro index b80aa2f2b7b..9011a33f612 100644 --- a/tests/auto/cplusplus/lookup/lookup.pro +++ b/tests/auto/cplusplus/lookup/lookup.pro @@ -1,8 +1,6 @@ TEMPLATE = app CONFIG += qt warn_on console depend_includepath -QT = core testlib - -include(../../../../src/libs/cplusplus/cplusplus-lib.pri) - +QT += testlib +include(../shared/shared.pri) SOURCES += tst_lookup.cpp TARGET=tst_$$TARGET diff --git a/tests/auto/cplusplus/preprocessor/preprocessor.pro b/tests/auto/cplusplus/preprocessor/preprocessor.pro index 463de3ccfb3..bc7c98ea4ea 100644 --- a/tests/auto/cplusplus/preprocessor/preprocessor.pro +++ b/tests/auto/cplusplus/preprocessor/preprocessor.pro @@ -1,8 +1,6 @@ TEMPLATE = app CONFIG += qt warn_on console depend_includepath -QT = core testlib +QT += testlib TARGET = tst_$$TARGET - -include(../../../../src/libs/cplusplus/cplusplus-lib.pri) - +include(../shared/shared.pri) SOURCES += tst_preprocessor.cpp diff --git a/tests/auto/cplusplus/semantic/semantic.pro b/tests/auto/cplusplus/semantic/semantic.pro index 09f80ab27ab..2198ab78c73 100644 --- a/tests/auto/cplusplus/semantic/semantic.pro +++ b/tests/auto/cplusplus/semantic/semantic.pro @@ -1,6 +1,6 @@ TEMPLATE = app CONFIG += qt warn_on console depend_includepath -QT = core testlib +QT += testlib include(../shared/shared.pri) SOURCES += tst_semantic.cpp diff --git a/tests/auto/cplusplus/shared/shared.pri b/tests/auto/cplusplus/shared/shared.pri index d0c398dae80..80dab035ba8 100644 --- a/tests/auto/cplusplus/shared/shared.pri +++ b/tests/auto/cplusplus/shared/shared.pri @@ -1,4 +1,5 @@ INCLUDEPATH += $$PWD/../../../../src/shared/cplusplus +INCLUDEPATH += $$PWD/../../../../src/libs/cplusplus DEPENDPATH += $$INCLUDEPATH . LIBS += -L$$PWD -lCPlusPlusTestSupport diff --git a/tests/auto/cplusplus/shared/shared.pro b/tests/auto/cplusplus/shared/shared.pro index f8eb83829da..72f904a9799 100644 --- a/tests/auto/cplusplus/shared/shared.pro +++ b/tests/auto/cplusplus/shared/shared.pro @@ -1,8 +1,8 @@ TEMPLATE = lib TARGET = CPlusPlusTestSupport -CONFIG += static -QT = core +CONFIG += static depend_includepath +QT = core gui DESTDIR = $$PWD +include($$PWD/../../../../src/libs/cplusplus/cplusplus-lib.pri) -include($$PWD/../../../../src/shared/cplusplus/cplusplus.pri) From 72da848073bfa895e25a2481239f03d58c486329 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 14:45:58 +0100 Subject: [PATCH 3/9] We expect failures in tst_Semantic::pointer_to_function_1 --- tests/auto/cplusplus/semantic/tst_semantic.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index bf113873fe4..cf2f6e23180 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -217,7 +217,6 @@ void tst_Semantic::nested_class_1() Identifier *objectId = classObjectNameId->identifier(); QCOMPARE(QByteArray(objectId->chars(), objectId->size()), QByteArray("Object")); QCOMPARE(classObject->baseClassCount(), 0U); - QEXPECT_FAIL("", "Requires support for forward classes", Continue); QCOMPARE(classObject->members()->symbolCount(), 2U); Class *classObjectData = doc->globals->symbolAt(1)->asClass(); @@ -383,7 +382,10 @@ void tst_Semantic::pointer_to_function_1() Function *funTy = ptrTy->elementType()->asFunctionType(); QVERIFY(funTy); + QEXPECT_FAIL("", "Requires initialize enclosing scope of pointer-to-function symbols", Continue); QVERIFY(funTy->scope()); + + QEXPECT_FAIL("", "Requires initialize enclosing scope of pointer-to-function symbols", Continue); QCOMPARE(funTy->scope(), decl->scope()); } From 1f61dbc3802b73f5ec31a629ff22c92fa01164b1 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 15:00:56 +0100 Subject: [PATCH 4/9] Test GenTemplateInstance. --- .../auto/cplusplus/semantic/tst_semantic.cpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index cf2f6e23180..4e1586e68b5 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include using namespace CPlusPlus; @@ -101,6 +103,8 @@ private slots: void const_1(); void const_2(); void pointer_to_function_1(); + + void template_instance_1(); }; void tst_Semantic::function_declaration_1() @@ -389,5 +393,29 @@ void tst_Semantic::pointer_to_function_1() QCOMPARE(funTy->scope(), decl->scope()); } +void tst_Semantic::template_instance_1() +{ + QSharedPointer doc = document("void append(const _Tp &value);"); + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->symbolCount(), 1U); + + Declaration *decl = doc->globals->symbolAt(0)->asDeclaration(); + QVERIFY(decl); + + GenTemplateInstance::Substitution subst; + Name *nameTp = control.nameId(control.findOrInsertIdentifier("_Tp")); + FullySpecifiedType intTy(control.integerType(IntegerType::Int)); + subst.append(qMakePair(nameTp, intTy)); + + GenTemplateInstance inst(&control, subst); + FullySpecifiedType genTy = inst(decl->type()); + + Overview oo; + oo.setShowReturnTypes(true); + + const QString genDecl = oo.prettyType(genTy); + QCOMPARE(genDecl, QString::fromLatin1("void(const int &)")); +} + QTEST_APPLESS_MAIN(tst_Semantic) #include "tst_semantic.moc" From 0ed33aa8a557820638f5c6a5ed4611ff2464aa1e Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 15:07:00 +0100 Subject: [PATCH 5/9] Test ExpressionUnderCursor --- .../auto/cplusplus/semantic/tst_semantic.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 4e1586e68b5..827a227f053 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include #include @@ -14,6 +16,7 @@ #include #include #include +#include using namespace CPlusPlus; @@ -105,6 +108,8 @@ private slots: void pointer_to_function_1(); void template_instance_1(); + + void expression_under_cursor_1(); }; void tst_Semantic::function_declaration_1() @@ -417,5 +422,21 @@ void tst_Semantic::template_instance_1() QCOMPARE(genDecl, QString::fromLatin1("void(const int &)")); } +void tst_Semantic::expression_under_cursor_1() +{ + const QString plainText = "void *ptr = foo(10, bar"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, QString("bar")); +} + QTEST_APPLESS_MAIN(tst_Semantic) #include "tst_semantic.moc" From fe9b4458c63fdabfb48afda4d7fe4db343a2abe6 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 15:21:21 +0100 Subject: [PATCH 6/9] Fixed the #include directive. --- src/shared/cplusplus/ASTfwd.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index f97bae2a84c..e0a5c59d9a6 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -49,8 +49,7 @@ #ifndef CPLUSPLUS_ASTFWD_H #define CPLUSPLUS_ASTFWD_H -#include - +#include "CPlusPlusForwardDeclarations.h" namespace CPlusPlus { From cd3435a9835dda6c0d5cc2295c5642c47045caca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Mon, 26 Oct 2009 15:31:43 +0100 Subject: [PATCH 7/9] Don't needlessly call updateProjectInfo() Should not be necessary when nothing changed in the project info. This also fixes a problem where include file scanning happened twice after saving a pro file. Reviewed-by: Roberto Raggi --- src/plugins/cpptools/cppmodelmanager.cpp | 3 +-- src/plugins/qt4projectmanager/qt4project.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 1d886920566..75f8f743b38 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -331,9 +331,8 @@ void CppPreprocessor::resetEnvironment() bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QString *result) { - if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { + if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) return true; - } if (m_workingCopy.contains(absoluteFilePath)) { m_included.insert(absoluteFilePath); diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index c58793bed76..96c080087a8 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -698,7 +698,7 @@ void Qt4Project::updateCodeModel() pinfo.includePaths == allIncludePaths && pinfo.frameworkPaths == allFrameworkPaths && pinfo.sourceFiles == files) { - modelmanager->updateProjectInfo(pinfo); + // Nothing to update... } else { if (pinfo.defines != predefinedMacros || pinfo.includePaths != allIncludePaths || From c6e9c041a76587c68aa6d866288e2e6093db5139 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Mon, 26 Oct 2009 15:35:37 +0100 Subject: [PATCH 8/9] Do not require QTDIR to be set. Reviewed-By: Oswald Buddenhagen --- doc/doc.pri | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/doc.pri b/doc/doc.pri index b15059163f9..5c93f3d3a55 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -1,15 +1,14 @@ -unix:QDOC_BIN = $$(QTDIR)/bin/qdoc3 -win32:QDOC_BIN = $$(QTDIR)/bin/qdoc3.exe +QDOC_BIN = $$[QT_INSTALL_BINS]/qdoc3 win32:QDOC_BIN = $$replace(QDOC_BIN, "/", "\\") unix { QDOC = SRCDIR=$$PWD OUTDIR=$$OUT_PWD/doc/html $$QDOC_BIN - HELPGENERATOR = $$(QTDIR)/bin/qhelpgenerator + HELPGENERATOR = $$[QT_INSTALL_BINS]/qhelpgenerator } else { QDOC = set SRCDIR=$$PWD&& set OUTDIR=$$OUT_PWD/doc/html&& $$QDOC_BIN # Always run qhelpgenerator inside its own cmd; this is a workaround for # an unusual bug which causes qhelpgenerator.exe to do nothing - HELPGENERATOR = cmd /C $$(QTDIR)\bin\qhelpgenerator.exe + HELPGENERATOR = cmd /C $$replace($$list($$[QT_INSTALL_BINS]/qhelpgenerator.exe), "/", "\\") } QHP_FILE = $$OUT_PWD/doc/html/qtcreator.qhp From 4091efb47f57e5c15b05089792389d9a512ad6e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 26 Oct 2009 15:37:09 +0100 Subject: [PATCH 9/9] S60: Provide a MessageBox for starting serial communication as well. Generalize the concept of the Bluetooth starter, extract base class BaseCommunicationStarter that can be used to start a serial communication without further resources (listener) as well. Introduce convenience functions for both types. Note: This will only work for COM-ports that are not used otherwise by the operating system. --- .../gdb/s60debuggerbluetoothstarter.cpp | 20 +++++ .../gdb/s60debuggerbluetoothstarter.h | 18 ++++- src/plugins/debugger/gdb/trkgdbadapter.cpp | 40 ++++------ src/plugins/debugger/gdb/trkoptions.h | 1 + .../qt-s60/s60devicerunconfiguration.cpp | 33 ++++---- .../s60devicerunconfigurationwidget.cpp | 32 ++++---- .../qt-s60/s60runconfigbluetoothstarter.cpp | 21 +++++ .../qt-s60/s60runconfigbluetoothstarter.h | 18 ++++- src/shared/trk/bluetoothlistener_gui.cpp | 70 +++++++++++------ src/shared/trk/bluetoothlistener_gui.h | 39 +++++++--- src/shared/trk/communicationstarter.cpp | 76 ++++++++++++------- src/shared/trk/communicationstarter.h | 67 ++++++++++------ src/shared/trk/trk.pri | 1 + 13 files changed, 291 insertions(+), 145 deletions(-) diff --git a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp index 8dcfa4b9042..ad2869aac58 100644 --- a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp +++ b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp @@ -30,6 +30,7 @@ #include "s60debuggerbluetoothstarter.h" #include "bluetoothlistener.h" #include "debuggermanager.h" +#include "trkoptions.h" namespace Debugger { namespace Internal { @@ -48,5 +49,24 @@ trk::BluetoothListener *S60DebuggerBluetoothStarter::createListener() return rc; } +trk::PromptStartCommunicationResult +S60DebuggerBluetoothStarter::startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage) +{ + // Bluetooth? + if (communicationType == TrkOptions::BlueTooth) { + S60DebuggerBluetoothStarter bluetoothStarter(trkDevice); + bluetoothStarter.setDevice(device); + return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage); + } + // Serial + BaseCommunicationStarter serialStarter(trkDevice); + serialStarter.setDevice(device); + return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h index 226e00072ac..234afa2c2c9 100644 --- a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h +++ b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h @@ -31,6 +31,7 @@ #define S60DEBUGGERBLUETOOTHSTARTER_H #include "communicationstarter.h" +#include "bluetoothlistener_gui.h" namespace Debugger { namespace Internal { @@ -38,15 +39,24 @@ namespace Internal { /* S60DebuggerBluetoothStarter: Creates a listener in 'Listen' mode * parented on the Debugger manager which outputs to the debugger window. * Note: This is a "last resort" starter, normally, the run configuration - * should have already started a listener. */ + * should have already started a listener. + * Provides a static convenience to prompt for both connection types. */ class S60DebuggerBluetoothStarter : public trk::AbstractBluetoothStarter -{ +{ public: - explicit S60DebuggerBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + static trk::PromptStartCommunicationResult + startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage); -protected: +protected: virtual trk::BluetoothListener *createListener(); + +private: + explicit S60DebuggerBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index e954396c30a..bf23a09eab5 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -1512,30 +1512,22 @@ void TrkGdbAdapter::startAdapter() debugMessage(_("TRYING TO START ADAPTER")); logMessage(QLatin1String("### Starting TrkGdbAdapter")); m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth); - // Prompt the user for a bluetooth connection - const QString device = effectiveTrkDevice(); - QString message; - if (effectiveTrkDeviceType() == TrkOptions::BlueTooth) { - S60DebuggerBluetoothStarter starter(m_trkDevice); - starter.setDevice(device); - const trk::StartBluetoothGuiResult src = trk::startBluetoothGui(starter, 0, &message); - switch (src) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - emit adapterStartFailed(message, QString()); - return; - case trk::BluetoothGuiError: - emit adapterStartFailed(message, TrkOptionsPage::settingsId()); - return; - }; - } else { - if (!m_trkDevice->isOpen() && !m_trkDevice->open(device, &message)) { - message = tr("Failed to connect to %1: %2\nCheck whether TRK is running.").arg(device).arg(message); - logMessage(message); - emit adapterStartFailed(message, TrkOptionsPage::settingsId()); - return; - } + // Prompt the user to start communication + QString message; + const trk::PromptStartCommunicationResult src = + S60DebuggerBluetoothStarter::startCommunication(m_trkDevice, + effectiveTrkDevice(), + effectiveTrkDeviceType(), + 0, &message); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + emit adapterStartFailed(message, QString()); + return; + case trk::PromptStartCommunicationError: + emit adapterStartFailed(message, TrkOptionsPage::settingsId()); + return; } QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer); diff --git a/src/plugins/debugger/gdb/trkoptions.h b/src/plugins/debugger/gdb/trkoptions.h index f4a288fe074..470b66ab52f 100644 --- a/src/plugins/debugger/gdb/trkoptions.h +++ b/src/plugins/debugger/gdb/trkoptions.h @@ -46,6 +46,7 @@ namespace Internal { struct TrkOptions { + // Matches the communication enumeration from the S60 devices listener. enum Mode { Serial, BlueTooth }; TrkOptions(); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index d547c3b6d83..0804a9fe258 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -582,21 +582,24 @@ void S60DeviceRunControlBase::signsisProcessFinished() initLauncher(runFileName, m_launcher); emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName)); QString errorMessage; - // Prompt the user to start up the Blue tooth connection - if (m_communicationType == BlueToothCommunication) { - S60RunConfigBluetoothStarter starter(m_launcher->trkDevice()); - switch (trk::startBluetoothGui(starter, 0, &errorMessage)) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - case trk::BluetoothGuiError: - delete m_launcher; - m_launcher = 0; - error(this, errorMessage); - emit finished(); - return; - }; - } + // Prompt the user to start up the Blue tooth connection + const trk::PromptStartCommunicationResult src = + S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(), + m_serialPortName, + m_communicationType, 0, + &errorMessage); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + case trk::PromptStartCommunicationError: + delete m_launcher; + m_launcher = 0; + error(this, errorMessage); + emit finished(); + return; + }; + if (!m_launcher->startServer(&errorMessage)) { delete m_launcher; m_launcher = 0; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp index 0b1554b1bae..46ebf4f0443 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp @@ -302,22 +302,22 @@ bool S60DeviceRunConfigurationWidget::getDeviceInfo(QString *message) const CommunicationDevice commDev = currentDevice(); launcher->setSerialFrame(commDev.type == SerialPortCommunication); launcher->setTrkServerName(commDev.portName); - // Prompt the user to start - if (commDev.type == BlueToothCommunication) { - S60RunConfigBluetoothStarter starter(launcher->trkDevice()); - starter.setDevice(launcher->trkServerName()); - const trk::StartBluetoothGuiResult src = trk::startBluetoothGui(starter, this, message); - switch (src) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - launcher->deleteLater(); - return true; - case trk::BluetoothGuiError: - launcher->deleteLater(); - return false; - }; - } + // Prompt user + const trk::PromptStartCommunicationResult src = + S60RunConfigBluetoothStarter::startCommunication(launcher->trkDevice(), + commDev.portName, + commDev.type, this, + message); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + launcher->deleteLater(); + return true; + case trk::PromptStartCommunicationError: + launcher->deleteLater(); + return false; + }; if (!launcher->startServer(message)) { launcher->deleteLater(); return false; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp index 1481dcacbc9..b12aa0f1d29 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp @@ -29,6 +29,7 @@ #include "s60runconfigbluetoothstarter.h" #include "bluetoothlistener.h" +#include "serialdevicelister.h" #include #include @@ -49,5 +50,25 @@ trk::BluetoothListener *S60RunConfigBluetoothStarter::createListener() connect(rc, SIGNAL(message(QString)), core->messageManager(), SLOT(printToOutputPane(QString))); return rc; } + +trk::PromptStartCommunicationResult +S60RunConfigBluetoothStarter::startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage) +{ + // Bluetooth? + if (communicationType == BlueToothCommunication) { + S60RunConfigBluetoothStarter bluetoothStarter(trkDevice); + bluetoothStarter.setDevice(device); + return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage); + } + // Serial + BaseCommunicationStarter serialStarter(trkDevice); + serialStarter.setDevice(device); + return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage); +} + } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h index 0da8817b323..70ea0123f5d 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h @@ -31,20 +31,34 @@ #define S60RUNCONFIGBLUETOOTHSTARTER_H #include "communicationstarter.h" +#include "bluetoothlistener_gui.h" namespace Qt4ProjectManager { namespace Internal { /* S60RunConfigBluetoothStarter: Creates a listener in 'Listen' mode - * parented on the Qt Creator core which outputs to the message manager. */ + * parented on the Qt Creator core which outputs to the message manager. + * Provides a static convenience to prompt for both connection types. */ class S60RunConfigBluetoothStarter : public trk::AbstractBluetoothStarter { public: - explicit S60RunConfigBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + typedef trk::AbstractBluetoothStarter::TrkDevicePtr TrkDevicePtr; + + // Convenience function to start communication depending on type, + // passing on the right messages. + static trk::PromptStartCommunicationResult + startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage); protected: virtual trk::BluetoothListener *createListener(); + +private: + explicit S60RunConfigBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); }; } // namespace Internal diff --git a/src/shared/trk/bluetoothlistener_gui.cpp b/src/shared/trk/bluetoothlistener_gui.cpp index ee21c82a7c5..edcb40a9a52 100644 --- a/src/shared/trk/bluetoothlistener_gui.cpp +++ b/src/shared/trk/bluetoothlistener_gui.cpp @@ -38,38 +38,62 @@ namespace trk { -StartBluetoothGuiResult - startBluetoothGui(AbstractBluetoothStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage) { errorMessage->clear(); + // Initial connection attempt. switch (starter.start()) { - case AbstractBluetoothStarter::Started: + case BaseCommunicationStarter::Started: break; - case AbstractBluetoothStarter::ConnectionSucceeded: - return BluetoothGuiConnected; - case AbstractBluetoothStarter::StartError: + case BaseCommunicationStarter::ConnectionSucceeded: + return PromptStartCommunicationConnected; + case BaseCommunicationStarter::StartError: *errorMessage = starter.errorString(); - return BluetoothGuiError; + return PromptStartCommunicationError; } - // Run the starter with the event loop of a message box, close it - // with the finished signals. - const QString title = QCoreApplication::translate("trk::startBluetoothGui", "Waiting for Bluetooth Connection"); - const QString message = QCoreApplication::translate("trk::startBluetoothGui", "Connecting to %1...").arg(starter.device()); - QMessageBox messageBox(QMessageBox::Information, title, message, QMessageBox::Cancel, msgBoxParent); + // Run the starter with the event loop of a message box, have the box + // closed by the signals of the starter. + QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); - messageBox.exec(); - // Only starter.state() is reliable here. - if (starter.state() == AbstractBluetoothStarter::Running) { - *errorMessage = QCoreApplication::translate("trk::startBluetoothGui", "Connection on %1 canceled.").arg(starter.device()); - return BluetoothGuiCanceled; - } - if (starter.state() != AbstractBluetoothStarter::Connected) { + messageBox.exec(); + // Only starter.state() is reliable here to obtain the state. + switch (starter.state()) { + case AbstractBluetoothStarter::Running: + *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); + return PromptStartCommunicationCanceled; + case AbstractBluetoothStarter::TimedOut: *errorMessage = starter.errorString(); - return BluetoothGuiError; + return PromptStartCommunicationError; + case AbstractBluetoothStarter::Connected: + break; } - return BluetoothGuiConnected; + return PromptStartCommunicationConnected; } + +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for TRK"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for TRK to start on %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + } // namespace trk diff --git a/src/shared/trk/bluetoothlistener_gui.h b/src/shared/trk/bluetoothlistener_gui.h index 2a7c57e291a..83cce425ea3 100644 --- a/src/shared/trk/bluetoothlistener_gui.h +++ b/src/shared/trk/bluetoothlistener_gui.h @@ -37,22 +37,39 @@ class QWidget; QT_END_NAMESPACE namespace trk { - class AbstractBluetoothStarter; +class BaseCommunicationStarter; - /* startBluetoothGui(): Prompt the user to start a Bluetooth - * connection with a message box he can cancel. Pass in - * the starter with device and parameters set up. */ +/* promptStartCommunication(): Convenience functions that + * prompt the user to start a communication (launching or + * connecting TRK) using a modal message box in which they can cancel. + * Pass in the starter with device and parameters set up. */ - enum StartBluetoothGuiResult { - BluetoothGuiConnected, - BluetoothGuiCanceled, - BluetoothGuiError - }; +enum PromptStartCommunicationResult { + PromptStartCommunicationConnected, + PromptStartCommunicationCanceled, + PromptStartCommunicationError +}; - StartBluetoothGuiResult - startBluetoothGui(AbstractBluetoothStarter &starter, +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start a serial connection (messages prompting +// to launch Trk). +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); + +// Convenience to start blue tooth connection (messages +// prompting to connect). +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); } // namespace trk #endif // BLUETOOTHLISTENER_GUI_H diff --git a/src/shared/trk/communicationstarter.cpp b/src/shared/trk/communicationstarter.cpp index 58a954cd26b..b425db25062 100644 --- a/src/shared/trk/communicationstarter.cpp +++ b/src/shared/trk/communicationstarter.cpp @@ -35,11 +35,12 @@ #include namespace trk { -// --------------- AbstractBluetoothStarter -struct AbstractBluetoothStarterPrivate { - explicit AbstractBluetoothStarterPrivate(const AbstractBluetoothStarter::TrkDevicePtr &d); - const AbstractBluetoothStarter::TrkDevicePtr trkDevice; +// --------------- AbstractBluetoothStarter +struct BaseCommunicationStarterPrivate { + explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); + + const BaseCommunicationStarter::TrkDevicePtr trkDevice; BluetoothListener *listener; QTimer *timer; int intervalMS; @@ -47,11 +48,10 @@ struct AbstractBluetoothStarterPrivate { int n; QString device; QString errorString; - AbstractBluetoothStarter::State state; + BaseCommunicationStarter::State state; }; -AbstractBluetoothStarterPrivate::AbstractBluetoothStarterPrivate(const AbstractBluetoothStarter::TrkDevicePtr &d) : - +BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : trkDevice(d), listener(0), timer(0), @@ -59,32 +59,38 @@ AbstractBluetoothStarterPrivate::AbstractBluetoothStarterPrivate(const AbstractB attempts(-1), n(0), device(QLatin1String("/dev/rfcomm0")), - state(AbstractBluetoothStarter::TimedOut) + state(BaseCommunicationStarter::TimedOut) { } -AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : +BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : QObject(parent), - d(new AbstractBluetoothStarterPrivate(trkDevice)) + d(new BaseCommunicationStarterPrivate(trkDevice)) { } -AbstractBluetoothStarter::~AbstractBluetoothStarter() +BaseCommunicationStarter::~BaseCommunicationStarter() { stopTimer(); delete d; } -void AbstractBluetoothStarter::stopTimer() +void BaseCommunicationStarter::stopTimer() { if (d->timer && d->timer->isActive()) d->timer->stop(); } -AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() +bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) +{ + errorMessage->clear(); + return true; +} + +BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() { if (state() == Running) { - d->errorString = QLatin1String("Internal error, attempt to re-start AbstractBluetoothStarter.\n"); + d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); return StartError; } // Before we instantiate timers, and such, try to open the device, @@ -92,10 +98,9 @@ AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() // 'Watch' mode if (d->trkDevice->open(d->device , &(d->errorString))) return ConnectionSucceeded; - // Fire up the listener + // Pull up resources for next attempt d->n = 0; - d->listener = createListener(); - if (!d->listener->start(d->device, &(d->errorString))) + if (!initializeStartupResources(&(d->errorString))) return StartError; // Start timer if (!d->timer) { @@ -109,49 +114,49 @@ AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() return Started; } -AbstractBluetoothStarter::State AbstractBluetoothStarter::state() const +BaseCommunicationStarter::State BaseCommunicationStarter::state() const { return d->state; } -int AbstractBluetoothStarter::intervalMS() const +int BaseCommunicationStarter::intervalMS() const { return d->intervalMS; } -void AbstractBluetoothStarter::setIntervalMS(int i) +void BaseCommunicationStarter::setIntervalMS(int i) { d->intervalMS = i; if (d->timer) d->timer->setInterval(i); } -int AbstractBluetoothStarter::attempts() const +int BaseCommunicationStarter::attempts() const { return d->attempts; } -void AbstractBluetoothStarter::setAttempts(int a) +void BaseCommunicationStarter::setAttempts(int a) { d->attempts = a; } -QString AbstractBluetoothStarter::device() const +QString BaseCommunicationStarter::device() const { return d->device; } -void AbstractBluetoothStarter::setDevice(const QString &dv) +void BaseCommunicationStarter::setDevice(const QString &dv) { d->device = dv; } -QString AbstractBluetoothStarter::errorString() const +QString BaseCommunicationStarter::errorString() const { return d->errorString; } -void AbstractBluetoothStarter::slotTimer() +void BaseCommunicationStarter::slotTimer() { ++d->n; // Check for timeout @@ -166,17 +171,32 @@ void AbstractBluetoothStarter::slotTimer() if (d->trkDevice->open(d->device , &(d->errorString))) { stopTimer(); const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); - d->listener->emitMessage(msg); + emit message(msg); d->state = Connected; emit connected(); } else { const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") .arg(d->device).arg(d->n).arg(d->errorString); - d->listener->emitMessage(msg); + emit message(msg); } } } +// --------------- AbstractBluetoothStarter + +AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + BaseCommunicationStarter(trkDevice, parent) +{ +} + +bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) +{ + // Create the listener and forward messages to it. + BluetoothListener *listener = createListener(); + connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); + return listener->start(device(), errorMessage); +} + // -------- ConsoleBluetoothStarter ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *listenerParent, diff --git a/src/shared/trk/communicationstarter.h b/src/shared/trk/communicationstarter.h index e90578dc171..7b89e2472ed 100644 --- a/src/shared/trk/communicationstarter.h +++ b/src/shared/trk/communicationstarter.h @@ -36,25 +36,28 @@ namespace trk { class TrkDevice; class BluetoothListener; -struct AbstractBluetoothStarterPrivate; +struct BaseCommunicationStarterPrivate; -/* AbstractBluetoothStarter: Repeatedly tries to open a trk device - * until a connection succeeds, allowing to do something else in the - * foreground (local event loop or asynchronous operation). - * Note that in case a Listener is already running in watch mode, it might - * also happen that connection succeeds immediately. - * Implementations must provide a factory function that creates and sets up the - * listener (mode, message connection, etc). */ +/* BaseCommunicationStarter: A QObject that repeatedly tries to open a + * trk device until a connection succeeds or a timeout occurs (emitting + * signals), allowing to do something else in the foreground (local event loop + * [say QMessageBox] or some asynchronous operation). If the initial + * connection attempt in start() fails, the + * virtual initializeStartupResources() is called to initialize resources + * required to pull up the communication (namely Bluetooth listeners). + * The base class can be used as is to prompt the user to launch TRK for a serial + * communication as this requires no further resource setup. */ -class AbstractBluetoothStarter : public QObject { +class BaseCommunicationStarter : public QObject { Q_OBJECT - Q_DISABLE_COPY(AbstractBluetoothStarter) + Q_DISABLE_COPY(BaseCommunicationStarter) public: - typedef QSharedPointer TrkDevicePtr; + typedef QSharedPointer TrkDevicePtr; enum State { Running, Connected, TimedOut }; - virtual ~AbstractBluetoothStarter(); + explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + virtual ~BaseCommunicationStarter(); int intervalMS() const; void setIntervalMS(int i); @@ -80,19 +83,40 @@ public: signals: void connected(); void timeout(); + void message(const QString &); private slots: void slotTimer(); protected: - explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - // Overwrite to create and parametrize the listener. - virtual BluetoothListener *createListener() = 0; + virtual bool initializeStartupResources(QString *errorMessage); private: inline void stopTimer(); - AbstractBluetoothStarterPrivate *d; + BaseCommunicationStarterPrivate *d; +}; + +/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth + * device. Note that in case a Listener is already running mode, the + * connection will succeed immediately. + * initializeStartupResources() is implemented to fire up the listener. + * Introduces a new virtual createListener() that derived classes must + * implement as a factory function that creates and sets up the + * listener (mode, message connection, etc). */ + +class AbstractBluetoothStarter : public BaseCommunicationStarter { + Q_OBJECT + Q_DISABLE_COPY(AbstractBluetoothStarter) +public: + +protected: + explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + + // Implemented to fire up the listener. + virtual bool initializeStartupResources(QString *errorMessage); + // New virtual: Overwrite to create and parametrize the listener. + virtual BluetoothListener *createListener() = 0; }; /* ConsoleBluetoothStarter: Convenience class for console processes. Creates a @@ -102,12 +126,11 @@ class ConsoleBluetoothStarter : public AbstractBluetoothStarter { Q_OBJECT Q_DISABLE_COPY(ConsoleBluetoothStarter) public: - - static bool startBluetooth(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - const QString &device, - int attempts, - QString *errorMessage); + static bool startBluetooth(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage); protected: virtual BluetoothListener *createListener(); diff --git a/src/shared/trk/trk.pri b/src/shared/trk/trk.pri index 5b0e067b158..2ce17c0a6c6 100644 --- a/src/shared/trk/trk.pri +++ b/src/shared/trk/trk.pri @@ -14,6 +14,7 @@ SOURCES += $$PWD/trkutils.cpp \ $$PWD/bluetoothlistener.cpp \ $$PWD/communicationstarter.cpp +# Tests/trklauncher is a console application contains(QT, gui) { HEADERS += $$PWD/bluetoothlistener_gui.h SOURCES += $$PWD/bluetoothlistener_gui.cpp