From 23b952e32b7a125ee7d51f00c894bb77d54c2d1c Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja <kavindra.palaraja@nokia.com> Date: Wed, 3 Jun 2009 17:00:30 +0200 Subject: [PATCH] Fixes: Doc - starting on modifying Part 3 RevBy: TrustMe --- doc/addressbook-sdk.qdoc | 32 +++++ .../addressbook-sdk/part3/addressbook.cpp | 121 ++++++++++++++++++ .../addressbook-sdk/part3/addressbook.h | 51 ++++++++ .../addressbook-sdk/part3/addressbook.ui | 93 ++++++++++++++ doc/examples/addressbook-sdk/part3/main.cpp | 12 ++ doc/examples/addressbook-sdk/part3/part3.pro | 16 +++ .../addressbook-tutorial-part3-linkedlist.png | Bin 0 -> 10209 bytes 7 files changed, 325 insertions(+) create mode 100644 doc/examples/addressbook-sdk/part3/addressbook.cpp create mode 100644 doc/examples/addressbook-sdk/part3/addressbook.h create mode 100644 doc/examples/addressbook-sdk/part3/addressbook.ui create mode 100644 doc/examples/addressbook-sdk/part3/main.cpp create mode 100644 doc/examples/addressbook-sdk/part3/part3.pro create mode 100644 doc/images/addressbook-tutorial-part3-linkedlist.png diff --git a/doc/addressbook-sdk.qdoc b/doc/addressbook-sdk.qdoc index 643f6d0b7e4..7514052c0e7 100644 --- a/doc/addressbook-sdk.qdoc +++ b/doc/addressbook-sdk.qdoc @@ -418,3 +418,35 @@ as you like. */ + + +/*! + \page tutorials-addressbook-sdk-part3.html + \previouspage Address Book 2 - Adding Addresses + \contentspage {Address Book Tutorial}{Contents} + \nextpage \l{examples/addressbook-sdk/part4}{Chapter 4} + \example examples/addressbook-sdk/part3 + \title Address Book 3 - Navigating between Entries} + + The address book application is now half complete. We need to add some + functions to navigate between contacts. But first, we have to decide what + sort of a data structure we would like to use to hold these contacts. + + In Chapter 2, we used a QMap of key-value pairs with the contact's name as + the \e key, and the contact's address as the \e value. This works well for + our case. However, in order to navigate and display each entry, a little + bit of enhancement is needed. + + We enhance the QMap by making it replicate a data structure similar to a + circularly-linked list, where all elements are connected, including the + first element and the last element. The figure below illustrates this data + structure; + + \image addressbook-tutorial-part3-linkedlist.png + + + \section1 Placing Widgets on the Form + + \section1 The AddressBook Class + +*/ diff --git a/doc/examples/addressbook-sdk/part3/addressbook.cpp b/doc/examples/addressbook-sdk/part3/addressbook.cpp new file mode 100644 index 00000000000..06bb6327d5a --- /dev/null +++ b/doc/examples/addressbook-sdk/part3/addressbook.cpp @@ -0,0 +1,121 @@ +#include "addressbook.h" +#include "ui_addressbook.h" + +AddressBook::AddressBook(QWidget *parent) + : QWidget(parent), ui(new Ui::AddressBookClass) +{ + ui->setupUi(this); + + //! [extract objects] + nameLine = new QLineEdit; + nameLine = ui->nameLine; + nameLine->setReadOnly(true); + + addressText = new QTextEdit; + addressText = ui->addressText; + addressText->setReadOnly(true); + + addButton = new QPushButton; + addButton = ui->addButton; + + submitButton = new QPushButton; + submitButton = ui->submitButton; + submitButton->hide(); + + cancelButton = new QPushButton; + cancelButton = ui->cancelButton; + cancelButton->hide(); + //! [extract objects] + + //! [signal slot] + connect(addButton, SIGNAL(clicked()), this, + SLOT(addContact())); + connect(submitButton, SIGNAL(clicked()), this, + SLOT(submitContact())); + connect(cancelButton, SIGNAL(clicked()), this, + SLOT(cancel())); + //! [signal slot] + + //! [window title] + setWindowTitle(tr("Simple Address Book")); + //! [window title] +} + +AddressBook::~AddressBook() +{ + delete ui; +} + +//! [addContact] +void AddressBook::addContact() +{ + oldName = nameLine->text(); + oldAddress = addressText->toPlainText(); + + nameLine->clear(); + addressText->clear(); + + nameLine->setReadOnly(false); + nameLine->setFocus(Qt::OtherFocusReason); + addressText->setReadOnly(false); + + addButton->setEnabled(false); + submitButton->show(); + cancelButton->show(); +} +//! [addContact] + +//! [submitContact part1] +void AddressBook::submitContact() +{ + QString name = nameLine->text(); + QString address = addressText->toPlainText(); + + if (name == "" || address == "") { + QMessageBox::information(this, tr("Empty Field"), + tr("Please enter a name and address.")); + return; + } +//! [submitContact part1] + +//! [submitContact part2] + if (!contacts.contains(name)) { + contacts.insert(name, address); + QMessageBox::information(this, tr("Add Successful"), + tr("\"%1\" has been added to your address book.").arg(name)); + return; + } else { + QMessageBox::information(this, tr("Add Unsuccessful"), + tr("Sorry, \"%1\" is already in your address book.").arg(name)); + return; + } +//! [submitContact part2] + +//! [submitContact part3] + if (contacts.isEmpty()) { + nameLine->clear(); + addressText->clear(); + } + + nameLine->setReadOnly(true); + addressText->setReadOnly(true); + addButton->setEnabled(true); + submitButton->hide(); + cancelButton->hide(); +} +//! [submitContact part3] + +//! [cancel] +void AddressBook::cancel() +{ + nameLine->setText(oldName); + nameLine->setReadOnly(true); + + addressText->setText(oldAddress); + addressText->setReadOnly(true); + + addButton->setEnabled(true); + submitButton->hide(); + cancelButton->hide(); +} +//! [cancel] diff --git a/doc/examples/addressbook-sdk/part3/addressbook.h b/doc/examples/addressbook-sdk/part3/addressbook.h new file mode 100644 index 00000000000..86cf5b07bd8 --- /dev/null +++ b/doc/examples/addressbook-sdk/part3/addressbook.h @@ -0,0 +1,51 @@ +//! [class definition] +#ifndef ADDRESSBOOK_H +#define ADDRESSBOOK_H + +#include <QtGui/QWidget> +#include <QtGui/QPushButton> +#include <QtGui/QLineEdit> +#include <QtGui/QTextEdit> +#include <QtGui/QMessageBox> + + +namespace Ui +{ + class AddressBookClass; +} + +class AddressBook : public QWidget +{ + Q_OBJECT + +public: + AddressBook(QWidget *parent = 0); + ~AddressBook(); + +//! [slot definition] +public slots: + void addContact(); + void submitContact(); + void cancel(); +//! [slot definition] + +private: + Ui::AddressBookClass *ui; + +//! [members1] + QPushButton *addButton; + QPushButton *submitButton; + QPushButton *cancelButton; + QLineEdit *nameLine; + QTextEdit *addressText; +//! [members1] + +//! [members2] + QMap<QString, QString> contacts; + QString oldName; + QString oldAddress; +//! [members2] +}; + +#endif // ADDRESSBOOK_H +//! [class definition] diff --git a/doc/examples/addressbook-sdk/part3/addressbook.ui b/doc/examples/addressbook-sdk/part3/addressbook.ui new file mode 100644 index 00000000000..493d546fc92 --- /dev/null +++ b/doc/examples/addressbook-sdk/part3/addressbook.ui @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>addressbook</class> + <widget class="QWidget" name="addressbook"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>505</width> + <height>326</height> + </rect> + </property> + <property name="windowTitle"> + <string>addressbook</string> + </property> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>413</width> + <height>225</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="nameLabel"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="nameLine"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="addressLabel"> + <property name="text"> + <string>Address:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QTextEdit" name="addressText"/> + </item> + <item row="1" column="2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="addButton"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="submitButton"> + <property name="text"> + <string>Submit</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/doc/examples/addressbook-sdk/part3/main.cpp b/doc/examples/addressbook-sdk/part3/main.cpp new file mode 100644 index 00000000000..3378b4adce4 --- /dev/null +++ b/doc/examples/addressbook-sdk/part3/main.cpp @@ -0,0 +1,12 @@ +//! [main function] +#include <QtGui/QApplication> +#include "addressbook.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + AddressBook w; + w.show(); + return a.exec(); +} +//! [main function] diff --git a/doc/examples/addressbook-sdk/part3/part3.pro b/doc/examples/addressbook-sdk/part3/part3.pro new file mode 100644 index 00000000000..0bfd2f9e314 --- /dev/null +++ b/doc/examples/addressbook-sdk/part3/part3.pro @@ -0,0 +1,16 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2009-06-03T16:54:49 +# +#------------------------------------------------- + +TARGET = part3 +TEMPLATE = app + + +SOURCES += main.cpp\ + addressbook.cpp + +HEADERS += addressbook.h + +FORMS += addressbook.ui diff --git a/doc/images/addressbook-tutorial-part3-linkedlist.png b/doc/images/addressbook-tutorial-part3-linkedlist.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f4725dceb7b9f602d55019e2d39c846d02b859 GIT binary patch literal 10209 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 bDT&CJ6c*lF`f6EE00000NkvXXu0mjf*KXFc literal 0 HcmV?d00001 -- GitLab