examples/serviceactions/mainwindow.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 "mainwindow.h"
       
    42 #include "attachmentlistwidget.h"
       
    43 #include "qmessageservice.h"
       
    44 #include <qmessagemanager.h>
       
    45 #include <QComboBox>
       
    46 #include <QListWidget>
       
    47 #include <QVBoxLayout>
       
    48 #include <QLabel>
       
    49 #include <QTabWidget>
       
    50 #include <QPointer>
       
    51 #include <QPushButton>
       
    52 #include <QDebug>
       
    53 #include <QLineEdit>
       
    54 #include <QTextEdit>
       
    55 #include <QTextBrowser>
       
    56 #include <QFileDialog>
       
    57 #include <QTimer>
       
    58 #include <QMessageBox>
       
    59 #include <QThread>
       
    60 #include <QStackedLayout>
       
    61 #include <QPair>
       
    62 #include <QScrollArea>
       
    63 #include <QMenuBar>
       
    64 #include <QApplication>
       
    65 #include <QStackedWidget>
       
    66 #include <QMutex>
       
    67 #include <QKeyEvent>
       
    68 
       
    69 static const QSize WindowGeometry(400,300);
       
    70 static const QString WindowTitle("Service-actions Example");
       
    71 static unsigned int RecentMessagesCount = 50;
       
    72 
       
    73 class AccountsWidget : public QWidget
       
    74 {
       
    75     Q_OBJECT
       
    76 
       
    77 private:
       
    78     class Loader : public QThread
       
    79     {
       
    80     public:
       
    81         Loader(AccountsWidget* parent);
       
    82         void run();
       
    83 
       
    84     private:
       
    85         AccountsWidget* m_parent;
       
    86     };
       
    87 
       
    88 public:
       
    89     AccountsWidget(QWidget* parent = 0);
       
    90     QMessageAccountId currentAccount() const;
       
    91     QString currentAccountName() const;
       
    92     bool isEmpty() const;
       
    93 
       
    94 signals:
       
    95     void accountChanged();
       
    96 
       
    97 protected:
       
    98     void showEvent(QShowEvent* e);
       
    99     void hideEvent(QHideEvent* e);
       
   100 
       
   101 private slots:
       
   102     void load();
       
   103     void loadStarted();
       
   104     void loadFinished();
       
   105 
       
   106 private:
       
   107     void setupUi();
       
   108     void setIds(const QMessageAccountIdList& ids);
       
   109     QMessageAccountIdList ids() const;
       
   110 
       
   111 private:
       
   112     QStackedLayout* m_stackedLayout;
       
   113     QComboBox* m_accountsCombo;
       
   114     QLabel* m_busyLabel;
       
   115 
       
   116     Loader m_loader;
       
   117     mutable QMutex m_loadMutex;
       
   118     QMessageAccountIdList m_ids;
       
   119 };
       
   120 
       
   121 AccountsWidget::Loader::Loader(AccountsWidget* parent)
       
   122 :
       
   123 QThread(parent),
       
   124 m_parent(parent)
       
   125 {
       
   126 }
       
   127 
       
   128 void AccountsWidget::Loader::run()
       
   129 {
       
   130     QMessageManager manager;
       
   131     m_parent->setIds(manager.queryAccounts());
       
   132 }
       
   133 
       
   134 AccountsWidget::AccountsWidget(QWidget* parent)
       
   135 :
       
   136 QWidget(parent),
       
   137 m_stackedLayout(0),
       
   138 m_accountsCombo(0),
       
   139 m_busyLabel(0),
       
   140 m_loader(this)
       
   141 {
       
   142     setupUi();
       
   143 
       
   144     connect(&m_loader,SIGNAL(started()),this,SLOT(loadStarted()));
       
   145     connect(&m_loader,SIGNAL(finished()),this,SLOT(loadFinished()));
       
   146 }
       
   147 
       
   148 QMessageAccountId AccountsWidget::currentAccount() const
       
   149 {
       
   150     QMessageAccountId result;
       
   151     if(m_loader.isFinished() && m_accountsCombo->count())
       
   152     {
       
   153         int index = m_accountsCombo->currentIndex();
       
   154         return ids().at(index);
       
   155     }
       
   156 
       
   157     return result;
       
   158 }
       
   159 
       
   160 QString AccountsWidget::currentAccountName() const
       
   161 {
       
   162     if(m_loader.isFinished() && m_accountsCombo->count())
       
   163         return m_accountsCombo->itemData(m_accountsCombo->currentIndex()).toString();
       
   164     return QString();
       
   165 }
       
   166 
       
   167 bool AccountsWidget::isEmpty() const
       
   168 {
       
   169     return m_accountsCombo->count() == 0;
       
   170 }
       
   171 
       
   172 void AccountsWidget::showEvent(QShowEvent* e)
       
   173 {
       
   174     load();
       
   175     QWidget::showEvent(e);
       
   176 }
       
   177 
       
   178 void AccountsWidget::hideEvent(QHideEvent* e)
       
   179 {
       
   180     if(m_loader.isRunning())
       
   181         m_loader.exit();
       
   182     QWidget::hideEvent(e);
       
   183 }
       
   184 
       
   185 void AccountsWidget::load()
       
   186 {
       
   187     static bool runonce = false;
       
   188     //#define NOTHREAD
       
   189 #ifdef NOTHREAD
       
   190     QMessageManager manager;
       
   191     if(!runonce)
       
   192      setIds(manager.queryAccounts());
       
   193     //        m_loader.start();
       
   194 
       
   195 #else 
       
   196     //    if(!runonce) 
       
   197          m_loader.start();
       
   198 #endif
       
   199     runonce = true;
       
   200 }
       
   201 
       
   202 void AccountsWidget::loadStarted()
       
   203 {
       
   204 #ifndef _WIN32_WCE
       
   205     setCursor(Qt::BusyCursor);
       
   206 #endif
       
   207     m_stackedLayout->setCurrentWidget(m_busyLabel);
       
   208 }
       
   209 
       
   210 void AccountsWidget::loadFinished()
       
   211 {
       
   212     m_accountsCombo->clear();
       
   213 
       
   214     QMessageAccountIdList accountIds = ids();
       
   215 
       
   216     if(!accountIds.isEmpty())
       
   217     {
       
   218         for(int i = 0; i < accountIds.count(); ++i)
       
   219         {
       
   220             QMessageAccount account(accountIds[i]);
       
   221             m_accountsCombo->addItem(QString("%1 - %2").arg(i+1).arg(account.name()),account.name());
       
   222         }
       
   223 
       
   224         m_stackedLayout->setCurrentWidget(m_accountsCombo);
       
   225     }
       
   226     else
       
   227         m_busyLabel->setText("No accounts!");
       
   228 
       
   229 #ifndef _WIN32_WCE
       
   230     setCursor(Qt::ArrowCursor);
       
   231 #endif
       
   232 }
       
   233 
       
   234 void AccountsWidget::setupUi()
       
   235 {
       
   236     m_stackedLayout = new QStackedLayout(this);
       
   237 
       
   238     m_accountsCombo = new QComboBox(this);
       
   239     m_stackedLayout->addWidget(m_accountsCombo);
       
   240     connect(m_accountsCombo,SIGNAL(currentIndexChanged(int)),this,SIGNAL(accountChanged()));
       
   241 
       
   242     m_busyLabel = new QLabel("Loading...");
       
   243     m_stackedLayout->addWidget(m_busyLabel);
       
   244 
       
   245     setSizePolicy(m_accountsCombo->sizePolicy());
       
   246 
       
   247 }
       
   248 
       
   249 void AccountsWidget::setIds(const QMessageAccountIdList& ids)
       
   250 {
       
   251     QMutexLocker mutex(&m_loadMutex);
       
   252 
       
   253     m_ids = ids;
       
   254 }
       
   255 
       
   256 QMessageAccountIdList AccountsWidget::ids() const
       
   257 {
       
   258     QMutexLocker mutex(&m_loadMutex);
       
   259     return m_ids;
       
   260 }
       
   261 
       
   262 class RecentMessagesWidget : public QWidget
       
   263 {
       
   264     Q_OBJECT
       
   265 
       
   266 public:
       
   267     RecentMessagesWidget(QWidget* parent = 0, unsigned int maxRecent = 10);
       
   268     ~RecentMessagesWidget();
       
   269     QMessageId currentMessage() const;
       
   270 
       
   271 signals:
       
   272     void selected(const QMessageId& messageId);
       
   273 
       
   274 protected:
       
   275     void showEvent(QShowEvent* e);
       
   276     void hideEvent(QHideEvent* e);
       
   277 
       
   278 private slots:
       
   279     void currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
       
   280     void messagesFound(const QMessageIdList& result);
       
   281     void stateChanged(QMessageService::State s);
       
   282     void messageUpdated(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filter);
       
   283     void messageRemoved(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filter);
       
   284     void processResults();
       
   285 
       
   286 private:
       
   287     void setupUi();
       
   288     void updateState();
       
   289     void load();
       
   290 
       
   291 private:
       
   292     enum State { Unloaded, Loading, LoadFinished, Processing, LoadFailed, Done };
       
   293     static const int MessageIdRole = Qt::UserRole + 1;
       
   294 
       
   295 private:
       
   296     QListWidget* m_messageListWidget;
       
   297     QLabel* m_statusLabel;
       
   298     QStackedLayout* m_layout;
       
   299     QMessageIdList m_ids;
       
   300     QMap<QMessageId,QListWidgetItem*> m_indexMap;
       
   301     unsigned int m_maxRecent;
       
   302     QMessageService* m_service;
       
   303     State m_state;
       
   304     QMessageManager::NotificationFilterId m_storeFilterId;
       
   305     QMessageManager m_manager;
       
   306 };
       
   307 
       
   308 RecentMessagesWidget::RecentMessagesWidget(QWidget* parent, unsigned int maxRecent)
       
   309 :
       
   310 QWidget(parent),
       
   311 m_messageListWidget(0),
       
   312 m_statusLabel(0),
       
   313 m_layout(0),
       
   314 m_maxRecent(maxRecent),
       
   315 m_service(new QMessageService(this)),
       
   316 m_state(Unloaded)
       
   317 {
       
   318     setupUi();
       
   319     connect(m_service,SIGNAL(messagesFound(const QMessageIdList&)),this,SLOT(messagesFound(const QMessageIdList&)));
       
   320     connect(m_service,SIGNAL(stateChanged(QMessageService::State)),this,SLOT(stateChanged(QMessageService::State)));
       
   321 
       
   322     //register for message update notifications
       
   323 
       
   324     connect(&m_manager, SIGNAL(messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)),
       
   325         this, SLOT(messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)));
       
   326     connect(&m_manager, SIGNAL(messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)),
       
   327         this, SLOT(messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet&)));
       
   328 
       
   329     m_storeFilterId = m_manager.registerNotificationFilter(QMessageFilter());
       
   330 }
       
   331 
       
   332 RecentMessagesWidget::~RecentMessagesWidget()
       
   333 {
       
   334      m_manager.unregisterNotificationFilter(m_storeFilterId);
       
   335 }
       
   336 
       
   337 QMessageId RecentMessagesWidget::currentMessage() const
       
   338 {
       
   339     QMessageId result;
       
   340 
       
   341     if(QListWidgetItem* currentItem = m_messageListWidget->currentItem())
       
   342         result = QMessageId(currentItem->data(MessageIdRole).toString());
       
   343 
       
   344     return result;
       
   345 }
       
   346 
       
   347 void RecentMessagesWidget::showEvent(QShowEvent* e)
       
   348 {
       
   349     if(m_state == Unloaded)
       
   350         load();
       
   351 
       
   352     updateState();
       
   353 
       
   354     QWidget::showEvent(e);
       
   355 }
       
   356 
       
   357 void RecentMessagesWidget::hideEvent(QHideEvent* e)
       
   358 {
       
   359     if(m_state == Loading || m_state == Processing)
       
   360     {
       
   361         m_service->cancel();
       
   362         m_state = Unloaded;
       
   363         m_ids.clear();
       
   364     }
       
   365 
       
   366     QWidget::hideEvent(e);
       
   367 }
       
   368 
       
   369 void RecentMessagesWidget::currentItemChanged(QListWidgetItem*, QListWidgetItem*)
       
   370 {
       
   371     if(m_state != Processing || m_state != Loading)
       
   372         emit selected(currentMessage());
       
   373 }
       
   374 
       
   375 //! [process-results]
       
   376 void RecentMessagesWidget::messagesFound(const QMessageIdList& ids)
       
   377 {
       
   378     m_ids.append(ids);
       
   379 }
       
   380 //! [process-results]
       
   381 
       
   382 void RecentMessagesWidget::stateChanged(QMessageService::State newState)
       
   383 {
       
   384     if (newState == QMessageService::FinishedState) {
       
   385         if ((m_state != LoadFailed) && (m_service->error() == QMessageManager::NoError)) {
       
   386             m_state = LoadFinished;
       
   387         } else {
       
   388             m_state = LoadFailed;
       
   389         }
       
   390     }
       
   391 
       
   392     updateState();
       
   393 }
       
   394 
       
   395 
       
   396 void RecentMessagesWidget::messageUpdated(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filter)
       
   397 {
       
   398     if(!filter.contains(m_storeFilterId) || m_state == Loading || !id.isValid() || !m_indexMap.contains(id))
       
   399         return;
       
   400 
       
   401     //update the pertinent entry to reflect completeness
       
   402 
       
   403     QListWidgetItem* item = m_indexMap.value(id);
       
   404     if(item)
       
   405     {
       
   406 
       
   407         QMessage message(id);
       
   408         bool partialMessage = !message.find(message.bodyId()).isContentAvailable();
       
   409         QFont itemFont = item->font();
       
   410         itemFont.setItalic(partialMessage);
       
   411         item->setFont(itemFont);
       
   412     }
       
   413 }
       
   414 
       
   415 void RecentMessagesWidget::messageRemoved(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filter)
       
   416 {
       
   417     if(!filter.contains(m_storeFilterId) || m_state == Loading || !id.isValid() || !m_indexMap.contains(id))
       
   418         return;
       
   419 
       
   420     QListWidgetItem* item = m_indexMap.value(id);
       
   421     if(item)
       
   422     {
       
   423         int row = m_messageListWidget->row(item);
       
   424         QListWidgetItem* item = m_messageListWidget->takeItem(row);
       
   425         m_indexMap.remove(id);
       
   426         delete item;
       
   427     }
       
   428     m_ids.removeAll(id);
       
   429 }
       
   430 
       
   431 void RecentMessagesWidget::setupUi()
       
   432 {
       
   433     m_layout = new QStackedLayout(this);
       
   434 
       
   435     m_messageListWidget = new QListWidget(this);
       
   436     m_layout->addWidget(m_messageListWidget);
       
   437     connect(m_messageListWidget,SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
       
   438         this,SLOT(currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
       
   439 
       
   440     m_statusLabel = new QLabel(this);
       
   441     m_statusLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
       
   442     m_statusLabel->setFrameStyle(QFrame::Box);
       
   443     m_layout->addWidget(m_statusLabel);
       
   444 
       
   445 }
       
   446 
       
   447 void RecentMessagesWidget::updateState()
       
   448 {
       
   449     switch(m_state)
       
   450     {
       
   451         case Unloaded:
       
   452         {
       
   453             m_statusLabel->setText(QString());
       
   454             m_layout->setCurrentWidget(m_statusLabel);
       
   455         }
       
   456         break;
       
   457         case Loading:
       
   458         {
       
   459             m_statusLabel->setText("Loading...");
       
   460             m_layout->setCurrentWidget(m_statusLabel);
       
   461         }
       
   462         break;
       
   463         case LoadFinished:
       
   464         {
       
   465             if(m_ids.isEmpty())
       
   466             {
       
   467                 m_statusLabel->setText("Finished. No messages.");
       
   468                 m_layout->setCurrentWidget(m_statusLabel);
       
   469             }
       
   470             else
       
   471             {
       
   472                 m_state = Processing;
       
   473                 updateState();
       
   474                 processResults();
       
   475             }
       
   476         }
       
   477         break;
       
   478         case Processing:
       
   479             m_layout->setCurrentWidget(m_messageListWidget);
       
   480         break;
       
   481         case LoadFailed:
       
   482         {
       
   483             m_statusLabel->setText("Load failed!");
       
   484             m_layout->setCurrentWidget(m_statusLabel);
       
   485         }
       
   486         break;
       
   487     }
       
   488 
       
   489 #ifndef _WIN32_WCE
       
   490     if(m_state == Loading || m_state == Processing)
       
   491         setCursor(Qt::BusyCursor);
       
   492     else
       
   493         setCursor(Qt::ArrowCursor);
       
   494 #endif
       
   495 
       
   496 }
       
   497 
       
   498 //! [load-message]
       
   499 void RecentMessagesWidget::load()
       
   500 {
       
   501     m_ids.clear();
       
   502     m_state = Loading;
       
   503     bool b;
       
   504 
       
   505     b=m_service->queryMessages(QMessageFilter(),QMessageSortOrder::byReceptionTimeStamp(Qt::DescendingOrder),m_maxRecent);
       
   506 //! [load-message]
       
   507 };
       
   508 
       
   509 //! [process-results2]
       
   510 void RecentMessagesWidget::processResults()
       
   511 {
       
   512     if(!m_ids.isEmpty())
       
   513     {
       
   514         QMessageId id = m_ids.takeFirst();
       
   515         QMessage message(id);
       
   516 
       
   517         QListWidgetItem* newItem = new QListWidgetItem(message.from().addressee()+QString(":")+message.subject());
       
   518         newItem->setData(MessageIdRole,id.toString());
       
   519         QFont itemFont = newItem->font();
       
   520         bool isPartialMessage = !message.find(message.bodyId()).isContentAvailable();
       
   521         itemFont.setItalic(isPartialMessage);
       
   522         newItem->setFont(itemFont);
       
   523         m_messageListWidget->addItem(newItem);
       
   524         m_indexMap.insert(id,newItem);
       
   525         m_messageListWidget->update();
       
   526         QTimer::singleShot(100,this,SLOT(processResults()));
       
   527     }
       
   528     else
       
   529     {
       
   530         m_state = Done;
       
   531         updateState();
       
   532     }
       
   533 }
       
   534 //! [process-results2]
       
   535 
       
   536 class ComposeSendWidget : public QWidget
       
   537 {
       
   538     Q_OBJECT
       
   539 
       
   540 public:
       
   541     ComposeSendWidget(QMessageService* service, QWidget* parent = 0);
       
   542 
       
   543 signals:
       
   544     void actionsChanged();
       
   545 
       
   546 private slots:
       
   547     void composeButtonClicked();
       
   548     void sendButtonClicked();
       
   549     void addAttachmentButtonClicked();
       
   550     void accountChanged();
       
   551 
       
   552 private:
       
   553     void setupUi();
       
   554     QMessage constructQMessage(bool asHtml = false) const;
       
   555 
       
   556 private:
       
   557     QStackedLayout* m_layoutStack;
       
   558     QMessageService* m_service;
       
   559     AccountsWidget* m_accountsWidget;
       
   560     QLineEdit* m_toEdit;
       
   561     QLineEdit* m_ccEdit;
       
   562     QLabel* m_ccLabel;
       
   563     QLineEdit* m_bccEdit;
       
   564     QLabel* m_bccLabel;
       
   565     QLineEdit* m_subjectEdit;
       
   566     QLabel* m_subjectLabel;
       
   567     QTextEdit* m_bodyEdit;
       
   568     AttachmentListWidget* m_attachmentList;
       
   569     QAction* m_attachmentsAction;
       
   570     QAction* m_sendAsHTMLAction;
       
   571 };
       
   572 
       
   573 ComposeSendWidget::ComposeSendWidget(QMessageService* service, QWidget* parent)
       
   574 :
       
   575 QWidget(parent),
       
   576 m_layoutStack(0),
       
   577 m_service(service),
       
   578 m_accountsWidget(0),
       
   579 m_toEdit(0),
       
   580 m_ccEdit(0),
       
   581 m_ccLabel(0),
       
   582 m_bccEdit(0),
       
   583 m_bccLabel(0),
       
   584 m_subjectEdit(0),
       
   585 m_subjectLabel(0),
       
   586 m_bodyEdit(0),
       
   587 m_attachmentList(0),
       
   588 m_attachmentsAction(0),
       
   589 m_sendAsHTMLAction(0)
       
   590 {
       
   591     setupUi();
       
   592 }
       
   593 
       
   594 static void notifyResult(bool result, const QString& description)
       
   595 {
       
   596 #ifndef _WIN32_WCE
       
   597     if(result) QMessageBox::information(0,description,"Succeeded!");
       
   598     else QMessageBox::critical(0,description,"Failed.");
       
   599 #else
       
   600     Q_UNUSED(result);
       
   601     Q_UNUSED(description);
       
   602 #endif
       
   603 }
       
   604 
       
   605 //! [send-compose-message]
       
   606 void ComposeSendWidget::composeButtonClicked()
       
   607 {
       
   608     QMessage message(constructQMessage());
       
   609     m_service->compose(message);
       
   610 }
       
   611 
       
   612 void ComposeSendWidget::sendButtonClicked()
       
   613 {
       
   614     bool asHtml = (sender() == m_sendAsHTMLAction);
       
   615     QMessage message(constructQMessage(asHtml));
       
   616     notifyResult(m_service->send(message),"Send message");
       
   617 }
       
   618 //! [send-compose-message]
       
   619 
       
   620 void ComposeSendWidget::addAttachmentButtonClicked()
       
   621 {
       
   622     QStringList filenames = QFileDialog::getOpenFileNames(this,tr("Select attachments"));
       
   623     m_attachmentList->addAttachments(filenames);
       
   624 }
       
   625 
       
   626 void ComposeSendWidget::accountChanged()
       
   627 {
       
   628     QMessageAccount currentAccount(m_accountsWidget->currentAccount());
       
   629 
       
   630     bool isSmsAccount = (currentAccount.messageTypes() & QMessage::Sms) > 0;
       
   631 
       
   632     foreach(QWidget* emailSpecificWidget , QList<QWidget*>() << m_bccEdit << m_bccLabel <<
       
   633                                                                 m_ccEdit <<  m_ccLabel <<
       
   634                                                                 m_subjectEdit << m_subjectLabel) {
       
   635         emailSpecificWidget->setVisible(!isSmsAccount);
       
   636     }
       
   637 
       
   638     m_attachmentsAction->setEnabled(!isSmsAccount);
       
   639     m_sendAsHTMLAction->setEnabled(!isSmsAccount);
       
   640 }
       
   641 
       
   642 void ComposeSendWidget::setupUi()
       
   643 {
       
   644     QGridLayout* gl = new QGridLayout(this);
       
   645 
       
   646     QLabel* accountLabel = new QLabel("Account:",this);
       
   647     gl->addWidget(accountLabel,0,0);
       
   648 
       
   649     m_accountsWidget = new AccountsWidget(this);
       
   650     gl->addWidget(m_accountsWidget,0,1);
       
   651 
       
   652     connect(m_accountsWidget,SIGNAL(accountChanged()),this,SLOT(accountChanged()));
       
   653 
       
   654     QLabel* toLabel = new QLabel("To:",this);
       
   655     gl->addWidget(toLabel,1,0);
       
   656 
       
   657     m_toEdit = new QLineEdit(this);
       
   658     gl->addWidget(m_toEdit,1,1);
       
   659 
       
   660     m_ccLabel = new QLabel("Cc:",this);
       
   661     gl->addWidget(m_ccLabel,2,0);
       
   662 
       
   663     m_ccEdit = new QLineEdit(this);
       
   664     gl->addWidget(m_ccEdit,2,1);
       
   665 
       
   666     m_bccLabel = new QLabel("Bcc",this);
       
   667     gl->addWidget(m_bccLabel,3,0);
       
   668 
       
   669     m_bccEdit = new QLineEdit(this);
       
   670     gl->addWidget(m_bccEdit,3,1);
       
   671 
       
   672     m_subjectLabel = new QLabel("Subject:",this);
       
   673     gl->addWidget(m_subjectLabel,4,0);
       
   674 
       
   675     m_subjectEdit = new QLineEdit(this);
       
   676     gl->addWidget(m_subjectEdit,4,1);
       
   677 
       
   678     m_bodyEdit = new QTextEdit(this);
       
   679     gl->addWidget(m_bodyEdit,5,0,1,2);
       
   680 
       
   681     m_attachmentList = new AttachmentListWidget(this);
       
   682     gl->addWidget(m_attachmentList,6,0,1,2);
       
   683     m_attachmentList->hide();
       
   684 
       
   685     QAction* composeAction = new QAction("Compose",this);
       
   686     connect(composeAction,SIGNAL(triggered()),this,SLOT(composeButtonClicked()));
       
   687     addAction(composeAction);
       
   688 
       
   689     QAction* sendAction = new QAction("Send",this);
       
   690     connect(sendAction,SIGNAL(triggered()),this,SLOT(sendButtonClicked()));
       
   691     addAction(sendAction);
       
   692 
       
   693     m_sendAsHTMLAction = new QAction("Send as HTML",this);
       
   694     connect(m_sendAsHTMLAction,SIGNAL(triggered()),this,SLOT(sendButtonClicked()));
       
   695     addAction(m_sendAsHTMLAction);
       
   696 
       
   697     QAction* separator = new QAction(this);
       
   698     separator->setSeparator(true);
       
   699     addAction(separator);
       
   700 
       
   701     m_attachmentsAction = new QAction("Add attachment",this);
       
   702     connect(m_attachmentsAction,SIGNAL(triggered()),this,SLOT(addAttachmentButtonClicked()));
       
   703     addAction(m_attachmentsAction);
       
   704 }
       
   705 
       
   706 
       
   707 //! [construct-message]
       
   708 QMessage ComposeSendWidget::constructQMessage(bool asHtml) const
       
   709 {
       
   710     QMessage message;
       
   711 
       
   712     if(m_accountsWidget->isEmpty())
       
   713     {
       
   714         QMessageBox::critical(const_cast<ComposeSendWidget*>(this),"No Accounts","Cannot send a message without any available accounts");
       
   715         return message;
       
   716     }
       
   717 
       
   718     QMessageAccountId selectedAccountId = m_accountsWidget->currentAccount();
       
   719     QMessageAccount selectedAccount(selectedAccountId);
       
   720 
       
   721     bool composingSms = (selectedAccount.messageTypes() & QMessage::Sms) > 0;
       
   722 
       
   723     QMessageAddressList toList;
       
   724     QMessageAddressList ccList;
       
   725     QMessageAddressList bccList;
       
   726 
       
   727     QMessageAddress::Type addressType = QMessageAddress::Email;
       
   728     if(composingSms)
       
   729     {
       
   730         addressType = QMessageAddress::Phone;
       
   731         message.setType(QMessage::Sms);
       
   732     }
       
   733 
       
   734     foreach(QString s, m_toEdit->text().split(QRegExp("\\s"),QString::SkipEmptyParts))
       
   735         toList.append(QMessageAddress(addressType, s));
       
   736     message.setTo(toList);
       
   737 
       
   738     if(!composingSms)
       
   739     {
       
   740         foreach(QString s, m_ccEdit->text().split(QRegExp("\\s"),QString::SkipEmptyParts))
       
   741             ccList.append(QMessageAddress(QMessageAddress::Email, s));
       
   742         message.setCc(ccList);
       
   743 
       
   744         foreach(QString s, m_bccEdit->text().split(QRegExp("\\s"),QString::SkipEmptyParts))
       
   745             bccList.append(QMessageAddress(QMessageAddress::Email, s));
       
   746         message.setBcc(bccList);
       
   747         message.setSubject(m_subjectEdit->text());
       
   748 
       
   749         message.setType(QMessage::Email);
       
   750 
       
   751         message.appendAttachments(m_attachmentList->attachments());
       
   752     }
       
   753 
       
   754     message.setParentAccountId(selectedAccountId);
       
   755 
       
   756     if(!composingSms && asHtml) {
       
   757         //create html body
       
   758         QString htmlBody("<html><head><title></title></head><body><h2 align=center>%1</h2><hr>%2</body></html>");
       
   759         message.setBody(htmlBody.arg(message.subject()).arg(m_bodyEdit->toPlainText()),"text/html");
       
   760     }
       
   761     else
       
   762         message.setBody(m_bodyEdit->toPlainText());
       
   763 
       
   764     return message;
       
   765 }
       
   766 //! [construct-message]
       
   767 
       
   768 class MessageViewWidget : public QWidget
       
   769 {
       
   770     Q_OBJECT
       
   771 
       
   772     static const unsigned int LoadTimeLimit = 20; //seconds
       
   773 
       
   774     static QString downloadLinkURL()
       
   775     {
       
   776         static const QString url("MessageViewWidget://download");
       
   777         return url;
       
   778     };
       
   779 
       
   780 public:
       
   781     MessageViewWidget(QWidget* parent = 0);
       
   782     ~MessageViewWidget();
       
   783 
       
   784     QMessageId viewing() const;
       
   785 
       
   786 public slots:
       
   787     void view(const QMessageId& messageId);
       
   788     bool retrieveBody();
       
   789 
       
   790 protected:
       
   791     void showEvent(QShowEvent* e);
       
   792     void hideEvent(QHideEvent* e);
       
   793 
       
   794 private slots:
       
   795     void stateChanged(QMessageService::State s);
       
   796     void loadTimeout();
       
   797     void linkClicked(const QUrl&);
       
   798     void messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet& filterSet);
       
   799     void messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet& filterSet);
       
   800 
       
   801 
       
   802 private:
       
   803     enum State { Unloaded , Loaded, Loading, LoadFailed };
       
   804     void setupUi();
       
   805     void updateState();
       
   806     void loadMessage();
       
   807     void resetService();
       
   808 
       
   809 private:
       
   810     QStackedLayout* m_layoutStack;
       
   811     QLabel* m_statusLabel;
       
   812     QMessageService* m_service;
       
   813     QLineEdit* m_fromLabel;
       
   814     QLineEdit* m_subjectLabel;
       
   815     QTextBrowser* m_messageBrowser;
       
   816     QMessageId m_messageId;
       
   817     State m_state;
       
   818     QTimer m_loadTimer;
       
   819     QMessageManager::NotificationFilterId m_storeFilterId;
       
   820     QMessageManager m_manager;
       
   821 };
       
   822 
       
   823 MessageViewWidget::MessageViewWidget(QWidget* parent)
       
   824 :
       
   825 QWidget(parent),
       
   826 m_layoutStack(0),
       
   827 m_statusLabel(0),
       
   828 m_service(new QMessageService(this)),
       
   829 m_messageBrowser(0),
       
   830 m_state(Unloaded)
       
   831 {
       
   832     setupUi();
       
   833     resetService();
       
   834     connect(&m_loadTimer,SIGNAL(timeout()),this,SLOT(loadTimeout()));
       
   835     connect(&m_manager, SIGNAL(messageUpdated(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)),
       
   836         this,SLOT(messageUpdated(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)));
       
   837     connect(&m_manager, SIGNAL(messageRemoved(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)),
       
   838         this,SLOT(messageRemoved(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)));
       
   839     m_storeFilterId = m_manager.registerNotificationFilter(QMessageFilter());
       
   840 }
       
   841 
       
   842 MessageViewWidget::~MessageViewWidget()
       
   843 {
       
   844     m_manager.unregisterNotificationFilter(m_storeFilterId);
       
   845 }
       
   846 
       
   847 void MessageViewWidget::view(const QMessageId& messageId)
       
   848 {
       
   849     m_messageId = messageId;
       
   850     m_state = m_messageId.isValid() ? Loaded : Unloaded;
       
   851 
       
   852     updateState();
       
   853 }
       
   854 
       
   855 //! [retrieve-message-body]
       
   856 bool MessageViewWidget::retrieveBody()
       
   857 {
       
   858     if(m_state != Loading && !m_loadTimer.isActive())
       
   859     {
       
   860         m_loadTimer.setSingleShot(true);
       
   861         m_loadTimer.start(LoadTimeLimit * 1000);
       
   862         m_state = Unloaded;
       
   863 
       
   864         return m_service->retrieveBody(m_messageId);
       
   865     }
       
   866 
       
   867     return false;
       
   868 }
       
   869 
       
   870 //! [retrieve-message-body]
       
   871 
       
   872 void MessageViewWidget::showEvent(QShowEvent* e)
       
   873 {
       
   874     updateState();
       
   875     QWidget::showEvent(e);
       
   876 }
       
   877 
       
   878 void MessageViewWidget::hideEvent(QHideEvent* e)
       
   879 {
       
   880     if(m_state == Loading)
       
   881     {
       
   882         m_service->cancel();
       
   883         m_state = Unloaded;
       
   884     }
       
   885 
       
   886     QWidget::hideEvent(e);
       
   887 }
       
   888 
       
   889 void MessageViewWidget::stateChanged(QMessageService::State newState)
       
   890 {
       
   891     if (m_state == LoadFailed)
       
   892         return;
       
   893 
       
   894     if (newState == QMessageService::ActiveState) {
       
   895         m_state = Loading;
       
   896     } else if (newState == QMessageService::FinishedState) {
       
   897         m_state = (m_service->error() == QMessageManager::NoError ? Loaded : LoadFailed);
       
   898     }
       
   899 
       
   900     updateState();
       
   901 }
       
   902 
       
   903 void MessageViewWidget::loadTimeout()
       
   904 {
       
   905     qWarning() << "Load timeout";
       
   906     m_service->cancel();
       
   907     m_state = LoadFailed;
       
   908     updateState();
       
   909 }
       
   910 
       
   911 void MessageViewWidget::linkClicked(const QUrl& url)
       
   912 {
       
   913     bool downloadLinkClicked = url.toString() == downloadLinkURL();
       
   914 
       
   915     if(downloadLinkClicked)
       
   916         retrieveBody();
       
   917 }
       
   918 
       
   919 void MessageViewWidget::messageUpdated(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filterSet)
       
   920 {
       
   921     if(!filterSet.contains(m_storeFilterId) || m_state == Loading || !id.isValid() || id != m_messageId)
       
   922         return;
       
   923 
       
   924     view(id);
       
   925 }
       
   926 
       
   927 void MessageViewWidget::messageRemoved(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filterSet)
       
   928 {
       
   929     if(id == m_messageId)
       
   930     {
       
   931         m_state = Unloaded;
       
   932         m_loadTimer.stop();
       
   933         m_messageId = QMessageId();
       
   934         view(QMessageId());
       
   935     }
       
   936 }
       
   937 
       
   938 QMessageId MessageViewWidget::viewing() const
       
   939 {
       
   940     return m_messageId;
       
   941 }
       
   942 
       
   943 void MessageViewWidget::setupUi()
       
   944 {
       
   945     m_layoutStack = new QStackedLayout(this);
       
   946 
       
   947     m_statusLabel = new QLabel(this);
       
   948     m_statusLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
       
   949     m_layoutStack->addWidget(m_statusLabel);
       
   950 
       
   951     m_messageBrowser = new QTextBrowser(this);
       
   952     m_messageBrowser->setOpenLinks(false);
       
   953     connect(m_messageBrowser,SIGNAL(anchorClicked(const QUrl&)),this,SLOT(linkClicked(const QUrl&)));
       
   954     m_layoutStack->addWidget(m_messageBrowser);
       
   955 }
       
   956 
       
   957 void MessageViewWidget::updateState()
       
   958 {
       
   959     switch(m_state)
       
   960     {
       
   961         case Unloaded:
       
   962         {
       
   963             m_messageBrowser->clear();
       
   964             m_layoutStack->setCurrentWidget(m_messageBrowser);
       
   965         } break;
       
   966         case Loading:
       
   967         {
       
   968             m_statusLabel->setText("Downloading...");
       
   969             m_layoutStack->setCurrentWidget(m_statusLabel);
       
   970         } break;
       
   971         case Loaded:
       
   972         {
       
   973             if(m_loadTimer.isActive())
       
   974             {
       
   975                 m_loadTimer.stop();
       
   976                 if(m_service->state() == QMessageService::ActiveState)
       
   977                     m_service->cancel();
       
   978             }
       
   979 
       
   980             loadMessage();
       
   981             m_layoutStack->setCurrentWidget(m_messageBrowser);
       
   982         } break;
       
   983         case LoadFailed:
       
   984         {
       
   985             m_statusLabel->setText("Download failed!");
       
   986             m_layoutStack->setCurrentWidget(m_statusLabel);
       
   987         } break;
       
   988     }
       
   989 }
       
   990 
       
   991 //! [partial-message-check]
       
   992 void MessageViewWidget::loadMessage()
       
   993 {
       
   994     m_messageBrowser->clear();
       
   995 
       
   996     static const QString htmlTemplate("\
       
   997     <html>\
       
   998     <head>\
       
   999     </head>\
       
  1000     <body>\
       
  1001     <table border=\"0\" cellspacing=\"0\">\
       
  1002         <tr><td><b>From: </b></td><td>%1</td></tr>\
       
  1003         <tr><td><b>Subject: </b></td><td>%2</td></tr>\
       
  1004         <tr><td><b>Date: </b></td><td>%3</td></tr>\
       
  1005     </table>\
       
  1006     <hr>%4\
       
  1007     <\body>\
       
  1008     </html>\
       
  1009     ");
       
  1010 
       
  1011     if(m_messageId.isValid())
       
  1012     {
       
  1013         QMessage message(m_messageId);
       
  1014 
       
  1015         QMessageContentContainer bodyPart = message.find(message.bodyId());
       
  1016 
       
  1017         QString bodyText;
       
  1018 
       
  1019         //for partial message display a download link instead
       
  1020 
       
  1021         bool bodyAvailable = bodyPart.isContentAvailable();
       
  1022 
       
  1023         if(bodyAvailable)
       
  1024         {
       
  1025             if(bodyPart.contentType() == "text")
       
  1026                 bodyText = bodyPart.textContent();
       
  1027             else bodyText = "<Non-text content>";
       
  1028         }
       
  1029         else
       
  1030             bodyText = QString("<p align=\"center\"><a href=\"%1\">Download</a></p>").arg(downloadLinkURL());
       
  1031         m_messageBrowser->setHtml(htmlTemplate\
       
  1032                                  .arg(message.from().addressee())\
       
  1033                                  .arg(message.subject())\
       
  1034                                  .arg(message.receivedDate().toString())\
       
  1035                                  .arg(bodyText));
       
  1036     }
       
  1037 }
       
  1038 //! [partial-message-check]
       
  1039 
       
  1040 void MessageViewWidget::resetService()
       
  1041 {
       
  1042     if(m_service)
       
  1043         m_service->deleteLater();
       
  1044     m_service = new QMessageService(this);
       
  1045     connect(m_service,SIGNAL(stateChanged(QMessageService::State)),this,SLOT(stateChanged(QMessageService::State)));
       
  1046 }
       
  1047 
       
  1048 class RetrieveWidget : public QWidget
       
  1049 {
       
  1050     Q_OBJECT
       
  1051 
       
  1052 public:
       
  1053     RetrieveWidget(QWidget* parent = 0);
       
  1054 
       
  1055 private slots:
       
  1056     void messageSelected(const QMessageId& messageId);
       
  1057 
       
  1058 private:
       
  1059     void setupUi();
       
  1060 
       
  1061 private:
       
  1062     QMessageService* m_service;
       
  1063     RecentMessagesWidget* m_recentMessagesWidget;
       
  1064     MessageViewWidget* m_messageViewWidget;
       
  1065     QAction* m_retrieveAction;
       
  1066 };
       
  1067 
       
  1068 RetrieveWidget::RetrieveWidget(QWidget* parent)
       
  1069 :
       
  1070 QWidget(parent),
       
  1071 m_recentMessagesWidget(0),
       
  1072 m_messageViewWidget(0),
       
  1073 m_retrieveAction(0)
       
  1074 {
       
  1075     setupUi();
       
  1076 }
       
  1077 
       
  1078 void RetrieveWidget::messageSelected(const QMessageId& messageId)
       
  1079 {
       
  1080     QMessage message(messageId);
       
  1081     bool partialMessage = !message.find(message.bodyId()).isContentAvailable();
       
  1082 
       
  1083     m_retrieveAction->setEnabled(partialMessage && messageId.isValid());
       
  1084 }
       
  1085 
       
  1086 void RetrieveWidget::setupUi()
       
  1087 {
       
  1088     QVBoxLayout* l = new QVBoxLayout(this);
       
  1089     l->addWidget(new QLabel(QString("Last %1 messages:").arg(RecentMessagesCount),this));
       
  1090 
       
  1091     m_recentMessagesWidget = new RecentMessagesWidget(this,RecentMessagesCount);
       
  1092     l->addWidget(m_recentMessagesWidget);
       
  1093 
       
  1094     m_messageViewWidget = new MessageViewWidget(this);
       
  1095     l->addWidget(m_messageViewWidget);
       
  1096 
       
  1097     m_retrieveAction = new QAction("Retrieve",this);
       
  1098     connect(m_retrieveAction,SIGNAL(triggered(bool)),m_messageViewWidget,SLOT(retrieveBody()));
       
  1099     addAction(m_retrieveAction);
       
  1100 
       
  1101     connect(m_recentMessagesWidget,SIGNAL(selected(const QMessageId&)),m_messageViewWidget,SLOT(view(const QMessageId&)));
       
  1102     connect(m_recentMessagesWidget,SIGNAL(selected(const QMessageId&)),this,SLOT(messageSelected(const QMessageId&)));
       
  1103 }
       
  1104 
       
  1105 class ShowWidget : public QWidget
       
  1106 {
       
  1107     Q_OBJECT
       
  1108 
       
  1109 public:
       
  1110     ShowWidget(QMessageService* service, QWidget* parent = 0);
       
  1111 
       
  1112 private slots:
       
  1113     void showButtonClicked();
       
  1114 
       
  1115 private:
       
  1116     void setupUi();
       
  1117 
       
  1118 private:
       
  1119     QMessageService* m_service;
       
  1120     RecentMessagesWidget* m_recentMessagesWidget;
       
  1121 };
       
  1122 
       
  1123 ShowWidget::ShowWidget(QMessageService* service, QWidget* parent)
       
  1124 :
       
  1125 QWidget(parent),
       
  1126 m_service(service),
       
  1127 m_recentMessagesWidget(0)
       
  1128 {
       
  1129     setupUi();
       
  1130 }
       
  1131 
       
  1132 //! [show-message]
       
  1133 void ShowWidget::showButtonClicked()
       
  1134 {
       
  1135 
       
  1136     QMessageId id = m_recentMessagesWidget->currentMessage();
       
  1137 
       
  1138     if(id.isValid())
       
  1139         m_service->show(id);
       
  1140 }
       
  1141 //! [show-message]
       
  1142 
       
  1143 void ShowWidget::setupUi()
       
  1144 {
       
  1145     QVBoxLayout* vbl = new QVBoxLayout(this);
       
  1146 
       
  1147     QString labelText("Last %1 messages:");
       
  1148     vbl->addWidget(new QLabel(labelText.arg(RecentMessagesCount),this));
       
  1149 
       
  1150     m_recentMessagesWidget = new RecentMessagesWidget(this,RecentMessagesCount);
       
  1151     vbl->addWidget(m_recentMessagesWidget);
       
  1152 
       
  1153     QAction* showAction = new QAction("Show",this);
       
  1154     connect(showAction,SIGNAL(triggered()),this,SLOT(showButtonClicked()));
       
  1155     addAction(showAction);
       
  1156 }
       
  1157 
       
  1158 class StoreSignalsWidget : public QWidget
       
  1159 {
       
  1160     Q_OBJECT
       
  1161 
       
  1162 public:
       
  1163     StoreSignalsWidget(QWidget* parent = 0);
       
  1164 
       
  1165 private slots:
       
  1166     void messageAdded(const QMessageId&, const QMessageManager::NotificationFilterIdSet&);
       
  1167     void messageUpdated(const QMessageId&, const QMessageManager::NotificationFilterIdSet&);
       
  1168     void messageRemoved(const QMessageId&, const QMessageManager::NotificationFilterIdSet&);
       
  1169 
       
  1170 private:
       
  1171     void setupUi();
       
  1172     void appendString(const QString& message);
       
  1173 
       
  1174 private:
       
  1175     QListWidget* m_activityListWidget;
       
  1176     QMessageManager::NotificationFilterId m_notificationFilterId;
       
  1177     QMessageManager m_manager;
       
  1178 };
       
  1179 
       
  1180 StoreSignalsWidget::StoreSignalsWidget(QWidget* parent)
       
  1181 :
       
  1182 QWidget(parent),
       
  1183 m_activityListWidget(0)
       
  1184 {
       
  1185     setupUi();
       
  1186 }
       
  1187 
       
  1188 //! [store-signals]
       
  1189 void StoreSignalsWidget::messageAdded(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filterSet)
       
  1190 {
       
  1191     if(!filterSet.contains(m_notificationFilterId))
       
  1192         return;
       
  1193 
       
  1194     QMessage message(id);
       
  1195 
       
  1196     QString msg = QString("Added: %1").arg(message.subject());
       
  1197     m_activityListWidget->addItem(msg);
       
  1198 }
       
  1199 
       
  1200 void StoreSignalsWidget::messageUpdated(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filterSet)
       
  1201 {
       
  1202     if(!filterSet.contains(m_notificationFilterId))
       
  1203         return;
       
  1204 
       
  1205     QMessage message(id);
       
  1206 
       
  1207     QString msg = QString("Updated: %1").arg(message.subject());
       
  1208     m_activityListWidget->addItem(msg);
       
  1209 }
       
  1210 
       
  1211 void StoreSignalsWidget::messageRemoved(const QMessageId& id, const QMessageManager::NotificationFilterIdSet& filterSet)
       
  1212 {
       
  1213     if(!filterSet.contains(m_notificationFilterId))
       
  1214         return;
       
  1215 
       
  1216     QString idString(id.toString());
       
  1217     idString.truncate(10);
       
  1218 
       
  1219     QString msg = QString("Removed ID: %1 ...").arg(idString);
       
  1220     m_activityListWidget->addItem(msg);
       
  1221 }
       
  1222 //! [store-signals]
       
  1223 
       
  1224 void StoreSignalsWidget::setupUi()
       
  1225 {
       
  1226     m_activityListWidget = new QListWidget(this);
       
  1227     QVBoxLayout* l = new QVBoxLayout(this);
       
  1228     l->setSpacing(0);
       
  1229     l->setContentsMargins(0,0,0,0);
       
  1230     l->addWidget(m_activityListWidget);
       
  1231 
       
  1232     connect(&m_manager, 
       
  1233             SIGNAL(messageAdded(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)),
       
  1234             this,
       
  1235             SLOT(messageAdded(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)));
       
  1236 
       
  1237     connect(&m_manager, 
       
  1238             SIGNAL(messageRemoved(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)),
       
  1239             this,
       
  1240             SLOT(messageRemoved(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)));
       
  1241 
       
  1242     connect(&m_manager, 
       
  1243             SIGNAL(messageUpdated(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)),
       
  1244             this,
       
  1245             SLOT(messageUpdated(const QMessageId&,const QMessageManager::NotificationFilterIdSet&)));
       
  1246 
       
  1247     m_notificationFilterId = m_manager.registerNotificationFilter(QMessageFilter());
       
  1248 
       
  1249     QAction* clearAction = new QAction("Clear",this);
       
  1250     connect(clearAction,SIGNAL(triggered(bool)),m_activityListWidget,SLOT(clear()));
       
  1251     addAction(clearAction);
       
  1252 }
       
  1253 
       
  1254 MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags f)
       
  1255 :
       
  1256 QMainWindow(parent,f),
       
  1257 m_tabWidget(0)
       
  1258 {
       
  1259 
       
  1260     m_service = new QMessageService(this);
       
  1261 
       
  1262     connect(m_service,SIGNAL(stateChanged(QMessageService::State)),
       
  1263             this,SLOT(serviceStateChanged(QMessageService::State)));
       
  1264 
       
  1265     //example widgets
       
  1266 
       
  1267     m_widgetStack = new QStackedWidget(this);
       
  1268     setCentralWidget(m_widgetStack);
       
  1269 
       
  1270     foreach(QWidget* exampleWidget, QWidgetList() << new ComposeSendWidget(m_service,this)
       
  1271                                                   << new ShowWidget(m_service,this)
       
  1272                                                   << new RetrieveWidget(this)
       
  1273                                                   << new StoreSignalsWidget(this)) {
       
  1274 
       
  1275         m_widgetStack->addWidget(exampleWidget);
       
  1276 #ifdef _WIN32_WCE
       
  1277         exampleWidget->installEventFilter(this);
       
  1278 #endif
       
  1279     }
       
  1280 
       
  1281     //main menu
       
  1282 #ifndef _WIN32_WCE
       
  1283     QMenu* fileMenu = new QMenu("File",this);
       
  1284 #endif
       
  1285 
       
  1286     int index = 0;
       
  1287     foreach(QAction* viewAction, QList<QAction*>() << new QAction("Compose\\Send",this)
       
  1288                                                    << new QAction("Show",this)
       
  1289                                                    << new QAction("Retrieve/Query",this)
       
  1290                                                    << new QAction("Store Signals",this))
       
  1291     {
       
  1292         connect(viewAction,SIGNAL(triggered()),this,SLOT(viewSelected()));
       
  1293 #ifndef _WIN32_WCE
       
  1294         fileMenu->addAction(viewAction);
       
  1295 #else
       
  1296         menuBar()->addAction(viewAction);
       
  1297 #endif
       
  1298         viewAction->setData(index);
       
  1299         index++;
       
  1300     }
       
  1301 #ifndef _WIN32_WCE
       
  1302     fileMenu->addSeparator();
       
  1303 #else
       
  1304     menuBar()->addSeparator();
       
  1305 #endif
       
  1306 
       
  1307     QAction* quitAction = new QAction("Quit",this);
       
  1308     connect(quitAction,SIGNAL(triggered()),qApp,SLOT(quit()));
       
  1309 #ifndef _WIN32_WCE
       
  1310     fileMenu->addAction(quitAction);
       
  1311     menuBar()->addMenu(fileMenu);
       
  1312 #else
       
  1313     menuBar()->addAction(quitAction);
       
  1314 #endif
       
  1315 
       
  1316     QTimer::singleShot(0,this,SLOT(viewSelected()));
       
  1317 
       
  1318     //window properties
       
  1319 
       
  1320     setWindowTitle(WindowTitle);
       
  1321     resize(WindowGeometry);
       
  1322 
       
  1323 }
       
  1324 
       
  1325 #ifdef _WIN32_WCE
       
  1326 bool MainWindow::eventFilter(QObject* source, QEvent* e)
       
  1327 {
       
  1328     bool actionChanged = (m_widgetStack->currentWidget() == source) && e->type() == QEvent::ActionChanged;
       
  1329     if(actionChanged)
       
  1330         viewSelected(); //update the menu items
       
  1331     return false;
       
  1332 }
       
  1333 #endif
       
  1334 
       
  1335 void MainWindow::serviceStateChanged(QMessageService::State newState)
       
  1336 {
       
  1337     if ((newState == QMessageService::FinishedState) && (m_service->error() != QMessageManager::NoError))
       
  1338         QMessageBox::critical(this,"Error","One or more service actions failed");
       
  1339 }
       
  1340 
       
  1341 void MainWindow::viewSelected()
       
  1342 {
       
  1343     static QMenu* actionMenu = 0;
       
  1344 
       
  1345     if(!actionMenu)
       
  1346     {
       
  1347         actionMenu = new QMenu("Action",this);
       
  1348 #ifndef _WIN32_WCE
       
  1349         menuBar()->addMenu(actionMenu);
       
  1350 #endif
       
  1351     }
       
  1352     QAction* senderAction = qobject_cast<QAction*>(sender());
       
  1353     if(senderAction)
       
  1354         m_widgetStack->setCurrentIndex(senderAction->data().toInt());
       
  1355 
       
  1356     bool currentViewHasActions = m_widgetStack->currentWidget() && !m_widgetStack->currentWidget()->actions().isEmpty();
       
  1357     actionMenu->clear();
       
  1358     if(currentViewHasActions)
       
  1359     {
       
  1360         foreach(QAction* a, m_widgetStack->currentWidget()->actions())
       
  1361             actionMenu->addAction(a);
       
  1362     }
       
  1363 #ifdef _WIN32_WCE
       
  1364     static QAction* leftSoftButton = new QAction("Action",this);
       
  1365     leftSoftButton->setMenu(actionMenu);
       
  1366     menuBar()->setDefaultAction(leftSoftButton);
       
  1367 #endif
       
  1368 }
       
  1369 
       
  1370 #include <mainwindow.moc>
       
  1371