diff options
-rw-r--r-- | doc/src/getting-started/gettingstarted.qdoc | 491 | ||||
-rw-r--r-- | doc/src/getting-started/gettingstartedqml.qdoc | 1050 | ||||
-rw-r--r-- | doc/src/getting-started/gettingstartedqt.qdoc | 517 | ||||
-rw-r--r-- | doc/src/platforms/platform-notes.qdocinc | 0 | ||||
-rw-r--r-- | examples/network/bearercloud/bluetooth.svg | 24 | ||||
-rw-r--r-- | examples/network/bearercloud/cell.svg | 25 | ||||
-rw-r--r-- | examples/network/bearercloud/cloud.cpp | 11 | ||||
-rw-r--r-- | examples/network/bearercloud/gprs.svg | 199 | ||||
-rw-r--r-- | examples/network/bearercloud/icons.qrc | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | examples/network/bearercloud/lan.svg | 109 | ||||
-rw-r--r-- | examples/network/bearercloud/umts.svg | 200 | ||||
-rw-r--r-- | src/plugins/bearer/connman/qconnmanengine.cpp | 57 | ||||
-rw-r--r-- | src/plugins/bearer/connman/qconnmanservice_linux.cpp | 107 | ||||
-rw-r--r-- | src/plugins/bearer/connman/qconnmanservice_linux_p.h | 7 | ||||
-rw-r--r-- | tools/qdoc3/htmlgenerator.cpp | 6 |
15 files changed, 2220 insertions, 587 deletions
diff --git a/doc/src/getting-started/gettingstarted.qdoc b/doc/src/getting-started/gettingstarted.qdoc index 9b6b5d5..145982b 100644 --- a/doc/src/getting-started/gettingstarted.qdoc +++ b/doc/src/getting-started/gettingstarted.qdoc @@ -26,491 +26,12 @@ ****************************************************************************/ /*! - \page gettingstarted.html + \title Getting Started Guides - \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 us 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 - qmake -project - qmake - 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 us 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 us 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 will not 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 - qmake - 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 us 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 - - We will 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 will not 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 us 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 + \group gettingStarted + + Following is a list. + \generatelist{related} + */ diff --git a/doc/src/getting-started/gettingstartedqml.qdoc b/doc/src/getting-started/gettingstartedqml.qdoc new file mode 100644 index 0000000..2bfb71c --- /dev/null +++ b/doc/src/getting-started/gettingstartedqml.qdoc @@ -0,0 +1,1050 @@ +/**************************************************************************** +** +** 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 qml-textEditor.html + + \title Getting Started programming with QML + \ingroup gettingStarted + + Welcome to the world of QML - the declarative UI language. In this Getting + Started guide, we will create a simple text editor application using QML. + After reading this guide, you should be ready to develop your own applications + using QML and Qt C++. + + \section1 QML to Build User Interfaces + + The application we are building is a simple text editor that will load, save, + and perform some text manipulation. This guide will consist of two parts. The + first part will involve designing the application layout and behaviors using + declarative language in QML. For the second part, file loading and saving will + be implemented using Qt C++. Using + \l {The Meta-Object System}{Qt's Meta-Object System}, we can expose C++ functions + as properties that QML elements can use. Utilizing QML and Qt C++, we can + efficiently decouple the interface logic from the application logic. + + \image qml-texteditor5_editmenu.png + + To run the QML example code, merely provide the included \l{QML Viewer}{qmlviewer} + tool with the QML file as the argument. The C++ portion of this tutorial assumes + that the reader possesses basic knowledge of Qt's compilation procedures. + + Tutorial chapters: + \list 1 + \o \l {Defining a Button and a Menu}{Defining a Button and a Menu} + \o \l {Implementing a Menu Bar}{Implementing a Menu Bar} + \o \l {Building a Text Editor}{Building a Text Editor} + \o \l {Decorating the Text Editor}{Decorating the Text Editor} + \o \l {Extending QML using Qt C++}{Extending QML using Qt C++} + \endlist + + \section1 Defining a Button and a Menu + + \section2 Basic Component - a Button + + We start our text editor by building a button. Functionally, a button has a mouse + sensitive area and a label. Buttons perform actions when a user presses the button. + + In QML, the basic visual item is the \l {Rectangle}{Rectangle} element. The + \c Rectangle element has properties to control the element's appearance and location. + + \code + import Qt 4.7 + Rectangle { + id: simplebutton + color: "grey" + width: 150; height: 75 + + Text{ + id: buttonLabel + anchors.centerIn: parent + text: "button label" + } + } + \endcode + + First, the \c { import Qt 4.7 } allows the qmlviewer tool to import the QML elements + we will later use. This line must exist for every QML file. Notice that the version + of Qt modules is included in the import statement. + + This simple rectangle has a unique identifier, \c simplebutton, which is bound to the + id property. The \c Rectangle element's properties are bound to values by listing the + property, followed by a colon, then the value. In the code sample, the color \c grey + is bound to the the Rectangle's \c color property. Similarly, we bind the \c width + and \c height of the Rectangle. + + The \l {Text}{Text} element is a non-editable text field. We name this \c Text element + \c buttonLabel. To set the string content of the Text field, we bind a value to the + \c text property. The label is contained within the Rectangle and in order to center + it in the middle, we assign the \c anchors of the Text element to its parent, which + is called \c simplebutton. Anchors may bind to other items' anchors, allowing layout + assignments simpler. + + We shall save this code as \c SimpleButton.qml. Running qmlviewer with the file as the + argument will display the grey rectangle with a text label. + + \image qml-texteditor1_simplebutton.png + + To implement the button click functionality, we can use QML's event handling. QML's event + handling is very similar to \l {Signals & Slots}{Qt's signal and slot} mechanism. Signals + are emitted and the connected slot is called. + + \code + Rectangle{ + id:simplebutton + ... + + MouseArea{ + id: buttonMouseArea + + anchors.fill: parent //anchor all sides of the mouse area to the rectangle's anchors + //onClicked handles valid mouse button clicks + onClicked: console.log(buttonLabel.text + " clicked" ) + } + } + \endcode + + We include a \l{MouseArea} element in our simplebutton. \c MouseArea elements describe + the interactive area where mouse movements are detected. For our button, we anchor the + whole MouseArea to its parent, which is \c simplebutton. The \c anchors.fill syntax is + one way of accessing a specific property called \c fill inside a group of properties + called \c anchors. QML uses \l {Anchor-based Layout in QML}{anchor based layouts} where + items can anchor to another item, creating robust layouts. + + The \c MouseArea has many signal handlers that are called during mouse movements within + the specfied \c MouseArea boundaries. One of them is \c onClicked and it is called + whenever the acceptable mouse button is clicked, the left click being the default. We + can bind actions to the onClicked handler. In our example, \c console.log() outputs text + whenever the mouse area is clicked. The function \c console.log() is a useful tool for + debugging purposes and for outputting text. + + The code in \c SimpleButton.qml is sufficient to display a button on the screen and + output text whenever it is clicked with a mouse. + + \code + Rectangle { + id:Button + ... + + property color buttonColor: "lightblue" + property color onHoverColor: "gold" + property color borderColor: "white" + + signal buttonClick() + onButtonClick: { + console.log(buttonLabel.text + " clicked" ) + } + + MouseArea{ + onClicked: buttonClick() + hoverEnabled: true + onEntered: parent.border.color = onHoverColor + onExited: parent.border.color = borderColor + } + + //determines the color of the button by using the conditional operator + color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor + } + \endcode + + A fully functioning button is in \c Button.qml. The code snippets in this article + have some code omitted, denoted by ellipses because they were either introduced + earlier in the previous sections or irrelevant to the current code discussion. + + Custom properties are declared using the \c {property type name} syntax. In the + code, the property \c buttonColor, of type \c color, is declared and bound to + the value \c{"lightblue"}. The \c buttonColor is later used in a conditional + operation to determine the buttons's fill color. Note that property value + assignment is possible using the \c= equals sign, in addition to value binding + using the \c : colon character. Custom properties allow internal items to be + accessible outside of the Rectangle's scope. There are basic + \l{QML Basic Types}{QML types} such as \c int, \c string, \c real, as well as + a type called \c variant. + + By binding the \c onEntered and \c onExited signal handlers to colors, the + button's border will turn yellow when the mouse hovers above the button and + reverts the color when the mouse exits the mouse area. + + A \c buttonClick() signal is declared in \c Button.qml by placing the \c signal + keyword in front of the signal name. All signals have their handlers automatically + created, their names starting with \c on. As a result, the \c onButtonClick is + \c buttonClick's handler. The \c onButtonClick is then assigned an action to + perform. In our button example, the \c onClicked mouse handler will simply call + \c onButtonClick, which displays a text. The \c onButtonClick enables outside + objects to access the \c {Button}'s mouse area easily. For example, items may + have more than one \c MouseArea declarations and a \c buttonClick signal can + make the distinction between the several \c MouseArea signal handlers better. + + We now have the basic knowledge to implement items in QML that can handle + basic mouse movements. We created a \c Text label inside a \c Rectangle, + customized its properties, and implemented behaviors that respond to mouse + movements. This idea of creating elements within elements is repeated + throughout the text editor application. + + This button is not useful unless used as a component to perform an action. + In the next section, we will soon create a menu containing several of these + buttons. + + \image qml-texteditor1_button.png + + \section2 Creating a Menu Page + + Up to this stage, we covered how to create elements and assign behaviors inside + a single QML file. In this section, we will cover how to import QML elements and how + to reuse some of the created components to build other components. + + Menus display the contents of a list, each item having the ability to perform an action. + In QML, we can create a menu in several ways. First, we will create a menu containing + buttons which will eventually perform different actions. The menu code is in + \c FileMenu.qml. + + \code + import Qt 4.7 \\import the main Qt QML module + import “folderName” \\import the contents of the folder + import “Button.qml” \\import a QML file + import “NewButton.qml” as ButtonModule \\import a QML file and give it a name + import “script.js” as Script \\import a Javascript file and name it as Script + \endcode + + To use the \c Button element in \c FileMenu.qml, we need to import \c Button.qml. + The syntax shown above, shows how to use the \c import keyword. However, the + \c {import Button.qml} is not necessary; qmlviewer will import all the contents + of the current directory. We can directly create a \c Button element by declaring + \c Button{}, similar to a \c Rectangle{} declaration. + + \code + In FileMenu.qml: + + Row{ + anchors.centerIn: parent + spacing: parent.width/6 + + Button{ + id: loadButton + buttonColor: "lightgrey" + label: "Load" + } + Button{ + buttonColor: "grey" + id: saveButton + label: "Save" + } + Button{ + id: exitButton + label: "Exit" + buttonColor: "darkgrey" + + onButtonClick: Qt.quit() + } + } + \endcode + + In \c FileMenu.qml, we declare three \c Button elements. They are declared + inside a \l {Row}{Row} element, a positioner that will position its children + along a vertical row. The \c Button declaration resides in Button.qml, + which is the same as the \c Button.qml we used in the previous section. + New property bindings can be declared within the newly created buttons, + effectively overwriting the properties set in \c Button.qml. The button + called \c exitButton will quit and close the window when it is clicked. + Note that the signal handler \c onButtonClick in \c Button.qml will be + called in addition to the \c onButtonClick handler in \c exitButton. + + \image qml-texteditor1_filemenu.png + + The \c Row declaration is declared in a \c Rectangle, creating a rectangle + container for the row of buttons. This additional rectangle creates an indirect + way of organizing the row of buttons inside a menu. + + The declaration of the edit menu is very similar at this stage. The menu has + buttons that have the labels: \c Copy, \c Paste, and \c {Select All}. + + \image qml-texteditor1_editmenu.png + + Armed with our knowledge of importing and customizing previously made + components, we may now combine these menu pages to create a menu bar, + consisting of buttons to select the menu, and look at how we may structure + data using QML. + + \section1 Implementing a Menu Bar + + Our text editor application will need a way to display menus using a menu bar. + The menu bar will switch the different menus and the user can choose which menu + to display. Menu switching implies that the menus need more structure than + merely displaying them in a row. QML uses models and views to structure data + and display the structured data. + + \section2 Using Data Models and Views + + QML has different \l {Data Models}{data views} that display + \l {Data Models}{data models}. Our menu bar will display the menus in a list, + with a header that displays a row of menu names. The list of menus are declared + inside a \c VisualItemModel. The \l{VisualItemModel}{\c VisualItemModel} + element contains items that already have views such as \c Rectangle elements + and imported UI elements. Other model types such as the \l {ListModel}{\c ListModel} + element need a delegate to display their data. + + We declare two visual items in the \c menuListModel, the \c FileMenu and the + \c EditMenu. We customize the two menus and display them using a + \l {ListView}{ListView}. The \c MenuBar.qml file contains the QML declarations + and a simple edit menu is defined in \c EditMenu.qml. + + \code + VisualItemModel{ + id: menuListModel + FileMenu{ + width: menuListView.width + height: menuBar.height + color: fileColor + } + EditMenu{ + color: editColor + width: menuListView.width + height: menuBar.height + } + } + \endcode + + The \l {ListView}{ListView} element will display a model according to a delegate. + The delegate may declare the model items to display in a \c Row element or display + the items in a grid. Our \c menuListModel already has visible items, therefore, + we do not need to declare a delegate. + + \code + ListView{ + id: menuListView + + //Anchors are set to react to window anchors + anchors.fill:parent + anchors.bottom: parent.bottom + width:parent.width + height: parent.height + + //the model contains the data + model: menuListModel + + //control the movement of the menu switching + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickDeceleration: 5000 + highlightFollowsCurrentItem: true + highlightMoveDuration:240 + highlightRangeMode: ListView.StrictlyEnforceRange + } + \endcode + + Additionally, \c ListView inherits from \l {Flickable}{\c Flickable}, making + the list respond to mouse drags and other gestures. The last portion of the + code above sets \c Flickable properties to create the desired flicking movement + to our view. In particular,the property \c highlightMoveDuration changes the + duration of the flick transition. A higher \c highlightMoveDuration value + results in slower menu switching. + + The \c ListView maintains the model items through an \c index and each visual + item in the model is accessible through the \c index, in the order of the + declaration. Changing the \c currentIndex effectively changes the highlighted + item in the \c ListView. The header of our menu bar exemplify this effect. + There are two buttons in a row, both changing the current menu when clicked. + The \c fileButton changes the current menu to the file menu when clicked, + the \c index being \c 0 because \c FileMenu is declared first in the + \c menuListModel. Similarly, the \c editButton will change the current + menu to the \c EditMenu when clicked. + + The \c labelList rectangle has \c z value of \c 1, denoting that it is displayed + at the front of the menu bar. Items with higher \c z values are displayed in front + of items with lower \c z values. The default \c z value is \c 0. + + \code + Rectangle{ + id: labelList + ... + z: 1 + Row{ + anchors.centerIn: parent + spacing:40 + Button{ + label: "File" + id: fileButton + ... + onButtonClick: menuListView.currentIndex = 0 + } + Button{ + id: editButton + label: "Edit" + ... + onButtonClick: menuListView.currentIndex = 1 + } + } + } + \endcode + + The menu bar we just created can be flicked to access the menus or by clicking + on the menu names at the top. Switching menu screens feel intuitive and responsive. + + \image qml-texteditor2_menubar.png + + */ + + /*! + \page qml-textEditor3.html + \title Building a Text Editor + + \section1 Declaring a TextArea + + Our text editor is not a text editor if it didn't contain an editable text area. + QML's \l {TextEdit}{TextEdit} element allows the declaration of a multi-line + editable text area. \l {TextEdit}{TextEdit} is different from a \l {Text}{Text} + element, which doesn't allow the user to directly edit the text. + + \code + TextEdit{ + id: textEditor + anchors.fill:parent + width:parent.width; height:parent.height + color:"midnightblue" + focus: true + + wrapMode: TextEdit.Wrap + + onCursorRectangleChanged: flickArea.ensureVisible(cursorRectangle) + } + \endcode + + The editor has its font color property set and set to wrap the text. The + \c TextEdit area is inside a flickable area that will scroll the text if the + text cursor is outside the visible area. The function \c ensureVisible() will + check if the cursor rectangle is outside the visible boundaries and move the + text area accordingly. QML uses Javascript syntax for its scripts, and as previously + mentioned, Javascript files can be imported and used within a QML file. + + \code + function ensureVisible(r){ + if (contentX >= r.x) + contentX = r.x; + else if (contentX+width <= r.x+r.width) + contentX = r.x+r.width-width; + if (contentY >= r.y) + contentY = r.y; + else if (contentY+height <= r.y+r.height) + contentY = r.y+r.height-height; + } + \endcode + + \section1 Combining Components for the Text Editor + + We are now ready to create the layout of our text editor using QML. The text + editor has two components, the menu bar we created and the text area. QML allows + us to reuse components, therefore making our code simpler, by importing components + and customizing when necessary. Our text editor splits the window into two; + one-third of the screen is dedicated to the menu bar and two-thirds of the screen + displays the text area. The menu bar is displayed in front of any other elements. + + \code + Rectangle{ + + id: screen + width: 1000; height: 1000 + + //the screen is partitioned into the MenuBar and TextArea. 1/3 of the screen is assigned to the MenuBar + property int partition: height/3 + + MenuBar{ + id:menuBar + height: partition + width:parent.width + z: 1 + } + + TextArea{ + id:textArea + anchors.bottom:parent.bottom + y: partition + color: "white" + height: partition*2 + width:parent.width + } + } + \endcode + + By importing reusable components, our \c TextEditor code looks much simpler. + We can then customize the main application, without worrying about properties + that already have defined behaviors. Using this approach, application layouts + and UI components can be created easily. + + \image qml-texteditor3_texteditor.png + + */ + + /*! + \page qml-textEditor4 + \title Decorating the Text Editor + \section1 Implementing a Drawer Interface + + Our text editor looks simple and we need to decorate it. Using QML, we can declare + transitions and animate our text editor. Our menu bar is occupying one-third of the + screen and it would be nice to have it only appear when we want it. + + We can add a drawer interface, that will contract or expand the menu bar when clicked. + In our implementation, we have a thin rectangle that responds to mouse clicks. The + \c drawer, as well as the application, has two sates: the "drawer is open" state and + the "drawer is closed" state. The \c drawer item is a strip of rectangle with a small + height. There is a nested \l {Image}{Image} element declaring that an arrow icon will + be centered inside the drawer. The drawer assigns a state to the whole application, + with the identifier \c screen, whenever a user clicks the mouse area. + + \code + Rectangle{ + id:drawer + height:15 + + Image{ + id: arrowIcon + source: "images/arrow.png" + anchors.horizontalCenter: parent.horizontalCenter + } + + MouseArea{ + id: drawerMouseArea + anchors.fill:parent + onClicked:{ + if (screen.state == "DRAWER_CLOSED"){ + screen.state = "DRAWER_OPEN" + } + else if (screen.state == "DRAWER_OPEN"){ + screen.state = "DRAWER_CLOSED" + } + } + ... + } + } + \endcode + + A state is simply a collection of configurations and it is declared in a + \l{State}{State} element. A list of states can be listed and bound to the + \c states property. In our application, the two states are called + \c DRAWER_CLOSED and \c DRAWER_OPEN. Item configurations are declared in + \l {PropertyChanges}{PropertyChanges} elements. In the \c DRAWER_OPEN state, + there are four items that will receive property changes. The first target, + \c menuBar, will change its \c y property to \c 0. Similarly, the \c textArea + will lower to a new position when the state is \c DRAWER_OPEN. The \c textArea, + the \c drawer, and the drawer's icon will undergo property changes to meet the + current state. + + \code + + states:[ + State{ + name: "DRAWER_OPEN" + PropertyChanges { target: menuBar; y:0} + PropertyChanges { target: textArea; y: partition + drawer.height} + PropertyChanges { target: drawer; y: partition} + PropertyChanges { target: arrowIcon; rotation: 180} + }, + State{ + name: "DRAWER_CLOSED" + PropertyChanges { target: menuBar; y:-partition} + PropertyChanges { target: textArea; y: drawer.height; height: screen.height - drawer.height} + PropertyChanges { target: drawer; y: 0} + PropertyChanges { target: arrowIcon; rotation: 0} + } + + ] + + \endcode + + State changes are abrupt and needs smoother transitions. Transitions between states + are defined using the \l {Transition}{Transition} element, which can then bind to + the item's \c transitions property. Our text editor has a state transition whenever + the state changes to either \c DRAWER_OPEN or \c DRAWER_CLOSED. Importantly, the + transition needs a \c from and a \c to state but for our transitions, we can use + the wild card \c * symbol to denote that the transition applies to all state changes. + + During transitions, we can assign animations to the property changes. Our + \c menuBar switches position from \c {y:0} to \c {y:-partition} and we can animate + this transition using the \l {NumberAnimation}{NumberAnimation} element. We declare + that the targets' properties will animate for a certain duration of time and using + a certain easing curve. An easing curve controls the animation rates and + interpolation behavior during state transitions. The easing curve we chose is + \l {PropertyAnimation::easing.type}{Easing.OutQuint}, which slows the movement near + the end of the animation. Pleae read \l {qdeclarativeanimation.html}{QML's Animation} + article. + + \code + transitions: [ + Transition{ + to: "*" + NumberAnimation { target: textArea; properties: "y, height"; duration: 100; easing.type: Easing.OutQuint } + NumberAnimation { target: menuBar; properties: "y"; duration: 100;easing.type: Easing.OutQuint } + NumberAnimation { target: drawer; properties: "y"; duration: 100;easing.type: Easing.OutQuint } + } + ] + \endcode + + Another way of animating property changes is by declaring a \l {Behavior}{Behavior} + element. A transition only works during state changes and \c Behavior can set an + animation for a general property change. In the text editor, the arrow has a + \c NumberAnimation animating its \c rotation property whenever the property changes. + + \code + In TextEditor.qml: + + Behavior{ + NumberAnimation{property: "rotation";easing.type: Easing.OutExpo } + } + \endcode + + Going back to our components with knowledge of states and animations, we can improve + the appearances of the components. In \c Button.qml, we can add \c color and \c scale + property changes when the button is clicked. Color types are animated using + \l {ColorAnimation}{ColorAnimation} and numbers are animated using + \l {NumberAnimation}{NumberAnimation}. The \c {on propertyName} syntax displayed below + is helpful when targeting a single property. + + \code + In Button.qml: + ... + + color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor + Behavior on color { ColorAnimation{ duration: 55} } + + scale: buttonMouseArea.pressed ? 1.1 : 1.00 + Behavior on scale { NumberAnimation{ duration: 55} } + \endcode + + Additionally, we can enhance the appearances of our QML components by adding color + effects such as gradients and opacity effects. Declaring a \l {Gradient}{Gradient} + element will override the \c color property of the element. You may declare a color + in the gradient using the \l {GradientStop}{GradientStop} element. The gradient is + positioned using a scale, between \c 0.0 and \c 1.0. + + \code + In MenuBar.qml + gradient: Gradient { + GradientStop { position: 0.0; color: "#8C8F8C" } + GradientStop { position: 0.17; color: "#6A6D6A" } + GradientStop { position: 0.98;color: "#3F3F3F" } + GradientStop { position: 1.0; color: "#0e1B20" } + } + \endcode + + This gradient is used by the menu bar to display a gradient simulating depth. + The first color starts at \c 0.0 and the last color is at \c 1.0. + + + \section2 Where to Go from Here + + We are finished building the user interface of a very simple text editor. + Going forward, the user interface is complete, and we can implement the + application logic using regular Qt and C++. QML works nicely as a prototyping + tool, separating the application logic away from the UI design. + + \image qml-texteditor4_texteditor.png + + \section1 Extending QML using Qt C++ + + Now that we have our text editor layout, we may now implement the text editor + functionalities in C++. Using QML with C++ enables us to create our application + logic using Qt. We can create a QML context in a C++ application using the + \l {Using QML in C++ Applications}{Qt's Declarative} classes and display the QML + elements using a Graphics Scene. Alternatively, we can export our C++ code into + a plugin that the \l {QML Viewer}{qmlviewer} tool can read. For our application, + we shall implement the load and save functions in C++ and export it as a plugin. + This way, we only need to load the QML file directly instead of running an executable. + + \section2 Exposing C++ Classes to QML + + We will be implementing file loading and saving using Qt and C++. C++ classes + and functions can be used in QML by registering them. The class also needs to be + compiled as a Qt plugin and the QML file will need to know where the plugin is located. + + For our application, we need to create the following items: + \list 1 + \o \c Directory class that will handle directory related operations + \o \c File class which is a QObject, simulating the list of files in a directory + \o plugin class that will register the class to the QML context + \o Qt project file that will compile the plugin + \o A \c qmldir file telling the qmlviewer tool where to find the plugin + \endlist + + \section2 Building a Qt Plugin + + To build a plugin, we need to set the following in a Qt project file. First, + the necessary sources, headers, and Qt modules need to be added into our + project file. All the C++ code and project files are in the \c filedialog + directory. + + \code + In cppPlugins.pro: + + TEMPLATE = lib + CONFIG += qt plugin + QT += declarative + + DESTDIR += ../plugins + OBJECTS_DIR = tmp + MOC_DIR = tmp + + TARGET = FileDialog + + HEADERS += directory.h \ + file.h \ + dialogPlugin.h + + SOURCES += directory.cpp \ + file.cpp \ + dialogPlugin.cpp + \endcode + + In particular, we compile Qt with the \c declarative module and configure it as a + \c plugin, needing a \c lib template. We shall put the compiled plugin into the + parent's \c plugins directory. + + + \section2 Registering a Class into QML + + \code + In dialogPlugin.h: + + #include <QtDeclarative/QDeclarativeExtensionPlugin> + + class DialogPlugin : public QDeclarativeExtensionPlugin + { + Q_OBJECT + + public: + void registerTypes(const char *uri); + + }; + + \endcode + Our plugin class, \c DialogPlugin is a subclass of \l {QDeclarativeExtensionPlugin}{QDeclarativeExtensionPlugin}. We need to implement the inherited function, \l {QDeclarativeExtensionPlugin::registerTypes}{registerTypes}. The \c dialogPlugin.cpp file looks like this: + + \code + DialogPlugin.cpp: + + #include "dialogPlugin.h" + #include "directory.h" + #include "file.h" + #include <QtDeclarative/qdeclarative.h> + + void DialogPlugin::registerTypes(const char *uri){ + + qmlRegisterType<Directory>(uri, 1, 0, "Directory"); + qmlRegisterType<File>(uri, 1, 0,"File"); + } + + Q_EXPORT_PLUGIN2(FileDialog, DialogPlugin); + \endcode + + The \l {QDeclarativeExtensionPlugin::registerTypes}{registerTypes} + function registers our File and Directory classes into QML. This function + needs the class name for its template, a major version number, a minor version + number, and a name for our classes. + + We need to export the plugin using the \l {Q_EXPORT_PLUGIN2}{Q_EXPORT_PLUGIN2} + macro. Note that in our \c dialogPlugin.h file, we have the \l {Q_OBJECT}{Q_OBJECT} + macro at the top of our class. As well, we need to run \c qmake on the project + file to generate the necessary meta-object code. + + + \section2 Creating QML Properties in a C++ class + + We can create QML elements and properties using C++ and + \l {The Meta-Object System}{Qt's Meta-Object System}. We can implement + properties using slots and signals, making Qt aware of these properties. + These properties can then be used in QML. + + For the text editor, we need to be able to load and save files. Typically, + these features are contained in a file dialog. Fortunately, we can use + \l {QDir}{QDir}, \l {QFile}{QFile}, and \l {QTextStream}{QTextStream} to + implement directory reading and input/output streams. + + \code + class Directory : public QObject{ + + Q_OBJECT + + Q_PROPERTY(int filesCount READ filesCount CONSTANT) + Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged) + Q_PROPERTY(QString fileContent READ fileContent WRITE setFileContent NOTIFY fileContentChanged) + Q_PROPERTY(QDeclarativeListProperty<File> files READ files CONSTANT ) + + ... + \endcode + + The \c Directory class uses Qt's Meta-Object System to register properties it + needs to accomplish file handling. The \c Directory class is exported as a plugin + and is useable in QML as the \c Directory element. Each of the listed properties + using the \l {Q_PROPERTY()}{Q_PROPERTY} macro is a QML property. + + The \l {Q_PROPERTY()} {Q_PROPERTY} declares a property as well as its read and + write functions into Qt's Meta-Object System. For example, the \c filename + property, of type \l {QString}{QString}, is readable using the \c filename() + function and writable using the function \c setFilename(). Additionally, there + is a signal associated to the filename property called \c filenameChanged(), + which is emitted whenever the property changes. The read and write functions + are declared as \c public in the header file. + + Similarly, we have the other properties declared according to their uses. The + \c filesCount property indicates the number of files in a directory. The filename + property is set to the currently selected file's name and the loaded/saved file + content is stored in \c fileContent property. + + \code + Q_PROPERTY(QDeclarativeListProperty<File> files READ files CONSTANT ) + \endcode + + The \c files list property is a list of all the filtered files in a directory. + The \c Directory class is implemented to filter out invalid text files; only + files with a \c .txt extension are valid. Further, \l {QLists}{QLists} can be + used in QML files by declaring them as a \c QDeclarativeListProperty in C++. + The templated object needs to inherit from a \l {QObject}{QObject}, therefore, + the \c File class must also inherit from \c QObject. In the \c Directory class, + the list of \c File objects is stored in a \c QList called \c m_fileList. + + \code + class File : public QObject{ + + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + + ... + }; + \endcode + + The properties can then be used in QML as part of the \c Directory element's + properties. Note that we do not have to create an identifier \c id property + in our C++ code. + + \code + Directory{ + id: directory + + filesCount + filename + fileContent + files + + files[0].name + } + + \endcode + + Because QML uses Javascript's syntax and structure, we can iterate through + the list of files and retrieve its properties. To retrieve the first file's + name property, we can call \c { files[0].name }. + + Regular C++ functions are also accessible from QML. The file loading and saving + functions are implemented in C++ and declared using the + \l {Q_INVOKABLE}{Q_INVOKABLE} macro. Alternatively, we can declare the functions + as a \c slot and the functions will be accessible from QML. + + \code + In Directory.h: + + Q_INVOKABLE void saveFile(); + Q_INVOKABLE void loadFile(); + \endcode + + The \c Directory class also has to notify other objects whenever the directory + contents change. This feature is performed using a \c signal. As previously + mentioned, QML signals have a corresponding handler with their names prepended + with \c on. The signal is called \c directoryChanged and it is emitted whenever + there is a directory refresh. The refresh simply reloads the directory contents + and updates the list of valid files in the directory. QML items can then be + notified by attaching an action to the \c onDirectoryChanged signal handler. + + The \c list properties need to be explored further. This is because list + properties use callbacks to access and modify the list contents. The list + property is of type \c QDeclarativeListProperty<File>. Whenever the list + is accessed, the accessor function needs to return a + \c QDeclarativeListProperty<File>. The template type, \c File, needs to be a + \c QObject derivative. Further, to create the + \l {QDeclarativeListProperty}{QDeclarativeListProperty}, the list's accessor + and modifiers need to be passed to the consructor as function pointers. The list, + a \c QList in our case, also needs to be a list of \c File pointers. + + The constructor of \l {QDeclarativeListProperty}{QDeclarativeListProperty} + constructor and the \c Directory implementation: + \code + QDeclarativeListProperty ( QObject * object, void * data, AppendFunction append, CountFunction count = 0, AtFunction at = 0, ClearFunction clear = 0 ) + QDeclarativeListProperty<File>( this, &m_fileList, &appendFiles, &filesSize, &fileAt, &clearFilesPtr ); + \endcode + + The constructor passes pointers to functions that will append the list, count + the list, retrieve the item using an index, and empty the list. Only the append + function is mandatory. Note that the function pointers must match the definition + of \l {QDeclarativeListProperty::AppendFunction}{AppendFunction}, + \l {QDeclarativeListProperty::CountFunction}{CountFunction}, + \l {QDeclarativeListProperty::AtFunction}{AtFunction}, or + \l {QDeclarativeListProperty::ClearFunction}{ClearFunction}. + + \code + void appendFiles(QDeclarativeListProperty<File> * property, File * file) + File* fileAt(QDeclarativeListProperty<File> * property, int index) + int filesSize(QDeclarativeListProperty<File> * property) + void clearFilesPtr(QDeclarativeListProperty<File> *property) + \endcode + + To simplify our file dialog, the \c Directory class filters out invalid text + files, which are files that do not have a \c .txt extension. If a file name + doesn't have the \c .txt extension, then it won't be seen in our file dialog. + Also, the implementation makes sure that saved files have a \c .txt extension in + the file name. \c Directory uses \l {QTextStream}{QTextStream} to read the file + and to output the file contents to a file. + + With our \c Directory element, we can retrieve the files as a list, know how many + text files is in the application directory, get the file's name and content as a + string, and be notified whenever there are changes in the directory contents. + + To build the plugin, run \c qmake on the \c cppPlugins.pro project file, then run + \c make to build and transfer the plugin to the \c plugins directory. + + + \section2 Importing a Plugin in QML + + The qmlviewer tool imports files that are in the same directory as the + application. We can also create a \c qmldir file containing the locations of + QML files we wish to import. The \c qmldir file can also store locations of + plugins and other resources. + + \code + In qmldir: + + Button ./Button.qml + FileDialog ./FileDialog.qml + TextArea ./TextArea.qml + TextEditor ./TextEditor.qml + EditMenu ./EditMenu.qml + + plugin FileDialog plugins + \endcode + + The plugin we just created is called \c FileDialog, as indicated by the + \c TARGET field in the project file. The compiled plugin is in the \c plugins directory. + + + \section2 Integrating a File Dialog into the File Menu + + Our \c FileMenu needs to display the \c FileDialog element, containing a list of + the text files in a directory thus allowing the user to select the file by + clicking on the list. We also need to assign the save, load, and new buttons + to their respective actions. The FileMenu contains an editable text input to + allow the user to type a file name using the keyboard. + + The \c Directory element is used in the \c FileMenu.qml file and it notifies the + \c FileDialog element that the directory refreshed its contents. This notification + is performed in the signal handler, \c onDirectoryChanged. + + \code + In FileMenu.qml: + + Directory{ + id:directory + filename: textInput.text + onDirectoryChanged: fileDialog.notifyRefresh() + } + \endcode + + Keeping with the simplicity of our application, the file dialog will always be + visible and will not display invalid text files, which do not have a \c .txt + extension to their filenames. + + \code + In FileDialog.qml: + + signal notifyRefresh() + onNotifyRefresh: dirView.model = directory.files + \endcode + + The \c FileDialog element will display the contents of a directory by reading its + list property called \c files. The files are used as the model of a + \l {GridView}{GridView} element, which displays data items in a grid according + to a delegate. The delegate handles the appearance of the model and our file + dialog will simply create a grid with text centered in the middle. Clicking on + the file name will result in the appearance of a rectangle to highlight the file + name. The \c FileDialog is notified whenever the \c notifyRefresh signal is emitted, + reloading the files in the directory. + + \code + In FileMenu.qml: + + Button{ + id: newButton + label: "New" + onButtonClick:{ + textArea.textContent = "" + } + } + Button{ + id: loadButton + label: "Load" + onButtonClick:{ + directory.filename = textInput.text + directory.loadFile() + textArea.textContent = directory.fileContent + } + } + Button{ + id: saveButton + label: "Save" + onButtonClick:{ + directory.fileContent = textArea.textContent + directory.filename = textInput.text + directory.saveFile() + } + } + Button{ + id: exitButton + label: "Exit" + onButtonClick:{ + Qt.quit() + } + } + \endcode + + Our \c FileMenu can now connect to their respective actions. The \c saveButton + will transfer the text from the \c TextEdit onto the directory's \c fileContent + property, then copy its file name from the editable text input. Finally, the button + calls the \c saveFile() function, saving the file. The \c sloadButton has a similar + execution. Also, the \c New action will empty the contents of the \c TextEdit. + + Further, the \c EditMenu buttons are connected to the \c TextEdit functions to copy, + paste, and select all the text in the text editor. + + \image qml-texteditor5_filemenu.png + + \section1 Text Editor Completion + + \image qml-texteditor5_newfile.png + + The application can function as a simple text editor, able to accept text + and save the text into a file. The text editor can also load from a file and + perform text manipulation. + + +*/
\ No newline at end of file diff --git a/doc/src/getting-started/gettingstartedqt.qdoc b/doc/src/getting-started/gettingstartedqt.qdoc new file mode 100644 index 0000000..1b3770f --- /dev/null +++ b/doc/src/getting-started/gettingstartedqt.qdoc @@ -0,0 +1,517 @@ +/**************************************************************************** +** +** 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 gettingstartedqt.html + + \title Getting Started programming with Qt + \ingroup gettingStarted + + 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 us 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 + qmake -project + qmake + 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 us 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 us 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 will not 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 + qmake + 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 us 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 + + We will 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 will not 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 us 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/platforms/platform-notes.qdocinc b/doc/src/platforms/platform-notes.qdocinc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/doc/src/platforms/platform-notes.qdocinc diff --git a/examples/network/bearercloud/bluetooth.svg b/examples/network/bearercloud/bluetooth.svg new file mode 100644 index 0000000..7ded90a --- /dev/null +++ b/examples/network/bearercloud/bluetooth.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg version="1.1" id="图层_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="21.792" height="21.819"
+ viewBox="0 0 21.792 21.819" overflow="visible" enable-background="new 0 0 21.792 21.819" xml:space="preserve">
+<linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="11.0322" y1="2.8701" x2="11.0322" y2="21.2133">
+ <stop offset="0" style="stop-color:#95D1DB"/>
+ <stop offset="0.0684" style="stop-color:#7FBAE0"/>
+ <stop offset="0.2073" style="stop-color:#5892EA"/>
+ <stop offset="0.3506" style="stop-color:#3871F1"/>
+ <stop offset="0.4971" style="stop-color:#2058F7"/>
+ <stop offset="0.648" style="stop-color:#0E45FC"/>
+ <stop offset="0.8061" style="stop-color:#033BFE"/>
+ <stop offset="0.9831" style="stop-color:#0037FF"/>
+</linearGradient>
+<path fill="url(#XMLID_2_)" stroke="#4D4D4D" stroke-width="0.5" stroke-linejoin="round" d="M10.496,10.931l5.303-4.672
+ L9.172,0.292l-0.05,9.427L9.109,9.708v0.029L7.304,8.168L6.266,9.364l1.802,1.567l-1.802,1.567l1.038,1.195l1.806-1.569v0.029
+ l0.013-0.012l0.05,9.428l6.627-5.966L10.496,10.931z M10.672,3.993l2.502,2.252l-2.525,2.225L10.672,3.993z M13.174,15.617
+ l-2.502,2.252l-0.023-4.477L13.174,15.617z"/>
+<rect opacity="0" fill="#FFFFFF" width="21.792" height="21.792"/>
+</svg>
diff --git a/examples/network/bearercloud/cell.svg b/examples/network/bearercloud/cell.svg new file mode 100644 index 0000000..d4ca57b --- /dev/null +++ b/examples/network/bearercloud/cell.svg @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg version="1.1" id="图层_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="15.667" height="15.794"
+ viewBox="0 0 15.667 15.794" style="overflow:visible;enable-background:new 0 0 15.667 15.794;" xml:space="preserve">
+<rect style="fill:none;" width="15.667" height="15.666"/>
+<g>
+ <rect x="3.791" y="0.583" style="fill:#996633;" width="1" height="7.963"/>
+ <rect x="10.917" y="0.583" style="fill:#996633;" width="1" height="7.963"/>
+ <linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="7.8936" y1="1.6753" x2="7.8936" y2="15.1908">
+ <stop offset="0" style="stop-color:#D9C7A8"/>
+ <stop offset="0.1575" style="stop-color:#CEB28C"/>
+ <stop offset="0.395" style="stop-color:#C09869"/>
+ <stop offset="0.6188" style="stop-color:#B58550"/>
+ <stop offset="0.8212" style="stop-color:#AF7940"/>
+ <stop offset="0.9831" style="stop-color:#AD753B"/>
+ </linearGradient>
+ <rect x="6.728" y="0.583" style="fill:url(#XMLID_2_);stroke:#000000;stroke-width:0.75;" width="2.333" height="14.836"/>
+ <rect x="3.433" y="2.541" style="fill:#C4AB96;stroke:#000000;stroke-width:0.75;" width="8.92" height="2.413"/>
+ <rect x="3.433" y="6.635" style="fill:#C4AB96;stroke:#000000;stroke-width:0.75;" width="8.92" height="2.412"/>
+</g>
+</svg>
diff --git a/examples/network/bearercloud/cloud.cpp b/examples/network/bearercloud/cloud.cpp index 8deaab3..6019d9b 100644 --- a/examples/network/bearercloud/cloud.cpp +++ b/examples/network/bearercloud/cloud.cpp @@ -323,6 +323,17 @@ void Cloud::newConfigurationActivated() case QNetworkConfiguration::BearerEthernet: renderer = new QSvgRenderer(QLatin1String(":lan.svg")); break; + case QNetworkConfiguration::Bearer2G: + renderer = new QSvgRenderer(QLatin1String(":cell.svg")); + break; + case QNetworkConfiguration::BearerBluetooth: + renderer = new QSvgRenderer(QLatin1String(":bluetooth.svg")); + break; + case QNetworkConfiguration::BearerCDMA2000: + case QNetworkConfiguration::BearerWCDMA: + case QNetworkConfiguration::BearerHSPA: + renderer = new QSvgRenderer(QLatin1String(":umts.svg")); + break; default: renderer = new QSvgRenderer(QLatin1String(":unknown.svg")); } diff --git a/examples/network/bearercloud/gprs.svg b/examples/network/bearercloud/gprs.svg new file mode 100644 index 0000000..4a992c1 --- /dev/null +++ b/examples/network/bearercloud/gprs.svg @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + id="图层_1" + width="13" + height="14" + viewBox="0 0 21.228 20.825" + style="overflow:visible;enable-background:new 0 0 21.228 20.825;" + xml:space="preserve" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docname="GPRS-online.svg" + sodipodi:docbase="/home/user"><metadata + id="metadata76"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs74"> + <linearGradient + y2="18.770201" + x2="19.1735" + y1="2.1933999" + x1="2.5967" + gradientUnits="userSpaceOnUse" + id="XMLID_5_" + gradientTransform="matrix(1.749056,0,0,1.749987,1.149567,1.483541)"> + <stop + id="stop6" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop8" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop10" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop12" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop14" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop16" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop18" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="13.7331" + x2="24.2068" + y1="-2.8408" + x1="7.6328001" + gradientUnits="userSpaceOnUse" + id="XMLID_6_"> + <stop + id="stop23" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop25" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop27" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop29" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop31" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop33" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop35" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="23.8965" + x2="14.043" + y1="7.3242002" + x1="-2.5293" + gradientUnits="userSpaceOnUse" + id="XMLID_7_"> + <stop + id="stop40" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop42" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop44" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop46" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop48" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop50" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop52" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="18.5788" + x2="19.364" + y1="2.0039001" + x1="2.7890999" + gradientUnits="userSpaceOnUse" + id="XMLID_8_"> + <stop + id="stop57" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop59" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop61" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop63" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop65" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop67" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop69" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + +</defs><sodipodi:namedview + inkscape:window-height="960" + inkscape:window-width="1183" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + width="13px" + height="14px" + inkscape:zoom="19.543817" + inkscape:cx="10.614" + inkscape:cy="10.386917" + inkscape:window-x="186" + inkscape:window-y="93" + inkscape:current-layer="图层_1" /> +<path + id="path20" + d="M 11.043976,12.916206 L 11.043976,9.4232323 L 19.388723,9.4232323 L 19.388723,16.573679 C 17.790085,17.616671 16.380346,18.330666 15.15076,18.708663 C 13.922922,19.084911 12.465959,19.272159 10.779869,19.272159 C 8.7054879,19.272159 7.0141507,18.934412 5.7076059,18.253667 C 4.399312,17.574672 3.3866086,16.564929 2.6677466,15.222689 C 1.9488846,13.880449 1.58683,12.336961 1.58683,10.599223 C 1.58683,8.7652372 1.9803676,7.172749 2.7674428,5.820009 C 3.5527689,4.4655191 4.7053968,3.4365268 6.2288246,2.7312819 C 7.4111865,2.190536 9.0045765,1.921038 11.008995,1.921038 C 12.939953,1.921038 14.386422,2.0890367 15.343156,2.4232842 C 16.301639,2.7610318 17.093961,3.2825279 17.728868,3.9860227 C 18.360278,4.6930174 18.834272,5.5890108 19.150851,6.6722527 L 13.938664,7.5629961 C 13.72353,6.9330008 13.361475,6.4465044 12.849002,6.1157569 C 12.33478,5.7815093 11.68588,5.6117606 10.890059,5.6117606 C 9.7111951,5.6117606 8.7632067,6.0072577 8.0653334,6.7965018 C 7.3622129,7.5839959 7.0071545,8.8352366 7.0071545,10.541474 C 7.0071545,12.35621 7.365711,13.654701 8.0740787,14.433445 C 8.7824464,15.212189 9.7776592,15.600686 11.043976,15.600686 C 11.647401,15.600686 12.224589,15.514937 12.770295,15.346938 C 13.321247,15.18069 13.943911,14.897192 14.652279,14.492945 L 14.652279,12.917956 L 11.043976,12.917956 L 11.043976,12.916206 z " + style="fill:black;stroke:white;stroke-width:1.30633846;stroke-miterlimit:4;stroke-dasharray:none;stroke-linejoin:round;stroke-linecap:butt;stroke-opacity:1;fill-opacity:1" /> +</svg> diff --git a/examples/network/bearercloud/icons.qrc b/examples/network/bearercloud/icons.qrc index 84a8939..7dea1f2 100644 --- a/examples/network/bearercloud/icons.qrc +++ b/examples/network/bearercloud/icons.qrc @@ -3,5 +3,9 @@ <file>wlan.svg</file> <file>lan.svg</file> <file>unknown.svg</file> + <file>bluetooth.svg</file> + <file>cell.svg</file> + <file>gprs.svg</file> + <file>umts.svg</file> </qresource> </RCC> diff --git a/examples/network/bearercloud/lan.svg b/examples/network/bearercloud/lan.svg index 3cce805..b8ee999 100644..100755 --- a/examples/network/bearercloud/lan.svg +++ b/examples/network/bearercloud/lan.svg @@ -1,76 +1,33 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="25.000002" - height="9.6406126" - id="svg2" - sodipodi:version="0.32" - inkscape:version="0.46" - version="1.0" - sodipodi:docname="lan.svg" - inkscape:output_extension="org.inkscape.output.svg.inkscape"> - <defs - id="defs4"> - <inkscape:perspective - sodipodi:type="inkscape:persp3d" - inkscape:vp_x="0 : 526.18109 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_z="744.09448 : 526.18109 : 1" - inkscape:persp3d-origin="372.04724 : 350.78739 : 1" - id="perspective10" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - gridtolerance="10000" - guidetolerance="10" - objecttolerance="10" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="19.416667" - inkscape:cx="15.244635" - inkscape:cy="11.639485" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - inkscape:window-width="1459" - inkscape:window-height="964" - inkscape:window-x="453" - inkscape:window-y="166" /> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-4.0978193e-8,-19.359387)"> - <text - xml:space="preserve" - style="font-size:13.99289513px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" - x="-1.1205248" - y="29" - id="text3239"><tspan - sodipodi:role="line" - id="tspan3241" - x="-1.1205248" - y="29">LAN</tspan></text> - </g> -</svg> +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg version="1.1" id="图层_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="21.929" height="20.665"
+ viewBox="0 0 21.929 20.665" style="overflow:visible;enable-background:new 0 0 21.929 20.665;" xml:space="preserve">
+<g>
+ <linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="1.7178" y1="5.3706" x2="20.9333" y2="5.3706">
+ <stop offset="0.0393" style="stop-color:#C2DC1A"/>
+ <stop offset="0.2192" style="stop-color:#BEDA1A"/>
+ <stop offset="0.3978" style="stop-color:#B2D61B"/>
+ <stop offset="0.5758" style="stop-color:#9ECE1D"/>
+ <stop offset="0.7536" style="stop-color:#82C320"/>
+ <stop offset="0.9298" style="stop-color:#5FB423"/>
+ <stop offset="0.9326" style="stop-color:#5EB423"/>
+ </linearGradient>
+ <polygon style="fill:url(#XMLID_3_);stroke:#000000;stroke-linejoin:round;" points="21.429,7.716 10.965,7.716 10.965,0.5
+ 0.5,10.241 21.429,10.241 "/>
+ <linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="1.7178" y1="15.2944" x2="20.9333" y2="15.2944">
+ <stop offset="0.0393" style="stop-color:#C2DC1A"/>
+ <stop offset="0.2192" style="stop-color:#BEDA1A"/>
+ <stop offset="0.3978" style="stop-color:#B2D61B"/>
+ <stop offset="0.5758" style="stop-color:#9ECE1D"/>
+ <stop offset="0.7536" style="stop-color:#82C320"/>
+ <stop offset="0.9298" style="stop-color:#5FB423"/>
+ <stop offset="0.9326" style="stop-color:#5EB423"/>
+ </linearGradient>
+ <polygon style="fill:url(#XMLID_4_);stroke:#000000;stroke-linejoin:round;" points="0.5,12.949 10.965,12.949 10.965,20.165
+ 21.429,10.424 0.5,10.424 "/>
+</g>
+</svg>
diff --git a/examples/network/bearercloud/umts.svg b/examples/network/bearercloud/umts.svg new file mode 100644 index 0000000..c1b372e --- /dev/null +++ b/examples/network/bearercloud/umts.svg @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + id="图层_1" + width="13" + height="14" + viewBox="0 0 21.228 20.825" + style="overflow:visible;enable-background:new 0 0 21.228 20.825;" + xml:space="preserve" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docname="umts-enabled.svg" + sodipodi:docbase="/home/user"><metadata + id="metadata76"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs74"> + <linearGradient + y2="18.770201" + x2="19.1735" + y1="2.1933999" + x1="2.5967" + gradientUnits="userSpaceOnUse" + id="XMLID_5_" + gradientTransform="matrix(1.749056,0,0,1.749987,1.149567,1.483541)"> + <stop + id="stop6" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop8" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop10" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop12" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop14" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop16" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop18" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="13.7331" + x2="24.2068" + y1="-2.8408" + x1="7.6328001" + gradientUnits="userSpaceOnUse" + id="XMLID_6_"> + <stop + id="stop23" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop25" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop27" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop29" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop31" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop33" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop35" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="23.8965" + x2="14.043" + y1="7.3242002" + x1="-2.5293" + gradientUnits="userSpaceOnUse" + id="XMLID_7_"> + <stop + id="stop40" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop42" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop44" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop46" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop48" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop50" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop52" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + + <linearGradient + y2="18.5788" + x2="19.364" + y1="2.0039001" + x1="2.7890999" + gradientUnits="userSpaceOnUse" + id="XMLID_8_"> + <stop + id="stop57" + style="stop-color:#F8DB41" + offset="0" /> + <stop + id="stop59" + style="stop-color:#F8D73F" + offset="0.1193" /> + <stop + id="stop61" + style="stop-color:#F9CB3A" + offset="0.2384" /> + <stop + id="stop63" + style="stop-color:#FAB731" + offset="0.3576" /> + <stop + id="stop65" + style="stop-color:#FC9B24" + offset="0.4768" /> + <stop + id="stop67" + style="stop-color:#FE7714" + offset="0.595" /> + <stop + id="stop69" + style="stop-color:#FE7513" + offset="0.6011" /> + </linearGradient> + +</defs><sodipodi:namedview + inkscape:window-height="960" + inkscape:window-width="1183" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + width="13px" + height="14px" + inkscape:zoom="53.714286" + inkscape:cx="6.5" + inkscape:cy="7" + inkscape:window-x="252" + inkscape:window-y="164" + inkscape:current-layer="图层_1" /> + +<path + style="font-size:26.12677002px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:black;fill-opacity:1;stroke:white;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + d="M 10.438113,0.60410378 C 9.5195858,0.60412318 8.5840584,0.67216158 7.6315264,0.80821918 C 6.6789835,0.94431518 5.6924268,1.1484304 4.7228823,1.4205653 L 4.7228823,5.0436132 C 5.5223309,4.6949314 6.3643059,4.4057684 7.1722669,4.2271517 C 7.9802179,4.0485668 8.7796689,3.9720237 9.5706225,3.9720075 C 10.64222,3.9720235 11.433166,4.1846436 12.020007,4.5843536 C 12.606829,4.9840947 12.938516,5.5369062 12.938526,6.2683055 C 12.938515,7.0592656 12.623838,7.663106 12.020007,8.054315 C 11.416156,8.4370429 10.497638,8.615644 9.2644494,8.615632 L 7.1722669,8.615632 L 7.1722669,11.779421 L 9.1623917,11.779421 C 10.548667,11.779429 11.569243,11.992048 12.275151,12.442796 C 12.989544,12.885053 13.346746,13.565437 13.346757,14.43292 C 13.346746,15.2749 13.023563,15.921266 12.32618,16.372017 C 11.637281,16.822775 10.616705,17.035395 9.3154783,17.035392 C 8.4394768,17.035395 7.5719873,16.907823 6.6619784,16.67819 C 5.7604653,16.440059 4.8249372,16.116877 3.9064208,15.657613 L 3.9064208,19.433747 C 4.8674613,19.748424 5.8370084,19.995064 6.815065,20.148151 C 7.8016169,20.309742 8.7966784,20.403295 9.7747379,20.403295 C 12.547295,20.403294 14.656485,19.901511 16.102315,18.923459 C 17.548116,17.936904 18.296539,16.474077 18.296555,14.586007 C 18.296539,13.318797 17.947843,12.289717 17.275978,11.473248 C 16.612589,10.648291 15.286744,9.8267627 14.975337,9.738267 C 15.211467,9.5707147 16.382959,8.96434 16.969805,8.2584304 C 17.556621,7.544039 17.837281,6.617016 17.837296,5.5028728 C 17.837281,3.8699658 17.233439,2.6367701 16.000257,1.8287961 C 14.775552,1.0123535 12.913001,0.60412318 10.438113,0.60410378 z M 10.570571,1.2772502 C 13.045459,1.2772695 14.306521,1.5736708 15.531226,2.3901134 C 16.764408,3.1980876 17.174992,3.8601944 17.175007,5.4931014 C 17.174992,6.6072444 16.924732,7.1976942 16.337916,7.9120856 C 15.75107,8.617996 15.186496,9.1223119 15.071966,9.2290638 L 14.321733,9.8826672 C 15.605945,10.214364 16.173958,10.84372 16.837348,11.668677 C 17.509211,12.485146 17.613621,13.298168 17.613637,14.565378 C 17.613621,16.453449 16.977028,17.365815 15.531226,18.35237 C 14.085396,19.330422 12.587467,19.720376 9.8149096,19.720377 C 8.8368504,19.720377 7.7809882,19.596424 6.7944362,19.434833 C 5.8163797,19.281747 5.4689503,19.167564 4.5079098,18.852887 L 4.4775095,16.626075 C 5.3960259,17.085338 5.6790363,17.174005 6.5805495,17.412136 C 7.4905585,17.641769 8.5827919,17.809513 9.4587934,17.80951 C 10.76002,17.809513 12.167112,17.341749 12.856012,16.89099 C 13.553395,16.440238 14.111093,15.203243 14.111104,14.361263 C 14.111093,13.493779 13.591033,12.385621 12.87664,11.943364 C 12.170732,11.492617 10.853754,11.107368 9.4674791,11.10736 L 7.8041559,11.117131 L 7.8041559,9.277922 L 9.3871358,9.257293 C 10.620324,9.257304 12.006788,8.936474 12.610639,8.553746 C 13.21447,8.1625376 13.682233,7.0288655 13.682244,6.2379054 C 13.682234,5.5065062 13.268032,4.4542632 12.681211,4.0545222 C 12.09437,3.6548121 10.824621,3.2391624 9.7530236,3.2391464 C 8.9620698,3.2391624 7.9791321,3.3048486 7.1711811,3.4834335 C 6.3632201,3.66205 6.1954773,3.6645831 5.3960287,4.0132649 L 5.3862573,1.9308538 C 6.3558019,1.6587188 6.8320701,1.5566613 7.784613,1.4205653 C 8.7371446,1.2845077 9.6520438,1.2772696 10.570571,1.2772502 z " + id="text1901" + sodipodi:nodetypes="csccsssssccccsssssccssssscsssccsssccsssssccsssssccccsssssccsc" /></svg>
\ No newline at end of file diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index b51596c..a1e7d37 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -149,7 +149,6 @@ void QConnmanEngine::getNetworkListing() } - void QConnmanEngine::doRequestUpdate() { connmanManager->requestScan(""); @@ -312,6 +311,9 @@ QString QConnmanEngine::getServiceForNetwork(const QString &netPath) QMutexLocker locker(&mutex); QConnmanNetworkInterface network(netPath, this); foreach(QString service,connmanManager->getServices()) { + + QString devicePath = netPath.section("/",5,5); + QConnmanServiceInterface serv(service,this); if(serv.getName() == network.getName() && network.getSignalStrength() == serv.getSignalStrength()) { @@ -354,17 +356,6 @@ void QConnmanEngine::propertyChangedContext(const QString &path,const QString &i technologies.insert(listPath, tech); } } - - foreach(const QString old, oldtech.keys()) { - if(!newlist.contains(old)) { - QConnmanTechnologyInterface *tech = oldtech.value(old); - disconnect(tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant))); - - technologies.remove(old); - getNetworkListing(); - } - } } } if(item == "State") { @@ -385,15 +376,21 @@ void QConnmanEngine::servicePropertyChangedContext(const QString &path,const QSt } } -void QConnmanEngine::networkPropertyChangedContext(const QString &/*path*/,const QString &/*item*/, const QDBusVariant &/*value*/) +void QConnmanEngine::networkPropertyChangedContext(const QString &path,const QString &item, const QDBusVariant &value) { QMutexLocker locker(&mutex); +// qDebug() << __FUNCTION__ << path << item << value.variant(); } void QConnmanEngine::devicePropertyChangedContext(const QString &devpath,const QString &item,const QDBusVariant &value) { +// qDebug() << __FUNCTION__ << devpath << item << value.variant(); QMutexLocker locker(&mutex); if(item == "Networks") { + + QConnmanNetworkInterface network(devpath, this); + + QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant()); QStringList remainingNetworks = qdbus_cast<QStringList>(arg); QString devicetype; @@ -431,6 +428,7 @@ void QConnmanEngine::devicePropertyChangedContext(const QString &devpath,const Q void QConnmanEngine::technologyPropertyChangedContext(const QString & path, const QString &item, const QDBusVariant &value) { +// qDebug() << __FUNCTION__ << path << item << value.variant(); if(item == "Devices") { QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant()); QStringList list = qdbus_cast<QStringList>(arg); @@ -452,6 +450,12 @@ void QConnmanEngine::technologyPropertyChangedContext(const QString & path, cons } if(value.variant().toString() == "offline") { deviceMap.remove(path); + QConnmanTechnologyInterface tech(path); + disconnect(&tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), + this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant))); + + technologies.remove(path); + getNetworkListing(); } } } @@ -523,7 +527,7 @@ QNetworkConfiguration::BearerType QConnmanEngine::typeToBearer(const QString &ty if (type == "bluetooth") return QNetworkConfiguration::BearerBluetooth; if (type == "cellular") { - return QNetworkConfiguration::BearerUnknown; + return QNetworkConfiguration::Bearer2G; // not handled: CDMA2000 HSPA } if (type == "wimax") @@ -588,8 +592,11 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath) QString networkName = serv->getName(); - if(serv->getType() == "Cellular") { + if(serv->getType() == "cellular") { networkName = serv->getAPN(); + if(networkName.isEmpty()) { + networkName = serv->getName(); + } } cpPriv->name = networkName; @@ -643,6 +650,9 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) { QMutexLocker locker(&mutex); + if(networkPath.isNull()) + return; + QConnmanNetworkInterface *network; network = new QConnmanNetworkInterface(networkPath, this); QString servicePath = getServiceForNetwork(networkPath); @@ -658,9 +668,10 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) serv = new QConnmanServiceInterface(servicePath,this); connect(serv,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), this,SLOT(servicePropertyChangedContext(QString,QString, QDBusVariant))); + } - if (!accessPointConfigurations.contains(id)) { + if (!id.isEmpty() && !accessPointConfigurations.contains(id)) { knownNetworks[device.getType()].append(networkPath); @@ -681,20 +692,26 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) if(servicePath.isEmpty()) { QString devicePath = networkPath.section("/",0,5); + QConnmanDeviceInterface device(devicePath,this); bearerType = typeToBearer(device.getType()); } else { bearerType = typeToBearer(serv->getType()); } - if (bearerType == QNetworkConfiguration::BearerUnknown) { + if (bearerType == QNetworkConfiguration::Bearer2G) { QString mode = serv->getMode(); if (mode == "gprs" || mode == "edge") { bearerType = QNetworkConfiguration::Bearer2G; } else if (mode == "umts") { bearerType = QNetworkConfiguration::BearerWCDMA; } - networkName = serv->getAPN(); + if(servicePath.isEmpty()) { + networkName = serv->getAPN(); + if(networkName.isEmpty()) { + networkName = serv->getName(); + } + } } cpPriv->name = networkName; @@ -723,7 +740,9 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) emit configurationAdded(ptr); locker.relock(); emit updateCompleted(); - } + } /*else { + qDebug() << "Not added~~~~~~~~~~~"; + }*/ } bool QConnmanEngine::requiresPolling() const diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index b20e7c1..00cfb31 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -129,8 +129,10 @@ QVariant QConnmanManagerInterface::getProperty(const QString &property) QVariantMap QConnmanManagerInterface::getProperties() { - QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties")); - return reply.value(); + if(this->isValid()) { + QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties")); + return reply.value(); + } else return QVariantMap(); } QString QConnmanManagerInterface::getState() @@ -551,8 +553,12 @@ void QConnmanServiceInterface::disconnectNotify(const char *signal) QVariantMap QConnmanServiceInterface::getProperties() { - QDBusReply<QVariantMap> reply = this->call(QLatin1String("GetProperties")); - return reply.value(); + if(this->isValid()) { + QDBusReply<QVariantMap> reply = this->call(QLatin1String("GetProperties")); + return reply.value(); + } + else + return QVariantMap(); } QVariant QConnmanServiceInterface::getProperty(const QString &property) @@ -725,6 +731,99 @@ QVariantMap QConnmanServiceInterface::getEthernet() return qdbus_cast<QVariantMap >(var); } +QString QConnmanServiceInterface::getMethod() +{ + QVariant var; + QVariantMap map = getEthernet(); + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "Method") { + return it.value().toString(); + } + } + return QString(); +} + +QString QConnmanServiceInterface::getInterface() +{ + QVariant var; + QVariantMap map = getEthernet(); + + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "Interface") { + return it.value().toString(); + } + } + + return QString(); +} + +QString QConnmanServiceInterface::getMacAddress() +{ + QVariant var; + QVariantMap map = getEthernet(); + + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "Address") { + return it.value().toString(); + } + } + return QString(); +} + +quint16 QConnmanServiceInterface::getMtu() +{ + quint16 mtu=0; + QVariant var; + QVariantMap map = getEthernet(); + + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "MTU") { + return it.value().toUInt(); + } + } + return mtu; +} + +quint16 QConnmanServiceInterface::getSpeed() +{ + quint16 speed=0; + QVariant var; + QVariantMap map = getEthernet(); + + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "Speed") { + return it.value().toUInt(); + } + } + return speed; +} + +QString QConnmanServiceInterface::getDuplex() +{ + QVariant var; + QVariantMap map = getEthernet(); + + QMapIterator<QString,QVariant> it(map); + while(it.hasNext()) { + it.next(); + if(it.key() == "Duplex") { + return it.value().toString(); + } + } + return QString(); +} + + bool QConnmanServiceInterface::isOfflineMode() { QVariant var = getProperty("OfflineMode"); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index 35e3f3d..18233b0 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -249,6 +249,13 @@ public: QVariantMap getProxy(); QVariantMap getEthernet(); + QString getMethod(); + QString getInterface(); + QString getMacAddress(); + quint16 getMtu(); + quint16 getSpeed(); + QString getDuplex(); + bool isOfflineMode(); QStringList getServices(); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 76d8c0d..723f516 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1756,10 +1756,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString& title, if (sl.contains("declarative")) out() << " <li><a href=\"qdeclarativeexamples.html\">QML Examples & Demos</a></li>"; else { - QString name = "examples-" + sl.at(0) + ".html"; + QString name = "examples-" + sl.at(0) + ".html"; // this generates an empty link QString t = CodeParser::titleFromName(name); - out() << " <li><a href=\"" << name << "\">" - << t << "</a></li>"; + // out() << " <li> <a href=\"" << name << "\">" + // << t << "</a></li>"; } out() << " <li>" << title << "</li>"; } |