Qt 1.6 | Enginio Manual | Enginio C++ Examples - Cloud Address Book | addressbookmodel.cpp Example File

Qt 1.6.3 Reference Documentation

# addressbookmodel.cpp Example File

cloudaddressbook/addressbookmodel.cpp

      /****************************************************************************
      **
      ** Copyright (C) 2015 The Qt Company Ltd.
      ** Contact: http://www.qt.io/licensing/
      **
      ** This file is part of the examples of the Qt Toolkit.
      **
      ** $QT_BEGIN_LICENSE:BSD$
      ** You may use this file under the terms of the BSD license as follows:
      **
      ** "Redistribution and use in source and binary forms, with or without
      ** modification, are permitted provided that the following conditions are
      ** met:
      **   * Redistributions of source code must retain the above copyright
      **     notice, this list of conditions and the following disclaimer.
      **   * Redistributions in binary form must reproduce the above copyright
      **     notice, this list of conditions and the following disclaimer in
      **     the documentation and/or other materials provided with the
      **     distribution.
      **   * Neither the name of The Qt Company Ltd nor the names of its
      **     contributors may be used to endorse or promote products derived
      **     from this software without specific prior written permission.
      **
      **
      ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
      **
      ** $QT_END_LICENSE$
      **
      ****************************************************************************/

      #include <QtCore/qhash.h>
      #include <QtCore/qbytearray.h>
      #include <QtCore/qjsondocument.h>
      #include <QtCore/qjsonvalue.h>
      #include <QtCore/qjsonobject.h>
      #include <QtCore/qjsonarray.h>

      #include <QtGui/qfont.h>

      #include "addressbookmodel.h"

      AddressBookModel::AddressBookModel(QObject *parent)
          : EnginioModel(parent)
          , _searchReply()
      {}

      AddressBookModel::~AddressBookModel()
      {}

      QVariant AddressBookModel::data(const QModelIndex &index, int role) const
      {
          if (role == Qt::DisplayRole) {
              // we assume here that column order is constant and it is the same as in AddressBookModel::Roles
              return EnginioModel::data(index, FirstNameRole + index.column()).value<QJsonValue>().toString();
          }
          if (role == Qt::FontRole) {
              // this role is used to mark items found in the full text search.
              QFont font;
              QString id = EnginioModel::data(index, Enginio::IdRole).value<QString>();
              font.setBold(_markedItems.contains(id));
              return font;
          }

          return EnginioModel::data(index, role);
      }

      bool AddressBookModel::setData(const QModelIndex &index, const QVariant &value, int role)
      {
          bool result = role == Qt::EditRole
                  ? EnginioModel::setData(this->index(index.row()), value, FirstNameRole + index.column())
                  : EnginioModel::setData(this->index(index.row()), value, role);

          // if the data was edited, the marked items set may not be valid anymore
          // so we need to clear it.
          if (result)
              _markedItems.clear();
          return result;
      }

      int AddressBookModel::columnCount(const QModelIndex &parent) const
      {
          return parent.isValid() ? 0 : 5;
      }

      QVariant AddressBookModel::headerData(int section, Qt::Orientation orientation, int role) const
      {
          if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
              switch (section) {
              case 0: return QStringLiteral("First name");
              case 1: return QStringLiteral("Last name");
              case 2: return QStringLiteral("Email");
              case 3: return QStringLiteral("Phone number");
              case 4: return QStringLiteral("Address");
              }
              return QVariant();
          }
          return EnginioModel::headerData(section, orientation, role);
      }

      QHash<int, QByteArray> AddressBookModel::roleNames() const
      {
          QHash<int, QByteArray> roles = EnginioModel::roleNames();
          roles.insert(FirstNameRole, "firstName");
          roles.insert(LastNameRole, "lastName");
          roles.insert(EmailRole, "email");
          roles.insert(PhoneRole, "phone");
          roles.insert(AddressRole, "address");
          return roles;
      }

      void AddressBookModel::newSearch(const QString &search)
      {
          if (search.isEmpty())
              return;

          // construct JSON object:
          //    {
          //        "objectTypes": ["objects.addressbook"],
          //        "search": { "phrase": "*PHRASE*",
          //            "properties": ["firstName", "lastName", "email", "phone", "address"]
          //        }
          //    }

          QJsonObject query;
          {
              QJsonArray objectTypes;
              objectTypes.append(QString::fromUtf8("objects.addressbook"));

              QJsonArray properties;
              properties.append(QString::fromUtf8("firstName"));
              properties.append(QString::fromUtf8("lastName"));
              properties.append(QString::fromUtf8("email"));
              properties.append(QString::fromUtf8("phone"));
              properties.append(QString::fromUtf8("address"));

              QJsonObject searchQuery;
              searchQuery.insert("phrase", "*" + search + "*");
              searchQuery.insert("properties", properties);

              query.insert("objectTypes", objectTypes);
              query.insert("search", searchQuery);
          }

          if (_searchReply) {
              // a new search is created before the old one was finished
              // we will not be interested in the results of the old search.
              _searchReply->disconnect(this);
          }

          _searchReply =  client()->fullTextSearch(query);
          QObject::connect(_searchReply, &EnginioReply::finished, this, &AddressBookModel::searchResultsArrived);
          QObject::connect(_searchReply, &EnginioReply::finished, _searchReply, &EnginioReply::deleteLater);
      }

      void AddressBookModel::searchResultsArrived()
      {
          // clear old marks.
          _markedItems.clear();

          // update marked ids.
          QJsonArray results = _searchReply->data()["results"].toArray();
          foreach (const QJsonValue &value, results) {
              QJsonObject person = value.toObject();
              _markedItems.insert(person["id"].toString());
          }

          QVector<int> roles;
          roles.append(Qt::FontRole);
          // We do not keep id -> row mapping, therefore it is easier to emit
          // data change signal for all items, even if it is not optimal from
          // the performance point of view.
          emit dataChanged(index(0), index(rowCount() - 1, columnCount() - 1) , roles);

          _searchReply = 0;
          emit searchFinished();
      }