examples/samplephonebook/contactlistpage.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:BSD$
       
    10 ** You may use this file under the terms of the BSD license as follows:
       
    11 **
       
    12 ** "Redistribution and use in source and binary forms, with or without
       
    13 ** modification, are permitted provided that the following conditions are
       
    14 ** met:
       
    15 **   * Redistributions of source code must retain the above copyright
       
    16 **     notice, this list of conditions and the following disclaimer.
       
    17 **   * Redistributions in binary form must reproduce the above copyright
       
    18 **     notice, this list of conditions and the following disclaimer in
       
    19 **     the documentation and/or other materials provided with the
       
    20 **     distribution.
       
    21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
       
    22 **     the names of its contributors may be used to endorse or promote
       
    23 **     products derived from this software without specific prior written
       
    24 **     permission.
       
    25 **
       
    26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
       
    37 ** $QT_END_LICENSE$
       
    38 **
       
    39 ****************************************************************************/
       
    40 
       
    41 #include "contactlistpage.h"
       
    42 #ifdef BUILD_VERSIT
       
    43 #include "qversitreader.h"
       
    44 #include "qversitcontactimporter.h"
       
    45 #include "qversitwriter.h"
       
    46 #include "qversitcontactexporter.h"
       
    47 #endif
       
    48 
       
    49 #include <QtGui>
       
    50 
       
    51 ContactListPage::ContactListPage(QMainWindow *mainWindow, QWidget *parent)
       
    52         : QWidget(parent), m_mainWindow(mainWindow)
       
    53 {
       
    54     m_manager = 0;
       
    55     m_currentFilter = QContactFilter();
       
    56 
       
    57     m_backendsCombo = new QComboBox(this);
       
    58     QStringList availableManagers = QContactManager::availableManagers();
       
    59     availableManagers.removeAll("invalid");
       
    60     foreach(QString managerName, availableManagers) {
       
    61 
       
    62         QMap<QString, QString> params;
       
    63         QString managerUri = QContactManager::buildUri(managerName, params);
       
    64 
       
    65         // Add some parameters to SIM backend so that we can use
       
    66         // all the stores.
       
    67         if (managerName == "symbiansim") {
       
    68             availableManagers.removeAll("symbiansim");
       
    69 
       
    70             availableManagers.append("symbiansim:adn");
       
    71             params.insert("store", "ADN");
       
    72             managerUri = QContactManager::buildUri(managerName, params);
       
    73             m_availableManagers.insert(availableManagers.last(), managerUri);
       
    74 
       
    75             availableManagers.append("symbiansim:fdn");
       
    76             params.clear();
       
    77             params.insert("store", "FDN");
       
    78             managerUri = QContactManager::buildUri(managerName, params);
       
    79             m_availableManagers.insert(availableManagers.last(), managerUri);
       
    80 
       
    81             availableManagers.append("symbiansim:sdn");
       
    82             params.clear();
       
    83             params.insert("store", "SDN");
       
    84             managerUri = QContactManager::buildUri(managerName, params);
       
    85             m_availableManagers.insert(availableManagers.last(), managerUri);
       
    86         }
       
    87         else {
       
    88             m_availableManagers.insert(managerName, managerUri);
       
    89         }
       
    90     }
       
    91     m_backendsCombo->addItems(availableManagers);
       
    92     connect(m_backendsCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(backendSelected()));
       
    93     m_filterActiveLabel = new QLabel(tr("Filter active"));
       
    94     m_filterActiveLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
       
    95 
       
    96     QVBoxLayout *bookLayout = new QVBoxLayout;
       
    97     QFormLayout *backendLayout = new QFormLayout;
       
    98     backendLayout->addRow(tr("Store:"), m_backendsCombo);
       
    99     backendLayout->addRow(m_filterActiveLabel);
       
   100     bookLayout->addLayout(backendLayout);
       
   101 
       
   102     m_contactsList = new QListWidget(this);
       
   103     bookLayout->addWidget(m_contactsList);
       
   104 
       
   105     // Action buttons at the bottom
       
   106     QHBoxLayout *btnLayout1 = new QHBoxLayout;
       
   107 
       
   108     QPushButton* addBtn = new QPushButton(tr("&Add"), this);
       
   109     connect(addBtn, SIGNAL(clicked()), this, SLOT(addClicked()));
       
   110     btnLayout1->addWidget(addBtn);
       
   111 
       
   112     QPushButton* editBtn = new QPushButton(tr("&Edit"), this);
       
   113     connect(editBtn, SIGNAL(clicked()), this, SLOT(editClicked()));
       
   114     btnLayout1->addWidget(editBtn);
       
   115 
       
   116     QPushButton* deleteBtn = new QPushButton(tr("&Delete"), this);
       
   117     connect(deleteBtn, SIGNAL(clicked()), this, SLOT(deleteClicked()));
       
   118     btnLayout1->addWidget(deleteBtn);
       
   119 
       
   120     bookLayout->addLayout(btnLayout1);
       
   121 
       
   122     setLayout(bookLayout);
       
   123 
       
   124     // Add items to the menu
       
   125     if (m_mainWindow) {
       
   126 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_OS_WINCE)
       
   127         // These platforms need their menu items added directly to the menu bar.
       
   128         QMenuBar *optionsMenu = m_mainWindow->menuBar();
       
   129 #else
       
   130         QMenu *optionsMenu = new QMenu(tr("&Contacts"), this);
       
   131         m_mainWindow->menuBar()->addMenu(optionsMenu);
       
   132 #endif
       
   133         QAction* filterAction = new QAction(tr("Apply &Filter..."), this);
       
   134         connect(filterAction, SIGNAL(triggered()), this, SLOT(filterClicked()));
       
   135         optionsMenu->addAction(filterAction);
       
   136         QAction* clearFilterAction = new QAction(tr("&Clear Filter"), this);
       
   137         connect(clearFilterAction, SIGNAL(triggered()), this, SIGNAL(clearFilter()));
       
   138         optionsMenu->addAction(clearFilterAction);
       
   139         optionsMenu->addSeparator();
       
   140 
       
   141 #ifdef BUILD_VERSIT
       
   142         QAction* importAction = new QAction(tr("&Import contacts..."), this);
       
   143         connect(importAction, SIGNAL(triggered()), this, SLOT(importClicked()));
       
   144         optionsMenu->addAction(importAction);
       
   145         QAction* exportAction = new QAction(tr("Ex&port contacts..."), this);
       
   146         connect(exportAction, SIGNAL(triggered()), this, SLOT(exportClicked()));
       
   147         optionsMenu->addAction(exportAction);
       
   148         optionsMenu->addSeparator();
       
   149 #endif
       
   150 #if !(defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6))
       
   151         // Maemo applications don't have an Exit button in the menu.
       
   152         QAction* exitAction = new QAction(tr("E&xit"), this);
       
   153         connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
       
   154         optionsMenu->addAction(exitAction);
       
   155 #endif
       
   156     }
       
   157 
       
   158     // force update to backend.
       
   159     QTimer::singleShot(0, this, SLOT(backendSelected()));
       
   160 }
       
   161 
       
   162 ContactListPage::~ContactListPage()
       
   163 {
       
   164     QList<QContactManager*> initialisedManagers = m_initialisedManagers.values();
       
   165     while (!initialisedManagers.isEmpty()) {
       
   166         QContactManager *deleteMe = initialisedManagers.takeFirst();
       
   167         delete deleteMe;
       
   168     }
       
   169 }
       
   170 
       
   171 void ContactListPage::backendSelected()
       
   172 {
       
   173     QString managerUri = m_availableManagers.value(m_backendsCombo->currentText());
       
   174 
       
   175     // first, check to see if they reselected the same backend.
       
   176     if (m_manager && m_manager->managerUri() == managerUri)
       
   177         return;
       
   178 
       
   179     // the change is real.  update.
       
   180     if (m_initialisedManagers.contains(managerUri)) {
       
   181         m_manager = m_initialisedManagers.value(managerUri);
       
   182     } else {
       
   183         m_manager = QContactManager::fromUri(managerUri);
       
   184         if (m_manager->error()) {
       
   185             QMessageBox::information(this, tr("Failed!"), QString("Failed to open store!\n(error code %1)").arg(m_manager->error()));
       
   186             delete m_manager;
       
   187             m_manager = 0;
       
   188             return;
       
   189         }
       
   190         m_initialisedManagers.insert(managerUri, m_manager);
       
   191     }
       
   192 
       
   193     // signal that the manager has changed.
       
   194     emit managerChanged(m_manager);
       
   195 
       
   196     // and... rebuild the list.
       
   197     rebuildList(m_currentFilter);
       
   198 }
       
   199 
       
   200 void ContactListPage::rebuildList(const QContactFilter& filter)
       
   201 {
       
   202     m_currentFilter = QContactManagerEngine::canonicalizedFilter(filter);
       
   203 
       
   204     m_filterActiveLabel->setVisible(m_currentFilter != QContactFilter());
       
   205 
       
   206     m_contactsList->clear();
       
   207     m_idToListIndex.clear();
       
   208     m_contacts = m_manager->contacts(m_currentFilter);
       
   209     foreach (QContact contact, m_contacts) {
       
   210         QListWidgetItem *currItem = new QListWidgetItem;
       
   211         currItem->setData(Qt::DisplayRole, contact.displayLabel());
       
   212         currItem->setData(Qt::UserRole, contact.localId()); // also store the id of the contact.
       
   213         m_idToListIndex.insert(contact.localId(), m_contactsList->count());
       
   214         m_contactsList->addItem(currItem);
       
   215     }
       
   216 }
       
   217 
       
   218 void ContactListPage::addClicked()
       
   219 {
       
   220     if (m_manager)
       
   221         emit showEditorPage(QContactLocalId(0));
       
   222 }
       
   223 
       
   224 void ContactListPage::editClicked()
       
   225 {
       
   226     if (m_contactsList->currentItem())
       
   227         emit showEditorPage(QContactLocalId(m_contactsList->currentItem()->data(Qt::UserRole).toUInt()));
       
   228     // else, nothing selected; ignore.
       
   229 }
       
   230 
       
   231 void ContactListPage::filterClicked()
       
   232 {
       
   233     if (m_manager)
       
   234         emit showFilterPage(m_currentFilter);
       
   235 }
       
   236 
       
   237 void ContactListPage::deleteClicked()
       
   238 {
       
   239     if (!m_manager) {
       
   240         qWarning() << "No manager selected; cannot delete.";
       
   241         return;
       
   242     }
       
   243 
       
   244     if (!m_contactsList->currentItem()) {
       
   245         qWarning() << "Nothing to delete.";
       
   246         return;
       
   247     }
       
   248 
       
   249     QContactLocalId contactId = QContactLocalId(m_contactsList->currentItem()->data(Qt::UserRole).toUInt());
       
   250     bool success = m_manager->removeContact(contactId);
       
   251     if (success) {
       
   252         delete m_contactsList->takeItem(m_contactsList->currentRow());
       
   253     }
       
   254     else
       
   255         QMessageBox::information(this, "Failed!", "Failed to delete contact!");
       
   256 }
       
   257 
       
   258 void ContactListPage::importClicked()
       
   259 {
       
   260 #ifdef BUILD_VERSIT
       
   261     if (!m_manager) {
       
   262         qWarning() << "No manager selected; cannot import";
       
   263         return;
       
   264     }
       
   265     QString fileName = QFileDialog::getOpenFileName(this,
       
   266        tr("Select vCard file"), ".", tr("vCard files (*.vcf)"));
       
   267     QFile file(fileName);
       
   268     file.open(QIODevice::ReadOnly);
       
   269     if (file.isReadable()) {
       
   270         QVersitReader reader;
       
   271         reader.setDevice(&file);
       
   272         if (reader.startReading() && reader.waitForFinished()) {
       
   273             QVersitContactImporter importer;
       
   274             if (importer.importDocuments(reader.results())) {
       
   275                 QList<QContact> contacts = importer.contacts();
       
   276                 QMap<int, QContactManager::Error> errorMap;
       
   277                 QList<QContact>::iterator it = contacts.begin();
       
   278                 while (it != contacts.end()) {
       
   279                     *it = m_manager->compatibleContact(*it);
       
   280                     it++;
       
   281                 }
       
   282                 m_manager->saveContacts(&contacts, &errorMap);
       
   283                 rebuildList(m_currentFilter);
       
   284             }
       
   285         }
       
   286     }
       
   287 #endif
       
   288 }
       
   289 
       
   290 void ContactListPage::exportClicked()
       
   291 {
       
   292 #ifdef BUILD_VERSIT
       
   293     if (!m_manager) {
       
   294         qWarning() << "No manager selected; cannot export";
       
   295         return;
       
   296     }
       
   297     QString fileName = QFileDialog::getSaveFileName(this, tr("Save vCard"),
       
   298                                                     "./contacts.vcf",
       
   299                                                     tr("vCards (*.vcf)"));
       
   300     QFile file(fileName);
       
   301     file.open(QIODevice::WriteOnly);
       
   302     if (file.isWritable()) {
       
   303         QVersitContactExporter exporter;
       
   304         if(exporter.exportContacts(m_contacts, QVersitDocument::VCard30Type)) {
       
   305             QList<QVersitDocument> documents = exporter.documents();
       
   306             QVersitWriter writer;
       
   307             writer.setDevice(&file);
       
   308             writer.startWriting(documents);
       
   309             writer.waitForFinished();
       
   310         }
       
   311     }
       
   312 #endif
       
   313 }