Commit bc3fde7f authored by dt's avatar dt

Merge branch 'master' of

parents a12dbe95 e8dafc28
......@@ -315,6 +315,12 @@
\snippet examples/addressbook-sdk/part2/addressbook.h members1
The Qt types used for our private members, e.g., QPushButton, QLineEdit,
QTextEdit, etc., need to be included with the \c include directive, as
shown below:
\snippet examples/addressbook-sdk/part2/addressbook.h include
\note The names, e.g., \c addButton etc., correspond to the name of the
actual object. You can modify them by double-clicking on their names within
\QD's \gui{Object Inspector}.
......@@ -727,6 +733,7 @@
dialog that can prompt the user for a contact's name. Qt provides QDialog,
which we subclass in this chapter, to implement a FindDialog class.
\section1 Designing \c FindDialog
......@@ -743,6 +750,7 @@
in a horizontal layout. Then set a top level layout - either horizontal or
\section1 Implementing \c FindDialog
Let's look at \c{FindDialog}'s header file. Here, we need to provide
......@@ -751,8 +759,38 @@
\snippet examples/addressbook-sdk/part5/finddialog.h private members
We define a public function, \c getFindText(), to be used by classes that
instantiate \c FindDialog. This function allows the these classes to obtain
the search string entered by the user. A public slot, \c findClicked(), is
also defined to handle the search string when the user clicks the \gui Find
\snippet examples/addressbook-sdk/part5/finddialog.h getFindText
\snippet examples/addressbook-sdk/part5/finddialog.h findClicked
Now, lets look at our constructor in the \c{finddialog.cpp} file. Here, we
set up the private variables, \c lineEdit, \c findButton, and \c findText.
\snippet examples/addressbook-sdk/part5/finddialog.cpp constructor
We connect our signals to their respective slots. Notice that
\c{findButton}'s \l{QPushButton:}{clicked()} signal is connected to
\c findClicked() and \l{QDialog::}{accept()}. The \l{QDialog::}{accept()}
slot provided by QDialog hides the dialog and sets the result code to
\l{QDialog::}{Accepted}. We use this function to help \c{AddressBook}'s
\c findContact() function know when the \c FindDialog object has been
closed. We will explain this logic in further detail when discussing the
\c findContact() function.
\image addressbook-tutorial-part5-signals-and-slots.png
In \c findClicked(), we validate to ensure that the user did not click the
\gui Find button without entering a contact's name. Then, we set
\c findText to the search string, extracted from \c lineEdit. After that,
we clear the contents of \c lineEdit and hide the dialog.
\snippet examples/addressbook-sdk/part5/finddialog.cpp findClicked
//! [class definition]
//! [include]
#include <QtGui/QWidget>
#include <QtGui/QPushButton>
#include <QtGui/QLineEdit>
#include <QtGui/QTextEdit>
#include <QtGui/QMessageBox>
//! [include]
namespace Ui
......@@ -48,4 +48,3 @@ private:
//! [class definition]
#include "finddialog.h"
#include "ui_finddialog.h"
//! [constructor]
FindDialog::FindDialog(QWidget *parent) :
m_ui(new Ui::FindDialog)
......@@ -18,12 +19,14 @@ FindDialog::FindDialog(QWidget *parent) :
setWindowTItle(tr("Find a Contact"));
//! [constructor]
delete m_ui;
//! [findClicked]
void FindDialog::findClicked()
QString text = lineEdit->text();
......@@ -38,6 +41,7 @@ void FindDialog::findClicked()
//! [findClicked]
QString FindDialog::getFindText()
......@@ -2,8 +2,8 @@
#include <QtGui/QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>
namespace Ui {
class FindDialog;
......@@ -14,10 +14,14 @@ class FindDialog : public QDialog {
FindDialog(QWidget *parent = 0);
//! [getFindText]
QString getFindText();
//! [getFindText]
//! [findClicked]
public slots:
void findClicked();
//! [findClicked]
//! [private members]
......@@ -279,8 +279,12 @@ void BreakHandler::removeAt(int index)
void BreakHandler::clear()
for (int index = size(); --index >= 0; )
int BreakHandler::findBreakpoint(const BreakpointData &needle)
......@@ -326,19 +330,19 @@ void BreakHandler::saveBreakpoints()
const BreakpointData *data = at(index);
QMap<QString, QVariant> map;
if (!data->fileName.isEmpty())
map["filename"] = data->fileName;
map.insert(QLatin1String("filename"), data->fileName);
if (!data->lineNumber.isEmpty())
map["linenumber"] = data->lineNumber;
map.insert(QLatin1String("linenumber"), data->lineNumber);
if (!data->funcName.isEmpty())
map["funcname"] = data->funcName;
map.insert(QLatin1String("funcname"), data->funcName);
if (!data->condition.isEmpty())
map["condition"] = data->condition;
map.insert(QLatin1String("condition"), data->condition);
if (!data->ignoreCount.isEmpty())
map["ignorecount"] = data->ignoreCount;
map.insert(QLatin1String("ignorecount"), data->ignoreCount);
if (!data->enabled)
map["disabled"] = "1";
map.insert(QLatin1String("disabled"), QLatin1String("1"));
if (data->useFullPath)
map["usefullpath"] = "1";
map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
setSessionValueRequested("Breakpoints", list);
......@@ -349,18 +353,31 @@ void BreakHandler::loadBreakpoints()
QVariant value;
sessionValueRequested("Breakpoints", &value);
QList<QVariant> list = value.toList();
foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap();
BreakpointData *data = new BreakpointData(this);
data->fileName = map["filename"].toString();
data->lineNumber = map["linenumber"].toString();
data->condition = map["condition"].toString();
data->ignoreCount = map["ignorecount"].toString();
data->funcName = map["funcname"].toString();
data->enabled = !map["disabled"].toInt();
data->useFullPath = bool(map["usefullpath"].toInt());
QVariant v = map.value(QLatin1String("filename"));
if (v.isValid())
data->fileName = v.toString();
v = map.value(QLatin1String("linenumber"));
if (v.isValid())
data->lineNumber = v.toString();
v = map.value(QLatin1String("condition"));
if (v.isValid())
data->condition = v.toString();
v = map.value(QLatin1String("ignorecount"));
if (v.isValid())
data->ignoreCount = v.toInt();
v = map.value(QLatin1String("funcname"));
if (v.isValid())
data->funcName = v.toString();
v = map.value(QLatin1String("disabled"));
if (v.isValid())
data->enabled = !v.toInt();
v = map.value(QLatin1String("usefullpath"));
if (v.isValid())
data->useFullPath = bool(v.toInt());
data->markerFileName = data->fileName;
data->markerLineNumber = data->lineNumber.toInt();
......@@ -407,12 +407,19 @@ static bool setBreakPointEnabledById(CIDebugControl *ctl, unsigned long id, bool
return true;
static inline QString msgCannotSetBreakAtFunction(const QString &func, const QString &why)
return QString::fromLatin1("Cannot set a breakpoint at '%1': %2").arg(func, why);
// Synchronize (halted) engine breakpoints with those of the BreakHandler.
bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
CIDebugSymbols *syms,
BreakHandler *handler,
QString *errorMessage)
QString *errorMessage, QStringList *warnings)
// Do an initial check whether we are in a state that allows
// for modifying breakPoints
ULONG engineCount;
......@@ -420,25 +427,29 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
*errorMessage = QString::fromLatin1("Cannot modify breakpoints: %1").arg(*errorMessage);
return false;
QString warning;
// Insert new ones
bool updateMarkers = false;
foreach (BreakpointData *nbd, handler->insertedBreakpoints()) {
// Function breakpoints: Are the module names specified?
bool breakPointOk = false;
if (nbd->funcName.isEmpty()) {
breakPointOk = true;
} else {
switch (resolveSymbol(syms, &nbd->funcName, errorMessage)) {
switch (resolveSymbol(syms, &nbd->funcName, &warning)) {
case ResolveSymbolOk:
breakPointOk = true;
case ResolveSymbolAmbiguous:
qWarning("Warning: %s\n", qPrintable(*errorMessage));
warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
breakPointOk = true;
case ResolveSymbolNotFound:
case ResolveSymbolError:
qWarning("Warning: %s\n", qPrintable(*errorMessage));
warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
} // function breakpoint
......@@ -447,7 +458,7 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
quint64 address;
unsigned long id;
CDBBreakPoint ncdbbp(*nbd);
breakPointOk = ncdbbp.add(debugControl, &address, &id, errorMessage);
breakPointOk = ncdbbp.add(debugControl, &address, &id, &warning);
if (breakPointOk) {
if (debugBP)
qDebug() << "Added " << id << " at " << address << ncdbbp;
......@@ -464,22 +475,21 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
nbd->bpFuncName = nbd->funcName;
} // had symbol
if (!breakPointOk)
qWarning("%s\n", qPrintable(*errorMessage));
if (!breakPointOk && !warning.isEmpty())
warnings->push_back(warning); }
// Delete
foreach (BreakpointData *rbd, handler->takeRemovedBreakpoints()) {
if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), errorMessage))
qWarning("%s\n", qPrintable(*errorMessage));
if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), &warning))
delete rbd;
// Enable/Disable
foreach (BreakpointData *ebd, handler->takeEnabledBreakpoints())
if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, errorMessage))
qWarning("%s\n", qPrintable(*errorMessage));
if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, &warning))
foreach (BreakpointData *dbd, handler->takeDisabledBreakpoints())
if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, errorMessage))
qWarning("%s\n", qPrintable(*errorMessage));
if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, &warning))
if (updateMarkers)
......@@ -73,7 +73,8 @@ struct CDBBreakPoint
static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
// Synchronize (halted) engine with BreakHandler.
static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms,
BreakHandler *bh, QString *errorMessage);
BreakHandler *bh,
QString *errorMessage, QStringList *warnings);
// Return a 'canonical' file (using '/' and capitalized drive letter)
static QString canonicalSourceFile(const QString &f);
......@@ -1182,6 +1182,8 @@ void CdbDebugEngine::selectThread(int index)
void CdbDebugEngine::attemptBreakpointSynchronization()
if (!m_d->m_hDebuggeeProcess) // Sometimes called from the breakpoint Window
QString errorMessage;
if (!m_d->attemptBreakpointSynchronization(&errorMessage))
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
......@@ -1215,10 +1217,15 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
return true;
return CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
QStringList warnings;
const bool ok = CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
errorMessage, &warnings);
if (const int warningsCount = warnings.size())
for (int w = 0; w < warningsCount; w++)
return ok;
void CdbDebugEngine::reloadDisassembler()
......@@ -138,6 +138,7 @@ static ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol,
QStringList *matches,
QString *errorMessage)
// Is it an incomplete symbol?
if (symbol->contains(QLatin1Char('!')))
return ResolveSymbolOk;
......@@ -168,19 +168,16 @@ static QStringList readLines(const QString &absoluteFileName)
return lines;
bool GenericProject::addFiles(const QStringList &filePaths)
bool GenericProject::setFiles(const QStringList &filePaths)
// Make sure we can open the file for writing
QFile file(filesFileName());
if (! | QIODevice::Text))
return false;
QStringList newFileList = m_files;
QTextStream stream(&file);
QDir baseDir(QFileInfo(m_fileName).dir());
foreach (const QString &filePath, newFileList)
foreach (const QString &filePath, filePaths)
stream << baseDir.relativeFilePath(filePath) << QLatin1Char('\n');
......@@ -188,6 +185,27 @@ bool GenericProject::addFiles(const QStringList &filePaths)
return true;
bool GenericProject::addFiles(const QStringList &filePaths)
QStringList newFileList = m_files;
return setFiles(newFileList);
bool GenericProject::removeFiles(const QStringList &filePaths)
QStringList newFileList;
QSet<QString> filesToRemove = filePaths.toSet();
foreach (const QString &file, m_files) {
if (!filesToRemove.contains(file))
return setFiles(newFileList);
void GenericProject::parseProject(RefreshOptions options)
if (options & Files)
......@@ -94,7 +94,9 @@ public:
QString buildParser(const QString &buildConfiguration) const;
ProjectExplorer::ToolChain *toolChain() const;
bool setFiles(const QStringList &filePaths);
bool addFiles(const QStringList &filePaths);
bool removeFiles(const QStringList &filePaths);
enum RefreshOptions {
Files = 0x01,
......@@ -167,7 +167,8 @@ bool GenericProjectNode::hasTargets() const
QList<ProjectExplorer::ProjectNode::ProjectAction> GenericProjectNode::supportedActions() const
return QList<ProjectAction>()
<< AddFile;
<< AddFile
<< RemoveFile;
bool GenericProjectNode::addSubProjects(const QStringList &proFilePaths)
......@@ -195,9 +196,9 @@ bool GenericProjectNode::removeFiles(const ProjectExplorer::FileType fileType,
const QStringList &filePaths, QStringList *notRemoved)
return false;
return m_project->removeFiles(filePaths);
bool GenericProjectNode::renameFile(const ProjectExplorer::FileType fileType,
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment