first release master
authorTom Chen <funpig@gmail.com>
Sat, 26 Jun 2010 01:49:42 +0000 (09:49 +0800)
committerTom Chen <funpig@gmail.com>
Sat, 26 Jun 2010 01:49:42 +0000 (09:49 +0800)
65 files changed:
groupsms.pro [new file with mode: 0644]
history [new file with mode: 0644]
sms/abstractpage.cpp [new file with mode: 0644]
sms/abstractpage.h [new file with mode: 0644]
sms/addcontacttogroup.cpp [new file with mode: 0644]
sms/addcontacttogroup.h [new file with mode: 0644]
sms/addcontacttogroupdialog.ui [new file with mode: 0644]
sms/common.h [new file with mode: 0644]
sms/contactinterface.cpp [new file with mode: 0644]
sms/contactinterface.h [new file with mode: 0644]
sms/contactpage.cpp [new file with mode: 0644]
sms/contactpage.h [new file with mode: 0644]
sms/contactwidget.cpp [new file with mode: 0644]
sms/contactwidget.h [new file with mode: 0644]
sms/contactwidgetitem.cpp [new file with mode: 0644]
sms/contactwidgetitem.h [new file with mode: 0644]
sms/data/26x26/groupsms.png [new file with mode: 0644]
sms/data/40x40/groupsms.png [new file with mode: 0644]
sms/data/64x64/groupsms.png [new file with mode: 0644]
sms/data/icon.svg [new file with mode: 0644]
sms/data/maemo/groupsms.xpm [new file with mode: 0644]
sms/groupsms.desktop [new file with mode: 0644]
sms/groupsms.qrc [new file with mode: 0644]
sms/groupwidgetitem.cpp [new file with mode: 0644]
sms/groupwidgetitem.h [new file with mode: 0644]
sms/images/addcontacttogroup.png [new file with mode: 0644]
sms/images/allselect.png [new file with mode: 0644]
sms/images/editgroup.png [new file with mode: 0644]
sms/images/female.png [new file with mode: 0644]
sms/images/male.png [new file with mode: 0644]
sms/images/newgroup.png [new file with mode: 0644]
sms/images/partselect.png [new file with mode: 0644]
sms/images/plus.png [new file with mode: 0644]
sms/images/recycle.png [new file with mode: 0644]
sms/images/select.png [new file with mode: 0644]
sms/images/sub.png [new file with mode: 0644]
sms/images/unselect.png [new file with mode: 0644]
sms/item.h [new file with mode: 0644]
sms/itemobserver.h [new file with mode: 0644]
sms/main.cpp [new file with mode: 0644]
sms/mainwindow.cpp [new file with mode: 0644]
sms/mainwindow.h [new file with mode: 0644]
sms/mainwindow.ui [new file with mode: 0644]
sms/newgroupdialog.cpp [new file with mode: 0644]
sms/newgroupdialog.h [new file with mode: 0644]
sms/newgroupdialog.ui [new file with mode: 0644]
sms/selectcontactwidget.cpp [new file with mode: 0644]
sms/selectcontactwidget.h [new file with mode: 0644]
sms/sendsmssession.cpp [new file with mode: 0644]
sms/sendsmssession.h [new file with mode: 0644]
sms/sms.pro [new file with mode: 0644]
sms/tpsession/tpsession.cpp [new file with mode: 0755]
sms/tpsession/tpsession.h [new file with mode: 0755]
sms/tpsession/tpsessionaccount.cpp [new file with mode: 0755]
sms/tpsession/tpsessionaccount.h [new file with mode: 0755]
sms/tpsession/tpsessionchannel.cpp [new file with mode: 0755]
sms/tpsession/tpsessionchannel.h [new file with mode: 0755]
sms/tpsession/tpsessionobserver.cpp [new file with mode: 0755]
sms/tpsession/tpsessionobserver.h [new file with mode: 0755]
sms/utility.cpp [new file with mode: 0644]
sms/utility.h [new file with mode: 0644]
sms/xmlcontroler.cpp [new file with mode: 0644]
sms/xmlcontroler.h [new file with mode: 0644]
sms/xmlstring.h [new file with mode: 0644]
welcome

diff --git a/groupsms.pro b/groupsms.pro
new file mode 100644 (file)
index 0000000..b3a2142
--- /dev/null
@@ -0,0 +1,3 @@
+TEMPLATE    = subdirs
+SUBDIRS     = sms
+#SUBDIRS     = tpsession-0.1
diff --git a/history b/history
new file mode 100644 (file)
index 0000000..63fbac0
--- /dev/null
+++ b/history
@@ -0,0 +1,17 @@
+Need to do/fix:
+* some GLIB CRITICAL when use libebook, libosso, libosso-abook in Qt4.(2010.06.08)
+
+Done:
+* fixed some display problem.(2010.06.17)
+* implement that remove seleted group/contact. (2010.06.12 / 2010.06.13)
+* implement add contacts to group.(2010.06.12)
+* display prolem after new group.(2010.06.11 / 2010.06.12)
+* display prolem after sent message.(2010.06.11)
+* use Q_SLOTS, Q_SIGNALS, Q_EMIT macro in TpSession for avoid build error when use together GTK/libosso.(2010.06.10)
+* implement send sms. maybe use ( TpSession & TelepathyQt4 ) or maemo lib.(2010.06.07 / 2010.06.10)
+* modify the icon of UI.(2010.06.10)
+* modify the UI position.(2010.06.10)
+* make a .DEB file(v0.0.1).(2010.06.09)
+* implement that get all contacts from DB of devices.(2010.06.03 / 2010.06.09)
+* add dialog to add contacts to groups.(2010.06.03 / 2010.06.07)
+* add dialog to add new group.(2010.06.03 / 2010.06.04)
diff --git a/sms/abstractpage.cpp b/sms/abstractpage.cpp
new file mode 100644 (file)
index 0000000..c43a04f
--- /dev/null
@@ -0,0 +1,11 @@
+#include "abstractpage.h"
+
+AbstractPage::AbstractPage(QWidget *parent) :
+    QWidget(parent)
+{
+    ////qDebug() << "AbstractPage::AbstractPage(QWidget *parent) , Entry";
+}
+
+void AbstractPage::clear()
+{
+}
diff --git a/sms/abstractpage.h b/sms/abstractpage.h
new file mode 100644 (file)
index 0000000..c58947f
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef ABSTRACTPAGE_H
+#define ABSTRACTPAGE_H
+
+#include <QObject>
+#include <QScrollArea>
+#include <QString>
+
+#include "contactwidget.h"
+
+class AbstractPage : public QWidget
+{
+    Q_OBJECT
+public:
+    AbstractPage(QWidget *parent = 0);
+
+    virtual void update() = 0;
+    virtual QString title() = 0;
+    virtual void updateSize() = 0;
+    virtual void clear();
+
+public:
+    QScrollArea *scrollArea;
+    bool isVisible;
+
+    ContactWidget *contactWidget;
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+
+};
+
+#endif // ABSTRACTPAGE_H
diff --git a/sms/addcontacttogroup.cpp b/sms/addcontacttogroup.cpp
new file mode 100644 (file)
index 0000000..3281bc2
--- /dev/null
@@ -0,0 +1,49 @@
+#include "addcontacttogroup.h"
+#include "contactinterface.h"
+#include "xmlstring.h"
+
+AddContactToGroup::AddContactToGroup(QWidget *parent) :
+    QDialog(parent)
+{
+    //qDebug() << "AddContactToGroup::AddContactToGroup(QWidget *parent), Entry";
+
+    setupUi(this);
+    setWindowModality( Qt::ApplicationModal );
+
+    comboBox_groupname->addItems( ContactInterface::getInstance()->getAllGroupNames() );
+
+    m_SelectContactWidget = new SelectContactWidget(this);
+    m_SelectContactWidget->initContactWidget();
+    m_SelectContactWidget->sizePolicy().setHorizontalPolicy(QSizePolicy::Maximum);
+    m_SelectContactWidget->setGeometry(0,0,600,600);
+    m_SelectContactWidget->update();
+
+
+    scrollArea = new QScrollArea(this);
+    scrollArea->setWidget( m_SelectContactWidget );
+    scrollArea->setBackgroundRole(QPalette::Light);
+    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+    scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+    this->verticalLayout->addWidget(scrollArea);
+
+    connect( btngroup_ok_cancel, SIGNAL( clicked(QAbstractButton*) ), this, SLOT( btn_clicked(QAbstractButton*) ) );
+}
+
+void AddContactToGroup::btn_clicked(QAbstractButton *button)
+{
+    if( QDialogButtonBox::AcceptRole == btngroup_ok_cancel->buttonRole( button ) )
+    {
+        //qDebug() << "add contact to group ";
+
+        QString groupname = comboBox_groupname->currentText();
+        if( STR_XML_ALLCONTACTS != groupname )
+        {
+            m_SelectContactWidget->addContactsToGroup(groupname);
+        }
+        done( QDialog::Accepted );
+    }else // button cancel
+    {
+        done( QDialog::Rejected );
+    }
+}
diff --git a/sms/addcontacttogroup.h b/sms/addcontacttogroup.h
new file mode 100644 (file)
index 0000000..870a9e5
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef ADDCONTACTTOGROUP_H
+#define ADDCONTACTTOGROUP_H
+
+#include <QDialog>
+#include "ui_addcontacttogroupdialog.h"
+#include "selectcontactwidget.h"
+
+class AddContactToGroup : public QDialog, Ui::AddContactToGroupDialog
+{
+    Q_OBJECT
+public:
+    AddContactToGroup(QWidget *parent = 0);
+
+private:
+    SelectContactWidget* m_SelectContactWidget;
+
+    QScrollArea *scrollArea;
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+    void btn_clicked(QAbstractButton * button);
+
+};
+
+#endif // ADDCONTACTTOGROUP_H
diff --git a/sms/addcontacttogroupdialog.ui b/sms/addcontacttogroupdialog.ui
new file mode 100644 (file)
index 0000000..48c1912
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddContactToGroupDialog</class>
+ <widget class="QDialog" name="AddContactToGroupDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QDialogButtonBox" name="btngroup_ok_cancel">
+   <property name="geometry">
+    <rect>
+     <x>310</x>
+     <y>20</y>
+     <width>81</width>
+     <height>241</height>
+    </rect>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Vertical</enum>
+   </property>
+   <property name="standardButtons">
+    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+   </property>
+  </widget>
+  <widget class="QWidget" name="verticalLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>291</width>
+     <height>281</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QLabel" name="label_add_to">
+        <property name="text">
+         <string>Add To:</string>
+        </property>
+        <property name="scaledContents">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QComboBox" name="comboBox_groupname"/>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>btngroup_ok_cancel</sender>
+   <signal>accepted()</signal>
+   <receiver>AddContactToGroupDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>btngroup_ok_cancel</sender>
+   <signal>rejected()</signal>
+   <receiver>AddContactToGroupDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/sms/common.h b/sms/common.h
new file mode 100644 (file)
index 0000000..f836d0d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <QDir>
+
+const QString HOME_DIR = QDir::homePath() + "/.groupsms/";
+
+#endif // COMMON_H
diff --git a/sms/contactinterface.cpp b/sms/contactinterface.cpp
new file mode 100644 (file)
index 0000000..64cf4ee
--- /dev/null
@@ -0,0 +1,204 @@
+#include "contactinterface.h"
+#include "xmlcontroler.h"
+#include "xmlstring.h"
+
+ContactInterface* ContactInterface::instance = 0;
+
+ContactInterface* ContactInterface::getInstance()
+{
+    if( !instance )
+    {
+        instance = new ContactInterface();
+    }
+    return instance;
+}
+
+ContactInterface::ContactInterface(QObject *parent) :
+    QObject(parent)
+{
+    instance = this;
+
+    initEbook();
+}
+
+ContactInterface::~ContactInterface()
+{
+    for( int i = 0; i < all_contacts_items_db.size(); i++ )
+    {
+        delete all_contacts_items_db.at(i);
+    }
+    all_contacts_items_db.clear();
+}
+
+void ContactInterface::setItemObserver(ItemObserver *observer)
+{
+    XmlControler::getInstance()->setItemObserver( observer );
+}
+
+void ContactInterface::setItemSelectObserver( ItemSelectObserver *observer )
+{
+    XmlControler::getInstance()->setItemSelectObserver( observer );
+}
+
+bool ContactInterface::initEbook()
+{
+    //qDebug() << "ContactInterface::initEbook(), Entry";
+
+#ifdef ONLY_FOR_EBOOK
+    GError *error = NULL;
+    roster = osso_abook_aggregator_get_default(&error);
+    if( error )
+    {
+        //qDebug() << "Couldn't open roster %s\n" << error->message;
+        g_error_free( error );
+    }
+    osso_abook_roster_start(roster);
+
+    //qDebug() << "osso_abook_roster_start";
+
+    osso_abook_waitable_run(OSSO_ABOOK_WAITABLE(roster), g_main_context_default(), &error);
+
+    if (!osso_abook_waitable_is_ready(OSSO_ABOOK_WAITABLE(roster), &error) )
+        g_critical("osso_abook_waitable_is_ready: %s\n", error->message);
+
+    //* for test
+//    OssoABookAggregator *_aggr;
+//    GList *list, *c;
+//    GError *err;
+
+//    osso_abook_waitable_run(OSSO_ABOOK_WAITABLE(roster), g_main_context_default(), &err);
+
+//    if (! osso_abook_waitable_is_ready(OSSO_ABOOK_WAITABLE(roster), &err))
+//        g_critical("osso_abook_waitable_is_ready: %s\n", err->message);
+
+//    _aggr = OSSO_ABOOK_AGGREGATOR(roster);
+//    list = osso_abook_aggregator_list_master_contacts(_aggr);
+
+//    printf("count = %d\n",  g_list_length(list)); // list is not empty !
+
+//    g_list_free(list);
+    //* test end
+#endif
+    return true;
+}
+
+bool ContactInterface::updateContactsFromEbookToXml()
+{
+    removeGroup( STR_XML_ALLCONTACTS );
+    getAllContacts();
+    addContactToGroup( all_contacts_items_db, STR_XML_ALLCONTACTS );
+    return true;
+}
+
+ItemListPtr ContactInterface::getAllContacts()
+{
+    //qDebug() << "ContactInterface::getAllContacts() from EBook, Entry";
+
+#ifdef ONLY_FOR_EBOOK
+    GList *list = NULL;
+    GList *it = NULL;
+    EContact *contact = NULL;
+    OssoABookAggregator *aggregator = OSSO_ABOOK_AGGREGATOR(roster);
+
+    list = osso_abook_aggregator_list_master_contacts( aggregator );
+
+    qDebug() << "get list from EBook";
+    //qDebug() << "list length is :" << g_list_length(list);
+
+    QString str;
+
+    for( it = list; it; it = it->next )
+    {
+        //qDebug() << "into list loop";
+
+        contact = (EContact *)it->data;
+        Item *item = new Item();
+
+        str = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_FULL_NAME) );
+        item->full_name = str;
+        qDebug() << "fullname is : " << item->full_name;
+
+        str = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_PHONE_MOBILE) );
+        item->mobile_number = str;
+        qDebug() << "mobile_number is : " << item->mobile_number;
+
+        item->group_owner =  "";
+        item->user_pic_uri = ":/images/male.png";
+
+        item->uid = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_UID) );
+        qDebug() << "uid is : " << item->uid;
+
+        all_contacts_items_db.append( item );
+    }
+
+    g_list_free( list );
+#endif
+    return all_contacts_items_db;
+}
+
+void ContactInterface::getAllContactsFromXml()
+{
+    //qDebug() << "ContactInterface::getAllContactsFromXml(), Entry";
+
+    XmlControler::getInstance()->getAllContactItems();
+}
+
+void ContactInterface::getAllContactsFromXml(const QString &groupname)
+{
+    //qDebug() << "ContactInterface::getAllContactsFromXml(const QString &groupname), Entry";
+
+    XmlControler::getInstance()->getAllContactItemsFromGroup(groupname);
+}
+
+QStringList ContactInterface::getAllGroupNames()
+{
+    //qDebug() << "ContactInterface::getAllGroupNames(), Entry";
+    return XmlControler::getInstance()->getAllGroupNames();
+}
+
+bool ContactInterface::createGroup(const QString &groupname)
+{
+    return XmlControler::getInstance()->createGroup(groupname);
+}
+
+bool ContactInterface::removeGroup(const QString &groupname)
+{
+    return XmlControler::getInstance()->removeGroup( groupname );
+}
+
+bool ContactInterface::addContactToGroup(ItemListPtr items, const QString &groupname)
+{
+    return XmlControler::getInstance()->createContact( groupname, items );
+}
+
+bool ContactInterface::removeContactToGroup( ItemListPtr items, const QString &groupname )
+{
+    return XmlControler::getInstance()->removeContactFromGroup( items, groupname );
+}
+
+bool ContactInterface::removeContactToGroup( ItemListPtr items )
+{
+    return XmlControler::getInstance()->removeContactFromGroup( items );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sms/contactinterface.h b/sms/contactinterface.h
new file mode 100644 (file)
index 0000000..dd4b840
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef CONTACTINTERFACE_H
+#define CONTACTINTERFACE_H
+
+#include <QObject>
+#include <QVector>
+#include <contactwidgetitem.h>
+
+#include "itemobserver.h"
+
+#ifdef ONLY_FOR_EBOOK
+
+extern "C" {
+#include <gtk/gtk.h>
+#include <libosso.h>
+#include <libebook/e-book.h>
+#include <libosso-abook/osso-abook.h>
+}
+
+#endif
+
+class ContactInterface : public QObject
+{
+    Q_OBJECT
+public:
+    static ContactInterface* getInstance();
+    ~ContactInterface();
+
+    bool initEbook();
+
+    bool updateContactsFromEbookToXml();
+
+    void setItemObserver( ItemObserver *observer );
+    void setItemSelectObserver( ItemSelectObserver *observer );
+
+    /**
+      get all contacts from libosso-abook
+     */
+    ItemListPtr getAllContacts();
+    /**
+      get all contacts from xml file
+     */
+    void getAllContactsFromXml();
+    void getAllContactsFromXml(const QString &groupname);
+
+    QStringList getAllGroupNames();
+
+    bool createGroup(const QString &groupname);
+    bool removeGroup(const QString &groupname);
+    bool addContactToGroup( ItemListPtr items, const QString &groupname );
+    bool removeContactToGroup( ItemListPtr items, const QString &groupname );
+    bool removeContactToGroup( ItemListPtr items );
+
+private:
+    static ContactInterface* instance;
+    ContactInterface(QObject *parent = 0);
+
+private:
+    ItemListPtr all_contacts_items;
+    ItemListPtr all_contacts_items_db;
+    Item current_contact_item;
+    QString current_uid;
+    QString current_fullname;
+    QString current_mobilenumber;
+
+#ifdef ONLY_FOR_EBOOK    
+    OssoABookRoster *roster;
+#endif
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+
+};
+
+#endif // CONTACTINTERFACE_H
diff --git a/sms/contactpage.cpp b/sms/contactpage.cpp
new file mode 100644 (file)
index 0000000..f7dae16
--- /dev/null
@@ -0,0 +1,89 @@
+#include <QtGui>
+#include <QDebug>
+
+#include "contactpage.h"
+
+ContactPage::ContactPage(QWidget* parent)
+    : AbstractPage(parent)
+{
+    //qDebug() << "ContactPage::ContactPage(), Entry";
+
+    contactWidget = new ContactWidget(this);    
+    contactWidget->sizePolicy().setHorizontalPolicy(QSizePolicy::Maximum);
+    connect( contactWidget, SIGNAL( validRecycle(bool) ), this, SLOT( onValidRecyele(bool) ) );
+    //contactWidget->setGeometry(0,0,600,600);    
+
+    QGridLayout *layout = new QGridLayout(this);
+
+    scrollArea = new QScrollArea(this);
+    scrollArea->setBackgroundRole(QPalette::Light);
+
+    // for test
+//    QLineEdit *edit = new QLineEdit("Line Edit");
+//    edit->setGeometry(0,0,1000,1000);
+//    scrollArea->setWidget(edit);
+    //
+
+
+    scrollArea->setWidget(contactWidget);
+    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+    scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+    //scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+    //scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+
+    layout->addWidget(scrollArea, 0, 0, 1, 1);
+    setLayout(layout);
+}
+
+void ContactPage::updateSize()
+{
+    //qDebug() << "ContactPage::updateSize()";
+    contactWidget->resize( ( scrollArea->width() - scrollArea->verticalScrollBar()->width() - 5 ),
+                           ( scrollArea->height() - scrollArea->horizontalScrollBar()->height() - 5 ));
+}
+
+void ContactPage::initContactWidget()
+{
+    contactWidget->initContactWidget();
+}
+
+void ContactPage::update()
+{
+    //qDebug() << "ContactPage::update()";
+    contactWidget->update();
+}
+
+void ContactPage::refreshContactList()
+{
+    contactWidget->refreshContactList();
+}
+
+QString ContactPage::title()
+{
+    return tr("ContactPage");
+}
+
+void ContactPage::cleanSelectedContactList()
+{
+    contactWidget->cleanSelectedContactList();
+}
+
+QVector<ContactWidgetItem*>* ContactPage::getSelectedContacts()
+{
+    return contactWidget->getSelectedContacts();
+}
+
+void ContactPage::onValidRecyele(bool valid)
+{
+    Q_EMIT validRecycle(valid);
+}
+
+void ContactPage::removeSelectedContact()
+{
+    contactWidget->removeSelectedContact();
+}
+
+void ContactPage::setContactItemObserver()
+{
+    contactWidget->setItemObserver();
+}
diff --git a/sms/contactpage.h b/sms/contactpage.h
new file mode 100644 (file)
index 0000000..169a28a
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef CONTACTPAGE_H
+#define CONTACTPAGE_H
+
+#include "abstractpage.h"
+
+class ContactPage : public AbstractPage
+{
+    Q_OBJECT
+public:
+    ContactPage(QWidget* parent = 0);
+
+    void updateSize();
+    void update();
+    void initContactWidget();
+    void refreshContactList();
+    void cleanSelectedContactList();
+    void removeSelectedContact();
+    void setContactItemObserver();
+    QVector<ContactWidgetItem*>* getSelectedContacts();
+    QString title();
+
+Q_SIGNALS:
+    void validRecycle(bool valid);
+
+public Q_SLOTS:
+    void onValidRecyele(bool valid);
+};
+
+#endif // CONTACTPAGE_H
diff --git a/sms/contactwidget.cpp b/sms/contactwidget.cpp
new file mode 100644 (file)
index 0000000..6464865
--- /dev/null
@@ -0,0 +1,451 @@
+#include <QtGui>
+#include <QDebug>
+
+#include "contactwidget.h"
+#include "contactwidgetitem.h"
+#include "groupwidgetitem.h"
+#include "contactinterface.h"
+#include "utility.h"
+
+
+ContactWidget::ContactWidget(QWidget *parent) :
+    QWidget(parent)
+{
+    //qDebug() << "ContactWidget::ContactWidget(QWidget *parent), Entry";
+    contact_items = new QVector<ContactWidgetItem*>;
+    contact_items_selected = new QVector<ContactWidgetItem*>;
+}
+
+ContactWidget::~ContactWidget()
+{
+    //qDebug() << "ContactWidget::~ContactWidget(), Entry";
+    destroyContactWidget();
+}
+
+void ContactWidget::setItemObserver()
+{
+    ContactInterface::getInstance()->setItemObserver( this );
+}
+
+void ContactWidget::initContactWidget()
+{
+    //qDebug() << "ContactWidget::initContactWidget(), Entry";
+
+    setItemObserver();
+    ContactInterface::getInstance()->getAllContactsFromXml();
+}
+
+void ContactWidget::destroyContactWidget()
+{
+    //qDebug() << ("ContactWidget::destroyContactWidget(), Entry");
+
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        contact_items->remove(i);
+    }
+    contact_items->clear();
+    delete contact_items;
+    contact_items = NULL;
+
+    for (int i = 0; i < contact_items_selected->size(); ++i)
+    {
+        contact_items_selected->remove(i);
+    }
+    contact_items_selected->clear();
+    delete contact_items_selected;
+    contact_items_selected = NULL;
+
+    //qDebug() << ("ContactWidget::destroyContactWidget(), Exit");
+}
+
+int ContactWidget::findGroup(const QString &groupname)
+{
+    for( int i = 0; i < contact_items->size(); i++ )
+    {
+        if( contact_items->at(i)->m_isGroup )
+        {
+            if( groupname == (static_cast<GroupWidgetItem*>(contact_items->at(i)))->group_name )
+                return i;
+        }
+    }
+    return -1;
+}
+
+// from ItemObserver
+void ContactWidget::refreshContactsList()
+{
+    update();
+}
+
+// from ItemObserver
+void ContactWidget::removeContact(Item *contact)
+{
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        if( contact->uid == contact_items->at(i)->uid && contact->group_owner == contact_items->at(i)->group_owner )
+        {
+            disconnect( contact_items->at(i), SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+            disconnect( contact_items->at(i), SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+            contact_items->remove(i);
+            break;
+        }
+    }
+}
+
+// from ItemObserver
+void ContactWidget::removeAllContacts()
+{
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        delete contact_items->at(i);
+    }
+    contact_items->clear();
+}
+
+// from ItemObserver
+void ContactWidget::addGroup( Item *item )
+{
+    //qDebug() << "ContactWidget::addGroup( Item *item ), Entry";
+    GroupWidgetItem *group = new GroupWidgetItem(this);
+    group->group_name = item->group_name;
+    group->label_group_name->setText( item->group_name );
+
+    contact_items->append( group );
+
+    connect( group, SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+    connect( group, SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+
+    update();
+}
+
+// from ItemObserver
+void ContactWidget::addContact( Item *item )
+{
+    addContact(item, -1);
+}
+
+void ContactWidget::addContact(ContactWidgetItem *contact, int index)
+{
+    //qDebug() << ("ContactWidget::addContact(ContactWidgetItem *contact), Entry");
+    //qDebug() << "contact is" << (int)contact;
+    if( -1 == index || index >= contact_items->size() )
+    {
+        contact_items->append(contact);
+    }else
+    {
+        contact_items->insert( ++index, contact);
+    }
+
+    connect( contact, SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+    connect( contact, SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+}
+
+void ContactWidget::addContact( Item *item, int groupindex )
+{
+    //qDebug() << "ContactWidget::addContact( Item *item, int groupindex ), Entry";
+    if( item->m_isGroup )
+    {
+        GroupWidgetItem *contact = new GroupWidgetItem(this);
+
+        contact->label_group_name->setText( item->group_name );
+        contact->group_name = item->group_name;
+
+        addContact( (static_cast<ContactWidgetItem*>(contact)), groupindex );
+    }else
+    {
+        ContactWidgetItem *contact = new ContactWidgetItem(this);
+
+        contact->label_fullname->setText( item->full_name );
+        contact->full_name = item->full_name;
+
+        contact->label_mobile_number->setText( item->mobile_number );
+        contact->mobile_number = item->mobile_number;
+
+        contact->group_owner =  item->group_owner;
+
+        contact->uid = item->uid;
+
+        addContact(contact, groupindex);
+    }
+}
+
+// from ItemObserver
+void ContactWidget::addContact( Item *item, const QString &groupname )
+{
+    int groupindex = findGroup( groupname );
+    addContact( item, groupindex);
+}
+
+// from ItemObserver
+void ContactWidget::addContact( ItemListPtr items, const QString &groupname )
+{
+    //qDebug() << "addContact(const QString &groupname, Item &item)";
+    int groupindex = findGroup( groupname );
+
+    for( int i = 0; i < items.size(); i++ )
+    {
+        Item *item = items.at(i);
+
+        addContact( item, groupindex);
+    }
+    update();
+}
+
+// from ItemObserver
+void ContactWidget::addContact( ItemList items, const QString &groupname )
+{
+    //qDebug() << "addContact(const QString &groupname, Item &item)";
+    int groupindex = findGroup( groupname );
+
+    for( int i = 0; i < items.size(); i++ )
+    {
+        Item item = items.at(i);
+
+        addContact( &item, groupindex);
+    }
+    update();
+}
+
+void ContactWidget::cleanContactList()
+{
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        disconnect( contact_items->at(i), SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+        disconnect( contact_items->at(i), SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+    }
+    contact_items->clear();
+}
+
+void ContactWidget::cleanSelectedContactList()
+{
+    contact_items_selected->clear();
+
+    resetContacts();
+    update();
+}
+
+void ContactWidget::refreshContactList()
+{
+    //qDebug() << "ContactWidget::refreshContactList()";
+    cleanContactList();
+
+    ContactInterface::getInstance()->getAllContactsFromXml();
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        connect( contact_items->at(i), SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+        connect( contact_items->at(i), SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+    }
+
+    update();
+}
+
+void ContactWidget::resetContacts()
+{
+    //qDebug() << ("ContactWidget::resetContacts(), Entry");
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        if( contact_items->at(i)->m_isGroup )
+        {
+            (static_cast<GroupWidgetItem*>(contact_items->at(i)))->reSet();
+        }else
+        {
+            contact_items->at(i)->reSet();
+        }
+    }
+}
+
+void ContactWidget::update()
+{
+    update( contact_items );
+}
+
+void ContactWidget::update(QVector<ContactWidgetItem *> *items)
+{
+    //qDebug() << ("ContactWidget::update(), Entry");
+
+    bool group_open = false;
+    int size = items->size();
+    //qDebug() << "size is" << items->size();
+    int x = 0;
+    int y = 0;
+    for( int i = 0; i < size; i++ )
+    {
+        ContactWidgetItem *item = items->at(i);
+        if( item->m_isGroup )
+        {
+            //qDebug() << "ContactWidget::update(), item is group";
+            group_open = false;
+            x = 0;
+            y = (static_cast<GroupWidgetItem*>(item))->move(x, y, this);
+            if( (static_cast<GroupWidgetItem*>(item))->m_isOpenContactList )
+            {
+                x += CONTACT_ITEM_MARGE_WIDTH;
+                group_open = true;
+                //qDebug() << "group open is true. x =" << x;
+            }
+            (static_cast<GroupWidgetItem*>(item))->showAll();
+            y += MARGE_HEIGH;
+        }else
+        {
+            //qDebug() << "ContactWidget::update(), item is contact";
+            if( group_open )
+            {
+                y = item->move(x, y, this);
+                item->showAll();
+                y += MARGE_HEIGH;
+            }else
+            {
+                item->hideAll();
+            }
+        }        
+    }
+    resize( qApp->desktop()->rect().width(), y );
+
+    //qDebug() << ("ContactWidget::update(), Exit");
+}
+
+void ContactWidget::paintEvent(QPaintEvent *event)
+{
+    //qDebug() << "ContactWidget::paintEvent(QPaintEvent *event), Entry";
+
+    QPainter painter(this);
+    for (int i = 0; i < contact_items->size(); i++) {
+        //ContactWidgetItem *item = contact_items->at(i);
+        //painter.fillRect(0, item->m_x, width(), item->m_height, QBrush(item->m_color));
+        //qDebug() << "paint item at:" << i << "m_x=" << item->m_x << "m_height=" << item->m_height;
+    }
+    event->accept();
+}
+
+void ContactWidget::resizeEvent(QResizeEvent *event)
+{
+    Q_UNUSED( event )
+    //qDebug() << ("ContactWidget::resizeEvent(QResizeEvent *event), Entry");
+}
+
+void ContactWidget::contactItemSelected( ContactWidgetItem *item, bool selected )
+{
+    //qDebug() << ("ContactWidget::contactItemSelected( ContactWidgetItem *item, bool selected ), Entry");
+    //qDebug() << "item is" << (int)item;
+
+    if( selected )
+    {
+        //qDebug() << "contact_items_selected->append(item)" << item->full_name;
+        if( item->m_isGroup )
+        {
+            QString str = (static_cast<GroupWidgetItem*>(item))->group_name;
+            for( int i = 0; i < contact_items->size(); i++ )
+            {
+                if( contact_items->at(i)->group_owner == str )
+                {
+                    contact_items_selected->append( contact_items->at(i) );
+                    contact_items->at(i)->setSelected(true);
+                }
+            }
+        }else
+        {
+            contact_items_selected->append(item);
+            checkGroupPartOfSelected(item);
+        }
+    }else
+    {
+        if( item->m_isGroup )
+        {
+            QString str = (static_cast<GroupWidgetItem*>(item))->group_name;
+            for( int i = 0; i < contact_items_selected->size(); i++ )
+            {
+                if( contact_items_selected->at(i)->group_owner == str )
+                {
+                    contact_items_selected->remove( i );
+                    contact_items->at(i)->setSelected(false);
+                }
+            }
+        }else
+        {
+            for( int i = 0; i < contact_items_selected->size(); i++ )
+            {
+                if( contact_items_selected->at(i)->uid == item->uid )
+                {
+                    contact_items_selected->remove( i );
+                    checkGroupPartOfSelected( item );
+                    break;
+                }
+            }
+        }
+    }
+    Q_EMIT validRecycle( isValidRecycle() );
+}
+
+void ContactWidget::checkGroupPartOfSelected(ContactWidgetItem* item)
+{
+    bool partselected = false;
+    GroupWidgetItem* group = NULL;
+    QString str = item->group_owner;
+    for( int i = 0; i < contact_items->size(); i++ )
+    {
+        if(  contact_items->at(i)->m_isGroup && str == (static_cast<GroupWidgetItem*>(contact_items->at(i)))->group_name )
+        {
+             group = (static_cast<GroupWidgetItem*>(contact_items->at(i)));
+             break;
+        }
+    }
+
+    for( int i = 0; i < contact_items_selected->size(); i++ )
+    {
+        if( group->group_name == contact_items_selected->at(i)->group_owner )
+        {
+            partselected = true;
+            break;
+        }
+    }
+    if( partselected )
+    {
+        group->partOfAllSeleted();
+    }else
+    {
+        group->setSelected(false);
+    }
+}
+
+QVector<ContactWidgetItem*>* ContactWidget::getSelectedContacts()
+{
+    return contact_items_selected;
+}
+
+bool ContactWidget::isValidRecycle()
+{
+    if( contact_items_selected->size() > 0 )
+        return true;
+    return false;
+}
+
+void ContactWidget::removeSelectedContact()
+{
+    ItemListPtr list;
+    for( int i = 0; i < contact_items_selected->size(); i++ )
+    {
+        ContactWidgetItem *contact = contact_items_selected->at(i);
+        if( contact->m_isGroup )
+        {
+            continue;
+        }
+
+        Item *item = new Item();
+        item->uid = contact->uid;
+        item->full_name = contact->full_name;
+        item->mobile_number = contact->mobile_number;
+        item->group_owner = contact->group_owner;
+
+        list.append(item);
+    }
+    ContactInterface::getInstance()->removeContactToGroup(list);
+    contact_items_selected->clear();
+}
+
+
+
+
+
+
+
+
diff --git a/sms/contactwidget.h b/sms/contactwidget.h
new file mode 100644 (file)
index 0000000..9a27ed4
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef CONTACTWIDGET_H
+#define CONTACTWIDGET_H
+
+#include <QtGui>
+#include <QVector>
+
+#include <contactwidgetitem.h>
+#include "itemobserver.h"
+
+class ContactWidget : public QWidget, public ItemObserver
+{
+    Q_OBJECT
+public:
+    ContactWidget(QWidget *parent = 0);
+    ~ContactWidget();
+
+    // from ItemObserver
+    void addGroup(Item *item);
+    void addContact( Item *item );
+    void addContact( Item *item, const QString &groupname );
+    void addContact( ItemList items, const QString &groupname );
+    void addContact( ItemListPtr items, const QString &groupname );
+    void removeContact(Item *contact);
+    void removeAllContacts();
+    void refreshContactsList();
+
+    void addContact( Item *item, int groupindex );
+    void addContact(ContactWidgetItem *contact, int index);
+    void removeSelectedContact();
+
+    virtual void initContactWidget();
+    void setItemObserver();
+
+    QVector<ContactWidgetItem*>* getSelectedContacts();
+
+    void cleanSelectedContactList();
+
+    bool isValidRecycle();
+
+protected:
+    void resizeEvent(QResizeEvent *event);
+    void paintEvent(QPaintEvent *event);
+    void update( QVector<ContactWidgetItem*>* items );
+
+    void cleanContactList();    
+
+    virtual void destroyContactWidget();
+
+    int findGroup(const QString &groupname);
+
+    void checkGroupPartOfSelected(ContactWidgetItem* item);
+
+protected:
+    QVector<ContactWidgetItem*> *contact_items;
+    QVector<ContactWidgetItem*> *contact_items_selected;
+
+    int last_height;
+
+Q_SIGNALS:
+    void validRecycle(bool valid);
+
+public Q_SLOTS:
+    void update();
+    void contactItemSelected(ContactWidgetItem *item, bool selected);
+    void refreshContactList();
+    void resetContacts();
+};
+
+#endif // CONTACTWIDGET_H
diff --git a/sms/contactwidgetitem.cpp b/sms/contactwidgetitem.cpp
new file mode 100644 (file)
index 0000000..5ddb673
--- /dev/null
@@ -0,0 +1,129 @@
+#include <QDebug>
+
+#include "contactwidgetitem.h"
+#include "utility.h"
+
+
+ContactWidgetItem::ContactWidgetItem(QObject *parent) : QObject(parent)
+{
+    btn_selected = new QToolButton();
+    btn_selected->setText("");
+    btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+    btn_selected->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_selected->setAutoRaise(true);
+
+    user_pic_uri = ":/images/male.png";
+    label_fullname = new QLabel();
+    label_mobile_number = new QLabel();
+    label_user_pic = new QLabel();
+    label_user_pic->setPixmap(Utility::getIconPixmap(user_pic_uri));
+
+    m_isSelected = false;
+    m_isGroup = false;
+    m_x = 0;
+    m_height = 0;
+    m_color.setRgb(255,0,0);
+
+    connect(btn_selected, SIGNAL( clicked() ), this, SLOT( btn_selected_clicked() ) );
+
+    //qDebug() << "ContactWidgetItem" << (int)this;
+}
+
+ContactWidgetItem::~ContactWidgetItem()
+{
+    //qDebug() << "~ContactWidgetItem" << (int)this;
+    delete btn_selected;
+    delete label_fullname;
+    delete label_mobile_number;
+    delete label_user_pic;
+}
+
+void ContactWidgetItem::loadUserPic()
+{
+    QPixmap pixmap(user_pic_uri);
+    if (!pixmap.isNull()) {
+        label_user_pic->setPixmap(pixmap.scaled(ICON_SIZE, ICON_SIZE));
+    }
+    label_user_pic->resize(ICON_SIZE, ICON_SIZE);
+}
+
+void ContactWidgetItem::reSet()
+{
+    m_isSelected = false;
+    m_isGroup = false;
+    btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+}
+
+int ContactWidgetItem::move(int x, int y, QWidget *parent)
+{
+    //qDebug() << "ContactWidgetItem::move(int x, int y), Entry";
+    //qDebug() << "x=" << x << "y=" << y << "screen_width=" << QApplication::desktop()->width();
+    //int screen_width = QApplication::desktop()->width();
+    m_x = x;
+    m_height = 0;
+    int _y = y;
+
+    btn_selected->setParent(parent);
+    btn_selected->move( ( x + BTN_SELECTED_OFFSET_X ), ( _y + BTN_SELECTED_OFFSET_Y ) );
+    //qDebug() << "btn_selected x=" << ( x + BTN_SELECTED_OFFSET_X ) << "btn_selected y=" << ( _y + BTN_SELECTED_OFFSET_Y );
+
+    label_user_pic->setParent(parent);
+    label_user_pic->move( ( x + USER_PIC_OFFSET_X ), ( _y + USER_PIC_OFFSET_Y ) );
+    //qDebug() << "label_user_pic x=" << ( x + USER_PIC_OFFSET_X ) << "label_user_pic y=" << ( _y + USER_PIC_OFFSET_Y );
+
+    label_fullname->setParent(parent);
+    label_fullname->move( ( x + FULL_NAME_OFFSET_X ), ( _y + FULL_NAME_OFFSET_Y ) );
+    //qDebug() << "label_fullname x=" << ( x + FULL_NAME_OFFSET_X ) << "label_fullname y=" << ( _y + FULL_NAME_OFFSET_Y );
+
+    label_mobile_number->setParent(parent);
+    label_mobile_number->move( ( x + MOBILE_NUMBER_OFFSET_X ), ( _y + MOBILE_NUMBER_OFFSET_Y ) );
+    //qDebug() << "label_mobile_number x=" << ( x + MOBILE_NUMBER_OFFSET_X ) << "label_mobile_number y=" << ( _y + MOBILE_NUMBER_OFFSET_Y );
+
+    m_height = y + ITEM_HEIGHT;
+    //qDebug() << "m_height=" << m_height;
+    //qDebug() << "ContactWidgetItem::move(int x, int y), Exit";
+
+    return m_height;
+}
+
+void ContactWidgetItem::showAll()
+{
+    btn_selected->show();
+    label_fullname->show();
+    label_mobile_number->show();
+    label_user_pic->show();
+}
+
+void ContactWidgetItem::hideAll()
+{
+    btn_selected->hide();
+    label_fullname->hide();
+    label_mobile_number->hide();
+    label_user_pic->hide();
+}
+
+void ContactWidgetItem::btn_selected_clicked()
+{
+    m_isSelected = !m_isSelected;
+    if( m_isSelected )
+    {
+        btn_selected->setIcon( Utility::getToolButtonIcon(":/images/select.png", true) );
+    }else
+    {
+        btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+    }
+    Q_EMIT itemSelected( this, m_isSelected );
+    //qDebug() << "ContactWidgetItem::btn_selected_clicked(), Exit";
+}
+
+void ContactWidgetItem::setSelected(bool selected)
+{
+    if( selected )
+    {
+        btn_selected->setIcon( Utility::getToolButtonIcon(":/images/select.png", true) );
+    }else
+    {
+        btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+    }
+    //qDebug() << "ContactWidgetItem::setSelected(bool selected), Exit";
+}
diff --git a/sms/contactwidgetitem.h b/sms/contactwidgetitem.h
new file mode 100644 (file)
index 0000000..f589413
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef CONTACTWIDGETITEM_H
+#define CONTACTWIDGETITEM_H
+
+#include <QToolButton>
+#include <QLabel>
+#include "item.h"
+
+
+const int ICON_SIZE = 38;
+const int MARGE_HEIGH = 4;
+const int CONTACT_ITEM_MARGE_WIDTH = 50;
+const int BTN_SELECTED_OFFSET_X = 10;
+const int BTN_SELECTED_OFFSET_Y = 5;
+const int USER_PIC_OFFSET_X = BTN_SELECTED_OFFSET_X + 80;
+const int USER_PIC_OFFSET_Y = BTN_SELECTED_OFFSET_Y + 20;
+const int FULL_NAME_OFFSET_X = USER_PIC_OFFSET_X + 50;
+const int FULL_NAME_OFFSET_Y = 5;
+const int MOBILE_NUMBER_OFFSET_X = FULL_NAME_OFFSET_X;
+const int MOBILE_NUMBER_OFFSET_Y = FULL_NAME_OFFSET_Y + 30;
+
+const int BTN_SELECTED_MARGE_WIDTH = 130;
+
+// GroupWidgetItem
+const int BTN_OPEN_GROUP_OFFSET_X = 10;
+const int BTN_OPEN_GROUP_OFFSET_Y = 5;
+const int BTN_GROUP_SELECTED_OFFSET_X = BTN_OPEN_GROUP_OFFSET_X + 60;
+const int BTN_GROUP_SELECTED_OFFSET_Y = 5;
+const int GROUP_USER_PIC_OFFSET_X = BTN_GROUP_SELECTED_OFFSET_X + 80;
+const int GROUP_USER_PIC_OFFSET_Y = BTN_OPEN_GROUP_OFFSET_Y + 25;
+const int GROUP_NAME_OFFSET_X = GROUP_USER_PIC_OFFSET_X + 50;
+const int GROUP_NAME_OFFSET_Y = 20;
+
+const int ITEM_HEIGHT = 60;
+
+const int BTN_TOOL_WIDTH = 60;
+const int BTN_TOOL_HEIGHT = 60;
+
+class ContactWidgetItem : public QObject
+{
+    Q_OBJECT
+public:
+    ContactWidgetItem(QObject *parent = 0);
+    ~ContactWidgetItem();
+
+    void loadUserPic();
+    int move(int x, int y, QWidget *parent = 0);
+    void showAll();
+    void hideAll();
+    void reSet();
+    void setData( Item &item );
+    void setSelected(bool selected);
+
+    QToolButton *btn_selected;
+    QLabel *label_fullname;
+    QLabel *label_mobile_number;
+    QLabel *label_user_pic;
+    QString user_pic_uri;
+
+    QString full_name;
+    QString mobile_number;
+    QString group_owner;
+    QString uid;
+
+    int m_x;
+    int m_height;
+    bool m_isSelected;
+    bool m_isGroup;
+    QColor m_color;
+
+Q_SIGNALS:
+    void itemUpdate();
+    void itemSelected( ContactWidgetItem *item, bool selected );
+
+public Q_SLOTS:
+    void btn_selected_clicked();
+};
+
+#endif // CONTACTWIDGETITEM_H
diff --git a/sms/data/26x26/groupsms.png b/sms/data/26x26/groupsms.png
new file mode 100644 (file)
index 0000000..ac1d101
Binary files /dev/null and b/sms/data/26x26/groupsms.png differ
diff --git a/sms/data/40x40/groupsms.png b/sms/data/40x40/groupsms.png
new file mode 100644 (file)
index 0000000..0f8a5af
Binary files /dev/null and b/sms/data/40x40/groupsms.png differ
diff --git a/sms/data/64x64/groupsms.png b/sms/data/64x64/groupsms.png
new file mode 100644 (file)
index 0000000..0703ae3
Binary files /dev/null and b/sms/data/64x64/groupsms.png differ
diff --git a/sms/data/icon.svg b/sms/data/icon.svg
new file mode 100644 (file)
index 0000000..df7182e
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="48"
+   height="48"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.45.1"
+   version="1.0"
+   sodipodi:docbase="/scratchbox/users/tim/home/tim/projects/MaemoRate/data/icons"
+   sodipodi:docname="icon.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:export-filename="/scratchbox/users/tim/home/tim/projects/MaemoRate/data/icons/icon40x40.png"
+   inkscape:export-xdpi="75"
+   inkscape:export-ydpi="75">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3142">
+      <stop
+         style="stop-color:#ed8300;stop-opacity:1;"
+         offset="0"
+         id="stop3144" />
+      <stop
+         style="stop-color:#edb400;stop-opacity:1;"
+         offset="1"
+         id="stop3146" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="19.291667"
+     inkscape:cx="24"
+     inkscape:cy="36.13239"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     width="48px"
+     height="48px"
+     borderlayer="true"
+     showgrid="true"
+     inkscape:object-bbox="true"
+     inkscape:object-points="true"
+     inkscape:object-nodes="true"
+     objecttolerance="10000"
+     inkscape:grid-points="true"
+     gridtolerance="10000"
+     inkscape:guide-points="true"
+     guidetolerance="10000"
+     inkscape:window-width="1600"
+     inkscape:window-height="1153"
+     inkscape:window-x="4"
+     inkscape:window-y="21" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       sodipodi:type="star"
+       style="fill:#e88e00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path2162"
+       sodipodi:sides="5"
+       sodipodi:cx="24"
+       sodipodi:cy="22"
+       sodipodi:r1="25"
+       sodipodi:r2="11.136072"
+       sodipodi:arg1="0.92729522"
+       sodipodi:arg2="1.5638015"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 39,42 L 24.077894,33.1358 L 9.6141245,42.446188 L 13.433296,25.515233 L 0.10904005,14.636439 L 17.391523,13.036734 L 23.62045,-2.9971187 L 30.482441,12.945164 L 47.656385,13.914492 L 34.614846,25.36707 L 39,42 z "
+       transform="matrix(1.0106664,2.4665321e-2,-2.3555045e-2,1.0583046,0.2345588,2.5892586)" />
+    <path
+       sodipodi:type="star"
+       style="fill:#b4b3b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path4119"
+       sodipodi:sides="5"
+       sodipodi:cx="24"
+       sodipodi:cy="22"
+       sodipodi:r1="25"
+       sodipodi:r2="11.136072"
+       sodipodi:arg1="0.92729522"
+       sodipodi:arg2="1.5638015"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 39,42 L 24.077894,33.1358 L 9.6141245,42.446188 L 13.433296,25.515233 L 0.10904005,14.636439 L 17.391523,13.036734 L 23.62045,-2.9971187 L 30.482441,12.945164 L 47.656385,13.914492 L 34.614846,25.36707 L 39,42 z "
+       transform="matrix(0.2943392,7.1940526e-3,-6.8600003e-3,0.3086722,2.0683112,1.7551995)" />
+    <path
+       sodipodi:type="star"
+       style="fill:#e88e00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path2216"
+       sodipodi:sides="5"
+       sodipodi:cx="24"
+       sodipodi:cy="22"
+       sodipodi:r1="25"
+       sodipodi:r2="11.136072"
+       sodipodi:arg1="0.92729522"
+       sodipodi:arg2="1.5638015"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="M 39,42 L 24.077894,33.1358 L 9.6141245,42.446188 L 13.433296,25.515233 L 0.10904005,14.636439 L 17.391523,13.036734 L 23.62045,-2.9971187 L 30.482441,12.945164 L 47.656385,13.914492 L 34.614846,25.36707 L 39,42 z "
+       transform="matrix(0.2943392,7.1940526e-3,-6.8600003e-3,0.3086722,32.068311,1.7551995)" />
+  </g>
+</svg>
diff --git a/sms/data/maemo/groupsms.xpm b/sms/data/maemo/groupsms.xpm
new file mode 100644 (file)
index 0000000..c3dfdb8
--- /dev/null
@@ -0,0 +1,324 @@
+/* XPM */
+static char * qt4_xpm[] = {
+"26 26 295 2",
+"      c None",
+".     c #85B623",
+"+     c #425911",
+"@     c #99D029",
+"#     c #9ED32C",
+"$     c #98CF28",
+"%     c #92C826",
+"&     c #85B723",
+"*     c #7EAC21",
+"=     c #455D12",
+"-     c #9ED42E",
+";     c #CEF24F",
+">     c #CBF14B",
+",     c #C3EB43",
+"'     c #B8E43B",
+")     c #ADDD34",
+"!     c #A2D62E",
+"~     c #95CB28",
+"{     c #88BA24",
+"]     c #80AF22",
+"^     c #36490E",
+"/     c #A4D735",
+"(     c #CDF05D",
+"_     c #CDF05B",
+":     c #CDF158",
+"<     c #CEF156",
+"[     c #CEF253",
+"}     c #CFF350",
+"|     c #CDF14B",
+"1     c #B7E33B",
+"2     c #AADC33",
+"3     c #9CD02B",
+"4     c #8ABD25",
+"5     c #82B222",
+"6     c #A6D83B",
+"7     c #CAED66",
+"8     c #CBED64",
+"9     c #CBEE63",
+"0     c #CCEE62",
+"a     c #CEF062",
+"b     c #D1F163",
+"c     c #D3F363",
+"d     c #D4F361",
+"e     c #D3F35D",
+"f     c #D1F357",
+"g     c #CFF250",
+"h     c #C8EF49",
+"i     c #BCE73F",
+"j     c #ADDD35",
+"k     c #84B424",
+"l     c #A6D73E",
+"m     c #C7EA6B",
+"n     c #C9EB6A",
+"o     c #CCED6C",
+"p     c #D2EF71",
+"q     c #CDE771",
+"r     c #B4CE67",
+"s     c #AAC661",
+"t     c #AFCB60",
+"u     c #C3E066",
+"v     c #D3F167",
+"w     c #CEF05F",
+"x     c #CCEF5A",
+"y     c #C4E653",
+"z     c #5C6C33",
+"A     c #3B2A55",
+"B     c #9360E4",
+"C     c #8858D0",
+"D     c #A5D63E",
+"E     c #C2E66C",
+"F     c #C4E76C",
+"G     c #C8E970",
+"H     c #D0ED76",
+"I     c #B7CC74",
+"J     c #92A56E",
+"K     c #93A670",
+"L     c #93A86E",
+"M     c #93A96B",
+"N     c #91A967",
+"O     c #A6BF68",
+"P     c #CDEB6E",
+"Q     c #C1E062",
+"R     c #889A4E",
+"S     c #3F3152",
+"T     c #8861C7",
+"U     c #A675F3",
+"V     c #9367D7",
+"W     c #A3D53D",
+"X     c #BEE36B",
+"Y     c #C0E46D",
+"Z     c #C9E973",
+"`     c #B9CE77",
+" .    c #929D7D",
+"..    c #95A080",
+"+.    c #9BAA77",
+"@.    c #B3C877",
+"#.    c #B6CA77",
+"$.    c #A0B175",
+"%.    c #94A378",
+"&.    c #A1B471",
+"*.    c #9FB75C",
+"=.    c #534660",
+"-.    c #785CA4",
+";.    c #9772D2",
+">.    c #AB82EC",
+",.    c #9E78D9",
+"'.    c #A1D43B",
+").    c #B8DF65",
+"!.    c #BEE269",
+"~.    c #C8E573",
+"{.    c #939C80",
+"].    c #9AA08F",
+"^.    c #A0AF7A",
+"/.    c #C9E674",
+"(.    c #C7E771",
+"_.    c #CBEA75",
+":.    c #CFE77A",
+"<.    c #AAB97B",
+"[.    c #858D77",
+"}.    c #645C69",
+"|.    c #705794",
+"1.    c #B593EB",
+"2.    c #432F65",
+"3.    c #B694EC",
+"4.    c #A98ADA",
+"5.    c #9ED337",
+"6.    c #B2DC5C",
+"7.    c #BBE163",
+"8.    c #AEC36E",
+"9.    c #989B93",
+"0.    c #939887",
+"a.    c #C0DE6C",
+"b.    c #BBE164",
+"c.    c #BEE267",
+"d.    c #B6CE70",
+"e.    c #8C9478",
+"f.    c #BCD36F",
+"g.    c #6B715D",
+"h.    c #442E66",
+"i.    c #AC92D6",
+"j.    c #AE95D8",
+"k.    c #766099",
+"l.    c #C7ACF3",
+"m.    c #C0A7EA",
+"n.    c #9BD131",
+"o.    c #ABD84F",
+"p.    c #B7DF59",
+"q.    c #95A467",
+"r.    c #8E8F8C",
+"s.    c #93A06F",
+"t.    c #B9E05B",
+"u.    c #B5DE58",
+"v.    c #B3D062",
+"w.    c #878B7D",
+"x.    c #848781",
+"y.    c #99B05A",
+"z.    c #646F42",
+"A.    c #271449",
+"B.    c #B8A3DB",
+"C.    c #D5C1F7",
+"D.    c #D4C0F6",
+"E.    c #D7C3F9",
+"F.    c #D3BFF4",
+"G.    c #98CF2A",
+"H.    c #A3D53E",
+"I.    c #B2DC49",
+"J.    c #808C57",
+"K.    c #7B7B7B",
+"L.    c #8C9D59",
+"M.    c #B3DD4A",
+"N.    c #AED24D",
+"O.    c #727763",
+"P.    c #808180",
+"Q.    c #879262",
+"R.    c #ACD149",
+"S.    c #71813E",
+"T.    c #363635",
+"U.    c #434E2A",
+"V.    c #312446",
+"W.    c #38205F",
+"X.    c #DCCAF6",
+"Y.    c #C8BBDE",
+"Z.    c #97CF28",
+"`.    c #9BD12B",
+" +    c #AAD937",
+".+    c #758542",
+"++    c #636363",
+"@+    c #768547",
+"#+    c #B1D83F",
+"$+    c #5B633F",
+"%+    c #5F5F5F",
+"&+    c #626262",
+"*+    c #5C5D5A",
+"=+    c #94AF3F",
+"-+    c #7A8B40",
+";+    c #4E5143",
+">+    c #6B8C20",
+",+    c #38441E",
+"'+    c #351F58",
+")+    c #C3B6D6",
+"!+    c #A6D733",
+"~+    c #869E3B",
+"{+    c #515151",
+"]+    c #515543",
+"^+    c #B4D544",
+"/+    c #545C39",
+"(+    c #575E3E",
+"_+    c #97AF43",
+":+    c #4E4F4B",
+"<+    c #505247",
+"[+    c #595D46",
+"}+    c #616D40",
+"|+    c #8FBE29",
+"1+    c #668B1B",
+"2+    c #98D028",
+"3+    c #A0D42F",
+"4+    c #AAD13C",
+"5+    c #41423B",
+"6+    c #454545",
+"7+    c #75853B",
+"8+    c #B2D443",
+"9+    c #A5CA3B",
+"0+    c #B5DF3E",
+"a+    c #8CA13F",
+"b+    c #464645",
+"c+    c #474747",
+"d+    c #849E3A",
+"e+    c #9ACF2B",
+"f+    c #7FAF22",
+"g+    c #36480E",
+"h+    c #AAD936",
+"i+    c #758935",
+"j+    c #373737",
+"k+    c #353534",
+"l+    c #5A6630",
+"m+    c #90AC38",
+"n+    c #93B038",
+"o+    c #647131",
+"p+    c #323332",
+"q+    c #313131",
+"r+    c #526227",
+"s+    c #9CD12B",
+"t+    c #84B523",
+"u+    c #35470E",
+"v+    c #98D029",
+"w+    c #9FD32E",
+"x+    c #AED93A",
+"y+    c #5D6C2C",
+"z+    c #252525",
+"A+    c #202020",
+"B+    c #1E1E1E",
+"C+    c #1D1D1D",
+"D+    c #363C21",
+"E+    c #4D5924",
+"F+    c #759429",
+"G+    c #9AD02A",
+"H+    c #33450D",
+"I+    c #ADDA39",
+"J+    c #84A131",
+"K+    c #46521F",
+"L+    c #2D3417",
+"M+    c #363F19",
+"N+    c #677D26",
+"O+    c #A6D137",
+"P+    c #A4D333",
+"Q+    c #9ED22D",
+"R+    c #81B122",
+"S+    c #33440D",
+"T+    c #9DD22C",
+"U+    c #A4D631",
+"V+    c #ACDA38",
+"W+    c #A9D835",
+"X+    c #A1D430",
+"Y+    c #9BD12A",
+"Z+    c #7AA820",
+"`+    c #9AD12A",
+" @    c #8EC326",
+".@    c #77A21F",
+"+@    c #5D8019",
+"@@    c #2A380B",
+"#@    c #96CE28",
+"$@    c #8BBF25",
+"%@    c #719A1E",
+"&@    c #547316",
+"*@    c #2F410D",
+"=@    c #405711",
+"-@    c #95CD28",
+";@    c #87B924",
+">@    c #6B931C",
+",@    c #4E6B15",
+"'@    c #28370B",
+")@    c #2E3F0C",
+"!@    c #678D1B",
+"~@    c #486213",
+"{@    c #202C08",
+"                                                    ",
+"          .                                         ",
+"        + @ # $ % & *                               ",
+"        = - ; > , ' ) ! ~ { ]                       ",
+"      ^ = / ( _ : < [ } | , 1 2 3 4 5               ",
+"      ^ = 6 7 8 9 0 a b c d e f g h i j k           ",
+"      ^ = l m m n o p q r s t u v w x y z A B C     ",
+"      ^ = D E F G H I J K L M N O P Q R S T U V     ",
+"      ^ = W X Y Z `  ...+.@.#.$.%.&.*.=.-.;.>.,.    ",
+"      ^ = '.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.    ",
+"      ^ = 5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.    ",
+"      ^ = n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.    ",
+"      ^ = G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.    ",
+"      ^ = Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+      ",
+"      ^ = Z.@ !+~+{+]+^+/+(+_+:+<+[+}+|+1+          ",
+"      ^ = Z.2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+          ",
+"      g+= Z.Z.`.h+i+j+k+l+m+n+o+p+q+r+s+t+          ",
+"      u+= Z.Z.v+w+x+y+z+z+A+B+C+D+E+F+G+t+          ",
+"      H+= Z.Z.Z.@ 3+I+J+K+L+M+N+O+P+Q+Z.R+          ",
+"      S+= Z.Z.Z.Z.@ T+U+h+V+W+X+Y+@ Z.Z.Z+          ",
+"      S+= Z.Z.Z.Z.Z.$ @ G+`+@ $ Z. @.@+@            ",
+"      @@= Z.Z.Z.Z.Z.Z.Z.#@$@%@&@*@                  ",
+"        =@Z.Z.Z.-@;@>@,@'@                          ",
+"        )@t+!@~@{@                                  ",
+"                                                    ",
+"                                                    "};
diff --git a/sms/groupsms.desktop b/sms/groupsms.desktop
new file mode 100644 (file)
index 0000000..b0c67eb
--- /dev/null
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.1
+Type=Application
+Name=Group SMS
+Exec=/usr/bin/groupsms
+Icon=groupsms
+StartupWMClass=groupsms
+X-Window-Icon=groupsms
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
+Terminal=false
+
diff --git a/sms/groupsms.qrc b/sms/groupsms.qrc
new file mode 100644 (file)
index 0000000..430b3cc
--- /dev/null
@@ -0,0 +1,16 @@
+<RCC>
+    <qresource prefix="/" >
+        <file>images/addcontacttogroup.png</file>
+        <file>images/female.png</file>
+        <file>images/male.png</file>
+        <file>images/newgroup.png</file>
+        <file>images/editgroup.png</file>
+        <file>images/plus.png</file>
+        <file>images/sub.png</file>
+        <file>images/recycle.png</file>
+        <file>images/select.png</file>
+        <file>images/allselect.png</file>
+        <file>images/unselect.png</file>
+        <file>images/partselect.png</file>
+    </qresource>
+</RCC>
diff --git a/sms/groupwidgetitem.cpp b/sms/groupwidgetitem.cpp
new file mode 100644 (file)
index 0000000..e7f3e67
--- /dev/null
@@ -0,0 +1,110 @@
+#include "groupwidgetitem.h"
+#include "utility.h"
+
+GroupWidgetItem::GroupWidgetItem(QObject *parent)
+    : ContactWidgetItem(parent)
+{
+    btn_selected = new QToolButton();
+    btn_selected->setText("");
+    btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+    btn_selected->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_selected->setAutoRaise(true);
+    btn_selected->adjustSize();
+
+    btn_open_group = new QToolButton();
+    btn_open_group->setText("");
+    btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) );
+    btn_open_group->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_open_group->setAutoRaise(true);
+    btn_open_group->adjustSize();
+
+    label_group_name = new QLabel();
+
+
+    m_isSelected = false;
+    m_isOpenContactList = false;
+    m_isGroup = true;
+
+    m_x = 0;
+    m_height = 0;
+
+    connect( btn_open_group, SIGNAL( clicked() ), this, SLOT( btn_open_group_clicked() ) );
+    connect(btn_selected, SIGNAL( clicked() ), this, SLOT( btn_selected_clicked() ) );
+    //qDebug() << "GroupWidgetItem::GroupWidgetItem(QObject *parent), Exit" << (int)this;
+}
+
+GroupWidgetItem::~GroupWidgetItem()
+{
+    //qDebug() << "GroupWidgetItem::~GroupWidgetItem()" << (int)this;
+    delete btn_open_group;
+    delete label_group_name;
+}
+
+int GroupWidgetItem::move(int x, int y, QWidget *parent)
+{
+    //qDebug() << "GroupWidgetItem::move(int x, int y), Entry";
+    m_x = x;
+    m_height = 0;
+    int _y = y;
+
+    btn_open_group->setParent(parent);
+    btn_open_group->move( ( x + BTN_OPEN_GROUP_OFFSET_X ), ( _y + BTN_OPEN_GROUP_OFFSET_Y ) );
+    //qDebug() << "btn_open_group x=" << ( x + BTN_OPEN_GROUP_OFFSET_X ) << "btn_open_group y=" << ( _y + BTN_OPEN_GROUP_OFFSET_Y );
+
+    btn_selected->setParent(parent);
+    btn_selected->move( ( x + BTN_GROUP_SELECTED_OFFSET_X ), ( _y + BTN_GROUP_SELECTED_OFFSET_Y ) );
+    //qDebug() << "btn_selected x=" << ( x + BTN_GROUP_SELECTED_OFFSET_X ) << "btn_selected y=" << ( _y + BTN_GROUP_SELECTED_OFFSET_Y );
+
+    label_user_pic->setParent(parent);
+    label_user_pic->move( ( x + GROUP_USER_PIC_OFFSET_X ), ( _y + GROUP_USER_PIC_OFFSET_Y ) );
+    //qDebug() << "label_user_pic x=" << ( x + GROUP_USER_PIC_OFFSET_X ) << "label_user_pic y=" << ( _y + GROUP_USER_PIC_OFFSET_Y );
+
+    label_group_name->setParent(parent);
+    label_group_name->move( ( x + GROUP_NAME_OFFSET_X ), ( _y + GROUP_NAME_OFFSET_Y ) );
+    //qDebug() << "label_fullname x=" << ( x + GROUP_NAME_OFFSET_X ) << "label_fullname y=" << ( _y + GROUP_NAME_OFFSET_Y );
+
+    m_height = y + ITEM_HEIGHT;
+
+    showAll();
+
+    //qDebug() << "m_height=" << m_height;
+    //qDebug() << "GroupWidgetItem::move(int x, int y), Exit";
+
+    return m_height;
+}
+
+void GroupWidgetItem::reSet()
+{
+    m_isSelected = false;
+    m_isGroup = true;
+    btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) );
+    btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) );
+}
+
+void GroupWidgetItem::btn_open_group_clicked()
+{
+    //qDebug() << "GroupWidgetItem::btn_open_group_clicked(), Entry";
+    m_isOpenContactList = !m_isOpenContactList;
+    if( m_isOpenContactList )
+    {
+        btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/sub.png", true) );
+    }else
+    {
+        btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) );
+    }
+    Q_EMIT itemUpdate();
+    //qDebug() << "GroupWidgetItem::btn_open_group_clicked(), Exit" << (int)this;
+}
+
+void GroupWidgetItem::showAll()
+{
+    btn_selected->show();
+    btn_open_group->show();
+    label_group_name->show();
+    label_user_pic->show();
+}
+
+void GroupWidgetItem::partOfAllSeleted()
+{
+    btn_selected->setIcon( Utility::getToolButtonIcon(":/images/partselect.png", true) );
+}
diff --git a/sms/groupwidgetitem.h b/sms/groupwidgetitem.h
new file mode 100644 (file)
index 0000000..48b8ff9
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef GROUPWIDGETITEM_H
+#define GROUPWIDGETITEM_H
+
+#include <QToolButton>
+#include <QLabel>
+
+#include "contactwidgetitem.h"
+
+class GroupWidgetItem : public ContactWidgetItem
+{
+    Q_OBJECT
+public:
+    GroupWidgetItem(QObject *parent = 0);
+    ~GroupWidgetItem();
+
+    int move(int x, int y, QWidget *parent = 0);
+    void showAll();
+    void reSet();
+    void partOfAllSeleted();
+
+    QToolButton *btn_open_group;
+    QLabel *label_group_name;
+    QString group_name;
+
+    bool m_isOpenContactList;
+
+public Q_SLOTS:
+    void btn_open_group_clicked();
+};
+
+#endif // GROUPWIDGETITEM_H
diff --git a/sms/images/addcontacttogroup.png b/sms/images/addcontacttogroup.png
new file mode 100644 (file)
index 0000000..1bc6a20
Binary files /dev/null and b/sms/images/addcontacttogroup.png differ
diff --git a/sms/images/allselect.png b/sms/images/allselect.png
new file mode 100644 (file)
index 0000000..c33da34
Binary files /dev/null and b/sms/images/allselect.png differ
diff --git a/sms/images/editgroup.png b/sms/images/editgroup.png
new file mode 100644 (file)
index 0000000..9dd67ec
Binary files /dev/null and b/sms/images/editgroup.png differ
diff --git a/sms/images/female.png b/sms/images/female.png
new file mode 100644 (file)
index 0000000..033f663
Binary files /dev/null and b/sms/images/female.png differ
diff --git a/sms/images/male.png b/sms/images/male.png
new file mode 100644 (file)
index 0000000..6172757
Binary files /dev/null and b/sms/images/male.png differ
diff --git a/sms/images/newgroup.png b/sms/images/newgroup.png
new file mode 100644 (file)
index 0000000..0e02c8a
Binary files /dev/null and b/sms/images/newgroup.png differ
diff --git a/sms/images/partselect.png b/sms/images/partselect.png
new file mode 100644 (file)
index 0000000..f729984
Binary files /dev/null and b/sms/images/partselect.png differ
diff --git a/sms/images/plus.png b/sms/images/plus.png
new file mode 100644 (file)
index 0000000..754ee70
Binary files /dev/null and b/sms/images/plus.png differ
diff --git a/sms/images/recycle.png b/sms/images/recycle.png
new file mode 100644 (file)
index 0000000..c3b6025
Binary files /dev/null and b/sms/images/recycle.png differ
diff --git a/sms/images/select.png b/sms/images/select.png
new file mode 100644 (file)
index 0000000..c33da34
Binary files /dev/null and b/sms/images/select.png differ
diff --git a/sms/images/sub.png b/sms/images/sub.png
new file mode 100644 (file)
index 0000000..e1ce919
Binary files /dev/null and b/sms/images/sub.png differ
diff --git a/sms/images/unselect.png b/sms/images/unselect.png
new file mode 100644 (file)
index 0000000..b01ce5f
Binary files /dev/null and b/sms/images/unselect.png differ
diff --git a/sms/item.h b/sms/item.h
new file mode 100644 (file)
index 0000000..51b3516
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef ITEM_H
+#define ITEM_H
+
+#include <QApplication>
+#include <QtDBus>
+
+class Item
+{
+public:
+    QString group_name;
+    QString full_name;
+    QString mobile_number;
+    QString group_owner;
+    QString user_pic_uri;
+    QString uid;
+
+    bool m_isSelected;
+    bool m_isGroup;
+    bool m_isOpenContactList;
+};
+typedef QList<Item> ItemList;
+typedef QList<Item*> ItemListPtr;
+Q_DECLARE_METATYPE(Item)
+Q_DECLARE_METATYPE(ItemList)
+Q_DECLARE_METATYPE(ItemListPtr)
+
+#endif // ITEM_H
diff --git a/sms/itemobserver.h b/sms/itemobserver.h
new file mode 100644 (file)
index 0000000..1cea9f9
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef ITEMOBSERVER_H
+#define ITEMOBSERVER_H
+
+#include <QtCore>
+#include "item.h"
+
+class ItemObserver
+{
+public:
+    virtual void addGroup( Item *item ) = 0;
+    virtual void addContact( ItemList items, const QString &groupname ) = 0;
+    virtual void addContact( ItemListPtr items, const QString &groupname ) = 0;
+    virtual void addContact( Item *item, const QString &groupname ) = 0;
+    virtual void addContact( Item *item) = 0;
+    virtual void removeContact(Item *contact) = 0;
+    virtual void removeAllContacts() = 0;
+    virtual void refreshContactsList() = 0;
+};
+
+class ItemSelectObserver
+{
+public:
+    virtual void getGroupContacts( ItemListPtr items ) = 0;
+};
+
+#endif // ITEMOBSERVER_H
diff --git a/sms/main.cpp b/sms/main.cpp
new file mode 100644 (file)
index 0000000..5b0df3d
--- /dev/null
@@ -0,0 +1,56 @@
+#include <QtGui/QApplication>
+#include "mainwindow.h"
+#include "contactinterface.h"
+#include "common.h"
+#include "item.h"
+
+#ifdef ONLY_FOR_EBOOK
+
+#include <gtk/gtk.h>
+
+#endif
+
+static void registerTypes()
+{
+    static bool registered = false;
+    if( !registered )
+    {
+        qRegisterMetaType<Item>();
+        qRegisterMetaType<ItemList>();
+        qRegisterMetaType<ItemListPtr>();
+        registered = true;
+    }
+}
+
+int main(int argc, char *argv[])
+{
+#ifdef ONLY_FOR_EBOOK
+//    gtk_init( &argc, &argv );
+
+    /* Initialize the osso context */
+    osso_context_t *osso_context = osso_initialize( "GroupSMS", "1.0", TRUE, NULL );
+    if( !osso_context )
+    {
+        //qDebug() << "Couldn't initialize osso context";
+        return false;
+    }
+
+    /* Initialize abook, which also initializes all the
+             * libraries it needs (GTK+, Galago, Gnome-VFS) */
+    osso_abook_init( &argc, &argv, osso_context);
+#endif
+
+    QDir dir( QDir::homePath() );
+    dir.mkdir( HOME_DIR );
+
+    QApplication a(argc, argv);
+
+    registerTypes();
+
+#if defined(Q_WS_S60)
+    MainWindow::getInstance()->show();
+#else
+    MainWindow::getInstance()->show();
+#endif
+    return a.exec();
+}
diff --git a/sms/mainwindow.cpp b/sms/mainwindow.cpp
new file mode 100644 (file)
index 0000000..4471e01
--- /dev/null
@@ -0,0 +1,303 @@
+#include "mainwindow.h"
+#include "newgroupdialog.h"
+#include "addcontacttogroup.h"
+#include "contactinterface.h"
+#include "common.h"
+#include "ui_mainwindow.h"
+#include "utility.h"
+
+#ifdef ONLY_FOR_TELEPATHYQT4
+#include "tpsession/tpsession.h"
+#endif
+
+MainWindow* MainWindow::instance = 0;
+
+MainWindow* MainWindow::getInstance()
+{
+    if (!instance) {
+        instance = new MainWindow();
+    }
+    return instance;
+}
+
+MainWindow::MainWindow(QWidget *parent) :
+    QMainWindow(parent),
+    ui(new Ui::MainWindow)
+{
+    instance = this;
+
+    ui->setupUi(this);
+    init();
+}
+
+MainWindow::~MainWindow()
+{
+    delete ui;
+}
+
+void MainWindow::changeEvent(QEvent *e)
+{
+    //qDebug() << "MainWindow::changeEvent(QEvent *e)";
+
+    QMainWindow::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+
+void MainWindow::init()
+{
+    //qDebug() << "MainWindow::init()";
+
+    ui->btn_send_message->setDisabled(true);
+    ui->textEdit_phone_numbers->setReadOnly(true);
+    connect( ui->textEdit_message, SIGNAL( textChanged() ), this, SLOT( send_message_enabled() ) );
+    connect( ui->textEdit_phone_numbers, SIGNAL( textChanged() ), this, SLOT( send_message_enabled() ) );
+    connect( ui->btn_send_to, SIGNAL( clicked() ), this, SLOT( send_to_clicked() ) );
+    connect( ui->btn_send_message, SIGNAL( clicked() ), this, SLOT( send_message_clicked() ) );
+    connect( ui->btn_cancel, SIGNAL( clicked() ), this, SLOT( cancel_clicked() ) );
+
+    hbox_layout = new QHBoxLayout(this);
+
+    btn_new_group = new QToolButton(this);
+    btn_new_group->setToolTip( tr("new group") );
+    btn_new_group->setText("");
+    btn_new_group->setIcon(Utility::getToolButtonIcon(":/images/newgroup.png", true));
+    btn_new_group->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_new_group->setAutoRaise(true);
+    btn_new_group->show();
+    connect( btn_new_group, SIGNAL( clicked() ), this, SLOT( new_group() ) );
+
+
+    btn_add_contact_to_group = new QToolButton(this);
+    btn_add_contact_to_group->setToolTip( tr("add contact to group") );
+    btn_add_contact_to_group->setText("");
+    btn_add_contact_to_group->setIcon(Utility::getToolButtonIcon(":/images/addcontacttogroup.png", true));
+    btn_add_contact_to_group->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_add_contact_to_group->setAutoRaise(true);
+    btn_add_contact_to_group->show();
+    connect( btn_add_contact_to_group, SIGNAL( clicked() ), this, SLOT( add_contact_to_group() ) );
+
+    btn_delete_contact = new QToolButton(this);
+    btn_delete_contact->setToolTip( tr("delete contacts") );
+    btn_delete_contact->setText("");
+    btn_delete_contact->setIcon(Utility::getToolButtonIcon(":/images/recycle.png"));
+    btn_delete_contact->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_delete_contact->setAutoRaise(true);
+    btn_delete_contact->setDisabled(true);
+    btn_delete_contact->show();
+    connect( btn_delete_contact, SIGNAL(clicked()), this, SLOT(removeSelectedContact()) );
+
+//    btn_delete_group = new QToolButton(this);
+//    btn_delete_group->setToolTip( tr("delete group") );
+//    btn_delete_group->setText("");
+//    btn_delete_group->setIcon(Utility::getToolButtonIcon(":/images/recycle.png"));
+//    btn_delete_group->setToolButtonStyle(Qt::ToolButtonIconOnly);
+//    btn_delete_group->setAutoRaise(true);
+//    btn_delete_group->show();
+
+    btn_sync_contacts = new QToolButton(this);
+    btn_sync_contacts->setToolTip( tr("sync contacts") );
+    btn_sync_contacts->setText("");
+    btn_sync_contacts->setIcon(Utility::getToolButtonIcon(":/images/editgroup.png", true));
+    btn_sync_contacts->setToolButtonStyle(Qt::ToolButtonIconOnly);
+    btn_sync_contacts->setAutoRaise(true);
+    btn_sync_contacts->show();
+    connect( btn_sync_contacts, SIGNAL( clicked() ), this, SLOT( sync_contacts() ) );
+
+    hbox_layout->addWidget( btn_new_group );
+    hbox_layout->addWidget( btn_add_contact_to_group );
+    hbox_layout->addWidget( btn_delete_contact );
+//    hbox_layout->addWidget( btn_delete_group );
+    hbox_layout->addWidget( btn_sync_contacts );
+
+    ui->groupBox->setTitle("");
+    ui->groupBox->setLayout( hbox_layout );
+    ui->groupBox->setEnabled(true);
+
+    contactPage = new ContactPage(this);
+    ui->tabWidget->insertTab(0, contactPage, contactPage->title());
+    ui->tabWidget->setCurrentIndex(0);
+    connect( ui->tabWidget, SIGNAL( currentChanged(int) ), this, SLOT( tab_changed(int) ) );
+    connect( contactPage, SIGNAL( validRecycle(bool) ), this, SLOT( onValidRecyele(bool) ) );
+
+    ui->vLayout_main->setAlignment(Qt::AlignCenter);
+    ui->sendSMS_tab->setLayout(ui->vLayout_main);
+
+    QString filename( HOME_DIR + "/group.xml" );
+    QFileInfo fileinfo(filename);
+    if( !fileinfo.exists() )
+    {
+        XmlControler::getInstance()->newXml( filename );
+#ifdef ONLY_FOR_EBOOK
+        contactPage->setContactItemObserver();
+        ContactInterface::getInstance()->updateContactsFromEbookToXml();
+#endif
+    }else
+    {
+        XmlControler::getInstance()->readXml( filename );
+        // for test xmlcontroler
+//        XmlControler::getInstance()->createGroup( "second_group" );
+//        XmlControler::getInstance()->createContact( "second_group", new ContactWidgetItem);
+//        XmlControler::getInstance()->createGroup( "one_group" );
+//        XmlControler::getInstance()->removeContact( "one_group", NULL);
+//        XmlControler::getInstance()->removeGroup( "one_group" );
+    }
+    contactPage->initContactWidget();
+    contactPage->update();
+
+    //qDebug() << "new SendSMSSession";
+#ifdef ONLY_FOR_TELEPATHYQT4
+    sendSMS = new SendSMSSession( false, this );
+    connect( sendSMS, SIGNAL(  smsSent(QString) ), this, SLOT( onSMSSent(QString) ) );
+#endif
+}
+
+void MainWindow::onSMSSent(QString msg)
+{
+    Q_UNUSED( msg )
+    //qDebug() << "MainWindow::onSMSSent" << msg << "OK";
+}
+
+void MainWindow::setSendToText(QVector<ContactWidgetItem *> *contacts)
+{
+    int count = contacts->size();
+    if( count < 1 )
+        return;
+    QString text;
+    ui->textEdit_phone_numbers->clear();
+    for( int i = 0; i < count; i++ )
+    {
+        text = contacts->at(i)->full_name + ";";
+        name_list.append( text );
+        ui->textEdit_phone_numbers->append( text );
+    }
+}
+
+void MainWindow::sync_contacts()
+{
+#ifdef ONLY_FOR_EBOOK
+    ContactInterface::getInstance()->updateContactsFromEbookToXml();
+#endif
+}
+
+void MainWindow::tab_changed(int index)
+{
+    if( 0 == index ) //contactpage
+    {
+        ui->groupBox->setShown(true);
+    }else //sendsms
+    {
+        ui->groupBox->setHidden(true);
+
+        setSendToText( contactPage->getSelectedContacts() );
+    }
+}
+
+void MainWindow::cancel_clicked()
+{
+    ui->textEdit_phone_numbers->document()->clear();
+    ui->textEdit_message->document()->clear();
+    ui->btn_send_message->setDisabled(true);
+    contactPage->cleanSelectedContactList();
+}
+
+void MainWindow::send_to_clicked()
+{
+    //qDebug() << "MainWindow::send_to_clicked()";
+}
+
+void MainWindow::send_message_clicked()
+{
+    //qDebug() << "MainWindow::send_message_clicked()";
+
+    QTextDocument *doc_phone_number = ui->textEdit_phone_numbers->document();
+    QTextDocument *doc_message = ui->textEdit_message->document();
+    if( !doc_message->isEmpty() && !doc_phone_number->isEmpty() )
+    {
+#ifdef ONLY_FOR_TELEPATHYQT4
+        QString txt = doc_message->toPlainText();
+        QVector<ContactWidgetItem *> *contacts = contactPage->getSelectedContacts();
+        QStringList addrs;
+        QStringList msgs;
+        for( int i = 0; i < contacts->size(); i++ )
+        {
+            //qDebug() << " send sms:" << txt << "to" << contacts->at(i)->mobile_number;
+            addrs.append( contacts->at(i)->mobile_number );
+            msgs.append( txt );
+
+        }
+        sendSMS->setSMSToSend( addrs, msgs );
+#endif
+        // for test
+//        TpSession *tps =new TpSession("ring",true);
+//        tps->sendMessageToAddress("ring",contacts->at(0)->mobile_number,txt);
+    }    
+    cancel_clicked();
+}
+
+void MainWindow::send_message_enabled()
+{
+    //qDebug() << "MainWindow::send_message_enabled()";
+
+    QTextDocument *doc_phone_number = ui->textEdit_phone_numbers->document();
+    QTextDocument *doc_message = ui->textEdit_message->document();
+    if( !doc_message->isEmpty() && !doc_phone_number->isEmpty() )
+    {
+        ui->btn_send_message->setEnabled(true);
+    }else
+    {
+        ui->btn_send_message->setDisabled(true);
+    }
+}
+
+void MainWindow::new_group()
+{
+    //qDebug() << "MainWindow::new_group()";
+
+    NewGroupDialog dlg;
+    int result = dlg.exec();
+    if( result == QDialog::Accepted )
+    {
+        //qDebug() << "new group is ok";
+    }
+}
+
+void MainWindow::add_contact_to_group()
+{
+    //qDebug() << "MainWindow::add_contact_to_group()";
+    AddContactToGroup dlg;
+    int result = dlg.exec();
+    if( result == QDialog::Accepted )
+    {
+        //qDebug() << "add contact is ok";
+    }
+}
+
+void MainWindow::onValidRecyele(bool valid)
+{
+    if( valid )
+    {
+        btn_delete_contact->setEnabled(true);
+    }else
+    {
+        btn_delete_contact->setDisabled(true);
+    }
+}
+
+void MainWindow::removeSelectedContact()
+{
+    //TODO : add confirm dialog
+    QMessageBox msgBox;
+    msgBox.setText("Do you want to delete that's selected contacts?");
+    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+    int ret = msgBox.exec();
+    if( ret == QDialog::Accepted )
+    {
+        contactPage->removeSelectedContact();
+    }
+}
diff --git a/sms/mainwindow.h b/sms/mainwindow.h
new file mode 100644 (file)
index 0000000..cc6ca92
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QToolButton>
+#include <QToolBox>
+#include <QHBoxLayout>
+
+#include "contactpage.h"
+#include "xmlcontroler.h"
+#include "contactwidgetitem.h"
+
+#ifdef ONLY_FOR_TELEPATHYQT4
+#include "sendsmssession.h"
+#endif
+
+namespace Ui {
+    class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    static MainWindow* getInstance();
+    ~MainWindow();
+
+public Q_SLOTS:
+    void send_to_clicked();
+    void cancel_clicked();
+    void send_message_clicked();
+    void send_message_enabled();
+    void sync_contacts();
+    void new_group();
+    void add_contact_to_group();
+    void removeSelectedContact();
+    void tab_changed(int index);
+
+    void onSMSSent( QString msg );
+
+    void onValidRecyele(bool valid);
+
+protected:    
+    void changeEvent(QEvent *e);
+    void init();
+
+private:
+    static MainWindow* instance;
+    MainWindow(QWidget *parent = 0);
+
+    void setSendToText(QVector<ContactWidgetItem*>* contacts);
+
+private:
+    Ui::MainWindow *ui;
+
+    QHBoxLayout *hbox_layout;
+
+    QToolButton *btn_new_group;
+    QToolButton *btn_add_contact_to_group;
+    QToolButton *btn_delete_contact;
+    QToolButton *btn_delete_group;
+    QToolButton *btn_sync_contacts;
+
+    ContactPage *contactPage;
+
+#ifdef ONLY_FOR_TELEPATHYQT4
+    SendSMSSession *sendSMS;
+#endif
+
+    QStringList name_list;
+};
+
+#endif // MAINWINDOW_H
diff --git a/sms/mainwindow.ui b/sms/mainwindow.ui
new file mode 100644 (file)
index 0000000..64abb67
--- /dev/null
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>GroupSMS</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <widget class="QTabWidget" name="tabWidget">
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="sendSMS_tab">
+       <attribute name="title">
+        <string>SendSMS</string>
+       </attribute>
+       <widget class="QWidget" name="layoutWidget">
+        <property name="geometry">
+         <rect>
+          <x>20</x>
+          <y>20</y>
+          <width>571</width>
+          <height>331</height>
+         </rect>
+        </property>
+        <layout class="QVBoxLayout" name="vLayout_main">
+         <item>
+          <spacer name="vSpacer_top">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>5</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="hLayout_send_to">
+           <item>
+            <widget class="QPushButton" name="btn_send_to">
+             <property name="text">
+              <string>Send To:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QTextEdit" name="textEdit_phone_numbers"/>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <spacer name="vSpacer_under_send_to">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <layout class="QVBoxLayout" name="vLayout_message">
+           <item>
+            <widget class="QTextEdit" name="textEdit_message"/>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="hLayout_btn_send_cancel">
+             <item>
+              <widget class="QPushButton" name="btn_send_message">
+               <property name="text">
+                <string>Send</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QPushButton" name="btn_cancel">
+               <property name="text">
+                <string>Cancel</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </widget>
+    </item>
+    <item>
+     <spacer name="horizontalSpacer">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="sizeHint" stdset="0">
+       <size>
+        <width>779</width>
+        <height>20</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+    <item>
+     <widget class="QGroupBox" name="groupBox">
+      <property name="title">
+       <string>GroupBox</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sms/newgroupdialog.cpp b/sms/newgroupdialog.cpp
new file mode 100644 (file)
index 0000000..b2be83c
--- /dev/null
@@ -0,0 +1,42 @@
+#include <QDebug>
+
+#include "newgroupdialog.h"
+#include "contactinterface.h"
+
+NewGroupDialog::NewGroupDialog(QDialog *parent) :
+    QDialog(parent)
+{
+    setupUi(this);
+    setWindowModality( Qt::ApplicationModal );
+    btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setDisabled(true);
+    groupNmaeEdit->setFocus();
+
+    connect( btngroup_ok_cancel, SIGNAL( clicked(QAbstractButton*) ), this, SLOT( btn_clicked(QAbstractButton*) ) );
+    connect( groupNmaeEdit, SIGNAL( textEdited(QString) ), this, SLOT( btn_ok_enabled(QString) ) );
+}
+
+void NewGroupDialog::btn_clicked(QAbstractButton *button)
+{
+    if( QDialogButtonBox::AcceptRole == btngroup_ok_cancel->buttonRole( button ) )
+    {
+        //qDebug() << "new group dialog : new group is" << groupNmaeEdit->text();
+
+        QString str = groupNmaeEdit->text();
+        ContactInterface::getInstance()->createGroup( str );
+        done( QDialog::Accepted );
+    }else // button cancel
+    {
+        done( QDialog::Rejected );
+    }
+}
+
+void NewGroupDialog::btn_ok_enabled(QString str)
+{
+    if( str.length() > 0 )
+    {
+        btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setEnabled(true);
+    }else
+    {
+        btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setDisabled(true);
+    }
+}
diff --git a/sms/newgroupdialog.h b/sms/newgroupdialog.h
new file mode 100644 (file)
index 0000000..77517bc
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef NEWGROUPDIALOG_H
+#define NEWGROUPDIALOG_H
+
+#include <QtGui>
+#include "ui_newgroupdialog.h"
+
+
+class NewGroupDialog : public QDialog, Ui::NewGroupDialog
+{
+    Q_OBJECT
+public:
+    NewGroupDialog(QDialog *parent = 0);
+
+public Q_SLOTS:
+    void btn_clicked(QAbstractButton * button);
+    void btn_ok_enabled(QString str);
+};
+
+#endif // NEWGROUPDIALOG_H
diff --git a/sms/newgroupdialog.ui b/sms/newgroupdialog.ui
new file mode 100644 (file)
index 0000000..0a23ddb
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NewGroupDialog</class>
+ <widget class="QDialog" name="NewGroupDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>102</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QDialogButtonBox" name="btngroup_ok_cancel">
+   <property name="geometry">
+    <rect>
+     <x>300</x>
+     <y>30</y>
+     <width>81</width>
+     <height>61</height>
+    </rect>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Vertical</enum>
+   </property>
+   <property name="standardButtons">
+    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="groupNmaeEdit">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>30</y>
+     <width>261</width>
+     <height>61</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_newgroup">
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>0</y>
+     <width>151</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <family>AlArabiya</family>
+     <pointsize>14</pointsize>
+    </font>
+   </property>
+   <property name="text">
+    <string>New Group Name</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>btngroup_ok_cancel</sender>
+   <signal>accepted()</signal>
+   <receiver>NewGroupDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>btngroup_ok_cancel</sender>
+   <signal>rejected()</signal>
+   <receiver>NewGroupDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/sms/selectcontactwidget.cpp b/sms/selectcontactwidget.cpp
new file mode 100644 (file)
index 0000000..5fef9a0
--- /dev/null
@@ -0,0 +1,89 @@
+#include "selectcontactwidget.h"
+#include "contactinterface.h"
+#include "xmlstring.h"
+
+SelectContactWidget::SelectContactWidget( QWidget *parent ) :
+        ContactWidget( parent )
+{
+    //qDebug() << "SelectContactWidget::SelectContactWidget(QWidget *parent), Entry";
+}
+
+SelectContactWidget::~SelectContactWidget()
+{
+    //qDebug() << "SelectContactWidget::~SelectContactWidget(), Entry";
+}
+
+void SelectContactWidget::initContactWidget()
+{
+    //qDebug() << "SelectContactWidget::initContactWidget(), Entry";
+
+    ContactInterface::getInstance()->setItemSelectObserver(this);
+    ContactInterface::getInstance()->getAllContactsFromXml( STR_XML_ALLCONTACTS );
+
+    for (int i = 0; i < contact_items->size(); ++i)
+    {
+        connect( contact_items->at(i), SIGNAL( itemUpdate() ), this, SLOT( update() ) );
+        connect( contact_items->at(i), SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) );
+    }
+}
+
+void SelectContactWidget::destroyContactWidget()
+{
+    //qDebug() << "SelectContactWidget::destroyContactWidget(), Entry";
+}
+
+void SelectContactWidget::getGroupContacts( ItemListPtr items )
+{
+    for( int i = 0; i < items.size(); i++ )
+    {
+        Item *item = items.at(i);
+
+        if( item->m_isGroup )
+        {
+            GroupWidgetItem *contact = new GroupWidgetItem(this);
+
+            contact->label_group_name->setText( item->group_name );
+            contact->group_name = item->group_name;
+
+            contact_items->append( contact );
+        }else
+        {
+            ContactWidgetItem *contact = new ContactWidgetItem(this);
+
+            contact->label_fullname->setText( item->full_name );
+            contact->full_name = item->full_name;
+
+            contact->label_mobile_number->setText( item->mobile_number );
+            contact->mobile_number = item->mobile_number;
+
+            contact->group_owner =  item->group_owner;
+
+            contact->uid = item->uid;
+
+            contact_items->append( contact );
+        }
+    }
+}
+
+QVector<ContactWidgetItem*>* SelectContactWidget::getSelectedContacts()
+{
+    return contact_items_selected;
+}
+
+void SelectContactWidget::addContactsToGroup(const QString &groupname)
+{
+    //qDebug() << "SelectContactWidget::addContactsToGroup(const QString &groupname)";
+    ItemListPtr list;
+    for( int i = 0; i < contact_items_selected->size(); i++ )
+    {
+        ContactWidgetItem *contact = contact_items_selected->at(i);
+        Item *item = new Item();
+        item->full_name = contact->full_name;
+        item->mobile_number = contact->mobile_number;
+        item->group_owner = groupname;
+        item->uid = contact->uid;
+
+        list.append(item);
+    }
+    ContactInterface::getInstance()->addContactToGroup(list, groupname);
+}
diff --git a/sms/selectcontactwidget.h b/sms/selectcontactwidget.h
new file mode 100644 (file)
index 0000000..49b9a15
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SELECTCONTACTWIDGET_H
+#define SELECTCONTACTWIDGET_H
+
+#include <QtGui>
+#include "contactwidget.h"
+#include "groupwidgetitem.h"
+#include "itemobserver.h"
+
+class SelectContactWidget : public ContactWidget, public ItemSelectObserver
+{
+    Q_OBJECT
+public:
+    SelectContactWidget( QWidget *parent = 0 );
+    ~SelectContactWidget();
+    void initContactWidget();
+
+    void getGroupContacts( ItemListPtr items );
+
+    QVector<ContactWidgetItem*>* getSelectedContacts();
+
+    void addContactsToGroup(const QString &groupname);
+
+protected:
+    void destroyContactWidget();
+
+};
+
+#endif // SELECTCONTACTWIDGET_H
diff --git a/sms/sendsmssession.cpp b/sms/sendsmssession.cpp
new file mode 100644 (file)
index 0000000..04c0d97
--- /dev/null
@@ -0,0 +1,98 @@
+#include <QtDebug>
+#include "sendsmssession.h"
+
+SendSMSSession::SendSMSSession( bool sync, QObject *parent ) :
+    QObject(parent)
+{
+    syncSend = sync;
+    isReady = false;
+    tps = NULL;
+}
+
+void SendSMSSession::initTpSession()
+{
+    qDebug() << __PRETTY_FUNCTION__ ;
+
+    if( tps == NULL )
+    {
+        tps = new TpSession( "ring", syncSend );
+
+        if( !isReady && !syncSend )
+        {
+            connect(tps,SIGNAL(accountReady(TpSessionAccount *)),SLOT(onAccountReady(TpSessionAccount *)));
+        }else
+        {
+            SendSMS();
+        }
+
+        connect(tps,SIGNAL(messageSent(const Tp::Message &,TpSessionAccount *)),
+                SLOT(onSMSSent(const Tp::Message &,TpSessionAccount *)));
+
+        connect(tps,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)),
+                SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)));
+    }else
+    {
+        if( !isReady && !syncSend )
+        {
+            connect(tps,SIGNAL(accountReady(TpSessionAccount *)),SLOT(onAccountReady(TpSessionAccount *)));
+        }else
+        {
+            SendSMS();
+        }
+    }
+}
+
+void SendSMSSession::setSMSToSend(QString addr, QString msg)
+{
+    qDebug() << __PRETTY_FUNCTION__ ;
+    addresses.append( addr );
+    messages.append( msg );
+
+    initTpSession();
+}
+
+void SendSMSSession::setSMSToSend( QStringList addrs, QStringList msgs )
+{
+    qDebug() << __PRETTY_FUNCTION__ ;
+    addresses = addrs ;
+    messages = msgs ;
+
+    initTpSession();
+}
+
+void SendSMSSession::SendSMS()
+{
+    qDebug() << __PRETTY_FUNCTION__ ;
+    for( int i = 0; i < addresses.size(); i++ )
+    {
+        tps->sendMessageToAddress( "ring", addresses.at(i), messages.at(i) );
+    }
+    addresses.clear();
+    messages.clear();
+}
+
+void SendSMSSession::onAccountReady(TpSessionAccount *tpsa)
+{
+    qDebug() << __PRETTY_FUNCTION__ ;
+
+    isReady = true;
+    for( int i = 0; i < addresses.size(); i++ )
+    {
+        tpsa->sendMessageToAddress( addresses.at(i), messages.at(i) );
+    }
+    addresses.clear();
+    messages.clear();
+}
+
+void SendSMSSession::onSMSSent( const Tp::Message &msg, TpSessionAccount *acc )
+{
+    qDebug() << "SendSMSSession::onSMSSent :" << msg.text();
+    Q_EMIT smsSent( msg.text() );
+}
+
+void SendSMSSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
+{
+    qDebug() << "SendSMSSession::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
+}
+
+
diff --git a/sms/sendsmssession.h b/sms/sendsmssession.h
new file mode 100644 (file)
index 0000000..0074160
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef SENDSMSSESSION_H
+#define SENDSMSSESSION_H
+
+#include <QObject>
+#include <QDebug>
+#include "tpsession/tpsession.h"
+#include "tpsession/tpsessionaccount.h"
+
+class SendSMSSession : public QObject
+{
+    Q_OBJECT
+public:
+    SendSMSSession( bool sync = false, QObject *parent = 0);
+
+    void setSMSToSend( QString addr,QString msg );
+    void setSMSToSend( QStringList addrs,QStringList msgs );
+
+private:
+    void initTpSession();
+    void SendSMS();
+
+private:
+    TpSession *tps;
+
+    QString sender;
+    QStringList addresses;
+    QStringList messages;
+
+    bool syncSend;
+    bool isReady;
+
+Q_SIGNALS:
+    void smsSent( QString msg, QString addr );
+    void smsSent( QString msg );
+
+public Q_SLOTS:
+    void onAccountReady(TpSessionAccount *);
+    void onSMSSent(const Tp::Message &,TpSessionAccount *);
+    void onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+
+};
+
+#endif // SENDSMSSESSION_H
diff --git a/sms/sms.pro b/sms/sms.pro
new file mode 100644 (file)
index 0000000..7d96479
--- /dev/null
@@ -0,0 +1,85 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2010-05-24T19:59:46
+#
+#-------------------------------------------------
+
+QT       += core gui xml
+
+TARGET = groupsms
+TEMPLATE = app
+
+# DEFINES += ONLY_FOR_EBOOK  # include libabook ets..
+# DEFINES += ONLY_FOR_TELEPATHYQT4
+
+CONFIG += no_keywords
+CONFIG += link_pkgconfig
+PKGCONFIG += glib-2.0 gtk+-2.0 # libosso libebook-1.2 libosso-abook-1.0 TelepathyQt4
+CONFIG += qdbus
+
+INCLUDEPATH += /usr/local/include/telepathy-1.0
+
+LIBS += -L/usr/lib
+
+SOURCES += main.cpp\
+        mainwindow.cpp \
+    abstractpage.cpp \
+    contactwidget.cpp \
+    contactwidgetitem.cpp \
+    xmlcontroler.cpp \
+    contactpage.cpp \
+    groupwidgetitem.cpp \
+    utility.cpp \
+    contactinterface.cpp \
+    newgroupdialog.cpp \
+    addcontacttogroup.cpp \
+    selectcontactwidget.cpp #\
+#    tpsession/tpsessionobserver.cpp \
+#    tpsession/tpsessionchannel.cpp \
+#    tpsession/tpsessionaccount.cpp \
+#    tpsession/tpsession.cpp \
+#    sendsmssession.cpp
+
+HEADERS  += mainwindow.h \
+    abstractpage.h \
+    contactwidget.h \
+    contactwidgetitem.h \
+    xmlcontroler.h \
+    xmlstring.h \
+    common.h \
+    contactpage.h \
+    groupwidgetitem.h \
+    utility.h \
+    contactinterface.h \
+    newgroupdialog.h \
+    addcontacttogroup.h \
+    selectcontactwidget.h \
+    itemobserver.h \
+    item.h #\
+#    tpsession/tpsessionobserver.h \
+#    tpsession/tpsessionchannel.h \
+#    tpsession/tpsessionaccount.h \
+#    tpsession/tpsession.h \
+#    sendsmssession.h
+
+
+FORMS    += mainwindow.ui \
+    newgroupdialog.ui \
+    addcontacttogroupdialog.ui
+
+RESOURCES = groupsms.qrc
+
+CONFIG += mobility
+MOBILITY = 
+
+symbian {
+    TARGET.UID3 = 0xe9d84f35
+    # TARGET.CAPABILITY += 
+    TARGET.EPOCSTACKSIZE = 0x14000
+    TARGET.EPOCHEAPSIZE = 0x020000 0x800000
+}
+
+# pkg.path = /usr/local/lib/pkgconfig
+# pkg.files = GroupSMS.pc
+# target.path += $$[QT_INSTALL_LIBS]
+# INSTALLS += target pkg
diff --git a/sms/tpsession/tpsession.cpp b/sms/tpsession/tpsession.cpp
new file mode 100755 (executable)
index 0000000..1b230cd
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alhola(a)nokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "tpsession.h"
+#include <QDebug>
+
+
+
+
+
+/**
+ * \class TpSession
+ * \headerfile <tpsession.h>
+ *
+ * Top level class, counterpart of Account Manager. TpSession connects to account manager and requests accounts from it. TpSession creates TpSessionAccount for all accounts .
+ * As top level class TpSession provides simålified interface to send and receive messages via any account. TpSession provides signal when it has accounts ready.
+ * If you require some specific account in constructor, you will receive signal only when this account is ready. If you use constructor without any parameters, you will get one
+ * signal for every account.  If synchronous is true, constructor is executed as synchronous and it does return after transactions to set up accounts are done.
+ */
+/**
+ * \fn void TpSession::accountReady(TpSessionAccount *);
+ *
+ * Emitted when the account becomes ready
+ *
+ * \param  TpSessionAccount  pointer to account become ready
+ */
+/**
+ * \fn void TpSession::amReady(TpSession *);
+ *
+ * Emitted when the account Manager becomes ready
+ *
+ * \param  TpSession  pointer to TpSession class
+ */
+/**
+ * \fn void TpSession::messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+ *
+ * Emitted when any of Account Managers recived message
+ *
+ * \param  Tp::ReceivedMessage  Message received
+ * \param  TpSessionAccount  pointer to account received message
+ */
+
+
+/**
+ * Construct a new TpSession object.
+ *
+ * \param cmname      Name of the default connection manager. Can be empty or omnitted, then there is no default connection manager
+ * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
+ *                    if True, synchronous behavior and function returns when accounts are ready
+ */
+TpSession::TpSession(QString cmname,bool synchronous)
+{
+    Tp::registerTypes();
+    Tp::enableDebug(false);
+    Tp::enableWarnings(false);
+
+    mAM = Tp::AccountManager::create();
+    reqCm=cmname;
+    sync=synchronous;
+    connect(mAM->becomeReady(),
+            SIGNAL(finished(Tp::PendingOperation *)),
+            SLOT(onAMReady(Tp::PendingOperation *)));
+    connect(mAM.data(),
+            SIGNAL(accountCreated(const QString &)),
+            SLOT(onAccountCreated(const QString &)));
+
+    // createObserver();
+    if(synchronous) loop.exec(); // Loop locally untill accounts are initialized
+    reqCm=cmname;
+
+}
+TpSession* TpSession::instancePtr=NULL;
+/**
+ * Returns pointer to TpSession singleton. If there is not yet TpSession Object, creates it with "Ring" connection manager as default
+ *
+ * \param synchronous if false, asynchronous behavior, function returns immediately and accountReady signals are emitted when accounts are ready
+ *                    if True, synchronous behavior and function returns when accounts are ready
+ */
+TpSession* TpSession::instance(bool synchronous)
+{
+    if(instancePtr==NULL) instancePtr=new TpSession("ring",synchronous);
+    return instancePtr;
+};
+
+void TpSession::onAMReady(Tp::PendingOperation *op)
+{
+    // qDebug() << "TpSession::onAMReady";
+    TpSessionAccount *tpacc;
+
+    Q_FOREACH (const QString &path, mAM->allAccountPaths()) {
+        accounts+=tpacc=new TpSessionAccount(mAM, path);
+        connect(tpacc,SIGNAL(accountReady(TpSessionAccount*)),
+                SLOT(onAccountReady(TpSessionAccount *)));
+    }
+
+}
+
+void TpSession::onReady(Tp::PendingOperation *)
+{
+};
+
+void TpSession::onAccountCreated(const QString &path)
+{
+
+    accounts+=new TpSessionAccount(mAM, path);
+}
+
+void TpSession::onAccountReady(TpSessionAccount *tpacc)
+{
+    qDebug() << "TpSession::onAccountReady:Account " << tpacc->acc->cmName() << "is Ready sync=" << sync << "waiting:" << reqCm;
+    connect(tpacc,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)),
+            SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)));
+    // Tom add
+    connect(tpacc,SIGNAL(messageSent(const Tp::Message &,TpSessionAccount *)),
+            SLOT(onMessageSent(const Tp::Message &,TpSessionAccount *)));
+    // Tom end
+    if(!reqCm.isEmpty() && tpacc->acc->cmName()==reqCm) {
+        if(sync) {
+            sync=false;
+            loop.quit();
+            qDebug() << "sync eventloop exit";
+        }
+        Q_EMIT accountReady(tpacc);
+        if(!reqMsg.isEmpty()) tpacc->sendMessageToAddress(reqAddress,reqMsg);
+    }
+}
+
+void TpSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc)
+{
+    //    qDebug() << "TestProg::onMessageReceived " << msg.text() << "from " << msg.sender()->id();
+    Q_EMIT messageReceived(msg,acc);
+}
+
+// Tom add
+void TpSession::onMessageSent(const Tp::Message &msg,TpSessionAccount *acc)
+{
+    //    qDebug() << "TpSession::onMessageSent " << msg.text() << "from " << msg.sender()->id();
+    Q_EMIT messageSent(msg,acc);
+}
+// Tom end
+
+/**
+ * Send message using specified connection manager to address
+ *
+ * \param connectionMgr  Name of the connection manager
+ * \param address Valid address for this connection manager type. Asexample telephone number to Ring, GoogleTalk address for Gabble
+ * \param message Message body
+ */
+void TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)
+{
+    qDebug() << "TpSession::sendMessageToAddress(QString connectionMgr,QString address,QString message)";
+    TpSessionAccount *tpsa=getAccount(connectionMgr);
+    if(tpsa)
+    {
+        tpsa->sendMessageToAddress(address,message);
+    }
+}
+/**
+ * Returns pointer to TpSessionAccout object with specified connection manager or protocol, returns NULL if no match found
+ *
+ * \param cm  Name of the connection manager, or iniqueIdentifier (dbus path  to cm) if left empty matches every entry
+ * \param protocol Name of the protocol manager, if left empty matches every entry
+ */
+TpSessionAccount* TpSession::getAccount(const  QString cm,QString protocol)
+{
+    // qDebug() << "TpSession::getAccount" << cm << " " << protocol;
+    Q_FOREACH (TpSessionAccount *tpacc, accounts) {
+        if((!cm.isEmpty()  && ((tpacc->acc->cmName()==cm) || (tpacc->acc->uniqueIdentifier()==cm))) || (!protocol.isEmpty() && tpacc->acc->protocol()==protocol)) {
+            //     qDebug() << "TpSession::getAccount found" << tpacc->acc->cmName() << " " << tpacc->acc->protocol() << " " << tpacc->acc->uniqueIdentifier();
+            return tpacc;
+        }
+    }
+    return NULL;
+}
+
+void TpSession::createObserver()
+{
+
+    qDebug() << __PRETTY_FUNCTION__ ;
+
+    registrar = Tp::ClientRegistrar::create();
+
+    Tp::ChannelClassList channelFilters;
+    QMap<QString, QDBusVariant> textFilter, mediaFilter;
+    // Registering Text channel observer
+    textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+                      QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT));
+    textFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+                      QDBusVariant(Tp::HandleTypeContact));
+    channelFilters.append(textFilter);
+
+    // Registering Media channel observer
+    mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+                       QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA));
+    mediaFilter.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+                       QDBusVariant(Tp::HandleTypeContact));
+    channelFilters.append(mediaFilter);
+
+    TpSessionObserver* observer = new TpSessionObserver( channelFilters, this );
+    bool registered = registrar->registerClient(
+            Tp::AbstractClientPtr::dynamicCast(Tp::SharedPtr<TpSessionObserver>(observer)),
+            "TpSessionChannelObserver");
+
+    //        qDebug() << "TpSession::createObserver" << (registered ? "started" : "failed");
+
+}
+
+
+void TpSession::createChannelListener(const QString &channelType,
+                                      const Tp::MethodInvocationContextPtr<> &context,
+                                      const Tp::AccountPtr &account,
+                                      const Tp::ChannelPtr &channel)
+{
+    qDebug() << "TpSession::createChannelListener";
+
+    QString channelObjectPath = channel->objectPath();
+
+
+    if ( channels.contains( channelObjectPath ) &&
+         !channelType.isEmpty() &&
+         !channelObjectPath.isEmpty() ) {
+        qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT";
+        return;
+    }
+    qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType;
+#if 0
+    ChannelListener* listener = 0;
+    if( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT ) {
+        listener = new TextChannelListener(account, channel, context);
+    } else if ( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA ) {
+        listener = new StreamChannelListener(account, channel, context);
+    }
+
+    if(listener) {
+        connect(listener, SIGNAL(channelClosed(ChannelListener *)),
+                this, SLOT(channelClosed(ChannelListener *)));
+        Channels.append( channelObjectPath );
+    }
+#endif
+}
+
+
+
+
+
+
+
+
diff --git a/sms/tpsession/tpsession.h b/sms/tpsession/tpsession.h
new file mode 100755 (executable)
index 0000000..2061640
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alholanokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef TPSESSION_H
+#define TPSESSION_H
+
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Account>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/PendingChannelRequest>
+#include <TelepathyQt4/ChannelRequest>
+#include <TelepathyQt4/PendingChannel>
+#include <TelepathyQt4/Channel>
+#include <TelepathyQt4/TextChannel>
+#include <TelepathyQt4/AccountManager>
+#include <TelepathyQt4/PendingOperation>
+#include <TelepathyQt4/PendingReady>
+#include <TelepathyQt4/ClientRegistrar>
+#include <TelepathyQt4/Debug>
+
+#include <QString>
+#include <QVector>
+#include <QObject>
+
+#include "tpsessionaccount.h"
+#include "tpsessionobserver.h"
+
+class TpSession:public QObject
+{
+       Q_OBJECT
+public:
+    TpSession(QString cmname=QString(),bool synchronous=FALSE);
+
+
+    static TpSession* instance(bool synchronous=TRUE);
+    void sendMessageToAddress(QString connectionMgr,QString address,QString message);
+    TpSessionAccount* getAccount(const  QString cm, const QString protocol=QString());
+    void createChannelListener(const QString &channelType,
+                               const Tp::MethodInvocationContextPtr<> &context,
+                               const Tp::AccountPtr &account,
+                               const Tp::ChannelPtr &channel);
+    void createObserver();
+
+Q_SIGNALS:
+    void amReady(TpSession *);
+    void accountReady(TpSessionAccount *);
+    void channeReady(TpSessionAccount *);
+    void messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+
+    // Tom add
+    void messageSent(const Tp::Message &,TpSessionAccount *);
+    // Tom end
+private Q_SLOTS:
+    void onAMReady(Tp::PendingOperation *);
+    void onAccountCreated(const QString &);
+    void onReady(Tp::PendingOperation *);
+    void onAccountReady(TpSessionAccount *tpacc);
+    void onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+
+    // Tom add
+    void onMessageSent(const Tp::Message &,TpSessionAccount *);
+    // Tom end
+public:
+    QVector<TpSessionAccount*> accounts;
+
+private:
+    static TpSession *instancePtr;
+    //TpSession *instancePtr;
+    QString reqCm;
+    QString reqAddress;
+    QString reqMsg;
+
+    bool sync;  // Synchronous initialization
+    QEventLoop loop;
+    Tp::AccountManagerPtr mAM;
+    QStringList channels;
+    Tp::ClientRegistrarPtr registrar;
+};
+
+
+
+#endif // TPSESSION_H
diff --git a/sms/tpsession/tpsessionaccount.cpp b/sms/tpsession/tpsessionaccount.cpp
new file mode 100755 (executable)
index 0000000..0626737
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alholanokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "tpsessionaccount.h"
+#include <TelepathyQt4/Message>
+
+/**
+ * \class TpSessionAccount
+ * \headerfile <tpsessionaccount.h>
+ *
+ * TpSessionAccount class represents every account you have. As example account for “Ring” connection manager represents your cellular
+ * account and you may send and receive SMS with it. Gabble represents your GoogleTalk account if you have defined them.
+ * TpSessionAccounts are created by TpSession class,they are not intended to be created stand-alone
+
+ */
+/**
+ * \fn void TpSessionAccount::accountReady(TpSessionAccount *);
+ *
+ * Emitted when the account becomes ready
+ *
+ * \param  TpSessionAccount  pointer to account become ready
+ */
+/**
+ * \fn void TpSessionAccount::channelReady(TpSessionAccount *);
+ *
+ * Emitted when the account Manager becomes ready
+ *
+ * \param  TpSession  pointer to TpSession class
+ */
+/**
+ * \fn void TpSessionAccount::messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+ *
+ * Emitted when any of Account Managers recived message
+ *
+ * \param  Tp::ReceivedMessage  Message received
+ * \param  TpSessionAccount  pointer to account received message
+ */
+
+/**
+ * \fn void TpSessionAccount::newChannel(TpSessionAccount *,QString CjhannelType,QString peerId,const Tp::ChannelDetails &);
+ * \param  TpSession  pointer to TpSession class
+ * \param  ChannelType type of Channel, TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT for text channel, TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA for steram media, as exmple for incoming call
+ * \param  peedId PeerId, as example caller telephone number
+ * \param channeDetails needed if you would like to create a channel. For text chanels TpSession creates channel automatically. For calls, Maemo Call UI handles callcreation
+ */
+
+/**
+ * Construct a new TpSessionAccount object. This constructor is called by TpSession class when new account is created or fetched from account manager. It is not inended to be used stand alone
+ *
+ * \param am          Telepathy-Qt4 account manager for this account
+ * \param objectPath  Dbus object path tonew account
+ */
+TpSessionAccount::TpSessionAccount(Tp::AccountManagerPtr am,const QString &objectPath):
+        mAcc(Tp::Account::create(am->dbusConnection(),am->busName(), objectPath))
+
+{
+    connect(mAcc->becomeReady(),SIGNAL(finished(Tp::PendingOperation *)),SLOT(onReady(Tp::PendingOperation *)));
+    ready=false;
+    //  qDebug() << "TpSessionAccount::TpSessionAccount objectPath=" << objectPath;
+};
+
+
+void TpSessionAccount::onReady(Tp::PendingOperation *op)
+{
+
+    acc = mAcc.data();
+    qDebug() << "TpSessionAccount::onReady cmName=" << acc->cmName() << "haveConnection=" <<
+        (acc->haveConnection()? ( acc->connection()->isReady() ? "Ready":"notReady"):"no");
+
+    if(acc->haveConnection())
+    {
+
+        connect(acc->connection()->becomeReady(Tp::Connection::FeatureRoster | Tp::Connection::FeatureSelfContact ),
+                SIGNAL(finished(Tp::PendingOperation *)),
+                SLOT(onContactsConnectionReady(Tp::PendingOperation *)));
+        if (acc->connection()->isReady() && acc->connection()->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS))
+        {
+            qDebug() << "TpSessionAccount::onReady: connecting to Connection.Interface.NewChannels";
+            connect(acc->connection()->requestsInterface(),
+                    SIGNAL(NewChannels(const Tp::ChannelDetailsList&)),
+                    SLOT(onNewChannels(const Tp::ChannelDetailsList&)));
+        }
+    }
+    else
+    { // If there is no connection, we are ready now, else we are ready when contacts connection is ready
+        qDebug() << "If there is no connection, we are ready now, else we are ready when contacts connection is ready";
+        ready=true;
+        Q_EMIT accountReady(this);
+    }
+}
+
+void TpSessionAccount::onContactsConnectionReady(Tp::PendingOperation *op)
+{
+    if (op->isError()) {
+        qWarning() << "Connection cannot become ready" << acc->cmName();
+        return;
+    }
+
+    if (acc->connection()->interfaces().contains(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_REQUESTS)) {
+        qDebug() << "TpSessionAccount::onContactsConectionReady: connecting to Connection.Interface.NewChannels";
+        connect(acc->connection()->requestsInterface(),
+                SIGNAL(NewChannels(const Tp::ChannelDetailsList&)),
+                SLOT(onNewChannels(const Tp::ChannelDetailsList&)));
+    } else qDebug() << "TpSessionAccount::onectionReady: does NO have CONNECTION_INTERFACE_REQUESTS";
+    Tp::PendingReady *pr = qobject_cast<Tp::PendingReady *>(op);
+    contactsConn = Tp::ConnectionPtr(qobject_cast<Tp::Connection *>(pr->object()));
+#if 0
+    connect(contactsConn->contactManager(),
+            SIGNAL(presencePublicationRequested(const Tp::Contacts &)),
+            SLOT(onPresencePublicationRequested(const Tp::Contacts &)));
+#endif
+    qDebug() << "TpSessionAccount::onContactsConnectionReady "<< acc->cmName() ;
+    //    RosterItem *item;
+    bool exists;
+    myContacts=contactsConn->contactManager()->allKnownContacts();
+    Q_FOREACH (const Tp::ContactPtr &contact, myContacts) {
+        qDebug() << "id=" <<contact->id() << " alias=" << contact->alias() << " presence=" << contact->presenceStatus()  ;
+        if(contact->id()==reqContact) {
+            addOutgoingChannel(contact);
+            reqContact="";
+        }
+    };
+    if(!reqContact.isEmpty() ) makeContactFromAddress(reqContact);
+    ready=true;
+    Q_EMIT accountReady(this);
+}
+
+
+/**
+ * Fetch Tp::ContactPtr for contact with given address. Contact is searched among contacts returned by contact manager for ths account.
+ * All connecions managers does not return contacts, as example Ring telephony contact manager does not. Gabble for Googletalk or Spirit for Skype does
+ * return contacts-
+ *
+ * \param id            Contact address/id, as example email address, telephone number etc. Only exact matches
+ * \return      TpContactPtr, if nontact is not returned TpContactPtr.isNull() is true
+ */
+
+Tp::ContactPtr TpSessionAccount::getContactFromAddress(QString id)
+{
+    Tp::ContactPtr p;
+    Q_FOREACH (const Tp::ContactPtr &contact, myContacts) {
+        if(contact->id()==reqContact) return p=contact;
+    }
+    return p;
+}
+/**
+ * Fetch TpSessionChannel for with given address. Contact is searched among active channels for this account.
+ *
+ *
+ * \param id            Contact address/id, as example email address, telephone number etc. Only exact matches
+ * \return          Pointer to TpSessionChannel or NULL if nit found
+ */
+
+TpSessionChannel* TpSessionAccount::getChannelFromPeerAddress(QString id)
+{
+    TpSessionChannel* p=NULL;
+    Q_FOREACH (TpSessionChannel* channel, myChannels) {
+        if(channel->peerId()==id) return p=channel;
+    }
+    return p;
+}
+/**
+ * Creates new contact with given address. This function is Acynchronous, it sends request to contact manager for contact creation,
+ *
+ * \param address           Contact address/id, as example email address, telephone number etc.
+ */
+
+void TpSessionAccount::makeContactFromAddress(QString address)
+{
+    qDebug() << "TpSessionAccount::makeContactFromAddress(QString address)";
+    reqContact=address;  // When we get retrieved signal, we check if it is this one
+    Tp::PendingContacts *pc = contactsConn->contactManager()->contactsForIdentifiers( QStringList(address) );
+    qDebug() << "111111111111111111";
+    connect(pc,SIGNAL(finished(Tp::PendingOperation *)),SLOT(onNewContactRetrieved(Tp::PendingOperation *)));
+}
+
+void TpSessionAccount::onNewContactRetrieved(Tp::PendingOperation *op)
+{
+    Tp::PendingContacts *pcontacts = qobject_cast<Tp::PendingContacts *>(op);
+    QList<Tp::ContactPtr> contacts = pcontacts->contacts();
+    QString username = pcontacts->identifiers().first();
+    if (contacts.size() != 1 || !contacts.first()) {
+        qDebug() << "Unable to add contact " <<reqContact;
+        return;
+    }
+
+    Tp::ContactPtr contact = contacts.first();
+    //    qDebug() << "TpSessionAccount::onContactRetrieved" << reqContact;
+    if(!reqContact.isEmpty()) addOutgoingChannel(contacts.first());
+}
+/**
+ * Send message to given address. This function is compled Acynchronous function that may produce multiple state transitions beforecomletion.
+ * If there is already existing TpSessionChannel for this contact, it simply queues message for sending and no forther transitions are needed
+ * If there are no hannel, it first check is there contact for this address, if is, it requests new channel to be created for ths channel and message
+ * is left waiting untill channel is created. If there is no contact, it sends request fr contact creation and when contact is created state machine
+ * proceeds to channel creation.
+ *
+ * MessageSent() signal is emitted when completed
+ *
+ * \param address           Contact address/id, as example email address, telephone number etc.
+ * \param message           Message string
+ */
+
+void TpSessionAccount::sendMessageToAddress(QString address,QString message)
+{
+    qDebug() << "TpSessionAccount::sendMessageToAddress(QString address,QString message)";
+
+    Tp::ContactPtr p;
+    TpSessionChannel* channel = getChannelFromPeerAddress(address);
+    if(channel) {
+        channel->sendMessage(message); // We have already channel
+        Q_EMIT messageQueued(this);
+    }
+    else {        
+        reqMessage=message;
+        p=getContactFromAddress(address); // Do we have contact ready ?
+        if(p.isNull())  // If not, create it
+        {
+            makeContactFromAddress(address); // Create and after created, send
+        }else
+        {
+            addOutgoingChannel(p); // Create channel and when ready, send
+        }
+    };
+}
+
+void TpSessionAccount::addOutgoingChannel(const Tp::ContactPtr &contact)
+{
+
+
+    //    qDebug() << "TpSessionAccount::addOutgoingChannel";
+
+    TpSessionChannel* newChannel=new TpSessionChannel(contact->manager()->connection(),contact);
+    connect(newChannel,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)),
+            SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)));
+    connect(newChannel,SIGNAL(channelReady(TpSessionChannel *)),
+            SLOT(onOutgoingChannelReady(TpSessionChannel*)));
+    myChannels+=newChannel;
+
+}
+
+void TpSessionAccount::onOutgoingChannelReady(TpSessionChannel *ch)
+{
+    // qDebug() << "TpSessionAccoiunt::onOutgoingChannelReady";
+    Q_EMIT channelReady(this);
+    if(!reqMessage.isEmpty()) {
+        ch->sendMessage(reqMessage);
+        Q_EMIT messageQueued(this);
+    };
+    reqMessage.clear();
+}
+
+
+void TpSessionAccount::onMessageSent(const Tp::Message &msg,Tp::MessageSendingFlags, const QString &flags)
+{
+    //    qDebug() << "TpSessionAccount::onMessageSent";
+    Q_EMIT messageSent(msg,this);
+};
+
+void TpSessionAccount::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionChannel *ch)
+{
+    //    qDebug() << "TpSessionAccount::onMessageReceived " << msg.text();
+    Q_EMIT messageReceived(msg,this);
+};
+
+void TpSessionAccount::onNewChannels(const Tp::ChannelDetailsList &channels)
+{
+
+    Tp::TextChannelPtr myIngoingTextChannel;
+    //    qDebug() << "TpSessionAccount::onNewChannels";
+    Q_FOREACH (const Tp::ChannelDetails &details, channels) {
+        QString channelType = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+        QString targetId = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetID")).toString();
+        bool requested = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".Requested")).toBool();
+       //        qDebug() << " channelType:" << channelType <<" requested  :" << requested << " targetId" << targetId;
+
+        Q_EMIT newChannel(this,channelType,targetId,details);
+        if (channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT && !requested) {
+
+            myIngoingTextChannel = Tp::TextChannel::create(acc->connection(),details.channel.path(),details.properties);
+           //            qDebug() << "TpSessionAccount::onNewChannels path=" <<"path " << myIngoingTextChannel->objectPath();
+
+            TpSessionChannel* newChannel=new TpSessionChannel( myIngoingTextChannel);
+            connect(newChannel,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)),
+                    SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)));
+            myChannels+=newChannel;
+        }
+        if (channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA && !requested) {
+            //            qDebug() << "Incoming call" ;
+        }
+    }
+}
diff --git a/sms/tpsession/tpsessionaccount.h b/sms/tpsession/tpsessionaccount.h
new file mode 100755 (executable)
index 0000000..3e00670
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alholanokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef TPSESSIONACCOUNT_H
+#define TPSESSIONACCOUNT_H
+
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Account>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/PendingChannelRequest>
+#include <TelepathyQt4/ChannelRequest>
+#include <TelepathyQt4/PendingChannel>
+#include <TelepathyQt4/PendingContacts>
+#include <TelepathyQt4/Channel>
+#include <TelepathyQt4/TextChannel>
+#include <TelepathyQt4/AccountManager>
+#include <TelepathyQt4/PendingReady>
+#include <TelepathyQt4/ContactManager>
+
+#include <QString>
+#include <QVector>
+
+#include "tpsessionchannel.h"
+
+class TpSessionAccount:public QObject
+{
+
+    Q_OBJECT
+public:
+  TpSessionAccount(Tp::AccountManagerPtr am,const QString &objectPath);
+  void makeContactFromAddress(QString address);
+  void sendMessageToAddress(QString address,QString message);
+  Tp::ContactPtr getContactFromAddress(QString address);
+  void addOutgoingChannel(const Tp::ContactPtr &contact);
+  void addOutgoingChannel(QString address);
+  TpSessionChannel *getChannelFromPeerAddress(QString id);
+Q_SIGNALS:
+  void accountReady(TpSessionAccount *);
+  void channelReady(TpSessionAccount *);
+  void messageQueued(TpSessionAccount *);
+  void messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *);
+  void messageSent(const Tp::Message &,TpSessionAccount *);
+  void newChannel(TpSessionAccount *,QString,QString,const Tp::ChannelDetails &);
+
+private Q_SLOTS:
+  void onReady(Tp::PendingOperation *op);
+  void onOutgoingChannelReady(TpSessionChannel *ch);
+  void onContactsConnectionReady(Tp::PendingOperation *op);
+  void onNewContactRetrieved(Tp::PendingOperation *op);
+  void onMessageReceived(const Tp::ReceivedMessage &,TpSessionChannel *);
+  void onMessageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &);
+  void onNewChannels(const Tp::ChannelDetailsList&);
+public:
+  bool ready;
+  QString reqContact;
+  QString reqMessage;
+  Tp::AccountPtr mAcc;
+  Tp::Account *acc;
+  Tp::ConnectionPtr contactsConn;
+  QSet<Tp::ContactPtr> myContacts;
+  QSet<TpSessionChannel *> myChannels;
+};
+
+#endif // TPSESSIONACCOUNT_H
diff --git a/sms/tpsession/tpsessionchannel.cpp b/sms/tpsession/tpsessionchannel.cpp
new file mode 100755 (executable)
index 0000000..930cf3d
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alholanokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "tpsessionchannel.h"
+
+
+/**
+ * \class TpSessionChannel
+ * \headerfile <tpsessionchannel.h>
+ *
+ *
+ * When you start chat session or call with your buddy, channel is established with your buddy.
+ * TpSessionChannel represents this connection. TpSession account makes automatically channel when
+ * you send message to your buddy's address. If you send successive messages to same buddy with
+ * TpSessionAccount, it automatically reuses existing connection.
+ */
+/**
+ * \fn void TpSessionChannel::channelReady(TpSessionChannel *);
+ *
+ * Emitted when the channel becomes ready
+ *
+ * \param  TpSessionChannel  pointer to channel become ready
+ */
+/**
+ * \fn void TpSessionChannel::channelDestroyed(TpSessionChannel *);
+ *
+ * Emitted when the channel is destroyed
+ *
+ * \param  TpSessionChannel  pointer to channel destroyed. The pointer is only for referenc to remove
+ * it from some possible places where it could be stored. It is not guaranteed to point any more valid TpSessionChannel object
+ */
+/**
+ * \fn void TpSessionChannel::messageReceived(const Tp::ReceivedMessage &,TpSessionConnection *);
+ *
+ * Emitted when any of Account Managers recived message
+ *
+ * \param  Tp::ReceivedMessage  Message received
+ * \param  TpSessionChannel  pointer to channel received message
+ */
+/**
+  * \fn void TpSessionChannel::messageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &,TpSessionChannel *);
+  *
+  * \param Tp::Message message sent
+  */
+
+/**
+ * Construct a new TpSessionChannel object. This constructor is called by TpSessionAccount class when
+ * new channel is created . It is not inended to be used stand alone
+ * This varient with connection and contact as parameter is intented for creationg new connection from origginator side to your peer
+ *
+ *
+ * \param conn connection where this channel is created
+ * \param contact  Contacto to your peer to establish channel
+ */
+
+
+TpSessionChannel::TpSessionChannel(Tp::ConnectionPtr conn,const Tp::ContactPtr &contact)
+{
+    QVariantMap request;
+    //    qDebug() << "TpSessionChannel::TpSessionChannel" <<"contact.id() " << contact->id();
+    request.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+                   TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT);
+    request.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+                   (uint) Tp::HandleTypeContact);
+    request.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandle"),
+                   contact->handle()[0]);
+
+    connect(conn->ensureChannel(request),
+            SIGNAL(finished(Tp::PendingOperation*)),
+            SLOT(onChannelCreated(Tp::PendingOperation*)));
+    peerContact=contact;
+}
+
+/**
+ * Construct a new TpSessionChannel object. This constructor is called by TpSessionAccount class when
+ * new channel is created . It is not inended to be used stand alone
+ * This varient with connection only parameter is intented for receiving new connection from your peer
+ *
+ *
+ * \param conn connection where this channel is created
+ */
+
+
+TpSessionChannel::TpSessionChannel(Tp::TextChannelPtr ch)
+{
+    //     qDebug() << "TpSessionChannel::TpSessionChannel" <<"path " << ch->objectPath();
+    channel=ch;
+    connect(channel->becomeReady(Tp::TextChannel::FeatureMessageQueue|Tp::TextChannel::FeatureMessageSentSignal),
+            SIGNAL(finished(Tp::PendingOperation *)),
+            SLOT(onChannelReady(Tp::PendingOperation *)));
+
+}
+
+void TpSessionChannel::onChannelCreated(Tp::PendingOperation *op)
+{
+    //   qDebug() << "TpSessionChannel::onOutgoingChannelCreated" ;
+    if (op->isError()) {
+        qWarning() << "Connection cannot become connected" ;
+        return;
+    }
+    Tp::PendingChannel *pc = qobject_cast<Tp::PendingChannel *>(op);
+
+    channel = Tp::TextChannel::create(pc->connection(),pc->objectPath(), pc->immutableProperties());
+
+    connect(channel->becomeReady(Tp::TextChannel::FeatureMessageQueue | Tp::TextChannel::FeatureMessageSentSignal),
+            SIGNAL(finished(Tp::PendingOperation*)),
+            SLOT(onChannelReady(Tp::PendingOperation*)));
+}
+
+void TpSessionChannel::onChannelReady(Tp::PendingOperation *op)
+{
+    // qDebug() << "TpSessionChannel::onChannelReady type=" << channel->channelType() <<"path " << channel->objectPath() <<
+    //            "initiatorContact=" << (channel->initiatorContact() ? channel->initiatorContact()->id():"NULL") ;
+    ;
+    connect(channel.data(),
+            SIGNAL(messageReceived(const Tp::ReceivedMessage &)),
+            SLOT(onMessageReceived(const Tp::ReceivedMessage &)));
+    connect(channel.data(),
+            SIGNAL(messageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &)),
+            SLOT(onMessageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &)));
+    connect(channel.data(),SIGNAL(destroyed(QObject *)),SLOT(onChannelDestroyed(QObject *)));
+    Q_EMIT channelReady(this);
+    peerContact=channel->initiatorContact();
+    QList<Tp::ReceivedMessage> queuedMessages = channel->messageQueue();
+    Q_FOREACH(Tp::ReceivedMessage message, queuedMessages) {
+        //      qDebug()  << "received " << message.text();
+        Q_EMIT messageReceived(message,this);
+    }
+}
+/**
+ *  Send message to to ths channel
+ *
+ *
+ * \param message   message to send
+ */
+
+void TpSessionChannel::sendMessage(QString message)
+{
+    channel->send(message);
+}
+void TpSessionChannel::onMessageReceived(const Tp::ReceivedMessage &msg)
+{
+    //    qDebug() << "TpSessionChannel::onMessageReceived " << msg.text();
+    Q_EMIT messageReceived(msg,this);
+};
+void TpSessionChannel::onMessageSent(const Tp::Message &msg,Tp::MessageSendingFlags sflags, const QString &flags)
+{
+    //    qDebug() << "TpSessionChannel::onMessageSent";
+    Q_EMIT messageSent(msg,sflags,flags,this);
+};
+/**
+ *  Get id ( address of your peer )
+ *
+ *
+ * \returns your peer id/address ir empty QString
+ */
+QString TpSessionChannel::peerId()
+{
+    return peerContact ? peerContact->id():"";
+}
+
+void TpSessionChannel::onChannelDestroyed(QObject *obj)
+{
+    //    qDebug() << "TpSessionChannel::onChannelDestroyed";
+    //TpSessionChannel *call = (TpSessionChannel *) obj;
+    Q_EMIT channelDestroyed(this);
+}
+
diff --git a/sms/tpsession/tpsessionchannel.h b/sms/tpsession/tpsessionchannel.h
new file mode 100755 (executable)
index 0000000..182eea4
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is part of TpSession
+ *
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * Contact Kate Alhola  kate.alholanokia.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef TPSESSIONCHANNEL_H
+#define TPSESSIONCHANNEL_H
+
+#include <QObject>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Message>
+#include <TelepathyQt4/PendingChannel>
+#include <TelepathyQt4/ChannelRequest>
+#include <TelepathyQt4/Channel>
+#include <TelepathyQt4/TextChannel>
+#include <TelepathyQt4/PendingReady>
+#include <TelepathyQt4/ContactManager>
+#include <TelepathyQt4/Connection>
+
+class TpSessionChannel : public QObject
+{
+  Q_OBJECT
+public:
+    TpSessionChannel(Tp::TextChannelPtr);
+    TpSessionChannel(Tp::ConnectionPtr conn,const Tp::ContactPtr &contact);
+    void sendMessage(QString message);
+    QString peerId();
+Q_SIGNALS:
+  void channelReady(TpSessionChannel *);
+  void channelDestroyed(TpSessionChannel *);
+  void messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *);
+  void messageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &,TpSessionChannel *);
+public Q_SLOTS:
+    void onChannelCreated(Tp::PendingOperation *op);
+    void onChannelReady(Tp::PendingOperation *op);
+    void onChannelDestroyed(QObject *);
+    void onMessageReceived(const Tp::ReceivedMessage &);
+    void onMessageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &);
+public:
+    Tp::ContactPtr peerContact;
+    Tp::TextChannelPtr channel;
+};
+
+#endif // TPSESSIONCHANNEL_H
diff --git a/sms/tpsession/tpsessionobserver.cpp b/sms/tpsession/tpsessionobserver.cpp
new file mode 100755 (executable)
index 0000000..211cd80
--- /dev/null
@@ -0,0 +1,37 @@
+#include "tpsessionobserver.h"
+#include "tpsession.h"
+#include <TelepathyQt4/Channel>
+
+TpSessionObserver::TpSessionObserver(const Tp::ChannelClassList &channelFilter,TpSession *session):Tp::AbstractClientObserver(channelFilter)
+{
+    tpSession=session;
+    qDebug() << __PRETTY_FUNCTION__ ;
+}
+
+void TpSessionObserver::observeChannels(const Tp::MethodInvocationContextPtr<> &context,
+            const Tp::AccountPtr &account,
+            const Tp::ConnectionPtr &connection,
+            const QList<Tp::ChannelPtr> &channels,
+            const Tp::ChannelDispatchOperationPtr &dispatchOperation,
+            const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
+            const QVariantMap &observerInfo)
+{
+    Q_UNUSED(dispatchOperation)
+    Q_UNUSED(requestsSatisfied)
+    Q_UNUSED(observerInfo)
+    Q_UNUSED(connection)
+
+    qDebug() << "TpSessionObserver::observeChannels";
+
+    Q_FOREACH( Tp::ChannelPtr channel, channels )
+    {
+        QVariantMap properties = channel->immutableProperties();
+        QString channelType = properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
+        if( !channelType.isNull() && !channelType.isEmpty())
+        {
+            qDebug() << "ChannelType=" << channelType;
+            tpSession->createChannelListener(channelType, context, account, channel);
+        }
+    }
+}
+
diff --git a/sms/tpsession/tpsessionobserver.h b/sms/tpsession/tpsessionobserver.h
new file mode 100755 (executable)
index 0000000..80cb661
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef TPSESSIONOBSERVER_H
+#define TPSESSIONOBSERVER_H
+
+#include <QObject>
+#include <TelepathyQt4/AbstractClientObserver>
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Channel>
+
+class TpSession;
+
+class TpSessionObserver : public QObject , public Tp::AbstractClientObserver
+{
+       Q_OBJECT
+public:
+    TpSessionObserver(const Tp::ChannelClassList &channelfilter,TpSession *session);
+    TpSession *tpSession;
+
+
+    /*!
+     * \brief Realisation of Tp::AbstractClientObserver
+     */
+    virtual void observeChannels(const Tp::MethodInvocationContextPtr<> &context,
+            const Tp::AccountPtr &account,
+            const Tp::ConnectionPtr &connection,
+            const QList<Tp::ChannelPtr> &channels,
+            const Tp::ChannelDispatchOperationPtr &dispatchOperation,
+            const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
+            const QVariantMap &observerInfo);
+};
+
+#endif // TPSESSIONOBSERVER_H
diff --git a/sms/utility.cpp b/sms/utility.cpp
new file mode 100644 (file)
index 0000000..c3da34d
--- /dev/null
@@ -0,0 +1,35 @@
+#include "utility.h"
+
+Utility::Utility(QObject *parent) :
+    QObject(parent)
+{
+}
+
+QIcon Utility::getToolButtonIcon(const QString &iconFileName, bool active)
+{
+    QIcon icon(iconFileName);
+    if (!active)
+    {
+        QPixmap normalPixmap = icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off);
+        QPixmap activePixmap = icon.pixmap(16, 16, QIcon::Normal, QIcon::Off);
+        icon.addPixmap(normalPixmap, QIcon::Normal, QIcon::Off);
+        icon.addPixmap(activePixmap, QIcon::Active, QIcon::Off);
+    } else
+    {
+        QPixmap activePixmap = icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off);
+        icon.addPixmap(activePixmap, QIcon::Active, QIcon::Off);
+    }
+    return icon;
+}
+
+QPixmap Utility::getIconPixmap(const QString &iconFileName, bool active)
+{
+    QIcon icon(iconFileName);
+    if (!active)
+    {
+        return icon.pixmap(16, 16, QIcon::Normal, QIcon::Off);
+    } else
+    {
+        return icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off);
+    }
+}
diff --git a/sms/utility.h b/sms/utility.h
new file mode 100644 (file)
index 0000000..9402c90
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef UTILITY_H
+#define UTILITY_H
+
+#include <QObject>
+#include <QtGui>
+
+class Utility : public QObject
+{
+    Q_OBJECT
+public:
+    Utility(QObject *parent = 0);
+
+    static QIcon getToolButtonIcon(const QString &iconFileName, bool active = false);
+    static QPixmap getIconPixmap(const QString &iconFileName, bool active = false);
+
+};
+
+#endif // UTILITY_H
diff --git a/sms/xmlcontroler.cpp b/sms/xmlcontroler.cpp
new file mode 100644 (file)
index 0000000..8946da8
--- /dev/null
@@ -0,0 +1,656 @@
+#include <QtGui>
+#include <QXmlStreamWriter>
+
+#include "xmlcontroler.h"
+#include "xmlstring.h"
+#include "groupwidgetitem.h"
+
+XmlControler* XmlControler::instance = 0;
+
+XmlControler* XmlControler::getInstance()
+{
+    if( !instance )
+    {
+        instance = new XmlControler();
+    }
+    return instance;
+}
+
+XmlControler::XmlControler(QObject *parent) :
+        QObject(parent)
+{
+    instance = this;
+}
+
+XmlControler::~XmlControler()
+{
+    closeXmlFile();
+}
+
+void XmlControler::closeXmlFile()
+{
+    if( m_XmlFileOut->isOpen() )
+    {
+        m_XmlFileOut->close();
+        delete m_XmlFileOut;
+        m_XmlFileOut = NULL;
+    }
+
+    if( m_XmlFileIn->isOpen() )
+    {
+        writeXml( m_XmlFileIn );
+        m_XmlFileIn->close();
+        delete m_XmlFileIn;
+        m_XmlFileIn = NULL;
+    }
+}
+
+bool XmlControler::newXml( const QString &filename )
+{
+    //qDebug() << "XmlControler::newXml( const QString &filename ), Entry";
+
+    m_filename = filename;
+    m_XmlFileOut = new QFile( filename );
+    if( !m_XmlFileOut->open( QFile::ReadWrite | QFile::Text ) )
+    {
+        //qDebug() << "open file is failed:" << m_XmlFileOut->errorString();
+        return false;
+    }
+
+    newXml( m_XmlFileOut );
+    m_XmlFileOut->close();
+    delete m_XmlFileOut;
+    m_XmlFileOut = NULL;
+
+    return true;
+}
+
+bool XmlControler::newXml( QIODevice *device )
+{
+    //qDebug() << "XmlControler::newXml( QIODevice *device ), Entry";
+
+    const int Indent = 4;
+
+    QTextStream out( device );
+    QDomNode xmlNode = m_DomDoc.createProcessingInstruction( "xml",
+                                                             "version=\"1.0\" encoding=\"UTF-8\"");
+    m_DomDoc.insertBefore( xmlNode, m_DomDoc.firstChild() );
+
+    QDomElement root = m_DomDoc.createElement( STR_XML_GROUPSMS );
+    root.setAttribute( STR_XML_VERSION, STR_XML_VERSION_NUMBER );
+    m_DomDoc.appendChild( root );
+
+    m_DomDoc.save( out, Indent );
+    return true;
+}
+
+bool XmlControler::readXml( const QString &filename )
+{
+    //qDebug() << "XmlControler::readXml( const QString &filename ), Entry";
+
+    m_filename = filename;
+    m_XmlFileOut = new QFile( filename );
+    if( !m_XmlFileOut->open( QFile::ReadOnly | QFile::Text ) )
+    {
+        //qDebug() << "open file is failed:" << m_XmlFileOut->errorString();
+        return false;
+    }
+
+    if( !readXml( m_XmlFileOut ) )
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool XmlControler::readXml( QIODevice *device )
+{
+    //qDebug() << "XmlControler::readXml( QIODevice *device ), Entry";
+
+    QString errorStr;
+    int errorLine;
+    int errorColumn;
+
+    if( !m_DomDoc.setContent( device, true, &errorStr, &errorLine, &errorColumn ) )
+    {
+        QMessageBox::information( NULL, tr("XML file"),
+                                  tr("Parse error at line %1, column %2:\n%3")
+                                  .arg(errorLine)
+                                  .arg(errorColumn)
+                                  .arg(errorStr) );
+        return false;
+    }
+
+    return true;
+}
+
+bool XmlControler::writeXml( QIODevice *device )
+{
+    //qDebug() << "XmlControler::writeXml( QIODevice *device ), Entry";
+
+    const int IndentSize = 4;
+
+    QTextStream out(device);
+    m_DomDoc.save( out, IndentSize );
+    return true;
+}
+
+bool XmlControler::writeXml()
+{
+    //qDebug() << "XmlControler::writeXml(), Entry";
+
+    const int IndentSize = 4;
+
+    m_XmlFileIn = new QFile( m_filename );
+    if( !m_XmlFileIn->open( QFile::WriteOnly | QFile::Text ) )
+    {
+        //qDebug() << "open file is failed:" << m_XmlFileIn->errorString();
+        return false;
+    }
+
+    QTextStream out(m_XmlFileIn);
+    m_DomDoc.save( out, IndentSize );
+    m_XmlFileIn->close();
+    delete m_XmlFileIn;
+    m_XmlFileIn = NULL;
+    return true;
+}
+
+bool XmlControler::createAllContacts()
+{
+    //qDebug() << "XmlControler::createAllContacts, Entry";
+
+    QDomElement root = m_DomDoc.documentElement();
+    QDomElement allcontacts = m_DomDoc.createElement( STR_XML_ALLCONTACTS );
+    root.appendChild( allcontacts );
+
+    QDomElement node_contact = m_DomDoc.createElement( STR_XML_CONTACT );
+    allcontacts.appendChild( node_contact );
+    QDomText contact_fullname = m_DomDoc.createTextNode( "Tom for Test" );
+    node_contact.appendChild( contact_fullname );
+    QDomText contact_mobilenumber = m_DomDoc.createTextNode( "number for Test" );
+    node_contact.appendChild( contact_mobilenumber );
+
+    m_DomDoc.appendChild( root );
+
+    return true;
+}
+
+bool XmlControler::createGroup(const QString &groupname)
+{
+    //qDebug() << "XmlControler::createGroup(const QString &groupname), Entry";
+
+    findGroup( groupname );
+    if( foundgroup )
+        return true;
+
+    QDomElement root = m_DomDoc.documentElement();
+    QDomElement group = m_DomDoc.createElement( STR_XML_GROUP );
+    group.setAttribute( STR_XML_GROUP_NAME, groupname );
+
+
+    root.appendChild( group );
+    writeXml();
+
+    Item *item = new Item();
+
+    item->group_name = groupname;
+    item->m_isGroup = true;
+
+    itemObserver->addGroup( item );
+
+    return true;
+}
+
+bool XmlControler::createContact(const QString &group, ItemListPtr contacts)
+{
+    QDomNode root = findGroup(group);
+    if( !foundgroup )
+    {
+        qDebug() << "could not find this" << group << "existed. create it.";
+        createGroup( group );
+        root = findGroup(group);
+    }
+
+    for( int i = 0; i < contacts.size(); i++ )
+    {
+        contacts.at(i)->group_owner = group;
+        createContact( &root, contacts.at(i) );
+    }
+    itemObserver->addContact( contacts, group);
+    return true;
+}
+
+bool XmlControler::createContact(const QString &group, Item *contact)
+{
+    //qDebug() << "XmlControler::createContact(const QString &group, Item *contact), Entry";
+
+    QDomNode root = findGroup(group);
+    if( !foundgroup )
+    {
+        //qDebug() << "could not find this" << group << "existed. create it.";
+        createGroup( group );
+        root = findGroup(group);
+    }
+
+    contact->group_owner = group;
+    createContact( &root, contact );
+
+    itemObserver->addContact( contact, group);
+
+    return true;
+}
+
+bool XmlControler::createContact(QDomNode *group, Item *contact)
+{
+    //qDebug() << "XmlControler::createContact(QDomElement *group, Item *contact), Entry";
+    Q_ASSERT(contact);
+
+    QDomElement node = m_DomDoc.createElement(STR_XML_CONTACT);
+    node.setAttribute( STR_XML_CONTACT_UID, contact->uid);
+    node.setAttribute( STR_XML_CONTACT_FULL_NAME, contact->full_name);
+    node.setAttribute( STR_XML_CONTACT_MOBILE_NUMBER, contact->mobile_number);
+    node.setAttribute( STR_XML_CONTACT_PIC_URI, contact->user_pic_uri);
+    node.setAttribute( STR_XML_CONTACT_GROUP_OWNER, contact->group_owner);
+
+//    node.setAttribute( STR_XML_CONTACT_UID, "1");
+//    node.setAttribute( STR_XML_CONTACT_FULL_NAME, "Tom 1");
+//    node.setAttribute( STR_XML_CONTACT_MOBILE_NUMBER, "12345678901");
+//    node.setAttribute( STR_XML_CONTACT_PIC_URI, "/alsdj/a;sdj/pic");
+//    node.setAttribute( STR_XML_CONTACT_GROUP_OWNER, "groupowner");
+
+    group->appendChild(node);
+    writeXml();
+
+    return true;
+}
+
+QDomNode XmlControler::findGroup(const QString &groupname)
+{
+    //qDebug() << "XmlControler::findGroup(const QString &group), Entry";
+
+    QDomNode root;
+    QDomNode node;
+    foundgroup = false;
+
+    node = m_DomDoc.firstChild();
+    while( !node.isNull() && !foundgroup )
+    {
+        //qDebug() << "node1 name : " << node.toElement().tagName();
+        //qDebug() << "node1 attr : " << node.toElement().attribute(STR_XML_VERSION);
+        if( node.hasChildNodes() )
+        {
+            QDomNode node2 = node.firstChild();
+            while( !node2.isNull() )
+            {
+                //qDebug() << "node2 name : " << node2.toElement().tagName();
+                //qDebug() << "node2 attr : " << node2.toElement().attribute(STR_XML_GROUP_NAME);
+
+                if( groupname == node2.toElement().attribute(STR_XML_GROUP_NAME) )
+                {
+                    //qDebug() << "group is found";
+                    root = node2;
+                    foundgroup = true;
+                    break;
+                }
+
+                node2 = node2.nextSibling();
+            }
+        }
+
+        node = node.nextSibling();
+    }
+    return root;
+}
+
+QDomNode XmlControler::findContact(const QString &groupname, Item *contact)
+{
+    //qDebug() << "XmlControler::findContact(const QString &groupname, ContactWidgetItem *contact), Entry";
+
+    QDomNode element;
+    QDomNode group = findGroup(groupname);
+    if( !foundgroup )
+        return group;
+    element = findContact(group, contact);
+
+    return element;
+}
+
+QDomNode XmlControler::findContact(QDomNode group, Item *contact)
+{
+    //qDebug() << "XmlControler::findContact(QDomNode *group, ContactWidgetItem *contact), Entry";
+
+    QDomNode element;
+    QDomNode node = group;
+    foundcontact = false;
+    while( !node.isNull() && !foundcontact )
+    {
+        if( node.hasChildNodes() )
+        {
+            QDomNode node2 = node.firstChild();
+            while( !node2.isNull() )
+            {
+                //qDebug() << "node2 name : " << node2.toElement().tagName();
+                //qDebug() << "node2 uid : " << node2.toElement().attribute(STR_XML_CONTACT_UID);
+
+                if( contact->uid == node2.toElement().attribute(STR_XML_CONTACT_UID) )
+                //if( "1" == node2.toElement().attribute(STR_XML_CONTACT_UID) ) // for Test
+                {
+                    //qDebug() << "contact is found";
+                    element = node2;
+                    foundcontact = true;
+                    break;
+                }
+
+                node2 = node2.nextSibling();
+            }
+        }
+
+        node = node.nextSibling();
+    }
+
+    return element;
+}
+
+bool XmlControler::removeGroup(const QString &groupname)
+{
+    //qDebug() << "XmlControler::removeGroup(const QString &groupname), Entry";
+
+    QDomNode group = findGroup(groupname);
+    if( !foundgroup )
+        return false;
+    QDomElement root = m_DomDoc.documentElement();
+    root.removeChild(group);
+    writeXml();
+
+    return true;
+}
+
+bool XmlControler::removeContact( Item *contact )
+{
+    //qDebug() << "XmlControler::removeContact(const QString &group, ContactWidgetItem *contact), Entry";
+
+    QDomNode root = findGroup( contact->group_owner );
+    if( !foundgroup )
+    {
+        //qDebug() << "root is NULL";
+        return false;
+    }
+    removeContact( root, contact );
+
+    return true;
+}
+
+bool XmlControler::removeContact(const QString &group, Item *contact)
+{
+    //qDebug() << "XmlControler::removeContact(const QString &group, ContactWidgetItem *contact), Entry";
+
+    QDomNode root = findGroup(group);
+    if( !foundgroup )
+    {
+        //qDebug() << "root is NULL";
+        return false;
+    }
+    removeContact( root, contact );
+
+    return true;
+}
+
+bool XmlControler::removeContact(QDomNode group, Item *contact)
+{
+    //qDebug() << "XmlControler::removeContact(QDomNode *group, ContactWidgetItem *contact), Entry";
+
+    QDomNode node = findContact(group, contact);
+    if( node.isNull() )
+    {
+        //qDebug() << "node is NULL";
+        return false;
+    }
+    QDomNode del = group.removeChild(node);
+    if( del.isNull() )
+    {
+        //qDebug() << "del node is NULL";
+        return false;
+    }
+    writeXml();
+    itemObserver->removeContact(contact);
+
+    return true;
+}
+
+bool XmlControler::cleanAllContacts()
+{
+    //TODO : clean all contacts in observer.
+    itemObserver->removeAllContacts();
+
+    return true;
+}
+
+bool XmlControler::cleanAllContactsGroup()
+{
+    for( int i = 0; i < all_contacts_items_group.size(); i++ )
+    {
+        delete all_contacts_items_group.at(i);
+    }
+    all_contacts_items_group.clear();
+
+    return true;
+}
+
+void XmlControler::setItemObserver(ItemObserver *observer)
+{
+    itemObserver = observer;
+}
+
+void XmlControler::setItemSelectObserver( ItemSelectObserver *observer )
+{
+    itemSelectObserver = observer;
+}
+
+void XmlControler::getAllContactItems()
+{
+    //qDebug() << "XmlControler::getAllContactItems(), Entry";
+
+    QDomElement root = m_DomDoc.documentElement();
+    QDomNode node = root.firstChild();
+    QString tagname;
+
+    cleanAllContacts();
+
+    while( !node.isNull() )
+    {
+        tagname = node.toElement().tagName();
+        //qDebug() << "node tagname : " << tagname;
+
+        if( STR_XML_GROUP == tagname )
+        {
+            //qDebug() << "node is : " << STR_XML_GROUP;
+
+            Item *item = new Item();
+
+            item->group_name = node.toElement().attribute(STR_XML_GROUP_NAME);
+            item->m_isGroup = true;
+
+            itemObserver->addGroup( item );
+
+            if( node.hasChildNodes() )
+            {
+                QDomNode node2 = node.firstChild();
+                while( !node2.isNull() )
+                {
+                    tagname = node2.toElement().tagName();
+                    if( STR_XML_CONTACT == tagname )
+                    {
+                        //qDebug() << "node is : " << STR_XML_CONTACT;
+
+                        Item *item = new Item();
+                        item->m_isGroup = false;
+
+                        item->full_name = node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME);
+                        //qDebug() << "fullname is : " << node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME);
+
+                        item->mobile_number = node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER);
+                        //qDebug() << "mobile number is : " << node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER);
+
+                        item->group_owner =  node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER);
+                        //qDebug() << "group owner is : " << node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER);
+
+                        item->uid = node2.toElement().attribute(STR_XML_CONTACT_UID);
+                        //qDebug() << "uid is : " << node2.toElement().attribute(STR_XML_CONTACT_UID);
+
+                        itemObserver->addContact( item );
+                    }
+                    node2 = node2.nextSibling();
+                }
+            }
+        }
+        node = node.nextSibling();
+    }
+    //qDebug() << "XmlControler::getAllContactItems(), Exit";
+}
+
+QStringList XmlControler::getAllGroupNames()
+{
+    //qDebug() << "XmlControler::getAllGroupNames(), Entry";
+
+    QDomElement root = m_DomDoc.documentElement();
+    QDomNode node = root.firstChild();
+    QString tagname;
+    QStringList strlist;
+
+    while( !node.isNull() )
+    {
+        tagname = node.toElement().tagName();
+
+        if( STR_XML_GROUP == tagname )
+        {
+            //qDebug() << "group name : " << node.toElement().attribute(STR_XML_GROUP_NAME);
+            strlist.append( node.toElement().attribute(STR_XML_GROUP_NAME) );
+        }
+        node = node.nextSibling();
+    }
+    //qDebug() << "XmlControler::getAllGroupNames(), Exit";
+
+    return strlist;
+}
+
+void XmlControler::getAllContactItemsFromGroup( QString groupname )
+{
+    //qDebug() << "XmlControler::getAllContactItemsFromGroup( QString groupname ), Entry";
+
+    QDomElement root = m_DomDoc.documentElement();
+    QDomNode node = root.firstChild();
+    QString tagname;
+    QString group;
+
+    if( old_groupname == groupname )
+    {
+        itemSelectObserver->getGroupContacts( all_contacts_items_group );
+        return;
+    }
+
+    cleanAllContactsGroup();
+
+    while( !node.isNull() )
+    {
+        tagname = node.toElement().tagName();
+        group = node.toElement().attribute(STR_XML_GROUP_NAME);
+        //qDebug() << "node tagname : " << tagname << "group:" << group;
+
+        if( (STR_XML_GROUP == tagname) && (group == groupname) )
+        {
+            //qDebug() << "node is : " << STR_XML_GROUP;
+
+            Item *item = new Item();
+
+            item->group_name = node.toElement().attribute(STR_XML_GROUP_NAME);
+            item->m_isGroup = true;
+
+            all_contacts_items_group.append( item );
+
+            if( node.hasChildNodes() )
+            {
+                QDomNode node2 = node.firstChild();
+                while( !node2.isNull() )
+                {
+                    tagname = node2.toElement().tagName();
+                    if( STR_XML_CONTACT == tagname )
+                    {
+                        //qDebug() << "node is : " << STR_XML_CONTACT;
+
+                        Item *item = new Item();
+                        //qDebug() << "new ContactWidgetItem";
+
+                        item->full_name = node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME);
+                        //qDebug() << "fullname is : " << node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME);
+
+                        item->mobile_number = node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER);
+                        //qDebug() << "mobile number is : " << node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER);
+
+                        item->group_owner =  node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER);
+                        //qDebug() << "group owner is : " << node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER);
+
+                        item->uid = node2.toElement().attribute(STR_XML_CONTACT_UID);
+                        //qDebug() << "uid is : " << node2.toElement().attribute(STR_XML_CONTACT_UID);
+
+                        all_contacts_items_group.append( item );
+                    }
+                    node2 = node2.nextSibling();
+                }
+            }
+        }
+        node = node.nextSibling();
+    }
+    itemSelectObserver->getGroupContacts( all_contacts_items_group );
+    old_groupname = groupname;
+    //qDebug() << "XmlControler::getAllContactItemsFromGroup( QString groupname ), Exit";
+}
+
+bool XmlControler::removeContactFromGroup( ItemListPtr items, const QString &groupname )
+{
+    QDomNode root = findGroup(groupname);
+    if( !foundgroup )
+    {
+        //qDebug() << "root is NULL";
+        return false;
+    }
+    for( int i = 0; items.size(); i++ )
+    {
+        removeContact( root, items.at(i) );
+    }
+    itemObserver->refreshContactsList();
+
+    return true;
+}
+
+bool XmlControler::removeContactFromGroup( ItemListPtr items )
+{
+    for( int i = 0; i < items.size(); i++ )
+    {
+        removeContact( items.at(i) );
+    }
+    itemObserver->refreshContactsList();
+
+    return true;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sms/xmlcontroler.h b/sms/xmlcontroler.h
new file mode 100644 (file)
index 0000000..d53f0dd
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef XMLCONTROLER_H
+#define XMLCONTROLER_H
+
+#include <QObject>
+#include <QtXml>
+
+#include "contactwidgetitem.h"
+#include "itemobserver.h"
+
+class XmlControler : public QObject
+{
+    Q_OBJECT
+public:
+    static XmlControler* getInstance();
+    ~XmlControler();
+
+    void setItemObserver( ItemObserver *observer );
+    void setItemSelectObserver( ItemSelectObserver *observer );
+
+    bool newXml( const QString &filename );
+    bool newXml( QIODevice *device );
+
+    bool readXml( const QString &filename );
+    bool readXml( QIODevice *device );
+
+    bool writeXml( QIODevice *device );
+    bool writeXml();
+
+    void closeXmlFile();
+
+    bool createGroup(const QString &groupname);
+    bool createContact(const QString &group, ItemListPtr contacts);
+    bool createContact(const QString &group, Item *contact);
+    bool createContact(QDomNode *group, Item *contact);
+
+    bool removeGroup(const QString &groupname);
+    bool removeContact(const QString &group, Item *contact);
+    bool removeContact(QDomNode group, Item *contact);
+    bool removeContact( Item *contact );
+    bool removeContactFromGroup( ItemListPtr items, const QString &groupname );
+    bool removeContactFromGroup( ItemListPtr items );
+
+    void getAllContactItems();
+    void getAllContactItemsFromGroup( QString groupname );
+
+    QStringList getAllGroupNames();
+
+
+private:
+    static XmlControler* instance;
+    XmlControler( QObject *parent = 0 );
+
+    bool createAllContacts();
+    QDomNode findGroup(const QString &groupname);
+    QDomNode findContact(const QString &groupname, Item *contact);
+    QDomNode findContact(QDomNode group, Item *contact);
+
+    bool cleanAllContacts();
+    bool cleanAllContactsGroup();
+
+private:
+    ItemObserver *itemObserver;
+    ItemSelectObserver *itemSelectObserver;
+
+    QDomDocument m_DomDoc;
+
+    ItemListPtr all_contacts_items;
+    ItemListPtr all_contacts_items_group;
+
+    QFile *m_XmlFileOut;
+    QFile *m_XmlFileIn;
+    QString m_filename;
+
+    bool foundgroup;
+    bool foundcontact;
+
+    QString old_groupname;
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+
+};
+
+#endif // XMLCONTROLER_H
diff --git a/sms/xmlstring.h b/sms/xmlstring.h
new file mode 100644 (file)
index 0000000..e11932c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef XMLSTRING_H
+#define XMLSTRING_H
+
+#include <QString>
+
+const QString STR_XML_GROUPSMS = "GroupSMS";
+const QString STR_XML_VERSION = "Version";
+const QString STR_XML_VERSION_NUMBER = "0.1";
+
+const QString STR_XML_GROUP = "Group";
+const QString STR_XML_GROUP_NAME = "GroupName";
+const QString STR_XML_ALLCONTACTS = "All_Contacts";
+const QString STR_XML_CONTACT = "Contact";
+const QString STR_XML_CONTACT_UID = "Uid";
+const QString STR_XML_CONTACT_FULL_NAME = "Full_Name";
+const QString STR_XML_CONTACT_MOBILE_NUMBER = "Mobile_Number";
+const QString STR_XML_CONTACT_GROUP_OWNER = "Group_Owner";
+const QString STR_XML_CONTACT_PIC_URI = "Pic_Uri";
+
+#endif // XMLSTRING_H
diff --git a/welcome b/welcome
index e69de29..a0c312c 100644 (file)
--- a/welcome
+++ b/welcome
@@ -0,0 +1,3 @@
+It's a Qt application. It manage group contacts by personal XML file. it 's base on local contacts DB (libosso-abook). It could be add/remove group contacts. Another, It's could send SMS to group contacts. that's use TpSession and TelepathyQt4 lib.
+
+Author: Tom Chen <funpig@gmail.com> <tom.chen@teleca.com>