Add example that alternatively uses Declarative Widgets or QtQuick1
authorKevin Krammer <kevin.krammer@kdab.com>
Tue, 20 Nov 2012 13:54:21 +0000 (14:54 +0100)
committerKevin Krammer <kevin.krammer@kdab.com>
Wed, 28 Nov 2012 14:05:15 +0000 (15:05 +0100)
15 files changed:
examples/bookstore/README.txt [new file with mode: 0644]
examples/bookstore/booklistproxymodel.cpp [new file with mode: 0644]
examples/bookstore/booklistproxymodel.h [new file with mode: 0644]
examples/bookstore/booksofauthormodel.cpp [new file with mode: 0644]
examples/bookstore/booksofauthormodel.h [new file with mode: 0644]
examples/bookstore/bookstore.cpp [new file with mode: 0644]
examples/bookstore/bookstore.db [new file with mode: 0644]
examples/bookstore/bookstore.h [new file with mode: 0644]
examples/bookstore/bookstore.pro [new file with mode: 0644]
examples/bookstore/bookstore.qrc [new file with mode: 0644]
examples/bookstore/bookstore.sqlite3.sql [new file with mode: 0644]
examples/bookstore/main.cpp [new file with mode: 0644]
examples/bookstore/qtquick/main.qml [new file with mode: 0644]
examples/bookstore/widgets/main.qml [new file with mode: 0644]
examples/examples.pro

diff --git a/examples/bookstore/README.txt b/examples/bookstore/README.txt
new file mode 100644 (file)
index 0000000..8705812
--- /dev/null
@@ -0,0 +1,6 @@
+Example Bookstore
+=================
+
+The idea of this example is to show the alternative usage of QtQuick and Declarative Widgets on top of the same exported objects.
+
+The application can be run in a mode suitable for the staff of a book store as well as in a mode more suited for customer needs.
diff --git a/examples/bookstore/booklistproxymodel.cpp b/examples/bookstore/booklistproxymodel.cpp
new file mode 100644 (file)
index 0000000..88ea68d
--- /dev/null
@@ -0,0 +1,85 @@
+#include "booklistproxymodel.h"
+
+#include <QDebug>
+
+static QHash<int, QByteArray> createRolesToNameMapping()
+{
+  QHash<int, QByteArray> mapping;
+
+  mapping[BookListProxyModel::BookIdRole] = "bookId";
+  mapping[BookListProxyModel::BookTitleRole] = "bookTitle";
+  mapping[BookListProxyModel::BookPriceRole] = "bookPrice";
+  mapping[BookListProxyModel::BookNotesRole] = "bookNotes";
+  mapping[BookListProxyModel::AuthorIdRole] = "authorId";
+  mapping[BookListProxyModel::AuthorFirstNameRole] = "authorFirstName";
+  mapping[BookListProxyModel::AuthorLastNameRole] = "authorLastName";
+
+  return mapping;
+}
+
+BookListProxyModel::BookListProxyModel(QObject *parent)
+  : QAbstractProxyModel(parent),
+    m_rolesToNames(createRolesToNameMapping())
+{
+}
+
+void BookListProxyModel::addColumnToRoleMapping(int column, int role)
+{
+  m_sourceColumnsToRoles[column] = role;
+  m_rolesToSourceColumns[role] = column;
+
+  QHash<int, QByteArray> rolesToNames = roleNames();
+  rolesToNames[role] = m_rolesToNames[role];
+  setRoleNames(rolesToNames);
+}
+
+int BookListProxyModel::columnCount(const QModelIndex &parent) const
+{
+  Q_UNUSED(parent);
+
+  return 1;
+}
+
+int BookListProxyModel::rowCount(const QModelIndex &parent) const
+{
+  if (parent.isValid())
+    return 0;
+
+  return sourceModel()->rowCount();
+}
+
+QModelIndex BookListProxyModel::index(int row, int column, const QModelIndex &parent) const
+{
+  Q_ASSERT(column == 0);
+  Q_UNUSED(column);
+
+  if (parent.isValid())
+    return QModelIndex();
+
+  return createIndex(row, 0, 0);
+}
+
+QModelIndex BookListProxyModel::parent(const QModelIndex &child) const
+{
+  Q_UNUSED(child);
+  return QModelIndex();
+}
+
+QVariant BookListProxyModel::data(const QModelIndex &proxyIndex, int role) const
+{
+  const int row = proxyIndex.row();
+  const int column = m_rolesToSourceColumns.contains(role) ? m_rolesToSourceColumns[role] : 0;
+
+  const QModelIndex sourceIndex = sourceModel()->index(row, column);
+  return sourceIndex.data(Qt::DisplayRole);
+}
+
+QModelIndex BookListProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
+{
+  return createIndex(sourceIndex.row(), 0, sourceIndex.column());
+}
+
+QModelIndex BookListProxyModel::mapToSource(const QModelIndex &proxyIndex) const
+{
+  return sourceModel()->index(proxyIndex.row(), proxyIndex.internalId());
+}
diff --git a/examples/bookstore/booklistproxymodel.h b/examples/bookstore/booklistproxymodel.h
new file mode 100644 (file)
index 0000000..8946145
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef BOOKLISTPROXYMODEL_H
+#define BOOKLISTPROXYMODEL_H
+
+#include <QAbstractProxyModel>
+#include <QHash>
+
+class BookListProxyModel : public QAbstractProxyModel
+{
+  Q_OBJECT
+
+  public:
+    enum Roles {
+      BookIdRole = Qt::UserRole + 1,
+      BookTitleRole,
+      BookPriceRole,
+      BookNotesRole,
+      AuthorIdRole,
+      AuthorFirstNameRole,
+      AuthorLastNameRole
+    };
+
+    explicit BookListProxyModel(QObject *parent = 0);
+
+    void addColumnToRoleMapping(int column, int role);
+
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+    QModelIndex parent(const QModelIndex &child) const;
+
+    QVariant data(const QModelIndex &proxyIndex, int role) const;
+
+    QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
+    QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
+
+  private:
+    const QHash<int, QByteArray> m_rolesToNames;
+
+    QHash<int, int> m_rolesToSourceColumns;
+    QHash<int, int> m_sourceColumnsToRoles;
+};
+
+#endif // BOOKLISTPROXYMODEL_H
diff --git a/examples/bookstore/booksofauthormodel.cpp b/examples/bookstore/booksofauthormodel.cpp
new file mode 100644 (file)
index 0000000..4796687
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "booksofauthormodel.h"
+
+#include "bookstore.h"
+
+#include <QSqlError>
+
+BooksOfAuthorModel::BooksOfAuthorModel(BookStore *store) :
+  QSqlQueryModel(store),
+  m_store(store),
+  m_authorId(-1)
+{
+  setHeaderData(1, Qt::Horizontal, tr("Title"));
+  setHeaderData(2, Qt::Horizontal, tr("Price"));
+  setHeaderData(3, Qt::Horizontal, tr("Notes"));
+
+  refresh();
+}
+
+void BooksOfAuthorModel::setAuthor(int authorId)
+{
+  m_authorId = authorId;
+  refresh();
+}
+
+void BooksOfAuthorModel::refresh()
+{
+  QString query = QString::fromUtf8("SELECT title, price, notes FROM book");
+  if (m_authorId != -1)
+    query += QString::fromUtf8(" WHERE authorid = %1").arg(m_authorId);
+
+  setQuery(query);
+  if (lastError().type() != QSqlError::NoError)
+    m_store->reportDbError(tr("Error running showAuthor query"), lastError());
+}
diff --git a/examples/bookstore/booksofauthormodel.h b/examples/bookstore/booksofauthormodel.h
new file mode 100644 (file)
index 0000000..1f84e3b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef BOOKSOFAUTHORMODEL_H
+#define BOOKSOFAUTHORMODEL_H
+
+#include <QSqlQueryModel>
+
+class BookStore;
+
+class BooksOfAuthorModel : public QSqlQueryModel
+{
+  Q_OBJECT
+  public:
+    explicit BooksOfAuthorModel(BookStore *store = 0);
+  
+  public slots:
+    void setAuthor(int authorId);
+
+  private:
+    void refresh();
+
+    BookStore *m_store;
+    int m_authorId;    
+};
+
+#endif // BOOKSOFAUTHORMODEL_H
diff --git a/examples/bookstore/bookstore.cpp b/examples/bookstore/bookstore.cpp
new file mode 100644 (file)
index 0000000..c2f5d89
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "bookstore.h"
+
+#include "booklistproxymodel.h"
+#include "booksofauthormodel.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QSqlDatabase>
+#include <QSqlError>
+#include <QSqlTableModel>
+
+BookStore::BookStore(QObject *parent)
+  : QObject(parent)
+{
+  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+  db.setDatabaseName("bookstore.db");
+  if (!db.open()) {
+    reportDbError( tr("Error When opening database"), db.lastError() );
+    QCoreApplication::instance()->exit(-1);
+  }
+
+  m_authorTable = new QSqlTableModel(this);
+  m_authorTable->setTable("author");
+  m_authorTable->select();
+  qDebug() << "authorTable.rowCount=" << m_authorTable->rowCount();
+  m_authorTable->setHeaderData(1, Qt::Horizontal, tr("First Name"));
+  m_authorTable->setHeaderData(2, Qt::Horizontal, tr("Last Name"));
+
+  m_bookTable = new QSqlTableModel(this);
+  m_bookTable->setTable("book");
+  m_bookTable->select();
+  m_bookTable->setHeaderData(1, Qt::Horizontal, tr("Title"));
+  m_bookTable->setHeaderData(2, Qt::Horizontal, tr("Price"));
+  m_bookTable->setHeaderData(4, Qt::Horizontal, tr("Notes"));
+
+  m_booksOfAuthorTable = new BooksOfAuthorModel(this);
+
+  m_bookList = new BookListProxyModel(this);
+
+  QSqlQueryModel *bookListSourceModel = new QSqlQueryModel(this);
+  m_bookList->setSourceModel(bookListSourceModel);
+  bookListSourceModel->setQuery("SELECT book.id, book.title, book.price, book.notes, "
+                                "author.id, author.firstname, author.surname "
+                                "FROM book, author WHERE book.authorid = author.id");
+
+  if (bookListSourceModel->lastError().type() != QSqlError::NoError)
+    reportDbError(tr("Error running book list source query"), bookListSourceModel->lastError());
+
+  m_bookList->addColumnToRoleMapping(0, BookListProxyModel::BookIdRole);
+  m_bookList->addColumnToRoleMapping(1, BookListProxyModel::BookTitleRole);
+  m_bookList->addColumnToRoleMapping(2, BookListProxyModel::BookPriceRole);
+  m_bookList->addColumnToRoleMapping(3, BookListProxyModel::BookNotesRole);
+  m_bookList->addColumnToRoleMapping(4, BookListProxyModel::AuthorIdRole);
+  m_bookList->addColumnToRoleMapping(5, BookListProxyModel::AuthorFirstNameRole);
+  m_bookList->addColumnToRoleMapping(6, BookListProxyModel::AuthorLastNameRole);
+}
+
+QObject *BookStore::authorTable() const
+{
+  return m_authorTable;
+}
+
+QObject *BookStore::bookTable() const
+{
+  return m_bookTable;
+}
+
+QObject *BookStore::booksOfAuthorTable() const
+{
+  return m_booksOfAuthorTable;
+}
+
+QObject *BookStore::bookList() const
+{
+  return m_bookList;
+}
+
+void BookStore::reportDbError(const QString &message, const QSqlError &error)
+{
+  const QString text = tr("%1\nDriver Message: %2\nDatabase Message %3")
+                          .arg(message)
+                          .arg(error.driverText())
+                          .arg(error.databaseText());
+
+  qCritical() << text;
+
+  emit critical(text);
+}
+
+int BookStore::authorId(const QModelIndex &index) const
+{
+  if (index.model() != m_authorTable) {
+    qWarning() << Q_FUNC_INFO << "index.model is not the authorModel";
+    return -1;
+  }
+
+  const QModelIndex idIndex = m_authorTable->index(index.row(), 0, index.parent());
+  return m_authorTable->data(idIndex).toInt();
+}
diff --git a/examples/bookstore/bookstore.db b/examples/bookstore/bookstore.db
new file mode 100644 (file)
index 0000000..e3533fd
Binary files /dev/null and b/examples/bookstore/bookstore.db differ
diff --git a/examples/bookstore/bookstore.h b/examples/bookstore/bookstore.h
new file mode 100644 (file)
index 0000000..a0a3778
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef BOOKSTORE_H
+#define BOOKSTORE_H
+
+#include <QObject>
+
+class BookListProxyModel;
+class BooksOfAuthorModel;
+
+class QModelIndex;
+class QSqlError;
+class QSqlTableModel;
+
+class BookStore : public QObject
+{
+  Q_OBJECT
+  Q_PROPERTY(QObject* authorTable READ authorTable CONSTANT)
+  Q_PROPERTY(QObject* bookTable READ bookTable CONSTANT)
+  Q_PROPERTY(QObject* booksOfAuthorTable READ booksOfAuthorTable CONSTANT)
+  Q_PROPERTY(QObject* bookList READ bookList CONSTANT)
+
+  public:
+    explicit BookStore(QObject *parent = 0);
+
+    QObject *authorTable() const;
+    QObject *bookTable() const;
+    QObject *booksOfAuthorTable() const;
+    QObject *bookList() const;
+
+    void reportDbError(const QString &message, const QSqlError &error);
+
+    Q_INVOKABLE int authorId(const QModelIndex &index) const;
+
+  Q_SIGNALS:
+    void information(const QString &message);
+    void critical(const QString &message);
+
+  private:
+    QSqlTableModel *m_authorTable;
+    QSqlTableModel *m_bookTable;
+    BooksOfAuthorModel *m_booksOfAuthorTable;
+    BookListProxyModel *m_bookList;
+};
+
+#endif // BOOKSTORE_H
diff --git a/examples/bookstore/bookstore.pro b/examples/bookstore/bookstore.pro
new file mode 100644 (file)
index 0000000..8d45058
--- /dev/null
@@ -0,0 +1,26 @@
+TEMPLATE = app
+
+INCLUDEPATH += . ../../lib
+
+LIBS += -L ../../lib -ldeclarativewidgets
+
+QT += declarative sql
+
+SOURCES += \
+    main.cpp \
+    bookstore.cpp \
+    booksofauthormodel.cpp \
+    booklistproxymodel.cpp
+
+HEADERS += \
+    bookstore.h \
+    booksofauthormodel.h \
+    booklistproxymodel.h
+
+OTHER_FILES += \
+    widgets/main.qml \
+    qtquick/main.qml \
+    README.txt
+
+RESOURCES += \
+    bookstore.qrc
diff --git a/examples/bookstore/bookstore.qrc b/examples/bookstore/bookstore.qrc
new file mode 100644 (file)
index 0000000..fc915e4
--- /dev/null
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/">
+        <file>widgets/main.qml</file>
+        <file>qtquick/main.qml</file>
+    </qresource>
+</RCC>
diff --git a/examples/bookstore/bookstore.sqlite3.sql b/examples/bookstore/bookstore.sqlite3.sql
new file mode 100644 (file)
index 0000000..77e0d38
--- /dev/null
@@ -0,0 +1,38 @@
+DROP TABLE IF EXISTS author;
+DROP TABLE IF EXISTS book;
+
+CREATE TABLE author 
+( 
+   id INTEGER PRIMARY KEY,
+   firstname VARCHAR(40) NOT NULL,
+   surname VARCHAR(40) NOT NULL
+);
+
+CREATE TABLE book 
+( 
+  id INTEGER PRIMARY KEY,
+  title VARCHAR(40),
+  price REAL,
+  authorid INTEGER,
+  notes VARCHAR(255) 
+);
+
+INSERT INTO author( id, firstname, surname ) VALUES ( 1, "Jesper", "Pedersen" );
+INSERT INTO author( id, firstname, surname ) VALUES ( 2, "Kalle Mathias", "Dalheimer" );
+INSERT INTO author( id, firstname, surname ) VALUES ( 3, "Bjarne", "Stroustrup");
+INSERT INTO author( id, firstname, surname ) VALUES ( 4, "Scott", "Meyers" );
+
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 1, "Sams Teach Yourself Emacs in 24 Hours", 24.99, 1, "Good book" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 2, "Practical Qt", 45.00, 1, "Learn Amazing Qt Techniques" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 3, "Running Linux", 31.96, 2, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 4, "Programming with Qt (1. ed)", 26.36, 2, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 5, "Programming with Qt (2. ed)", 39.95, 2, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 6, "The C++ Programming Language SE.", 59.95, 3, "Special Edition" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 7, "The C++ Programming Language", 47.66, 3, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 8, "The Annotated C++ Reference Manual", 55.95, 3, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 9, "The Design and Evolution of C++", 34.95, 3, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 10, "Effective C++", 37.95, 4, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 11, "More Effective C++", 39.95, 4, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 12, "Effective C++ Cd", 29.95, 4, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 13, "Effective C++ (50 ways)", 39.95, 4, "" );
+INSERT INTO book( id, title, price, authorid, notes) VALUES ( 14, "Effective STL", 39.99, 4, "" );
diff --git a/examples/bookstore/main.cpp b/examples/bookstore/main.cpp
new file mode 100644 (file)
index 0000000..63f0673
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "bookstore.h"
+
+#include "declarativewidgetsdocument.h"
+
+#include <QApplication>
+#include <QDebug>
+#include <QDeclarativeContext>
+#include <QDeclarativeEngine>
+#include <QDeclarativeView>
+#include <QWidget>
+
+static QWidget *createDeclarativeWidgetsUi(BookStore *bookStore)
+{
+  const QUrl documentUrl = QUrl("qrc:///widgets/main.qml");
+
+  DeclarativeWidgetsDocument *document = new DeclarativeWidgetsDocument(documentUrl, bookStore);
+  QObject::connect(document->engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+
+  document->setContextProperty("_store", bookStore);
+
+  QWidget *widget = document->create<QWidget>();
+  if (!widget)
+    qFatal("Failed to create widget from document");
+
+  return widget;
+}
+
+static QWidget *createQtQuickUi(BookStore *bookStore)
+{
+  QDeclarativeView *view = new QDeclarativeView();
+
+  QObject::connect(view->engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+
+  view->engine()->rootContext()->setContextProperty("_store", bookStore);
+
+  view->setSource(QUrl("qrc:///qtquick/main.qml"));
+
+  return view;
+}
+
+int main(int argc, char **argv)
+{
+  QApplication app(argc, argv);
+
+  bool useDeclarativeWidgets = false;
+
+  const QStringList args = app.arguments();
+  if (args.count() >= 2) {
+    Q_FOREACH (const QString &arg, args) {
+      if (arg == "-h" || arg == "-help" || arg == "--help") {
+        qDebug() << "Usage: bookstore --mode staff|customer";
+        return 0;
+      }
+    }
+
+    if (args.count() != 3 || args[1] != "--mode")
+      qFatal("Usage: bookstore --mode staff|customer");
+
+    if (args[2] != "staff" && args[2] != "customer")
+      qFatal("Unknown mode option %s\nUsage: bookstore --mode staff|customer", qPrintable(argv[2]));
+
+    useDeclarativeWidgets = (args[2] == "staff");
+  }
+
+  BookStore bookStore;
+
+  QWidget *widget = useDeclarativeWidgets ? createDeclarativeWidgetsUi(&bookStore) : createQtQuickUi(&bookStore);
+    
+  widget->show();
+
+  return app.exec();
+}
diff --git a/examples/bookstore/qtquick/main.qml b/examples/bookstore/qtquick/main.qml
new file mode 100644 (file)
index 0000000..745f7f5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+import QtQuick 1.1
+
+Column {
+  Text {
+    text: qsTr("Currently available books")
+    horizontalAlignment: Qt.AlignHCenter
+    font.pointSize: 24
+  }
+
+  ListView {
+    id: listView
+
+    width: 800
+    height: 600
+    model: _store.bookList;
+    highlightFollowsCurrentItem: true
+
+    delegate: Column {
+      property real price: bookPrice
+      property string notes: bookNotes
+
+      Text {
+        text: bookTitle
+        font.pointSize: 16
+      }
+      Text {
+        text: qsTr("by %1, %2").arg(authorLastName).arg(authorFirstName)
+      }
+    }
+
+    highlight: Rectangle {
+      color: "#ADD8E6"
+
+      width: listView.width
+      height: listView.currentItem.height
+      y: listView.currentItem.y
+    }
+  }
+
+  Text {
+    property real price: listView.currentIndex >= 0 ? listView.currentItem.price : 0
+
+    text: qsTr("Price: %1").arg(price)
+    horizontalAlignment: Qt.AlignHCenter
+    font.pointSize: 24
+  }
+  Text {
+    property string notes: listView.currentIndex >= 0 ? listView.currentItem.notes : qsTr("N/A")
+
+    text: qsTr("Notes: %1").arg(notes)
+    horizontalAlignment: Qt.AlignHCenter
+  }
+}
diff --git a/examples/bookstore/widgets/main.qml b/examples/bookstore/widgets/main.qml
new file mode 100644 (file)
index 0000000..5053038
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+  Author: Kevin Krammer, krake@kdab.com
+  Author: Tobias Koenig, tokoe@kdab.com
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+import QtQuick 1.0
+import QtGui 1.0
+
+Widget {
+  windowTitle: qsTr("Book Store")
+  geometry: Qt.rect(0, 0, 800, 600)
+
+  VBoxLayout {
+    TabWidget {
+      Widget {
+        TabWidget.label: qsTr("Store View")
+
+        HBoxLayout {
+          TableView {
+            id: storeAuthorTable
+
+            model: _store.authorTable;
+
+            Component.onCompleted:
+              storeAuthorTable.hideColumn(0)
+
+            onActivated: _store.booksOfAuthorTable.setAuthor(_store.authorId(index))
+          }
+          TableView {
+            id: storeBooksOfAuthorTable
+
+            model: _store.booksOfAuthorTable
+          }
+        }
+      }
+
+      Widget {
+        TabWidget.label: qsTr("Database View")
+
+        VBoxLayout {
+          TableView {
+            model: _store.authorTable;
+          }
+          TableView {
+            model: _store.bookTable;
+          }
+        }
+      }
+    }
+  }
+}
index defb139..55dc0bc 100644 (file)
@@ -1,6 +1,6 @@
 TEMPLATE = subdirs
 
-SUBDIRS += text-editor
+SUBDIRS += text-editor bookstore
 
 OTHER_FILES += \
     animation.qml \