--- /dev/null
+TEMPLATE = subdirs
+SUBDIRS = sms
+#SUBDIRS = tpsession-0.1
--- /dev/null
+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)
--- /dev/null
+#include "abstractpage.h"
+
+AbstractPage::AbstractPage(QWidget *parent) :
+ QWidget(parent)
+{
+ ////qDebug() << "AbstractPage::AbstractPage(QWidget *parent) , Entry";
+}
+
+void AbstractPage::clear()
+{
+}
--- /dev/null
+#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
--- /dev/null
+#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 );
+ }
+}
--- /dev/null
+#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
--- /dev/null
+<?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>
--- /dev/null
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <QDir>
+
+const QString HOME_DIR = QDir::homePath() + "/.groupsms/";
+
+#endif // COMMON_H
--- /dev/null
+#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 );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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();
+}
--- /dev/null
+#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
--- /dev/null
+#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();
+}
+
+
+
+
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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";
+}
--- /dev/null
+#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
--- /dev/null
+<?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>
--- /dev/null
+/* 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+!@~@{@ ",
+" ",
+" "};
--- /dev/null
+[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
+
--- /dev/null
+<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>
--- /dev/null
+#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) );
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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();
+}
--- /dev/null
+#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();
+ }
+}
--- /dev/null
+#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
--- /dev/null
+<?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>
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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
--- /dev/null
+<?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>
--- /dev/null
+#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);
+}
--- /dev/null
+#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
--- /dev/null
+#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();
+}
+
+
--- /dev/null
+#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
--- /dev/null
+#-------------------------------------------------
+#
+# 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
--- /dev/null
+/*
+ * 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
+}
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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" ;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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);
+ }
+ }
+}
+
--- /dev/null
+#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
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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
--- /dev/null
+#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;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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
+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>