diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-07-28 10:43:29 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-07-28 10:43:29 (GMT) |
commit | 75f5b49b9a722c5f3827ea538e13a69dff1d8c78 (patch) | |
tree | 59b8dda72708be8a835c7716cd60b57405553cd1 | |
parent | 953e91c582cd396082250748e4c4d8424292c1de (diff) | |
parent | c3557c0fd00f107da77e932ff0f42b5aaa09c1d3 (diff) | |
download | Qt-75f5b49b9a722c5f3827ea538e13a69dff1d8c78.zip Qt-75f5b49b9a722c5f3827ea538e13a69dff1d8c78.tar.gz Qt-75f5b49b9a722c5f3827ea538e13a69dff1d8c78.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Fix missing license header
Add test for getting a backtrace in QML
Doc: add link to new gettings started to index.html
Doc: Added new getting started document.
QtDeclarative: Give name to function bindings and signals.
18 files changed, 743 insertions, 5 deletions
diff --git a/doc/src/getting-started/gettingstarted.qdoc b/doc/src/getting-started/gettingstarted.qdoc new file mode 100644 index 0000000..391aec3 --- /dev/null +++ b/doc/src/getting-started/gettingstarted.qdoc @@ -0,0 +1,516 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in a +** written agreement between you and Nokia. +** +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page gettingstarted.html + + \title Getting Started + + Welcome to the world of Qt--the cross-platform GUI toolkit. In + this getting started guide, we teach basic Qt knowledge by + implementing a simple Notepad application. After reading this + guide, you should be ready to delve into our overviews and API + documentation, and find the information you need for the + application you are developing. + + \section1 Hello Notepad + + In this first example, we simply create and show a text edit in a + window frame on the desktop. This represents the simplest possible + Qt program that has a GUI. + + \image gs1.png + + Here is the code: + + \code + 1 #include <QApplication> + 2 #include <QTextEdit> + 3 + 4 int main(int argv, char **args) + 5 { + 6 QApplication app(argv, args); + 7 + 8 QTextEdit textEdit; + 9 textEdit.show(); +10 +11 return app.exec(); +12 } + \endcode + + Let's go through the code line by line. In the first two lines, we + include the header files for QApplication and QTextEdit, which are + the two classes that we need for this example. All Qt classes have + a header file named after them. + + Line 6 creates a QApplication object. This object manages + application-wide resources and is necessary to run any Qt program + that has a GUI. It needs \c argv and \c args because Qt accepts a + few command line arguments. + + Line 8 creates a QTextEdit object. A text edit is a visual element + in the GUI. In Qt, we call such elements widgets. Examples of + other widgets are scroll bars, labels, and radio buttons. A widget + can also be a container for other widgets; a dialog or a main + application window, for example. + + Line 9 shows the text edit on the screen in its own window frame. + Since widgets also function as containers (for instance a + QMainWindow, which has toolbars, menus, a status bar, and a few + other widgets), it is possible to show a single widget in its own + window. Widgets are not visible by default; the function + \l{QWidget::}{show()} makes the widget visible. + + Line 11 makes the QApplication enter its event loop. When a Qt + application is running, events are generated and sent to the + widgets of the application. Examples of events are mouse presses + and key strokes. When you type text in the text edit widget, it + receives key pressed events and responds by drawing the text + typed. + + To run the application, open a command prompt, and enter the + directory in which you have the \c .cpp file of the program. The + following shell commands build the program. + + \code + vattekar@positive:~/testing/gssnippets/part1$ qmake -project + vattekar@positive:~/testing/gssnippets/part1$ qmake + vattekar@positive:~/testing/gssnippets/part1$ make + \endcode + + This will leave an executable in the \c part1 directory (note that + on Windows, you may have to use \c nmake instead of \c make. Also, + the executable will be placed in part1/debug or part1/release). \c + qmake is Qt's build tool, which takes a configuration file. \c + qmake generates this for us when given the \c{-project} argument. + Given the configuration file (suffixed .pro), \c qmake produces a + \c make file that will build the program for you. We will look + into writing our own \c .pro files later. + + \section2 Learn More + + \table + \header + \o About + \o Here + \row + \o Widgets and Window Geometry + \o \l{Window and Dialog Widgets} + \row + \o Events and event handling + \o \l{The Event System} + \endtable + + \section1 Adding a Quit Button + + In a real application, you will normally need more than one + widget. We will now introduce a QPushButton beneath the text edit. + The button will exit the Notepad application when pushed (i.e., + clicked on with the mouse). + + \image gs2.png + + Let's take a look at the code. + + \code + 1 #include <QtGui> + 2 + 3 int main(int argv, char **args) + 4 { + 5 QApplication app(argv, args); + 6 + 7 QTextEdit textEdit; + 8 QPushButton quitButton("Quit"); + 9 +10 QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit())); +11 +12 QVBoxLayout layout; +13 layout.addWidget(&textEdit); +14 layout.addWidget(&quitButton); +15 +16 QWidget window; +17 window.setLayout(&layout); +18 +19 window.show(); +20 +21 return app.exec(); +22 } + \endcode + + Line 1 includes QtGui, which contains all of Qt's GUI classes. + + Line 10 uses Qt's Signals and Slots mechanism to make the + application exit when the \gui {Quit button} is pushed. A slot is + a function that can be invoked at runtime using its name (as a + literal string). A signal is a function that when called will + invoke slots registered with it; we call that to connect the slot + to the signal and to emit the signal. + + \l{QApplication::}{quit()} is a slot of QApplication that exits + the application. \l{QPushButton::}{clicked()} is a signal that + QPushButton emits when it is pushed. The static + QObject::connect() function takes care of connecting the slot to + the signal. SIGNAL() and SLOT() are two macros that take the + function signatures of the signal and slot to connect. We also + need to give pointers to the objects that should send and receive + the signal. + + Line 12 creates a QVBoxLayout. As mentioned, widgets can contain + other widgets. It is possible to set the bounds (the location and + size) of child widgets directly, but it is usually easier to use a + layout. A layout manages the bounds of a widget's children. + QVBoxLayout, for instance, places the children in a vertical row. + + Line 13 and 14 adds the text edit and button to the layout. In + line 17, we set the layout on a widget. + + \section2 Learn More + + \table + \header + \o About + \o Here + \row + \o Signals and slots + \o \l{Signals & Slots} + \row + \o Layouts + \o \l{Layout Management}, + \l{Widgets and Layouts}, + \l{Layout Examples} + \row + \o The widgets that come with Qt + \o \l{Qt Widget Gallery}, + \l{Widget Examples} + \endtable + + \section1 Subclassing QWidget + + When the user wants to quit an application, you might want to + pop-up a dialog that asks whether he/she really wants to quit. In + this example, we subclass QWidget, and add a slot that we connect + to the \gui {Quit button}. + + \image gs3.png + + Let's look at the code: + + \code + 5 class Notepad : public QWidget + 6 { + 7 Q_OBJECT + 8 + 9 public: +10 Notepad(); +11 +12 private slots: +13 void quit(); +14 +15 private: +16 QTextEdit *textEdit; +17 QPushButton *quitButton; +18 }; + \endcode + + The \c Q_OBJECT macro must be first in the class definition, and + declares our class as a \c QObject (Naturally, it must also + inherit from QObject). A \l{QObject} adds several abilities to a + normal C++ class. Notably, the class name and slot names can be + queried at run-time. It is also possible to query a slot's + parameter types and invoke it. + + Line 13 declares the slot \c quit(). This is easy using the \c + slots macro. The \c quit() slot can now be connected to signals + with a matching signature (any signal that takes no parameters). + + Instead of setting up the GUI and connecting the slot in the \c + main() function, we now use \c{Notepad}'s constructor. + + \code + Notepad::Notepad() + { + textEdit = new QTextEdit; + quitButton = new QPushButton(tr("Quit")); + + connect(quitButton, SIGNAL(clicked()), this, SLOT(quit())); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(textEdit); + layout->addWidget(quitButton); + + setLayout(layout); + + setWindowTitle(tr("Notepad")); + } + \endcode + + As you saw in the class definition, we use pointers to our \l + {QObject}s (\c textEdit and \c quitButton). As a rule, you should + always allocate \l{QObject}s on the heap and never copy them. + + We now use the function \l{QObject::}{tr()} around our user + visible strings. This function is necessary when you want to + provide your application in more than one language (e.g. English + and Chinese). We won't go into details here, but you can follow + the \c {Qt Linguist} link from the learn more table. + + \section2 Learn More + + \table + \header + \o About + \o Here + \row + \o tr() and internationalization + \o \l{Qt Linguist Manual}, + \l{Writing Source Code for Translation}, + \l{Hello tr() Example}, + \l{Internationalization with Qt} + \row + \o QObjects and the Qt Object model (This is essential to understand Qt) + \o \l{Object Model} + \row + \o qmake and the Qt build system + \o \l{qmake Manual} + \endtable + + \section2 Creating a .pro file + + For this example, we write our own \c .pro file instead of + using \c qmake's \c -project option. + + \code + HEADERS = notepad.h + SOURCES = notepad.cpp \ + main.cpp + \endcode + + The following shell commands build the example. + + \code + vattekar@positive:~/testing/gssnippets/part3$ qmake + vattekar@positive:~/testing/gssnippets/part3$ make + \endcode + + \section1 Using a QMainWindow + + Many applications will benefit from using a QMainWindow, which has + its own layout to which you can add a menu bar, dock widgets, tool + bars, and a status bar. QMainWindow has a center area that can be + occupied by any kind of widget. In our case, we will place our + text edit there. + + \image gs4.png + + Let's look at the new \c Notepad class definition. + + \code + #include <QtGui> + + class Notepad : public QMainWindow + { + Q_OBJECT + + public: + Notepad(); + + private slots: + void open(); + void save(); + void quit(); + + private: + QTextEdit *textEdit; + + QAction *openAction; + QAction *saveAction; + QAction *exitAction; + + QMenu *fileMenu; + }; + \endcode + + We include two more slots that can save and open a document. We + will implement these in the next section. + + Often, in a main window, the same slot should be invoked by + several widgets. Examples are menu items and buttons on a tool + bar. To make this easier, Qt provides QAction, which can be given + to several widgets, and be connected to a slot. For instance, both + QMenu and QToolBar can create menu items and tool buttons from the + same \l{QAction}s. We will see how this works shortly. + + As before, we use the \c {Notepad}s constructor to set up the + GUI. + + \code + Notepad::Notepad() + { + saveAction = new QAction(tr("&Open"), this); + saveAction = new QAction(tr("&Save"), this); + exitAction = new QAction(tr("E&xit"), this); + + connect(openAction, SIGNAL(triggered()), this, SLOT(open())); + connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(openAction); + fileMenu->addAction(saveAction); + fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + textEdit = new QTextEdit; + setCentralWidget(textEdit); + + setWindowTitle(tr("Notepad")); + } + \endcode + + \l{QAction}s are created with the text that should appear on the + widgets that we add them to (in our case, menu items). If we also + wanted to add them to a tool bar, we could have given + \l{QIcon}{icons} to the actions. + + When a menu item is clicked now, the item will trigger the action, + and the respective slot will be invoked. + + \section2 Learn More + + \table + \header + \o About + \o Here + \row + \o Main windows and main window classes + \o \l{Application Main Window}, + \l{Main Window Examples} + \row + \o MDI applications + \o QMdiArea, + \l{MDI Example} + \endtable + + \section1 Saving and Loading + + In this example, we will implement the functionality of the \c + open() and \c save() slots that we added in the previous example. + + \image gs5.png + + Let's start with the \c open() slot: + + \code + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", + tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); + + if (fileName != "") { + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, tr("Error"), + tr("Could not open file")); + return; + } + QString contents = file.readAll().constData(); + textEdit->setPlainText(contents); + file.close(); + } + \endcode + + The first step is asking the user for the name of the file to + open. Qt comes with QFileDialog, which is a dialog from which the + user can select a file. The image above shows the dialog on + Kubuntu. The static \l{QFileDialog::}{getOpenFileName()} function + displays a modal file dialog, and does not return until the user + has selected a file. It returns the file path of the file + selected, or an empty string if the user canceled the dialog. + + If we have a file name, we try to open the file with + \l{QIODevice::}{open()}, which returns true if the file could be + opened. We won't go into error handling here, but you can follow + the links from the learn more section. If the file could not be + opened, we use QMessageBox to display a dialog with an error + message (see the QMessageBox class description for further + details). + + Actually reading in the data is trivial using the + \l{QIODevice::}{readAll()} function, which returns all data in the + file in a QByteArray. The \l{QByteArray::}{constData()} returns all + data in the array as a const char*, which QString has a + constructor for. The contents can then be displayed in the text + edit. We then \l{QIODevice::}{close()} the file to return the file + descriptor back to the operating system. + + Now, let's move on to the the \c save() slot. + + \code + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", + tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); + + if (fileName != "") { + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + // error message + } else { + QTextStream stream(&file); + stream << textEdit->toPlainText(); + stream.flush(); + file.close(); + } + } + \endcode + + When we write the contents of the text edit to the file, we use + the QTextStream class, which wraps the QFile object. The text + stream can write QStrings directly to the file; QFile only accepts + raw data (char*) with the \l{QIODevice::}{write()} functions of + QIODevice. + + \section2 Learn More + + \table + \header + \o About + \o Here + \row + \o Files and I/O devices + \o QFile, QIODevice + \endtable + + \omit + \section1 Moving On + + This may not be true for the first release. + The Qt documentation comes with three getting started guides. You + have come to the end of the first, which concerns itself with + basic Qt concepts. We also have guides covering intermediate and + advanced topics. They are found here: You may also have noticed that the learn more sections in + this guide frequently linked to them. + Basic Qt Architecture + \endomit +*/ + diff --git a/doc/src/images/gs1.png b/doc/src/images/gs1.png Binary files differnew file mode 100644 index 0000000..875dd39 --- /dev/null +++ b/doc/src/images/gs1.png diff --git a/doc/src/images/gs2.png b/doc/src/images/gs2.png Binary files differnew file mode 100644 index 0000000..aaba3b2 --- /dev/null +++ b/doc/src/images/gs2.png diff --git a/doc/src/images/gs3.png b/doc/src/images/gs3.png Binary files differnew file mode 100644 index 0000000..5e474e3 --- /dev/null +++ b/doc/src/images/gs3.png diff --git a/doc/src/images/gs4.png b/doc/src/images/gs4.png Binary files differnew file mode 100644 index 0000000..7a8237e --- /dev/null +++ b/doc/src/images/gs4.png diff --git a/doc/src/images/gs5.png b/doc/src/images/gs5.png Binary files differnew file mode 100644 index 0000000..b3cab60 --- /dev/null +++ b/doc/src/images/gs5.png diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index bd3ac05..4acf212 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -40,7 +40,7 @@ </div> <div class="section sectionlist"> <ul> - <li><a href="how-to-learn-qt.html">Getting started</a></li> + <li><a href="gettingstarted.html">Getting started</a></li> <li><a href="installation.html">Installation</a></li> <li><a href="how-to-learn-qt.html">How to learn Qt</a></li> <li><a href="tutorials.html">Tutorials</a></li> diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index febcdef..ba757fc 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1070,6 +1070,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) store.storeSignal.value = output->indexForString(v->value.asScript().trimmed()); store.storeSignal.context = ctxt.stack; + store.storeSignal.name = output->indexForByteArray(prop->name); output->bytecode << store; } @@ -2765,6 +2766,7 @@ bool QDeclarativeCompiler::completeComponentBuild() bool isSharable = sharableTest.isSharable(expression); QDeclarativeRewrite::RewriteBinding rewriteBinding; + rewriteBinding.setName('$'+binding.property->name); expression = rewriteBinding(expression); quint32 length = expression.length(); diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 9935e38..585fb69 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -604,6 +604,7 @@ QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QDeclarativeRewrite::RewriteBinding rewriteBinding; + rewriteBinding.setName(name); bool ok = true; const QString code = rewriteBinding(expression, &ok); if (ok) diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index b629e20..1700335 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -194,6 +194,7 @@ public: QString url; // This is a QString for a reason. QUrls are slooooooow... int line; + QByteArray name; //function name, hint for the debugger }; QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data) diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index d1a0a0a..f0b032c 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -292,7 +292,8 @@ public: struct StoreSignalInstruction { int signalIndex; int value; - int context; + short context; + int name; }; struct AssignSignalObjectInstruction { int signal; diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp index 3d40e77..bc9a114 100644 --- a/src/declarative/qml/qdeclarativerewrite.cpp +++ b/src/declarative/qml/qdeclarativerewrite.cpp @@ -102,7 +102,7 @@ QString RewriteBinding::rewrite(QString code, unsigned position, unsigned startOfStatement = node->firstSourceLocation().begin() - _position; unsigned endOfStatement = node->lastSourceLocation().end() - _position; - _writer->replace(startOfStatement, 0, QLatin1String("(function() { ")); + _writer->replace(startOfStatement, 0, QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ")); _writer->replace(endOfStatement, 0, QLatin1String(" })")); if (rewriteDump()) { diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h index 33b168c..6f3c46e 100644 --- a/src/declarative/qml/qdeclarativerewrite_p.h +++ b/src/declarative/qml/qdeclarativerewrite_p.h @@ -78,10 +78,14 @@ class RewriteBinding: protected AST::Visitor { unsigned _position; TextWriter *_writer; + QByteArray _name; public: QString operator()(const QString &code, bool *ok = 0); + //name of the function: used for the debugger + void setName(const QByteArray &name) { _name = name; } + protected: using AST::Visitor::visit; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 3247f85..4e41c22 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -621,14 +621,15 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, case QDeclarativeInstruction::StoreSignal: { QObject *target = stack.top(); - QObject *context = stack.at(stack.count() - 1 - instr.assignBinding.context); - + QObject *context = stack.at(stack.count() - 1 - instr.storeSignal.context); + QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex); QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target); QDeclarativeExpression *expr = new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value)); expr->setSourceLocation(comp->name, instr.line); + static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.storeSignal.name); bs->setExpression(expr); } break; diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js new file mode 100644 index 0000000..8decbf0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js @@ -0,0 +1,11 @@ + +function function2InScript(a) +{ + mainRectangle.foo = a; +} + + +function functionInScript(a , b) +{ + function2InScript(a + b); +} diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml new file mode 100644 index 0000000..ad627ef --- /dev/null +++ b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml @@ -0,0 +1,27 @@ +import Qt 4.7 +import Qt.test 1.0 +import "backtrace1.js" as Script + +Rectangle { + id: mainRectangle + + property string foo: "Default"; + width: 200 + height: 200 + + + MyTestObject { + + function append(a, b) { + return a + " " + b; + } + + + id: testObject; + someProperty: append("Hello", mainRectangle.foo) + + onSignaled: { + Script.functionInScript(value , "b"); + } + } +} diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro new file mode 100644 index 0000000..c2d30a0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro @@ -0,0 +1,20 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative script +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativescriptdebugging.cpp +INCLUDEPATH += ../shared + +# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage +# LIBS += -lgcov + +symbian: { + importFiles.sources = data + importFiles.path = . + DEPLOYMENT = importFiles +} else { + DEFINES += SRCDIR=\\\"$$PWD\\\" +} + +CONFIG += parallel_test + diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp b/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp new file mode 100644 index 0000000..b0743c0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qtest.h> +#include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtDeclarative/qdeclarativecontext.h> +#include <QtCore/QDir> +#include <QtScript/QScriptEngineAgent> +#include <private/qdeclarativeengine_p.h> + +class MyTestObject : public QObject { + Q_OBJECT + Q_PROPERTY(QString someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged) + +public: + QString someProperty() { return _someProperty; } + void setSomeProperty(const QString &p) { _someProperty = p; } + QString _someProperty; + + void emitSignal(const QString &value) { emit signaled(value); } + +signals: + void signaled(const QString &value); + void somePropertyChanged(); +}; + + +class BtAgent : public QScriptEngineAgent { +public: + BtAgent(QScriptEngine *engine) : QScriptEngineAgent(engine) + { count = 0; engine->setAgent(this); } + + QStringList bt; + int count; + int breakpoint; + void positionChange(qint64 , int lineNumber, int ) + { + if(lineNumber == breakpoint) { + count++; + bt = engine()->currentContext()->backtrace(); + } + } +}; + + + +/* +This test covers evaluation of ECMAScript expressions and bindings from within +QML. This does not include static QML language issues. + +Static QML language issues are covered in qmllanguage +*/ +inline QUrl TEST_FILE(const QString &filename) +{ + QFileInfo fileInfo(__FILE__); + return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename)); +} + +inline QUrl TEST_FILE(const char *filename) +{ + return TEST_FILE(QLatin1String(filename)); +} + +class tst_qdeclarativescriptdebugging : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativescriptdebugging() {} + +private slots: + void initTestCase(); + void backtrace1(); +}; + +void tst_qdeclarativescriptdebugging::initTestCase() +{ + qmlRegisterType<MyTestObject>("Qt.test", 1,0, "MyTestObject"); +} + +void tst_qdeclarativescriptdebugging::backtrace1() +{ + { + QDeclarativeEngine engine; + QUrl file = TEST_FILE("backtrace1.qml"); + QDeclarativeComponent component(&engine, file); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create()); + QVERIFY(item); + MyTestObject *obj = item->findChild<MyTestObject *>(); + QVERIFY(obj); + QCOMPARE(obj->someProperty(), QString("Hello Default")); + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine); + BtAgent agent(&ep->scriptEngine); + agent.breakpoint = 16; + + obj->emitSignal("blah"); + QCOMPARE(obj->someProperty(), QString("Hello blahb")); + QCOMPARE(agent.count, 1); + + QStringList expected; + expected << "append(a = 'Hello', b = 'blahb') at @PREFIX@/backtrace1.qml:16" + << "$someProperty() at @PREFIX@/backtrace1.qml:21" + << "function2InScript(a = 'blahb') at @PREFIX@/backtrace1.js:4" + << "functionInScript(a = 'blah', b = 'b') at @PREFIX@/backtrace1.js:10" + << "onSignaled() at @PREFIX@/backtrace1.qml:24" + << "<global>() at -1"; + expected.replaceInStrings("@PREFIX@", file.toString().section('/', 0, -2)); + QCOMPARE(agent.bt, expected); + } +} + + +QTEST_MAIN(tst_qdeclarativescriptdebugging) + +#include "tst_qdeclarativescriptdebugging.moc" |