From: Tom Chen Date: Sat, 26 Jun 2010 01:49:42 +0000 (+0800) Subject: first release X-Git-Url: http://vcs.maemo.org/git/?p=groupsms;a=commitdiff_plain;h=7f26d7b5e6ae5759bb11942a69a9ada134744e98 first release --- diff --git a/groupsms.pro b/groupsms.pro new file mode 100644 index 0000000..b3a2142 --- /dev/null +++ b/groupsms.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = sms +#SUBDIRS = tpsession-0.1 diff --git a/history b/history new file mode 100644 index 0000000..63fbac0 --- /dev/null +++ b/history @@ -0,0 +1,17 @@ +Need to do/fix: +* some GLIB CRITICAL when use libebook, libosso, libosso-abook in Qt4.(2010.06.08) + +Done: +* fixed some display problem.(2010.06.17) +* implement that remove seleted group/contact. (2010.06.12 / 2010.06.13) +* implement add contacts to group.(2010.06.12) +* display prolem after new group.(2010.06.11 / 2010.06.12) +* display prolem after sent message.(2010.06.11) +* use Q_SLOTS, Q_SIGNALS, Q_EMIT macro in TpSession for avoid build error when use together GTK/libosso.(2010.06.10) +* implement send sms. maybe use ( TpSession & TelepathyQt4 ) or maemo lib.(2010.06.07 / 2010.06.10) +* modify the icon of UI.(2010.06.10) +* modify the UI position.(2010.06.10) +* make a .DEB file(v0.0.1).(2010.06.09) +* implement that get all contacts from DB of devices.(2010.06.03 / 2010.06.09) +* add dialog to add contacts to groups.(2010.06.03 / 2010.06.07) +* add dialog to add new group.(2010.06.03 / 2010.06.04) diff --git a/sms/abstractpage.cpp b/sms/abstractpage.cpp new file mode 100644 index 0000000..c43a04f --- /dev/null +++ b/sms/abstractpage.cpp @@ -0,0 +1,11 @@ +#include "abstractpage.h" + +AbstractPage::AbstractPage(QWidget *parent) : + QWidget(parent) +{ + ////qDebug() << "AbstractPage::AbstractPage(QWidget *parent) , Entry"; +} + +void AbstractPage::clear() +{ +} diff --git a/sms/abstractpage.h b/sms/abstractpage.h new file mode 100644 index 0000000..c58947f --- /dev/null +++ b/sms/abstractpage.h @@ -0,0 +1,33 @@ +#ifndef ABSTRACTPAGE_H +#define ABSTRACTPAGE_H + +#include +#include +#include + +#include "contactwidget.h" + +class AbstractPage : public QWidget +{ + Q_OBJECT +public: + AbstractPage(QWidget *parent = 0); + + virtual void update() = 0; + virtual QString title() = 0; + virtual void updateSize() = 0; + virtual void clear(); + +public: + QScrollArea *scrollArea; + bool isVisible; + + ContactWidget *contactWidget; + +Q_SIGNALS: + +public Q_SLOTS: + +}; + +#endif // ABSTRACTPAGE_H diff --git a/sms/addcontacttogroup.cpp b/sms/addcontacttogroup.cpp new file mode 100644 index 0000000..3281bc2 --- /dev/null +++ b/sms/addcontacttogroup.cpp @@ -0,0 +1,49 @@ +#include "addcontacttogroup.h" +#include "contactinterface.h" +#include "xmlstring.h" + +AddContactToGroup::AddContactToGroup(QWidget *parent) : + QDialog(parent) +{ + //qDebug() << "AddContactToGroup::AddContactToGroup(QWidget *parent), Entry"; + + setupUi(this); + setWindowModality( Qt::ApplicationModal ); + + comboBox_groupname->addItems( ContactInterface::getInstance()->getAllGroupNames() ); + + m_SelectContactWidget = new SelectContactWidget(this); + m_SelectContactWidget->initContactWidget(); + m_SelectContactWidget->sizePolicy().setHorizontalPolicy(QSizePolicy::Maximum); + m_SelectContactWidget->setGeometry(0,0,600,600); + m_SelectContactWidget->update(); + + + scrollArea = new QScrollArea(this); + scrollArea->setWidget( m_SelectContactWidget ); + scrollArea->setBackgroundRole(QPalette::Light); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + this->verticalLayout->addWidget(scrollArea); + + connect( btngroup_ok_cancel, SIGNAL( clicked(QAbstractButton*) ), this, SLOT( btn_clicked(QAbstractButton*) ) ); +} + +void AddContactToGroup::btn_clicked(QAbstractButton *button) +{ + if( QDialogButtonBox::AcceptRole == btngroup_ok_cancel->buttonRole( button ) ) + { + //qDebug() << "add contact to group "; + + QString groupname = comboBox_groupname->currentText(); + if( STR_XML_ALLCONTACTS != groupname ) + { + m_SelectContactWidget->addContactsToGroup(groupname); + } + done( QDialog::Accepted ); + }else // button cancel + { + done( QDialog::Rejected ); + } +} diff --git a/sms/addcontacttogroup.h b/sms/addcontacttogroup.h new file mode 100644 index 0000000..870a9e5 --- /dev/null +++ b/sms/addcontacttogroup.h @@ -0,0 +1,26 @@ +#ifndef ADDCONTACTTOGROUP_H +#define ADDCONTACTTOGROUP_H + +#include +#include "ui_addcontacttogroupdialog.h" +#include "selectcontactwidget.h" + +class AddContactToGroup : public QDialog, Ui::AddContactToGroupDialog +{ + Q_OBJECT +public: + AddContactToGroup(QWidget *parent = 0); + +private: + SelectContactWidget* m_SelectContactWidget; + + QScrollArea *scrollArea; + +Q_SIGNALS: + +public Q_SLOTS: + void btn_clicked(QAbstractButton * button); + +}; + +#endif // ADDCONTACTTOGROUP_H diff --git a/sms/addcontacttogroupdialog.ui b/sms/addcontacttogroupdialog.ui new file mode 100644 index 0000000..48c1912 --- /dev/null +++ b/sms/addcontacttogroupdialog.ui @@ -0,0 +1,97 @@ + + + AddContactToGroupDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 310 + 20 + 81 + 241 + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 10 + 291 + 281 + + + + + + + + + Add To: + + + false + + + + + + + + + + + + + + + btngroup_ok_cancel + accepted() + AddContactToGroupDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + btngroup_ok_cancel + rejected() + AddContactToGroupDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sms/common.h b/sms/common.h new file mode 100644 index 0000000..f836d0d --- /dev/null +++ b/sms/common.h @@ -0,0 +1,8 @@ +#ifndef COMMON_H +#define COMMON_H + +#include + +const QString HOME_DIR = QDir::homePath() + "/.groupsms/"; + +#endif // COMMON_H diff --git a/sms/contactinterface.cpp b/sms/contactinterface.cpp new file mode 100644 index 0000000..64cf4ee --- /dev/null +++ b/sms/contactinterface.cpp @@ -0,0 +1,204 @@ +#include "contactinterface.h" +#include "xmlcontroler.h" +#include "xmlstring.h" + +ContactInterface* ContactInterface::instance = 0; + +ContactInterface* ContactInterface::getInstance() +{ + if( !instance ) + { + instance = new ContactInterface(); + } + return instance; +} + +ContactInterface::ContactInterface(QObject *parent) : + QObject(parent) +{ + instance = this; + + initEbook(); +} + +ContactInterface::~ContactInterface() +{ + for( int i = 0; i < all_contacts_items_db.size(); i++ ) + { + delete all_contacts_items_db.at(i); + } + all_contacts_items_db.clear(); +} + +void ContactInterface::setItemObserver(ItemObserver *observer) +{ + XmlControler::getInstance()->setItemObserver( observer ); +} + +void ContactInterface::setItemSelectObserver( ItemSelectObserver *observer ) +{ + XmlControler::getInstance()->setItemSelectObserver( observer ); +} + +bool ContactInterface::initEbook() +{ + //qDebug() << "ContactInterface::initEbook(), Entry"; + +#ifdef ONLY_FOR_EBOOK + GError *error = NULL; + roster = osso_abook_aggregator_get_default(&error); + if( error ) + { + //qDebug() << "Couldn't open roster %s\n" << error->message; + g_error_free( error ); + } + osso_abook_roster_start(roster); + + //qDebug() << "osso_abook_roster_start"; + + osso_abook_waitable_run(OSSO_ABOOK_WAITABLE(roster), g_main_context_default(), &error); + + if (!osso_abook_waitable_is_ready(OSSO_ABOOK_WAITABLE(roster), &error) ) + g_critical("osso_abook_waitable_is_ready: %s\n", error->message); + + //* for test +// OssoABookAggregator *_aggr; +// GList *list, *c; +// GError *err; + +// osso_abook_waitable_run(OSSO_ABOOK_WAITABLE(roster), g_main_context_default(), &err); + +// if (! osso_abook_waitable_is_ready(OSSO_ABOOK_WAITABLE(roster), &err)) +// g_critical("osso_abook_waitable_is_ready: %s\n", err->message); + +// _aggr = OSSO_ABOOK_AGGREGATOR(roster); +// list = osso_abook_aggregator_list_master_contacts(_aggr); + +// printf("count = %d\n", g_list_length(list)); // list is not empty ! + +// g_list_free(list); + //* test end +#endif + return true; +} + +bool ContactInterface::updateContactsFromEbookToXml() +{ + removeGroup( STR_XML_ALLCONTACTS ); + getAllContacts(); + addContactToGroup( all_contacts_items_db, STR_XML_ALLCONTACTS ); + return true; +} + +ItemListPtr ContactInterface::getAllContacts() +{ + //qDebug() << "ContactInterface::getAllContacts() from EBook, Entry"; + +#ifdef ONLY_FOR_EBOOK + GList *list = NULL; + GList *it = NULL; + EContact *contact = NULL; + OssoABookAggregator *aggregator = OSSO_ABOOK_AGGREGATOR(roster); + + list = osso_abook_aggregator_list_master_contacts( aggregator ); + + qDebug() << "get list from EBook"; + //qDebug() << "list length is :" << g_list_length(list); + + QString str; + + for( it = list; it; it = it->next ) + { + //qDebug() << "into list loop"; + + contact = (EContact *)it->data; + Item *item = new Item(); + + str = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_FULL_NAME) ); + item->full_name = str; + qDebug() << "fullname is : " << item->full_name; + + str = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_PHONE_MOBILE) ); + item->mobile_number = str; + qDebug() << "mobile_number is : " << item->mobile_number; + + item->group_owner = ""; + item->user_pic_uri = ":/images/male.png"; + + item->uid = QString::fromLocal8Bit( (char*)e_contact_get(contact, E_CONTACT_UID) ); + qDebug() << "uid is : " << item->uid; + + all_contacts_items_db.append( item ); + } + + g_list_free( list ); +#endif + return all_contacts_items_db; +} + +void ContactInterface::getAllContactsFromXml() +{ + //qDebug() << "ContactInterface::getAllContactsFromXml(), Entry"; + + XmlControler::getInstance()->getAllContactItems(); +} + +void ContactInterface::getAllContactsFromXml(const QString &groupname) +{ + //qDebug() << "ContactInterface::getAllContactsFromXml(const QString &groupname), Entry"; + + XmlControler::getInstance()->getAllContactItemsFromGroup(groupname); +} + +QStringList ContactInterface::getAllGroupNames() +{ + //qDebug() << "ContactInterface::getAllGroupNames(), Entry"; + return XmlControler::getInstance()->getAllGroupNames(); +} + +bool ContactInterface::createGroup(const QString &groupname) +{ + return XmlControler::getInstance()->createGroup(groupname); +} + +bool ContactInterface::removeGroup(const QString &groupname) +{ + return XmlControler::getInstance()->removeGroup( groupname ); +} + +bool ContactInterface::addContactToGroup(ItemListPtr items, const QString &groupname) +{ + return XmlControler::getInstance()->createContact( groupname, items ); +} + +bool ContactInterface::removeContactToGroup( ItemListPtr items, const QString &groupname ) +{ + return XmlControler::getInstance()->removeContactFromGroup( items, groupname ); +} + +bool ContactInterface::removeContactToGroup( ItemListPtr items ) +{ + return XmlControler::getInstance()->removeContactFromGroup( items ); +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/sms/contactinterface.h b/sms/contactinterface.h new file mode 100644 index 0000000..dd4b840 --- /dev/null +++ b/sms/contactinterface.h @@ -0,0 +1,75 @@ +#ifndef CONTACTINTERFACE_H +#define CONTACTINTERFACE_H + +#include +#include +#include + +#include "itemobserver.h" + +#ifdef ONLY_FOR_EBOOK + +extern "C" { +#include +#include +#include +#include +} + +#endif + +class ContactInterface : public QObject +{ + Q_OBJECT +public: + static ContactInterface* getInstance(); + ~ContactInterface(); + + bool initEbook(); + + bool updateContactsFromEbookToXml(); + + void setItemObserver( ItemObserver *observer ); + void setItemSelectObserver( ItemSelectObserver *observer ); + + /** + get all contacts from libosso-abook + */ + ItemListPtr getAllContacts(); + /** + get all contacts from xml file + */ + void getAllContactsFromXml(); + void getAllContactsFromXml(const QString &groupname); + + QStringList getAllGroupNames(); + + bool createGroup(const QString &groupname); + bool removeGroup(const QString &groupname); + bool addContactToGroup( ItemListPtr items, const QString &groupname ); + bool removeContactToGroup( ItemListPtr items, const QString &groupname ); + bool removeContactToGroup( ItemListPtr items ); + +private: + static ContactInterface* instance; + ContactInterface(QObject *parent = 0); + +private: + ItemListPtr all_contacts_items; + ItemListPtr all_contacts_items_db; + Item current_contact_item; + QString current_uid; + QString current_fullname; + QString current_mobilenumber; + +#ifdef ONLY_FOR_EBOOK + OssoABookRoster *roster; +#endif + +Q_SIGNALS: + +public Q_SLOTS: + +}; + +#endif // CONTACTINTERFACE_H diff --git a/sms/contactpage.cpp b/sms/contactpage.cpp new file mode 100644 index 0000000..f7dae16 --- /dev/null +++ b/sms/contactpage.cpp @@ -0,0 +1,89 @@ +#include +#include + +#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* ContactPage::getSelectedContacts() +{ + return contactWidget->getSelectedContacts(); +} + +void ContactPage::onValidRecyele(bool valid) +{ + Q_EMIT validRecycle(valid); +} + +void ContactPage::removeSelectedContact() +{ + contactWidget->removeSelectedContact(); +} + +void ContactPage::setContactItemObserver() +{ + contactWidget->setItemObserver(); +} diff --git a/sms/contactpage.h b/sms/contactpage.h new file mode 100644 index 0000000..169a28a --- /dev/null +++ b/sms/contactpage.h @@ -0,0 +1,29 @@ +#ifndef CONTACTPAGE_H +#define CONTACTPAGE_H + +#include "abstractpage.h" + +class ContactPage : public AbstractPage +{ + Q_OBJECT +public: + ContactPage(QWidget* parent = 0); + + void updateSize(); + void update(); + void initContactWidget(); + void refreshContactList(); + void cleanSelectedContactList(); + void removeSelectedContact(); + void setContactItemObserver(); + QVector* getSelectedContacts(); + QString title(); + +Q_SIGNALS: + void validRecycle(bool valid); + +public Q_SLOTS: + void onValidRecyele(bool valid); +}; + +#endif // CONTACTPAGE_H diff --git a/sms/contactwidget.cpp b/sms/contactwidget.cpp new file mode 100644 index 0000000..6464865 --- /dev/null +++ b/sms/contactwidget.cpp @@ -0,0 +1,451 @@ +#include +#include + +#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; + contact_items_selected = new QVector; +} + +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(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(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(contact_items->at(i)))->reSet(); + }else + { + contact_items->at(i)->reSet(); + } + } +} + +void ContactWidget::update() +{ + update( contact_items ); +} + +void ContactWidget::update(QVector *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(item))->move(x, y, this); + if( (static_cast(item))->m_isOpenContactList ) + { + x += CONTACT_ITEM_MARGE_WIDTH; + group_open = true; + //qDebug() << "group open is true. x =" << x; + } + (static_cast(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(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(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(contact_items->at(i)))->group_name ) + { + group = (static_cast(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* ContactWidget::getSelectedContacts() +{ + return contact_items_selected; +} + +bool ContactWidget::isValidRecycle() +{ + if( contact_items_selected->size() > 0 ) + return true; + return false; +} + +void ContactWidget::removeSelectedContact() +{ + ItemListPtr list; + for( int i = 0; i < contact_items_selected->size(); i++ ) + { + ContactWidgetItem *contact = contact_items_selected->at(i); + if( contact->m_isGroup ) + { + continue; + } + + Item *item = new Item(); + item->uid = contact->uid; + item->full_name = contact->full_name; + item->mobile_number = contact->mobile_number; + item->group_owner = contact->group_owner; + + list.append(item); + } + ContactInterface::getInstance()->removeContactToGroup(list); + contact_items_selected->clear(); +} + + + + + + + + diff --git a/sms/contactwidget.h b/sms/contactwidget.h new file mode 100644 index 0000000..9a27ed4 --- /dev/null +++ b/sms/contactwidget.h @@ -0,0 +1,69 @@ +#ifndef CONTACTWIDGET_H +#define CONTACTWIDGET_H + +#include +#include + +#include +#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* getSelectedContacts(); + + void cleanSelectedContactList(); + + bool isValidRecycle(); + +protected: + void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); + void update( QVector* items ); + + void cleanContactList(); + + virtual void destroyContactWidget(); + + int findGroup(const QString &groupname); + + void checkGroupPartOfSelected(ContactWidgetItem* item); + +protected: + QVector *contact_items; + QVector *contact_items_selected; + + int last_height; + +Q_SIGNALS: + void validRecycle(bool valid); + +public Q_SLOTS: + void update(); + void contactItemSelected(ContactWidgetItem *item, bool selected); + void refreshContactList(); + void resetContacts(); +}; + +#endif // CONTACTWIDGET_H diff --git a/sms/contactwidgetitem.cpp b/sms/contactwidgetitem.cpp new file mode 100644 index 0000000..5ddb673 --- /dev/null +++ b/sms/contactwidgetitem.cpp @@ -0,0 +1,129 @@ +#include + +#include "contactwidgetitem.h" +#include "utility.h" + + +ContactWidgetItem::ContactWidgetItem(QObject *parent) : QObject(parent) +{ + btn_selected = new QToolButton(); + btn_selected->setText(""); + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); + btn_selected->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_selected->setAutoRaise(true); + + user_pic_uri = ":/images/male.png"; + label_fullname = new QLabel(); + label_mobile_number = new QLabel(); + label_user_pic = new QLabel(); + label_user_pic->setPixmap(Utility::getIconPixmap(user_pic_uri)); + + m_isSelected = false; + m_isGroup = false; + m_x = 0; + m_height = 0; + m_color.setRgb(255,0,0); + + connect(btn_selected, SIGNAL( clicked() ), this, SLOT( btn_selected_clicked() ) ); + + //qDebug() << "ContactWidgetItem" << (int)this; +} + +ContactWidgetItem::~ContactWidgetItem() +{ + //qDebug() << "~ContactWidgetItem" << (int)this; + delete btn_selected; + delete label_fullname; + delete label_mobile_number; + delete label_user_pic; +} + +void ContactWidgetItem::loadUserPic() +{ + QPixmap pixmap(user_pic_uri); + if (!pixmap.isNull()) { + label_user_pic->setPixmap(pixmap.scaled(ICON_SIZE, ICON_SIZE)); + } + label_user_pic->resize(ICON_SIZE, ICON_SIZE); +} + +void ContactWidgetItem::reSet() +{ + m_isSelected = false; + m_isGroup = false; + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); +} + +int ContactWidgetItem::move(int x, int y, QWidget *parent) +{ + //qDebug() << "ContactWidgetItem::move(int x, int y), Entry"; + //qDebug() << "x=" << x << "y=" << y << "screen_width=" << QApplication::desktop()->width(); + //int screen_width = QApplication::desktop()->width(); + m_x = x; + m_height = 0; + int _y = y; + + btn_selected->setParent(parent); + btn_selected->move( ( x + BTN_SELECTED_OFFSET_X ), ( _y + BTN_SELECTED_OFFSET_Y ) ); + //qDebug() << "btn_selected x=" << ( x + BTN_SELECTED_OFFSET_X ) << "btn_selected y=" << ( _y + BTN_SELECTED_OFFSET_Y ); + + label_user_pic->setParent(parent); + label_user_pic->move( ( x + USER_PIC_OFFSET_X ), ( _y + USER_PIC_OFFSET_Y ) ); + //qDebug() << "label_user_pic x=" << ( x + USER_PIC_OFFSET_X ) << "label_user_pic y=" << ( _y + USER_PIC_OFFSET_Y ); + + label_fullname->setParent(parent); + label_fullname->move( ( x + FULL_NAME_OFFSET_X ), ( _y + FULL_NAME_OFFSET_Y ) ); + //qDebug() << "label_fullname x=" << ( x + FULL_NAME_OFFSET_X ) << "label_fullname y=" << ( _y + FULL_NAME_OFFSET_Y ); + + label_mobile_number->setParent(parent); + label_mobile_number->move( ( x + MOBILE_NUMBER_OFFSET_X ), ( _y + MOBILE_NUMBER_OFFSET_Y ) ); + //qDebug() << "label_mobile_number x=" << ( x + MOBILE_NUMBER_OFFSET_X ) << "label_mobile_number y=" << ( _y + MOBILE_NUMBER_OFFSET_Y ); + + m_height = y + ITEM_HEIGHT; + //qDebug() << "m_height=" << m_height; + //qDebug() << "ContactWidgetItem::move(int x, int y), Exit"; + + return m_height; +} + +void ContactWidgetItem::showAll() +{ + btn_selected->show(); + label_fullname->show(); + label_mobile_number->show(); + label_user_pic->show(); +} + +void ContactWidgetItem::hideAll() +{ + btn_selected->hide(); + label_fullname->hide(); + label_mobile_number->hide(); + label_user_pic->hide(); +} + +void ContactWidgetItem::btn_selected_clicked() +{ + m_isSelected = !m_isSelected; + if( m_isSelected ) + { + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/select.png", true) ); + }else + { + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); + } + Q_EMIT itemSelected( this, m_isSelected ); + //qDebug() << "ContactWidgetItem::btn_selected_clicked(), Exit"; +} + +void ContactWidgetItem::setSelected(bool selected) +{ + if( selected ) + { + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/select.png", true) ); + }else + { + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); + } + //qDebug() << "ContactWidgetItem::setSelected(bool selected), Exit"; +} diff --git a/sms/contactwidgetitem.h b/sms/contactwidgetitem.h new file mode 100644 index 0000000..f589413 --- /dev/null +++ b/sms/contactwidgetitem.h @@ -0,0 +1,78 @@ +#ifndef CONTACTWIDGETITEM_H +#define CONTACTWIDGETITEM_H + +#include +#include +#include "item.h" + + +const int ICON_SIZE = 38; +const int MARGE_HEIGH = 4; +const int CONTACT_ITEM_MARGE_WIDTH = 50; +const int BTN_SELECTED_OFFSET_X = 10; +const int BTN_SELECTED_OFFSET_Y = 5; +const int USER_PIC_OFFSET_X = BTN_SELECTED_OFFSET_X + 80; +const int USER_PIC_OFFSET_Y = BTN_SELECTED_OFFSET_Y + 20; +const int FULL_NAME_OFFSET_X = USER_PIC_OFFSET_X + 50; +const int FULL_NAME_OFFSET_Y = 5; +const int MOBILE_NUMBER_OFFSET_X = FULL_NAME_OFFSET_X; +const int MOBILE_NUMBER_OFFSET_Y = FULL_NAME_OFFSET_Y + 30; + +const int BTN_SELECTED_MARGE_WIDTH = 130; + +// GroupWidgetItem +const int BTN_OPEN_GROUP_OFFSET_X = 10; +const int BTN_OPEN_GROUP_OFFSET_Y = 5; +const int BTN_GROUP_SELECTED_OFFSET_X = BTN_OPEN_GROUP_OFFSET_X + 60; +const int BTN_GROUP_SELECTED_OFFSET_Y = 5; +const int GROUP_USER_PIC_OFFSET_X = BTN_GROUP_SELECTED_OFFSET_X + 80; +const int GROUP_USER_PIC_OFFSET_Y = BTN_OPEN_GROUP_OFFSET_Y + 25; +const int GROUP_NAME_OFFSET_X = GROUP_USER_PIC_OFFSET_X + 50; +const int GROUP_NAME_OFFSET_Y = 20; + +const int ITEM_HEIGHT = 60; + +const int BTN_TOOL_WIDTH = 60; +const int BTN_TOOL_HEIGHT = 60; + +class ContactWidgetItem : public QObject +{ + Q_OBJECT +public: + ContactWidgetItem(QObject *parent = 0); + ~ContactWidgetItem(); + + void loadUserPic(); + int move(int x, int y, QWidget *parent = 0); + void showAll(); + void hideAll(); + void reSet(); + void setData( Item &item ); + void setSelected(bool selected); + + QToolButton *btn_selected; + QLabel *label_fullname; + QLabel *label_mobile_number; + QLabel *label_user_pic; + QString user_pic_uri; + + QString full_name; + QString mobile_number; + QString group_owner; + QString uid; + + int m_x; + int m_height; + bool m_isSelected; + bool m_isGroup; + QColor m_color; + +Q_SIGNALS: + void itemUpdate(); + void itemSelected( ContactWidgetItem *item, bool selected ); + +public Q_SLOTS: + void btn_selected_clicked(); +}; + +#endif // CONTACTWIDGETITEM_H diff --git a/sms/data/26x26/groupsms.png b/sms/data/26x26/groupsms.png new file mode 100644 index 0000000..ac1d101 Binary files /dev/null and b/sms/data/26x26/groupsms.png differ diff --git a/sms/data/40x40/groupsms.png b/sms/data/40x40/groupsms.png new file mode 100644 index 0000000..0f8a5af Binary files /dev/null and b/sms/data/40x40/groupsms.png differ diff --git a/sms/data/64x64/groupsms.png b/sms/data/64x64/groupsms.png new file mode 100644 index 0000000..0703ae3 Binary files /dev/null and b/sms/data/64x64/groupsms.png differ diff --git a/sms/data/icon.svg b/sms/data/icon.svg new file mode 100644 index 0000000..df7182e --- /dev/null +++ b/sms/data/icon.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/sms/data/maemo/groupsms.xpm b/sms/data/maemo/groupsms.xpm new file mode 100644 index 0000000..c3dfdb8 --- /dev/null +++ b/sms/data/maemo/groupsms.xpm @@ -0,0 +1,324 @@ +/* XPM */ +static char * qt4_xpm[] = { +"26 26 295 2", +" c None", +". c #85B623", +"+ c #425911", +"@ c #99D029", +"# c #9ED32C", +"$ c #98CF28", +"% c #92C826", +"& c #85B723", +"* c #7EAC21", +"= c #455D12", +"- c #9ED42E", +"; c #CEF24F", +"> c #CBF14B", +", c #C3EB43", +"' c #B8E43B", +") c #ADDD34", +"! c #A2D62E", +"~ c #95CB28", +"{ c #88BA24", +"] c #80AF22", +"^ c #36490E", +"/ c #A4D735", +"( c #CDF05D", +"_ c #CDF05B", +": c #CDF158", +"< c #CEF156", +"[ c #CEF253", +"} c #CFF350", +"| c #CDF14B", +"1 c #B7E33B", +"2 c #AADC33", +"3 c #9CD02B", +"4 c #8ABD25", +"5 c #82B222", +"6 c #A6D83B", +"7 c #CAED66", +"8 c #CBED64", +"9 c #CBEE63", +"0 c #CCEE62", +"a c #CEF062", +"b c #D1F163", +"c c #D3F363", +"d c #D4F361", +"e c #D3F35D", +"f c #D1F357", +"g c #CFF250", +"h c #C8EF49", +"i c #BCE73F", +"j c #ADDD35", +"k c #84B424", +"l c #A6D73E", +"m c #C7EA6B", +"n c #C9EB6A", +"o c #CCED6C", +"p c #D2EF71", +"q c #CDE771", +"r c #B4CE67", +"s c #AAC661", +"t c #AFCB60", +"u c #C3E066", +"v c #D3F167", +"w c #CEF05F", +"x c #CCEF5A", +"y c #C4E653", +"z c #5C6C33", +"A c #3B2A55", +"B c #9360E4", +"C c #8858D0", +"D c #A5D63E", +"E c #C2E66C", +"F c #C4E76C", +"G c #C8E970", +"H c #D0ED76", +"I c #B7CC74", +"J c #92A56E", +"K c #93A670", +"L c #93A86E", +"M c #93A96B", +"N c #91A967", +"O c #A6BF68", +"P c #CDEB6E", +"Q c #C1E062", +"R c #889A4E", +"S c #3F3152", +"T c #8861C7", +"U c #A675F3", +"V c #9367D7", +"W c #A3D53D", +"X c #BEE36B", +"Y c #C0E46D", +"Z c #C9E973", +"` c #B9CE77", +" . c #929D7D", +".. c #95A080", +"+. c #9BAA77", +"@. c #B3C877", +"#. c #B6CA77", +"$. c #A0B175", +"%. c #94A378", +"&. c #A1B471", +"*. c #9FB75C", +"=. c #534660", +"-. c #785CA4", +";. c #9772D2", +">. c #AB82EC", +",. c #9E78D9", +"'. c #A1D43B", +"). c #B8DF65", +"!. c #BEE269", +"~. c #C8E573", +"{. c #939C80", +"]. c #9AA08F", +"^. c #A0AF7A", +"/. c #C9E674", +"(. c #C7E771", +"_. c #CBEA75", +":. c #CFE77A", +"<. c #AAB97B", +"[. c #858D77", +"}. c #645C69", +"|. c #705794", +"1. c #B593EB", +"2. c #432F65", +"3. c #B694EC", +"4. c #A98ADA", +"5. c #9ED337", +"6. c #B2DC5C", +"7. c #BBE163", +"8. c #AEC36E", +"9. c #989B93", +"0. c #939887", +"a. c #C0DE6C", +"b. c #BBE164", +"c. c #BEE267", +"d. c #B6CE70", +"e. c #8C9478", +"f. c #BCD36F", +"g. c #6B715D", +"h. c #442E66", +"i. c #AC92D6", +"j. c #AE95D8", +"k. c #766099", +"l. c #C7ACF3", +"m. c #C0A7EA", +"n. c #9BD131", +"o. c #ABD84F", +"p. c #B7DF59", +"q. c #95A467", +"r. c #8E8F8C", +"s. c #93A06F", +"t. c #B9E05B", +"u. c #B5DE58", +"v. c #B3D062", +"w. c #878B7D", +"x. c #848781", +"y. c #99B05A", +"z. c #646F42", +"A. c #271449", +"B. c #B8A3DB", +"C. c #D5C1F7", +"D. c #D4C0F6", +"E. c #D7C3F9", +"F. c #D3BFF4", +"G. c #98CF2A", +"H. c #A3D53E", +"I. c #B2DC49", +"J. c #808C57", +"K. c #7B7B7B", +"L. c #8C9D59", +"M. c #B3DD4A", +"N. c #AED24D", +"O. c #727763", +"P. c #808180", +"Q. c #879262", +"R. c #ACD149", +"S. c #71813E", +"T. c #363635", +"U. c #434E2A", +"V. c #312446", +"W. c #38205F", +"X. c #DCCAF6", +"Y. c #C8BBDE", +"Z. c #97CF28", +"`. c #9BD12B", +" + c #AAD937", +".+ c #758542", +"++ c #636363", +"@+ c #768547", +"#+ c #B1D83F", +"$+ c #5B633F", +"%+ c #5F5F5F", +"&+ c #626262", +"*+ c #5C5D5A", +"=+ c #94AF3F", +"-+ c #7A8B40", +";+ c #4E5143", +">+ c #6B8C20", +",+ c #38441E", +"'+ c #351F58", +")+ c #C3B6D6", +"!+ c #A6D733", +"~+ c #869E3B", +"{+ c #515151", +"]+ c #515543", +"^+ c #B4D544", +"/+ c #545C39", +"(+ c #575E3E", +"_+ c #97AF43", +":+ c #4E4F4B", +"<+ c #505247", +"[+ c #595D46", +"}+ c #616D40", +"|+ c #8FBE29", +"1+ c #668B1B", +"2+ c #98D028", +"3+ c #A0D42F", +"4+ c #AAD13C", +"5+ c #41423B", +"6+ c #454545", +"7+ c #75853B", +"8+ c #B2D443", +"9+ c #A5CA3B", +"0+ c #B5DF3E", +"a+ c #8CA13F", +"b+ c #464645", +"c+ c #474747", +"d+ c #849E3A", +"e+ c #9ACF2B", +"f+ c #7FAF22", +"g+ c #36480E", +"h+ c #AAD936", +"i+ c #758935", +"j+ c #373737", +"k+ c #353534", +"l+ c #5A6630", +"m+ c #90AC38", +"n+ c #93B038", +"o+ c #647131", +"p+ c #323332", +"q+ c #313131", +"r+ c #526227", +"s+ c #9CD12B", +"t+ c #84B523", +"u+ c #35470E", +"v+ c #98D029", +"w+ c #9FD32E", +"x+ c #AED93A", +"y+ c #5D6C2C", +"z+ c #252525", +"A+ c #202020", +"B+ c #1E1E1E", +"C+ c #1D1D1D", +"D+ c #363C21", +"E+ c #4D5924", +"F+ c #759429", +"G+ c #9AD02A", +"H+ c #33450D", +"I+ c #ADDA39", +"J+ c #84A131", +"K+ c #46521F", +"L+ c #2D3417", +"M+ c #363F19", +"N+ c #677D26", +"O+ c #A6D137", +"P+ c #A4D333", +"Q+ c #9ED22D", +"R+ c #81B122", +"S+ c #33440D", +"T+ c #9DD22C", +"U+ c #A4D631", +"V+ c #ACDA38", +"W+ c #A9D835", +"X+ c #A1D430", +"Y+ c #9BD12A", +"Z+ c #7AA820", +"`+ c #9AD12A", +" @ c #8EC326", +".@ c #77A21F", +"+@ c #5D8019", +"@@ c #2A380B", +"#@ c #96CE28", +"$@ c #8BBF25", +"%@ c #719A1E", +"&@ c #547316", +"*@ c #2F410D", +"=@ c #405711", +"-@ c #95CD28", +";@ c #87B924", +">@ c #6B931C", +",@ c #4E6B15", +"'@ c #28370B", +")@ c #2E3F0C", +"!@ c #678D1B", +"~@ c #486213", +"{@ c #202C08", +" ", +" . ", +" + @ # $ % & * ", +" = - ; > , ' ) ! ~ { ] ", +" ^ = / ( _ : < [ } | , 1 2 3 4 5 ", +" ^ = 6 7 8 9 0 a b c d e f g h i j k ", +" ^ = l m m n o p q r s t u v w x y z A B C ", +" ^ = D E F G H I J K L M N O P Q R S T U V ", +" ^ = W X Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,. ", +" ^ = '.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4. ", +" ^ = 5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m. ", +" ^ = n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F. ", +" ^ = G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y. ", +" ^ = Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+ ", +" ^ = Z.@ !+~+{+]+^+/+(+_+:+<+[+}+|+1+ ", +" ^ = Z.2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+ ", +" g+= Z.Z.`.h+i+j+k+l+m+n+o+p+q+r+s+t+ ", +" u+= Z.Z.v+w+x+y+z+z+A+B+C+D+E+F+G+t+ ", +" H+= Z.Z.Z.@ 3+I+J+K+L+M+N+O+P+Q+Z.R+ ", +" S+= Z.Z.Z.Z.@ T+U+h+V+W+X+Y+@ Z.Z.Z+ ", +" S+= Z.Z.Z.Z.Z.$ @ G+`+@ $ Z. @.@+@ ", +" @@= Z.Z.Z.Z.Z.Z.Z.#@$@%@&@*@ ", +" =@Z.Z.Z.-@;@>@,@'@ ", +" )@t+!@~@{@ ", +" ", +" "}; diff --git a/sms/groupsms.desktop b/sms/groupsms.desktop new file mode 100644 index 0000000..b0c67eb --- /dev/null +++ b/sms/groupsms.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=0.1 +Type=Application +Name=Group SMS +Exec=/usr/bin/groupsms +Icon=groupsms +StartupWMClass=groupsms +X-Window-Icon=groupsms +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable +Terminal=false + diff --git a/sms/groupsms.qrc b/sms/groupsms.qrc new file mode 100644 index 0000000..430b3cc --- /dev/null +++ b/sms/groupsms.qrc @@ -0,0 +1,16 @@ + + + images/addcontacttogroup.png + images/female.png + images/male.png + images/newgroup.png + images/editgroup.png + images/plus.png + images/sub.png + images/recycle.png + images/select.png + images/allselect.png + images/unselect.png + images/partselect.png + + diff --git a/sms/groupwidgetitem.cpp b/sms/groupwidgetitem.cpp new file mode 100644 index 0000000..e7f3e67 --- /dev/null +++ b/sms/groupwidgetitem.cpp @@ -0,0 +1,110 @@ +#include "groupwidgetitem.h" +#include "utility.h" + +GroupWidgetItem::GroupWidgetItem(QObject *parent) + : ContactWidgetItem(parent) +{ + btn_selected = new QToolButton(); + btn_selected->setText(""); + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); + btn_selected->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_selected->setAutoRaise(true); + btn_selected->adjustSize(); + + btn_open_group = new QToolButton(); + btn_open_group->setText(""); + btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) ); + btn_open_group->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_open_group->setAutoRaise(true); + btn_open_group->adjustSize(); + + label_group_name = new QLabel(); + + + m_isSelected = false; + m_isOpenContactList = false; + m_isGroup = true; + + m_x = 0; + m_height = 0; + + connect( btn_open_group, SIGNAL( clicked() ), this, SLOT( btn_open_group_clicked() ) ); + connect(btn_selected, SIGNAL( clicked() ), this, SLOT( btn_selected_clicked() ) ); + //qDebug() << "GroupWidgetItem::GroupWidgetItem(QObject *parent), Exit" << (int)this; +} + +GroupWidgetItem::~GroupWidgetItem() +{ + //qDebug() << "GroupWidgetItem::~GroupWidgetItem()" << (int)this; + delete btn_open_group; + delete label_group_name; +} + +int GroupWidgetItem::move(int x, int y, QWidget *parent) +{ + //qDebug() << "GroupWidgetItem::move(int x, int y), Entry"; + m_x = x; + m_height = 0; + int _y = y; + + btn_open_group->setParent(parent); + btn_open_group->move( ( x + BTN_OPEN_GROUP_OFFSET_X ), ( _y + BTN_OPEN_GROUP_OFFSET_Y ) ); + //qDebug() << "btn_open_group x=" << ( x + BTN_OPEN_GROUP_OFFSET_X ) << "btn_open_group y=" << ( _y + BTN_OPEN_GROUP_OFFSET_Y ); + + btn_selected->setParent(parent); + btn_selected->move( ( x + BTN_GROUP_SELECTED_OFFSET_X ), ( _y + BTN_GROUP_SELECTED_OFFSET_Y ) ); + //qDebug() << "btn_selected x=" << ( x + BTN_GROUP_SELECTED_OFFSET_X ) << "btn_selected y=" << ( _y + BTN_GROUP_SELECTED_OFFSET_Y ); + + label_user_pic->setParent(parent); + label_user_pic->move( ( x + GROUP_USER_PIC_OFFSET_X ), ( _y + GROUP_USER_PIC_OFFSET_Y ) ); + //qDebug() << "label_user_pic x=" << ( x + GROUP_USER_PIC_OFFSET_X ) << "label_user_pic y=" << ( _y + GROUP_USER_PIC_OFFSET_Y ); + + label_group_name->setParent(parent); + label_group_name->move( ( x + GROUP_NAME_OFFSET_X ), ( _y + GROUP_NAME_OFFSET_Y ) ); + //qDebug() << "label_fullname x=" << ( x + GROUP_NAME_OFFSET_X ) << "label_fullname y=" << ( _y + GROUP_NAME_OFFSET_Y ); + + m_height = y + ITEM_HEIGHT; + + showAll(); + + //qDebug() << "m_height=" << m_height; + //qDebug() << "GroupWidgetItem::move(int x, int y), Exit"; + + return m_height; +} + +void GroupWidgetItem::reSet() +{ + m_isSelected = false; + m_isGroup = true; + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/unselect.png", true) ); + btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) ); +} + +void GroupWidgetItem::btn_open_group_clicked() +{ + //qDebug() << "GroupWidgetItem::btn_open_group_clicked(), Entry"; + m_isOpenContactList = !m_isOpenContactList; + if( m_isOpenContactList ) + { + btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/sub.png", true) ); + }else + { + btn_open_group->setIcon( Utility::getToolButtonIcon(":/images/plus.png", true) ); + } + Q_EMIT itemUpdate(); + //qDebug() << "GroupWidgetItem::btn_open_group_clicked(), Exit" << (int)this; +} + +void GroupWidgetItem::showAll() +{ + btn_selected->show(); + btn_open_group->show(); + label_group_name->show(); + label_user_pic->show(); +} + +void GroupWidgetItem::partOfAllSeleted() +{ + btn_selected->setIcon( Utility::getToolButtonIcon(":/images/partselect.png", true) ); +} diff --git a/sms/groupwidgetitem.h b/sms/groupwidgetitem.h new file mode 100644 index 0000000..48b8ff9 --- /dev/null +++ b/sms/groupwidgetitem.h @@ -0,0 +1,31 @@ +#ifndef GROUPWIDGETITEM_H +#define GROUPWIDGETITEM_H + +#include +#include + +#include "contactwidgetitem.h" + +class GroupWidgetItem : public ContactWidgetItem +{ + Q_OBJECT +public: + GroupWidgetItem(QObject *parent = 0); + ~GroupWidgetItem(); + + int move(int x, int y, QWidget *parent = 0); + void showAll(); + void reSet(); + void partOfAllSeleted(); + + QToolButton *btn_open_group; + QLabel *label_group_name; + QString group_name; + + bool m_isOpenContactList; + +public Q_SLOTS: + void btn_open_group_clicked(); +}; + +#endif // GROUPWIDGETITEM_H diff --git a/sms/images/addcontacttogroup.png b/sms/images/addcontacttogroup.png new file mode 100644 index 0000000..1bc6a20 Binary files /dev/null and b/sms/images/addcontacttogroup.png differ diff --git a/sms/images/allselect.png b/sms/images/allselect.png new file mode 100644 index 0000000..c33da34 Binary files /dev/null and b/sms/images/allselect.png differ diff --git a/sms/images/editgroup.png b/sms/images/editgroup.png new file mode 100644 index 0000000..9dd67ec Binary files /dev/null and b/sms/images/editgroup.png differ diff --git a/sms/images/female.png b/sms/images/female.png new file mode 100644 index 0000000..033f663 Binary files /dev/null and b/sms/images/female.png differ diff --git a/sms/images/male.png b/sms/images/male.png new file mode 100644 index 0000000..6172757 Binary files /dev/null and b/sms/images/male.png differ diff --git a/sms/images/newgroup.png b/sms/images/newgroup.png new file mode 100644 index 0000000..0e02c8a Binary files /dev/null and b/sms/images/newgroup.png differ diff --git a/sms/images/partselect.png b/sms/images/partselect.png new file mode 100644 index 0000000..f729984 Binary files /dev/null and b/sms/images/partselect.png differ diff --git a/sms/images/plus.png b/sms/images/plus.png new file mode 100644 index 0000000..754ee70 Binary files /dev/null and b/sms/images/plus.png differ diff --git a/sms/images/recycle.png b/sms/images/recycle.png new file mode 100644 index 0000000..c3b6025 Binary files /dev/null and b/sms/images/recycle.png differ diff --git a/sms/images/select.png b/sms/images/select.png new file mode 100644 index 0000000..c33da34 Binary files /dev/null and b/sms/images/select.png differ diff --git a/sms/images/sub.png b/sms/images/sub.png new file mode 100644 index 0000000..e1ce919 Binary files /dev/null and b/sms/images/sub.png differ diff --git a/sms/images/unselect.png b/sms/images/unselect.png new file mode 100644 index 0000000..b01ce5f Binary files /dev/null and b/sms/images/unselect.png differ diff --git a/sms/item.h b/sms/item.h new file mode 100644 index 0000000..51b3516 --- /dev/null +++ b/sms/item.h @@ -0,0 +1,27 @@ +#ifndef ITEM_H +#define ITEM_H + +#include +#include + +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 ItemList; +typedef QList ItemListPtr; +Q_DECLARE_METATYPE(Item) +Q_DECLARE_METATYPE(ItemList) +Q_DECLARE_METATYPE(ItemListPtr) + +#endif // ITEM_H diff --git a/sms/itemobserver.h b/sms/itemobserver.h new file mode 100644 index 0000000..1cea9f9 --- /dev/null +++ b/sms/itemobserver.h @@ -0,0 +1,26 @@ +#ifndef ITEMOBSERVER_H +#define ITEMOBSERVER_H + +#include +#include "item.h" + +class ItemObserver +{ +public: + virtual void addGroup( Item *item ) = 0; + virtual void addContact( ItemList items, const QString &groupname ) = 0; + virtual void addContact( ItemListPtr items, const QString &groupname ) = 0; + virtual void addContact( Item *item, const QString &groupname ) = 0; + virtual void addContact( Item *item) = 0; + virtual void removeContact(Item *contact) = 0; + virtual void removeAllContacts() = 0; + virtual void refreshContactsList() = 0; +}; + +class ItemSelectObserver +{ +public: + virtual void getGroupContacts( ItemListPtr items ) = 0; +}; + +#endif // ITEMOBSERVER_H diff --git a/sms/main.cpp b/sms/main.cpp new file mode 100644 index 0000000..5b0df3d --- /dev/null +++ b/sms/main.cpp @@ -0,0 +1,56 @@ +#include +#include "mainwindow.h" +#include "contactinterface.h" +#include "common.h" +#include "item.h" + +#ifdef ONLY_FOR_EBOOK + +#include + +#endif + +static void registerTypes() +{ + static bool registered = false; + if( !registered ) + { + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + registered = true; + } +} + +int main(int argc, char *argv[]) +{ +#ifdef ONLY_FOR_EBOOK +// gtk_init( &argc, &argv ); + + /* Initialize the osso context */ + osso_context_t *osso_context = osso_initialize( "GroupSMS", "1.0", TRUE, NULL ); + if( !osso_context ) + { + //qDebug() << "Couldn't initialize osso context"; + return false; + } + + /* Initialize abook, which also initializes all the + * libraries it needs (GTK+, Galago, Gnome-VFS) */ + osso_abook_init( &argc, &argv, osso_context); +#endif + + QDir dir( QDir::homePath() ); + dir.mkdir( HOME_DIR ); + + QApplication a(argc, argv); + + registerTypes(); + +#if defined(Q_WS_S60) + MainWindow::getInstance()->show(); +#else + MainWindow::getInstance()->show(); +#endif + return a.exec(); +} diff --git a/sms/mainwindow.cpp b/sms/mainwindow.cpp new file mode 100644 index 0000000..4471e01 --- /dev/null +++ b/sms/mainwindow.cpp @@ -0,0 +1,303 @@ +#include "mainwindow.h" +#include "newgroupdialog.h" +#include "addcontacttogroup.h" +#include "contactinterface.h" +#include "common.h" +#include "ui_mainwindow.h" +#include "utility.h" + +#ifdef ONLY_FOR_TELEPATHYQT4 +#include "tpsession/tpsession.h" +#endif + +MainWindow* MainWindow::instance = 0; + +MainWindow* MainWindow::getInstance() +{ + if (!instance) { + instance = new MainWindow(); + } + return instance; +} + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + instance = this; + + ui->setupUi(this); + init(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::changeEvent(QEvent *e) +{ + //qDebug() << "MainWindow::changeEvent(QEvent *e)"; + + QMainWindow::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void MainWindow::init() +{ + //qDebug() << "MainWindow::init()"; + + ui->btn_send_message->setDisabled(true); + ui->textEdit_phone_numbers->setReadOnly(true); + connect( ui->textEdit_message, SIGNAL( textChanged() ), this, SLOT( send_message_enabled() ) ); + connect( ui->textEdit_phone_numbers, SIGNAL( textChanged() ), this, SLOT( send_message_enabled() ) ); + connect( ui->btn_send_to, SIGNAL( clicked() ), this, SLOT( send_to_clicked() ) ); + connect( ui->btn_send_message, SIGNAL( clicked() ), this, SLOT( send_message_clicked() ) ); + connect( ui->btn_cancel, SIGNAL( clicked() ), this, SLOT( cancel_clicked() ) ); + + hbox_layout = new QHBoxLayout(this); + + btn_new_group = new QToolButton(this); + btn_new_group->setToolTip( tr("new group") ); + btn_new_group->setText(""); + btn_new_group->setIcon(Utility::getToolButtonIcon(":/images/newgroup.png", true)); + btn_new_group->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_new_group->setAutoRaise(true); + btn_new_group->show(); + connect( btn_new_group, SIGNAL( clicked() ), this, SLOT( new_group() ) ); + + + btn_add_contact_to_group = new QToolButton(this); + btn_add_contact_to_group->setToolTip( tr("add contact to group") ); + btn_add_contact_to_group->setText(""); + btn_add_contact_to_group->setIcon(Utility::getToolButtonIcon(":/images/addcontacttogroup.png", true)); + btn_add_contact_to_group->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_add_contact_to_group->setAutoRaise(true); + btn_add_contact_to_group->show(); + connect( btn_add_contact_to_group, SIGNAL( clicked() ), this, SLOT( add_contact_to_group() ) ); + + btn_delete_contact = new QToolButton(this); + btn_delete_contact->setToolTip( tr("delete contacts") ); + btn_delete_contact->setText(""); + btn_delete_contact->setIcon(Utility::getToolButtonIcon(":/images/recycle.png")); + btn_delete_contact->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_delete_contact->setAutoRaise(true); + btn_delete_contact->setDisabled(true); + btn_delete_contact->show(); + connect( btn_delete_contact, SIGNAL(clicked()), this, SLOT(removeSelectedContact()) ); + +// btn_delete_group = new QToolButton(this); +// btn_delete_group->setToolTip( tr("delete group") ); +// btn_delete_group->setText(""); +// btn_delete_group->setIcon(Utility::getToolButtonIcon(":/images/recycle.png")); +// btn_delete_group->setToolButtonStyle(Qt::ToolButtonIconOnly); +// btn_delete_group->setAutoRaise(true); +// btn_delete_group->show(); + + btn_sync_contacts = new QToolButton(this); + btn_sync_contacts->setToolTip( tr("sync contacts") ); + btn_sync_contacts->setText(""); + btn_sync_contacts->setIcon(Utility::getToolButtonIcon(":/images/editgroup.png", true)); + btn_sync_contacts->setToolButtonStyle(Qt::ToolButtonIconOnly); + btn_sync_contacts->setAutoRaise(true); + btn_sync_contacts->show(); + connect( btn_sync_contacts, SIGNAL( clicked() ), this, SLOT( sync_contacts() ) ); + + hbox_layout->addWidget( btn_new_group ); + hbox_layout->addWidget( btn_add_contact_to_group ); + hbox_layout->addWidget( btn_delete_contact ); +// hbox_layout->addWidget( btn_delete_group ); + hbox_layout->addWidget( btn_sync_contacts ); + + ui->groupBox->setTitle(""); + ui->groupBox->setLayout( hbox_layout ); + ui->groupBox->setEnabled(true); + + contactPage = new ContactPage(this); + ui->tabWidget->insertTab(0, contactPage, contactPage->title()); + ui->tabWidget->setCurrentIndex(0); + connect( ui->tabWidget, SIGNAL( currentChanged(int) ), this, SLOT( tab_changed(int) ) ); + connect( contactPage, SIGNAL( validRecycle(bool) ), this, SLOT( onValidRecyele(bool) ) ); + + ui->vLayout_main->setAlignment(Qt::AlignCenter); + ui->sendSMS_tab->setLayout(ui->vLayout_main); + + QString filename( HOME_DIR + "/group.xml" ); + QFileInfo fileinfo(filename); + if( !fileinfo.exists() ) + { + XmlControler::getInstance()->newXml( filename ); +#ifdef ONLY_FOR_EBOOK + contactPage->setContactItemObserver(); + ContactInterface::getInstance()->updateContactsFromEbookToXml(); +#endif + }else + { + XmlControler::getInstance()->readXml( filename ); + // for test xmlcontroler +// XmlControler::getInstance()->createGroup( "second_group" ); +// XmlControler::getInstance()->createContact( "second_group", new ContactWidgetItem); +// XmlControler::getInstance()->createGroup( "one_group" ); +// XmlControler::getInstance()->removeContact( "one_group", NULL); +// XmlControler::getInstance()->removeGroup( "one_group" ); + } + contactPage->initContactWidget(); + contactPage->update(); + + //qDebug() << "new SendSMSSession"; +#ifdef ONLY_FOR_TELEPATHYQT4 + sendSMS = new SendSMSSession( false, this ); + connect( sendSMS, SIGNAL( smsSent(QString) ), this, SLOT( onSMSSent(QString) ) ); +#endif +} + +void MainWindow::onSMSSent(QString msg) +{ + Q_UNUSED( msg ) + //qDebug() << "MainWindow::onSMSSent" << msg << "OK"; +} + +void MainWindow::setSendToText(QVector *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 *contacts = contactPage->getSelectedContacts(); + QStringList addrs; + QStringList msgs; + for( int i = 0; i < contacts->size(); i++ ) + { + //qDebug() << " send sms:" << txt << "to" << contacts->at(i)->mobile_number; + addrs.append( contacts->at(i)->mobile_number ); + msgs.append( txt ); + + } + sendSMS->setSMSToSend( addrs, msgs ); +#endif + // for test +// TpSession *tps =new TpSession("ring",true); +// tps->sendMessageToAddress("ring",contacts->at(0)->mobile_number,txt); + } + cancel_clicked(); +} + +void MainWindow::send_message_enabled() +{ + //qDebug() << "MainWindow::send_message_enabled()"; + + QTextDocument *doc_phone_number = ui->textEdit_phone_numbers->document(); + QTextDocument *doc_message = ui->textEdit_message->document(); + if( !doc_message->isEmpty() && !doc_phone_number->isEmpty() ) + { + ui->btn_send_message->setEnabled(true); + }else + { + ui->btn_send_message->setDisabled(true); + } +} + +void MainWindow::new_group() +{ + //qDebug() << "MainWindow::new_group()"; + + NewGroupDialog dlg; + int result = dlg.exec(); + if( result == QDialog::Accepted ) + { + //qDebug() << "new group is ok"; + } +} + +void MainWindow::add_contact_to_group() +{ + //qDebug() << "MainWindow::add_contact_to_group()"; + AddContactToGroup dlg; + int result = dlg.exec(); + if( result == QDialog::Accepted ) + { + //qDebug() << "add contact is ok"; + } +} + +void MainWindow::onValidRecyele(bool valid) +{ + if( valid ) + { + btn_delete_contact->setEnabled(true); + }else + { + btn_delete_contact->setDisabled(true); + } +} + +void MainWindow::removeSelectedContact() +{ + //TODO : add confirm dialog + QMessageBox msgBox; + msgBox.setText("Do you want to delete that's selected contacts?"); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + int ret = msgBox.exec(); + if( ret == QDialog::Accepted ) + { + contactPage->removeSelectedContact(); + } +} diff --git a/sms/mainwindow.h b/sms/mainwindow.h new file mode 100644 index 0000000..cc6ca92 --- /dev/null +++ b/sms/mainwindow.h @@ -0,0 +1,74 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include + +#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* contacts); + +private: + Ui::MainWindow *ui; + + QHBoxLayout *hbox_layout; + + QToolButton *btn_new_group; + QToolButton *btn_add_contact_to_group; + QToolButton *btn_delete_contact; + QToolButton *btn_delete_group; + QToolButton *btn_sync_contacts; + + ContactPage *contactPage; + +#ifdef ONLY_FOR_TELEPATHYQT4 + SendSMSSession *sendSMS; +#endif + + QStringList name_list; +}; + +#endif // MAINWINDOW_H diff --git a/sms/mainwindow.ui b/sms/mainwindow.ui new file mode 100644 index 0000000..64abb67 --- /dev/null +++ b/sms/mainwindow.ui @@ -0,0 +1,133 @@ + + + MainWindow + + + + 0 + 0 + 800 + 480 + + + + GroupSMS + + + + + + + 0 + + + + SendSMS + + + + + 20 + 20 + 571 + 331 + + + + + + + Qt::Vertical + + + + 20 + 5 + + + + + + + + + + Send To: + + + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + + + + + + + Send + + + + + + + Cancel + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 779 + 20 + + + + + + + + GroupBox + + + + + + + + + + diff --git a/sms/newgroupdialog.cpp b/sms/newgroupdialog.cpp new file mode 100644 index 0000000..b2be83c --- /dev/null +++ b/sms/newgroupdialog.cpp @@ -0,0 +1,42 @@ +#include + +#include "newgroupdialog.h" +#include "contactinterface.h" + +NewGroupDialog::NewGroupDialog(QDialog *parent) : + QDialog(parent) +{ + setupUi(this); + setWindowModality( Qt::ApplicationModal ); + btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setDisabled(true); + groupNmaeEdit->setFocus(); + + connect( btngroup_ok_cancel, SIGNAL( clicked(QAbstractButton*) ), this, SLOT( btn_clicked(QAbstractButton*) ) ); + connect( groupNmaeEdit, SIGNAL( textEdited(QString) ), this, SLOT( btn_ok_enabled(QString) ) ); +} + +void NewGroupDialog::btn_clicked(QAbstractButton *button) +{ + if( QDialogButtonBox::AcceptRole == btngroup_ok_cancel->buttonRole( button ) ) + { + //qDebug() << "new group dialog : new group is" << groupNmaeEdit->text(); + + QString str = groupNmaeEdit->text(); + ContactInterface::getInstance()->createGroup( str ); + done( QDialog::Accepted ); + }else // button cancel + { + done( QDialog::Rejected ); + } +} + +void NewGroupDialog::btn_ok_enabled(QString str) +{ + if( str.length() > 0 ) + { + btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setEnabled(true); + }else + { + btngroup_ok_cancel->button(QDialogButtonBox::Ok)->setDisabled(true); + } +} diff --git a/sms/newgroupdialog.h b/sms/newgroupdialog.h new file mode 100644 index 0000000..77517bc --- /dev/null +++ b/sms/newgroupdialog.h @@ -0,0 +1,19 @@ +#ifndef NEWGROUPDIALOG_H +#define NEWGROUPDIALOG_H + +#include +#include "ui_newgroupdialog.h" + + +class NewGroupDialog : public QDialog, Ui::NewGroupDialog +{ + Q_OBJECT +public: + NewGroupDialog(QDialog *parent = 0); + +public Q_SLOTS: + void btn_clicked(QAbstractButton * button); + void btn_ok_enabled(QString str); +}; + +#endif // NEWGROUPDIALOG_H diff --git a/sms/newgroupdialog.ui b/sms/newgroupdialog.ui new file mode 100644 index 0000000..0a23ddb --- /dev/null +++ b/sms/newgroupdialog.ui @@ -0,0 +1,97 @@ + + + NewGroupDialog + + + + 0 + 0 + 400 + 102 + + + + Dialog + + + + + 300 + 30 + 81 + 61 + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 30 + 30 + 261 + 61 + + + + + + + 110 + 0 + 151 + 31 + + + + + AlArabiya + 14 + + + + New Group Name + + + + + + + btngroup_ok_cancel + accepted() + NewGroupDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + btngroup_ok_cancel + rejected() + NewGroupDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sms/selectcontactwidget.cpp b/sms/selectcontactwidget.cpp new file mode 100644 index 0000000..5fef9a0 --- /dev/null +++ b/sms/selectcontactwidget.cpp @@ -0,0 +1,89 @@ +#include "selectcontactwidget.h" +#include "contactinterface.h" +#include "xmlstring.h" + +SelectContactWidget::SelectContactWidget( QWidget *parent ) : + ContactWidget( parent ) +{ + //qDebug() << "SelectContactWidget::SelectContactWidget(QWidget *parent), Entry"; +} + +SelectContactWidget::~SelectContactWidget() +{ + //qDebug() << "SelectContactWidget::~SelectContactWidget(), Entry"; +} + +void SelectContactWidget::initContactWidget() +{ + //qDebug() << "SelectContactWidget::initContactWidget(), Entry"; + + ContactInterface::getInstance()->setItemSelectObserver(this); + ContactInterface::getInstance()->getAllContactsFromXml( STR_XML_ALLCONTACTS ); + + for (int i = 0; i < contact_items->size(); ++i) + { + connect( contact_items->at(i), SIGNAL( itemUpdate() ), this, SLOT( update() ) ); + connect( contact_items->at(i), SIGNAL( itemSelected( ContactWidgetItem*, bool) ), this, SLOT( contactItemSelected( ContactWidgetItem*, bool ) ) ); + } +} + +void SelectContactWidget::destroyContactWidget() +{ + //qDebug() << "SelectContactWidget::destroyContactWidget(), Entry"; +} + +void SelectContactWidget::getGroupContacts( ItemListPtr items ) +{ + for( int i = 0; i < items.size(); i++ ) + { + Item *item = items.at(i); + + if( item->m_isGroup ) + { + GroupWidgetItem *contact = new GroupWidgetItem(this); + + contact->label_group_name->setText( item->group_name ); + contact->group_name = item->group_name; + + contact_items->append( contact ); + }else + { + ContactWidgetItem *contact = new ContactWidgetItem(this); + + contact->label_fullname->setText( item->full_name ); + contact->full_name = item->full_name; + + contact->label_mobile_number->setText( item->mobile_number ); + contact->mobile_number = item->mobile_number; + + contact->group_owner = item->group_owner; + + contact->uid = item->uid; + + contact_items->append( contact ); + } + } +} + +QVector* SelectContactWidget::getSelectedContacts() +{ + return contact_items_selected; +} + +void SelectContactWidget::addContactsToGroup(const QString &groupname) +{ + //qDebug() << "SelectContactWidget::addContactsToGroup(const QString &groupname)"; + ItemListPtr list; + for( int i = 0; i < contact_items_selected->size(); i++ ) + { + ContactWidgetItem *contact = contact_items_selected->at(i); + Item *item = new Item(); + item->full_name = contact->full_name; + item->mobile_number = contact->mobile_number; + item->group_owner = groupname; + item->uid = contact->uid; + + list.append(item); + } + ContactInterface::getInstance()->addContactToGroup(list, groupname); +} diff --git a/sms/selectcontactwidget.h b/sms/selectcontactwidget.h new file mode 100644 index 0000000..49b9a15 --- /dev/null +++ b/sms/selectcontactwidget.h @@ -0,0 +1,28 @@ +#ifndef SELECTCONTACTWIDGET_H +#define SELECTCONTACTWIDGET_H + +#include +#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* getSelectedContacts(); + + void addContactsToGroup(const QString &groupname); + +protected: + void destroyContactWidget(); + +}; + +#endif // SELECTCONTACTWIDGET_H diff --git a/sms/sendsmssession.cpp b/sms/sendsmssession.cpp new file mode 100644 index 0000000..04c0d97 --- /dev/null +++ b/sms/sendsmssession.cpp @@ -0,0 +1,98 @@ +#include +#include "sendsmssession.h" + +SendSMSSession::SendSMSSession( bool sync, QObject *parent ) : + QObject(parent) +{ + syncSend = sync; + isReady = false; + tps = NULL; +} + +void SendSMSSession::initTpSession() +{ + qDebug() << __PRETTY_FUNCTION__ ; + + if( tps == NULL ) + { + tps = new TpSession( "ring", syncSend ); + + if( !isReady && !syncSend ) + { + connect(tps,SIGNAL(accountReady(TpSessionAccount *)),SLOT(onAccountReady(TpSessionAccount *))); + }else + { + SendSMS(); + } + + connect(tps,SIGNAL(messageSent(const Tp::Message &,TpSessionAccount *)), + SLOT(onSMSSent(const Tp::Message &,TpSessionAccount *))); + + connect(tps,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionAccount *)), + SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *))); + }else + { + if( !isReady && !syncSend ) + { + connect(tps,SIGNAL(accountReady(TpSessionAccount *)),SLOT(onAccountReady(TpSessionAccount *))); + }else + { + SendSMS(); + } + } +} + +void SendSMSSession::setSMSToSend(QString addr, QString msg) +{ + qDebug() << __PRETTY_FUNCTION__ ; + addresses.append( addr ); + messages.append( msg ); + + initTpSession(); +} + +void SendSMSSession::setSMSToSend( QStringList addrs, QStringList msgs ) +{ + qDebug() << __PRETTY_FUNCTION__ ; + addresses = addrs ; + messages = msgs ; + + initTpSession(); +} + +void SendSMSSession::SendSMS() +{ + qDebug() << __PRETTY_FUNCTION__ ; + for( int i = 0; i < addresses.size(); i++ ) + { + tps->sendMessageToAddress( "ring", addresses.at(i), messages.at(i) ); + } + addresses.clear(); + messages.clear(); +} + +void SendSMSSession::onAccountReady(TpSessionAccount *tpsa) +{ + qDebug() << __PRETTY_FUNCTION__ ; + + isReady = true; + for( int i = 0; i < addresses.size(); i++ ) + { + tpsa->sendMessageToAddress( addresses.at(i), messages.at(i) ); + } + addresses.clear(); + messages.clear(); +} + +void SendSMSSession::onSMSSent( const Tp::Message &msg, TpSessionAccount *acc ) +{ + qDebug() << "SendSMSSession::onSMSSent :" << msg.text(); + Q_EMIT smsSent( msg.text() ); +} + +void SendSMSSession::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionAccount *acc) +{ + qDebug() << "SendSMSSession::onMessageReceived " << msg.text() << "from " << msg.sender()->id(); +} + + diff --git a/sms/sendsmssession.h b/sms/sendsmssession.h new file mode 100644 index 0000000..0074160 --- /dev/null +++ b/sms/sendsmssession.h @@ -0,0 +1,43 @@ +#ifndef SENDSMSSESSION_H +#define SENDSMSSESSION_H + +#include +#include +#include "tpsession/tpsession.h" +#include "tpsession/tpsessionaccount.h" + +class SendSMSSession : public QObject +{ + Q_OBJECT +public: + SendSMSSession( bool sync = false, QObject *parent = 0); + + void setSMSToSend( QString addr,QString msg ); + void setSMSToSend( QStringList addrs,QStringList msgs ); + +private: + void initTpSession(); + void SendSMS(); + +private: + TpSession *tps; + + QString sender; + QStringList addresses; + QStringList messages; + + bool syncSend; + bool isReady; + +Q_SIGNALS: + void smsSent( QString msg, QString addr ); + void smsSent( QString msg ); + +public Q_SLOTS: + void onAccountReady(TpSessionAccount *); + void onSMSSent(const Tp::Message &,TpSessionAccount *); + void onMessageReceived(const Tp::ReceivedMessage &,TpSessionAccount *); + +}; + +#endif // SENDSMSSESSION_H diff --git a/sms/sms.pro b/sms/sms.pro new file mode 100644 index 0000000..7d96479 --- /dev/null +++ b/sms/sms.pro @@ -0,0 +1,85 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-05-24T19:59:46 +# +#------------------------------------------------- + +QT += core gui xml + +TARGET = groupsms +TEMPLATE = app + +# DEFINES += ONLY_FOR_EBOOK # include libabook ets.. +# DEFINES += ONLY_FOR_TELEPATHYQT4 + +CONFIG += no_keywords +CONFIG += link_pkgconfig +PKGCONFIG += glib-2.0 gtk+-2.0 # libosso libebook-1.2 libosso-abook-1.0 TelepathyQt4 +CONFIG += qdbus + +INCLUDEPATH += /usr/local/include/telepathy-1.0 + +LIBS += -L/usr/lib + +SOURCES += main.cpp\ + mainwindow.cpp \ + abstractpage.cpp \ + contactwidget.cpp \ + contactwidgetitem.cpp \ + xmlcontroler.cpp \ + contactpage.cpp \ + groupwidgetitem.cpp \ + utility.cpp \ + contactinterface.cpp \ + newgroupdialog.cpp \ + addcontacttogroup.cpp \ + selectcontactwidget.cpp #\ +# tpsession/tpsessionobserver.cpp \ +# tpsession/tpsessionchannel.cpp \ +# tpsession/tpsessionaccount.cpp \ +# tpsession/tpsession.cpp \ +# sendsmssession.cpp + +HEADERS += mainwindow.h \ + abstractpage.h \ + contactwidget.h \ + contactwidgetitem.h \ + xmlcontroler.h \ + xmlstring.h \ + common.h \ + contactpage.h \ + groupwidgetitem.h \ + utility.h \ + contactinterface.h \ + newgroupdialog.h \ + addcontacttogroup.h \ + selectcontactwidget.h \ + itemobserver.h \ + item.h #\ +# tpsession/tpsessionobserver.h \ +# tpsession/tpsessionchannel.h \ +# tpsession/tpsessionaccount.h \ +# tpsession/tpsession.h \ +# sendsmssession.h + + +FORMS += mainwindow.ui \ + newgroupdialog.ui \ + addcontacttogroupdialog.ui + +RESOURCES = groupsms.qrc + +CONFIG += mobility +MOBILITY = + +symbian { + TARGET.UID3 = 0xe9d84f35 + # TARGET.CAPABILITY += + TARGET.EPOCSTACKSIZE = 0x14000 + TARGET.EPOCHEAPSIZE = 0x020000 0x800000 +} + +# pkg.path = /usr/local/lib/pkgconfig +# pkg.files = GroupSMS.pc +# target.path += $$[QT_INSTALL_LIBS] +# INSTALLS += target pkg diff --git a/sms/tpsession/tpsession.cpp b/sms/tpsession/tpsession.cpp new file mode 100755 index 0000000..1b230cd --- /dev/null +++ b/sms/tpsession/tpsession.cpp @@ -0,0 +1,265 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alhola(a)nokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "tpsession.h" +#include + + + + + +/** + * \class TpSession + * \headerfile + * + * 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 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(observer)), + "TpSessionChannelObserver"); + + // qDebug() << "TpSession::createObserver" << (registered ? "started" : "failed"); + +} + + +void TpSession::createChannelListener(const QString &channelType, + const Tp::MethodInvocationContextPtr<> &context, + const Tp::AccountPtr &account, + const Tp::ChannelPtr &channel) +{ + qDebug() << "TpSession::createChannelListener"; + + QString channelObjectPath = channel->objectPath(); + + + if ( channels.contains( channelObjectPath ) && + !channelType.isEmpty() && + !channelObjectPath.isEmpty() ) { + qDebug() << "TELEPATHY_ERROR_INVALID_ARGUMENT"; + return; + } + qDebug() << "creating listener for: " << channelObjectPath << " type " << channelType; +#if 0 + ChannelListener* listener = 0; + if( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT ) { + listener = new TextChannelListener(account, channel, context); + } else if ( channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA ) { + listener = new StreamChannelListener(account, channel, context); + } + + if(listener) { + connect(listener, SIGNAL(channelClosed(ChannelListener *)), + this, SLOT(channelClosed(ChannelListener *))); + Channels.append( channelObjectPath ); + } +#endif +} + + + + + + + + diff --git a/sms/tpsession/tpsession.h b/sms/tpsession/tpsession.h new file mode 100755 index 0000000..2061640 --- /dev/null +++ b/sms/tpsession/tpsession.h @@ -0,0 +1,99 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alholanokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef TPSESSION_H +#define TPSESSION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 accounts; + +private: + static TpSession *instancePtr; + //TpSession *instancePtr; + QString reqCm; + QString reqAddress; + QString reqMsg; + + bool sync; // Synchronous initialization + QEventLoop loop; + Tp::AccountManagerPtr mAM; + QStringList channels; + Tp::ClientRegistrarPtr registrar; +}; + + + +#endif // TPSESSION_H diff --git a/sms/tpsession/tpsessionaccount.cpp b/sms/tpsession/tpsessionaccount.cpp new file mode 100755 index 0000000..0626737 --- /dev/null +++ b/sms/tpsession/tpsessionaccount.cpp @@ -0,0 +1,309 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alholanokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "tpsessionaccount.h" +#include + +/** + * \class TpSessionAccount + * \headerfile + * + * 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(op); + contactsConn = Tp::ConnectionPtr(qobject_cast(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=" <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(op); + QList contacts = pcontacts->contacts(); + QString username = pcontacts->identifiers().first(); + if (contacts.size() != 1 || !contacts.first()) { + qDebug() << "Unable to add contact " <sendMessage(message); // We have already channel + Q_EMIT messageQueued(this); + } + else { + reqMessage=message; + p=getContactFromAddress(address); // Do we have contact ready ? + if(p.isNull()) // If not, create it + { + makeContactFromAddress(address); // Create and after created, send + }else + { + addOutgoingChannel(p); // Create channel and when ready, send + } + }; +} + +void TpSessionAccount::addOutgoingChannel(const Tp::ContactPtr &contact) +{ + + + // qDebug() << "TpSessionAccount::addOutgoingChannel"; + + TpSessionChannel* newChannel=new TpSessionChannel(contact->manager()->connection(),contact); + connect(newChannel,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)), + SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionChannel *))); + connect(newChannel,SIGNAL(channelReady(TpSessionChannel *)), + SLOT(onOutgoingChannelReady(TpSessionChannel*))); + myChannels+=newChannel; + +} + +void TpSessionAccount::onOutgoingChannelReady(TpSessionChannel *ch) +{ + // qDebug() << "TpSessionAccoiunt::onOutgoingChannelReady"; + Q_EMIT channelReady(this); + if(!reqMessage.isEmpty()) { + ch->sendMessage(reqMessage); + Q_EMIT messageQueued(this); + }; + reqMessage.clear(); +} + + +void TpSessionAccount::onMessageSent(const Tp::Message &msg,Tp::MessageSendingFlags, const QString &flags) +{ + // qDebug() << "TpSessionAccount::onMessageSent"; + Q_EMIT messageSent(msg,this); +}; + +void TpSessionAccount::onMessageReceived(const Tp::ReceivedMessage &msg,TpSessionChannel *ch) +{ + // qDebug() << "TpSessionAccount::onMessageReceived " << msg.text(); + Q_EMIT messageReceived(msg,this); +}; + +void TpSessionAccount::onNewChannels(const Tp::ChannelDetailsList &channels) +{ + + Tp::TextChannelPtr myIngoingTextChannel; + // qDebug() << "TpSessionAccount::onNewChannels"; + Q_FOREACH (const Tp::ChannelDetails &details, channels) { + QString channelType = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString(); + QString targetId = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetID")).toString(); + bool requested = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".Requested")).toBool(); + // qDebug() << " channelType:" << channelType <<" requested :" << requested << " targetId" << targetId; + + Q_EMIT newChannel(this,channelType,targetId,details); + if (channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_TEXT && !requested) { + + myIngoingTextChannel = Tp::TextChannel::create(acc->connection(),details.channel.path(),details.properties); + // qDebug() << "TpSessionAccount::onNewChannels path=" <<"path " << myIngoingTextChannel->objectPath(); + + TpSessionChannel* newChannel=new TpSessionChannel( myIngoingTextChannel); + connect(newChannel,SIGNAL(messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *)), + SLOT(onMessageReceived(const Tp::ReceivedMessage &,TpSessionChannel *))); + myChannels+=newChannel; + } + if (channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA && !requested) { + // qDebug() << "Incoming call" ; + } + } +} diff --git a/sms/tpsession/tpsessionaccount.h b/sms/tpsession/tpsessionaccount.h new file mode 100755 index 0000000..3e00670 --- /dev/null +++ b/sms/tpsession/tpsessionaccount.h @@ -0,0 +1,81 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alholanokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef TPSESSIONACCOUNT_H +#define TPSESSIONACCOUNT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 myContacts; + QSet myChannels; +}; + +#endif // TPSESSIONACCOUNT_H diff --git a/sms/tpsession/tpsessionchannel.cpp b/sms/tpsession/tpsessionchannel.cpp new file mode 100755 index 0000000..930cf3d --- /dev/null +++ b/sms/tpsession/tpsessionchannel.cpp @@ -0,0 +1,185 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alholanokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "tpsessionchannel.h" + + +/** + * \class TpSessionChannel + * \headerfile + * + * + * 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(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 queuedMessages = channel->messageQueue(); + Q_FOREACH(Tp::ReceivedMessage message, queuedMessages) { + // qDebug() << "received " << message.text(); + Q_EMIT messageReceived(message,this); + } +} +/** + * Send message to to ths channel + * + * + * \param message message to send + */ + +void TpSessionChannel::sendMessage(QString message) +{ + channel->send(message); +} +void TpSessionChannel::onMessageReceived(const Tp::ReceivedMessage &msg) +{ + // qDebug() << "TpSessionChannel::onMessageReceived " << msg.text(); + Q_EMIT messageReceived(msg,this); +}; +void TpSessionChannel::onMessageSent(const Tp::Message &msg,Tp::MessageSendingFlags sflags, const QString &flags) +{ + // qDebug() << "TpSessionChannel::onMessageSent"; + Q_EMIT messageSent(msg,sflags,flags,this); +}; +/** + * Get id ( address of your peer ) + * + * + * \returns your peer id/address ir empty QString + */ +QString TpSessionChannel::peerId() +{ + return peerContact ? peerContact->id():""; +} + +void TpSessionChannel::onChannelDestroyed(QObject *obj) +{ + // qDebug() << "TpSessionChannel::onChannelDestroyed"; + //TpSessionChannel *call = (TpSessionChannel *) obj; + Q_EMIT channelDestroyed(this); +} + diff --git a/sms/tpsession/tpsessionchannel.h b/sms/tpsession/tpsessionchannel.h new file mode 100755 index 0000000..182eea4 --- /dev/null +++ b/sms/tpsession/tpsessionchannel.h @@ -0,0 +1,60 @@ +/* + * This file is part of TpSession + * + * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Contact Kate Alhola kate.alholanokia.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef TPSESSIONCHANNEL_H +#define TPSESSIONCHANNEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TpSessionChannel : public QObject +{ + Q_OBJECT +public: + TpSessionChannel(Tp::TextChannelPtr); + TpSessionChannel(Tp::ConnectionPtr conn,const Tp::ContactPtr &contact); + void sendMessage(QString message); + QString peerId(); +Q_SIGNALS: + void channelReady(TpSessionChannel *); + void channelDestroyed(TpSessionChannel *); + void messageReceived(const Tp::ReceivedMessage &,TpSessionChannel *); + void messageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &,TpSessionChannel *); +public Q_SLOTS: + void onChannelCreated(Tp::PendingOperation *op); + void onChannelReady(Tp::PendingOperation *op); + void onChannelDestroyed(QObject *); + void onMessageReceived(const Tp::ReceivedMessage &); + void onMessageSent(const Tp::Message &,Tp::MessageSendingFlags, const QString &); +public: + Tp::ContactPtr peerContact; + Tp::TextChannelPtr channel; +}; + +#endif // TPSESSIONCHANNEL_H diff --git a/sms/tpsession/tpsessionobserver.cpp b/sms/tpsession/tpsessionobserver.cpp new file mode 100755 index 0000000..211cd80 --- /dev/null +++ b/sms/tpsession/tpsessionobserver.cpp @@ -0,0 +1,37 @@ +#include "tpsessionobserver.h" +#include "tpsession.h" +#include + +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 &channels, + const Tp::ChannelDispatchOperationPtr &dispatchOperation, + const QList &requestsSatisfied, + const QVariantMap &observerInfo) +{ + Q_UNUSED(dispatchOperation) + Q_UNUSED(requestsSatisfied) + Q_UNUSED(observerInfo) + Q_UNUSED(connection) + + qDebug() << "TpSessionObserver::observeChannels"; + + Q_FOREACH( Tp::ChannelPtr channel, channels ) + { + QVariantMap properties = channel->immutableProperties(); + QString channelType = properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString(); + if( !channelType.isNull() && !channelType.isEmpty()) + { + qDebug() << "ChannelType=" << channelType; + tpSession->createChannelListener(channelType, context, account, channel); + } + } +} + diff --git a/sms/tpsession/tpsessionobserver.h b/sms/tpsession/tpsessionobserver.h new file mode 100755 index 0000000..80cb661 --- /dev/null +++ b/sms/tpsession/tpsessionobserver.h @@ -0,0 +1,31 @@ +#ifndef TPSESSIONOBSERVER_H +#define TPSESSIONOBSERVER_H + +#include +#include +#include +#include + +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 &channels, + const Tp::ChannelDispatchOperationPtr &dispatchOperation, + const QList &requestsSatisfied, + const QVariantMap &observerInfo); +}; + +#endif // TPSESSIONOBSERVER_H diff --git a/sms/utility.cpp b/sms/utility.cpp new file mode 100644 index 0000000..c3da34d --- /dev/null +++ b/sms/utility.cpp @@ -0,0 +1,35 @@ +#include "utility.h" + +Utility::Utility(QObject *parent) : + QObject(parent) +{ +} + +QIcon Utility::getToolButtonIcon(const QString &iconFileName, bool active) +{ + QIcon icon(iconFileName); + if (!active) + { + QPixmap normalPixmap = icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off); + QPixmap activePixmap = icon.pixmap(16, 16, QIcon::Normal, QIcon::Off); + icon.addPixmap(normalPixmap, QIcon::Normal, QIcon::Off); + icon.addPixmap(activePixmap, QIcon::Active, QIcon::Off); + } else + { + QPixmap activePixmap = icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off); + icon.addPixmap(activePixmap, QIcon::Active, QIcon::Off); + } + return icon; +} + +QPixmap Utility::getIconPixmap(const QString &iconFileName, bool active) +{ + QIcon icon(iconFileName); + if (!active) + { + return icon.pixmap(16, 16, QIcon::Normal, QIcon::Off); + } else + { + return icon.pixmap(16, 16, QIcon::Disabled, QIcon::Off); + } +} diff --git a/sms/utility.h b/sms/utility.h new file mode 100644 index 0000000..9402c90 --- /dev/null +++ b/sms/utility.h @@ -0,0 +1,18 @@ +#ifndef UTILITY_H +#define UTILITY_H + +#include +#include + +class Utility : public QObject +{ + Q_OBJECT +public: + Utility(QObject *parent = 0); + + static QIcon getToolButtonIcon(const QString &iconFileName, bool active = false); + static QPixmap getIconPixmap(const QString &iconFileName, bool active = false); + +}; + +#endif // UTILITY_H diff --git a/sms/xmlcontroler.cpp b/sms/xmlcontroler.cpp new file mode 100644 index 0000000..8946da8 --- /dev/null +++ b/sms/xmlcontroler.cpp @@ -0,0 +1,656 @@ +#include +#include + +#include "xmlcontroler.h" +#include "xmlstring.h" +#include "groupwidgetitem.h" + +XmlControler* XmlControler::instance = 0; + +XmlControler* XmlControler::getInstance() +{ + if( !instance ) + { + instance = new XmlControler(); + } + return instance; +} + +XmlControler::XmlControler(QObject *parent) : + QObject(parent) +{ + instance = this; +} + +XmlControler::~XmlControler() +{ + closeXmlFile(); +} + +void XmlControler::closeXmlFile() +{ + if( m_XmlFileOut->isOpen() ) + { + m_XmlFileOut->close(); + delete m_XmlFileOut; + m_XmlFileOut = NULL; + } + + if( m_XmlFileIn->isOpen() ) + { + writeXml( m_XmlFileIn ); + m_XmlFileIn->close(); + delete m_XmlFileIn; + m_XmlFileIn = NULL; + } +} + +bool XmlControler::newXml( const QString &filename ) +{ + //qDebug() << "XmlControler::newXml( const QString &filename ), Entry"; + + m_filename = filename; + m_XmlFileOut = new QFile( filename ); + if( !m_XmlFileOut->open( QFile::ReadWrite | QFile::Text ) ) + { + //qDebug() << "open file is failed:" << m_XmlFileOut->errorString(); + return false; + } + + newXml( m_XmlFileOut ); + m_XmlFileOut->close(); + delete m_XmlFileOut; + m_XmlFileOut = NULL; + + return true; +} + +bool XmlControler::newXml( QIODevice *device ) +{ + //qDebug() << "XmlControler::newXml( QIODevice *device ), Entry"; + + const int Indent = 4; + + QTextStream out( device ); + QDomNode xmlNode = m_DomDoc.createProcessingInstruction( "xml", + "version=\"1.0\" encoding=\"UTF-8\""); + m_DomDoc.insertBefore( xmlNode, m_DomDoc.firstChild() ); + + QDomElement root = m_DomDoc.createElement( STR_XML_GROUPSMS ); + root.setAttribute( STR_XML_VERSION, STR_XML_VERSION_NUMBER ); + m_DomDoc.appendChild( root ); + + m_DomDoc.save( out, Indent ); + return true; +} + +bool XmlControler::readXml( const QString &filename ) +{ + //qDebug() << "XmlControler::readXml( const QString &filename ), Entry"; + + m_filename = filename; + m_XmlFileOut = new QFile( filename ); + if( !m_XmlFileOut->open( QFile::ReadOnly | QFile::Text ) ) + { + //qDebug() << "open file is failed:" << m_XmlFileOut->errorString(); + return false; + } + + if( !readXml( m_XmlFileOut ) ) + { + return false; + } + + return true; +} + +bool XmlControler::readXml( QIODevice *device ) +{ + //qDebug() << "XmlControler::readXml( QIODevice *device ), Entry"; + + QString errorStr; + int errorLine; + int errorColumn; + + if( !m_DomDoc.setContent( device, true, &errorStr, &errorLine, &errorColumn ) ) + { + QMessageBox::information( NULL, tr("XML file"), + tr("Parse error at line %1, column %2:\n%3") + .arg(errorLine) + .arg(errorColumn) + .arg(errorStr) ); + return false; + } + + return true; +} + +bool XmlControler::writeXml( QIODevice *device ) +{ + //qDebug() << "XmlControler::writeXml( QIODevice *device ), Entry"; + + const int IndentSize = 4; + + QTextStream out(device); + m_DomDoc.save( out, IndentSize ); + return true; +} + +bool XmlControler::writeXml() +{ + //qDebug() << "XmlControler::writeXml(), Entry"; + + const int IndentSize = 4; + + m_XmlFileIn = new QFile( m_filename ); + if( !m_XmlFileIn->open( QFile::WriteOnly | QFile::Text ) ) + { + //qDebug() << "open file is failed:" << m_XmlFileIn->errorString(); + return false; + } + + QTextStream out(m_XmlFileIn); + m_DomDoc.save( out, IndentSize ); + m_XmlFileIn->close(); + delete m_XmlFileIn; + m_XmlFileIn = NULL; + return true; +} + +bool XmlControler::createAllContacts() +{ + //qDebug() << "XmlControler::createAllContacts, Entry"; + + QDomElement root = m_DomDoc.documentElement(); + QDomElement allcontacts = m_DomDoc.createElement( STR_XML_ALLCONTACTS ); + root.appendChild( allcontacts ); + + QDomElement node_contact = m_DomDoc.createElement( STR_XML_CONTACT ); + allcontacts.appendChild( node_contact ); + QDomText contact_fullname = m_DomDoc.createTextNode( "Tom for Test" ); + node_contact.appendChild( contact_fullname ); + QDomText contact_mobilenumber = m_DomDoc.createTextNode( "number for Test" ); + node_contact.appendChild( contact_mobilenumber ); + + m_DomDoc.appendChild( root ); + + return true; +} + +bool XmlControler::createGroup(const QString &groupname) +{ + //qDebug() << "XmlControler::createGroup(const QString &groupname), Entry"; + + findGroup( groupname ); + if( foundgroup ) + return true; + + QDomElement root = m_DomDoc.documentElement(); + QDomElement group = m_DomDoc.createElement( STR_XML_GROUP ); + group.setAttribute( STR_XML_GROUP_NAME, groupname ); + + + root.appendChild( group ); + writeXml(); + + Item *item = new Item(); + + item->group_name = groupname; + item->m_isGroup = true; + + itemObserver->addGroup( item ); + + return true; +} + +bool XmlControler::createContact(const QString &group, ItemListPtr contacts) +{ + QDomNode root = findGroup(group); + if( !foundgroup ) + { + qDebug() << "could not find this" << group << "existed. create it."; + createGroup( group ); + root = findGroup(group); + } + + for( int i = 0; i < contacts.size(); i++ ) + { + contacts.at(i)->group_owner = group; + createContact( &root, contacts.at(i) ); + } + itemObserver->addContact( contacts, group); + return true; +} + +bool XmlControler::createContact(const QString &group, Item *contact) +{ + //qDebug() << "XmlControler::createContact(const QString &group, Item *contact), Entry"; + + QDomNode root = findGroup(group); + if( !foundgroup ) + { + //qDebug() << "could not find this" << group << "existed. create it."; + createGroup( group ); + root = findGroup(group); + } + + contact->group_owner = group; + createContact( &root, contact ); + + itemObserver->addContact( contact, group); + + return true; +} + +bool XmlControler::createContact(QDomNode *group, Item *contact) +{ + //qDebug() << "XmlControler::createContact(QDomElement *group, Item *contact), Entry"; + Q_ASSERT(contact); + + QDomElement node = m_DomDoc.createElement(STR_XML_CONTACT); + node.setAttribute( STR_XML_CONTACT_UID, contact->uid); + node.setAttribute( STR_XML_CONTACT_FULL_NAME, contact->full_name); + node.setAttribute( STR_XML_CONTACT_MOBILE_NUMBER, contact->mobile_number); + node.setAttribute( STR_XML_CONTACT_PIC_URI, contact->user_pic_uri); + node.setAttribute( STR_XML_CONTACT_GROUP_OWNER, contact->group_owner); + +// node.setAttribute( STR_XML_CONTACT_UID, "1"); +// node.setAttribute( STR_XML_CONTACT_FULL_NAME, "Tom 1"); +// node.setAttribute( STR_XML_CONTACT_MOBILE_NUMBER, "12345678901"); +// node.setAttribute( STR_XML_CONTACT_PIC_URI, "/alsdj/a;sdj/pic"); +// node.setAttribute( STR_XML_CONTACT_GROUP_OWNER, "groupowner"); + + group->appendChild(node); + writeXml(); + + return true; +} + +QDomNode XmlControler::findGroup(const QString &groupname) +{ + //qDebug() << "XmlControler::findGroup(const QString &group), Entry"; + + QDomNode root; + QDomNode node; + foundgroup = false; + + node = m_DomDoc.firstChild(); + while( !node.isNull() && !foundgroup ) + { + //qDebug() << "node1 name : " << node.toElement().tagName(); + //qDebug() << "node1 attr : " << node.toElement().attribute(STR_XML_VERSION); + if( node.hasChildNodes() ) + { + QDomNode node2 = node.firstChild(); + while( !node2.isNull() ) + { + //qDebug() << "node2 name : " << node2.toElement().tagName(); + //qDebug() << "node2 attr : " << node2.toElement().attribute(STR_XML_GROUP_NAME); + + if( groupname == node2.toElement().attribute(STR_XML_GROUP_NAME) ) + { + //qDebug() << "group is found"; + root = node2; + foundgroup = true; + break; + } + + node2 = node2.nextSibling(); + } + } + + node = node.nextSibling(); + } + return root; +} + +QDomNode XmlControler::findContact(const QString &groupname, Item *contact) +{ + //qDebug() << "XmlControler::findContact(const QString &groupname, ContactWidgetItem *contact), Entry"; + + QDomNode element; + QDomNode group = findGroup(groupname); + if( !foundgroup ) + return group; + element = findContact(group, contact); + + return element; +} + +QDomNode XmlControler::findContact(QDomNode group, Item *contact) +{ + //qDebug() << "XmlControler::findContact(QDomNode *group, ContactWidgetItem *contact), Entry"; + + QDomNode element; + QDomNode node = group; + foundcontact = false; + while( !node.isNull() && !foundcontact ) + { + if( node.hasChildNodes() ) + { + QDomNode node2 = node.firstChild(); + while( !node2.isNull() ) + { + //qDebug() << "node2 name : " << node2.toElement().tagName(); + //qDebug() << "node2 uid : " << node2.toElement().attribute(STR_XML_CONTACT_UID); + + if( contact->uid == node2.toElement().attribute(STR_XML_CONTACT_UID) ) + //if( "1" == node2.toElement().attribute(STR_XML_CONTACT_UID) ) // for Test + { + //qDebug() << "contact is found"; + element = node2; + foundcontact = true; + break; + } + + node2 = node2.nextSibling(); + } + } + + node = node.nextSibling(); + } + + return element; +} + +bool XmlControler::removeGroup(const QString &groupname) +{ + //qDebug() << "XmlControler::removeGroup(const QString &groupname), Entry"; + + QDomNode group = findGroup(groupname); + if( !foundgroup ) + return false; + QDomElement root = m_DomDoc.documentElement(); + root.removeChild(group); + writeXml(); + + return true; +} + +bool XmlControler::removeContact( Item *contact ) +{ + //qDebug() << "XmlControler::removeContact(const QString &group, ContactWidgetItem *contact), Entry"; + + QDomNode root = findGroup( contact->group_owner ); + if( !foundgroup ) + { + //qDebug() << "root is NULL"; + return false; + } + removeContact( root, contact ); + + return true; +} + +bool XmlControler::removeContact(const QString &group, Item *contact) +{ + //qDebug() << "XmlControler::removeContact(const QString &group, ContactWidgetItem *contact), Entry"; + + QDomNode root = findGroup(group); + if( !foundgroup ) + { + //qDebug() << "root is NULL"; + return false; + } + removeContact( root, contact ); + + return true; +} + +bool XmlControler::removeContact(QDomNode group, Item *contact) +{ + //qDebug() << "XmlControler::removeContact(QDomNode *group, ContactWidgetItem *contact), Entry"; + + QDomNode node = findContact(group, contact); + if( node.isNull() ) + { + //qDebug() << "node is NULL"; + return false; + } + QDomNode del = group.removeChild(node); + if( del.isNull() ) + { + //qDebug() << "del node is NULL"; + return false; + } + writeXml(); + itemObserver->removeContact(contact); + + return true; +} + +bool XmlControler::cleanAllContacts() +{ + //TODO : clean all contacts in observer. + itemObserver->removeAllContacts(); + + return true; +} + +bool XmlControler::cleanAllContactsGroup() +{ + for( int i = 0; i < all_contacts_items_group.size(); i++ ) + { + delete all_contacts_items_group.at(i); + } + all_contacts_items_group.clear(); + + return true; +} + +void XmlControler::setItemObserver(ItemObserver *observer) +{ + itemObserver = observer; +} + +void XmlControler::setItemSelectObserver( ItemSelectObserver *observer ) +{ + itemSelectObserver = observer; +} + +void XmlControler::getAllContactItems() +{ + //qDebug() << "XmlControler::getAllContactItems(), Entry"; + + QDomElement root = m_DomDoc.documentElement(); + QDomNode node = root.firstChild(); + QString tagname; + + cleanAllContacts(); + + while( !node.isNull() ) + { + tagname = node.toElement().tagName(); + //qDebug() << "node tagname : " << tagname; + + if( STR_XML_GROUP == tagname ) + { + //qDebug() << "node is : " << STR_XML_GROUP; + + Item *item = new Item(); + + item->group_name = node.toElement().attribute(STR_XML_GROUP_NAME); + item->m_isGroup = true; + + itemObserver->addGroup( item ); + + if( node.hasChildNodes() ) + { + QDomNode node2 = node.firstChild(); + while( !node2.isNull() ) + { + tagname = node2.toElement().tagName(); + if( STR_XML_CONTACT == tagname ) + { + //qDebug() << "node is : " << STR_XML_CONTACT; + + Item *item = new Item(); + item->m_isGroup = false; + + item->full_name = node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME); + //qDebug() << "fullname is : " << node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME); + + item->mobile_number = node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER); + //qDebug() << "mobile number is : " << node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER); + + item->group_owner = node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER); + //qDebug() << "group owner is : " << node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER); + + item->uid = node2.toElement().attribute(STR_XML_CONTACT_UID); + //qDebug() << "uid is : " << node2.toElement().attribute(STR_XML_CONTACT_UID); + + itemObserver->addContact( item ); + } + node2 = node2.nextSibling(); + } + } + } + node = node.nextSibling(); + } + //qDebug() << "XmlControler::getAllContactItems(), Exit"; +} + +QStringList XmlControler::getAllGroupNames() +{ + //qDebug() << "XmlControler::getAllGroupNames(), Entry"; + + QDomElement root = m_DomDoc.documentElement(); + QDomNode node = root.firstChild(); + QString tagname; + QStringList strlist; + + while( !node.isNull() ) + { + tagname = node.toElement().tagName(); + + if( STR_XML_GROUP == tagname ) + { + //qDebug() << "group name : " << node.toElement().attribute(STR_XML_GROUP_NAME); + strlist.append( node.toElement().attribute(STR_XML_GROUP_NAME) ); + } + node = node.nextSibling(); + } + //qDebug() << "XmlControler::getAllGroupNames(), Exit"; + + return strlist; +} + +void XmlControler::getAllContactItemsFromGroup( QString groupname ) +{ + //qDebug() << "XmlControler::getAllContactItemsFromGroup( QString groupname ), Entry"; + + QDomElement root = m_DomDoc.documentElement(); + QDomNode node = root.firstChild(); + QString tagname; + QString group; + + if( old_groupname == groupname ) + { + itemSelectObserver->getGroupContacts( all_contacts_items_group ); + return; + } + + cleanAllContactsGroup(); + + while( !node.isNull() ) + { + tagname = node.toElement().tagName(); + group = node.toElement().attribute(STR_XML_GROUP_NAME); + //qDebug() << "node tagname : " << tagname << "group:" << group; + + if( (STR_XML_GROUP == tagname) && (group == groupname) ) + { + //qDebug() << "node is : " << STR_XML_GROUP; + + Item *item = new Item(); + + item->group_name = node.toElement().attribute(STR_XML_GROUP_NAME); + item->m_isGroup = true; + + all_contacts_items_group.append( item ); + + if( node.hasChildNodes() ) + { + QDomNode node2 = node.firstChild(); + while( !node2.isNull() ) + { + tagname = node2.toElement().tagName(); + if( STR_XML_CONTACT == tagname ) + { + //qDebug() << "node is : " << STR_XML_CONTACT; + + Item *item = new Item(); + //qDebug() << "new ContactWidgetItem"; + + item->full_name = node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME); + //qDebug() << "fullname is : " << node2.toElement().attribute(STR_XML_CONTACT_FULL_NAME); + + item->mobile_number = node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER); + //qDebug() << "mobile number is : " << node2.toElement().attribute(STR_XML_CONTACT_MOBILE_NUMBER); + + item->group_owner = node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER); + //qDebug() << "group owner is : " << node2.toElement().attribute(STR_XML_CONTACT_GROUP_OWNER); + + item->uid = node2.toElement().attribute(STR_XML_CONTACT_UID); + //qDebug() << "uid is : " << node2.toElement().attribute(STR_XML_CONTACT_UID); + + all_contacts_items_group.append( item ); + } + node2 = node2.nextSibling(); + } + } + } + node = node.nextSibling(); + } + itemSelectObserver->getGroupContacts( all_contacts_items_group ); + old_groupname = groupname; + //qDebug() << "XmlControler::getAllContactItemsFromGroup( QString groupname ), Exit"; +} + +bool XmlControler::removeContactFromGroup( ItemListPtr items, const QString &groupname ) +{ + QDomNode root = findGroup(groupname); + if( !foundgroup ) + { + //qDebug() << "root is NULL"; + return false; + } + for( int i = 0; items.size(); i++ ) + { + removeContact( root, items.at(i) ); + } + itemObserver->refreshContactsList(); + + return true; +} + +bool XmlControler::removeContactFromGroup( ItemListPtr items ) +{ + for( int i = 0; i < items.size(); i++ ) + { + removeContact( items.at(i) ); + } + itemObserver->refreshContactsList(); + + return true; +} + + + + + + + + + + + + + + + + + + + + diff --git a/sms/xmlcontroler.h b/sms/xmlcontroler.h new file mode 100644 index 0000000..d53f0dd --- /dev/null +++ b/sms/xmlcontroler.h @@ -0,0 +1,85 @@ +#ifndef XMLCONTROLER_H +#define XMLCONTROLER_H + +#include +#include + +#include "contactwidgetitem.h" +#include "itemobserver.h" + +class XmlControler : public QObject +{ + Q_OBJECT +public: + static XmlControler* getInstance(); + ~XmlControler(); + + void setItemObserver( ItemObserver *observer ); + void setItemSelectObserver( ItemSelectObserver *observer ); + + bool newXml( const QString &filename ); + bool newXml( QIODevice *device ); + + bool readXml( const QString &filename ); + bool readXml( QIODevice *device ); + + bool writeXml( QIODevice *device ); + bool writeXml(); + + void closeXmlFile(); + + bool createGroup(const QString &groupname); + bool createContact(const QString &group, ItemListPtr contacts); + bool createContact(const QString &group, Item *contact); + bool createContact(QDomNode *group, Item *contact); + + bool removeGroup(const QString &groupname); + bool removeContact(const QString &group, Item *contact); + bool removeContact(QDomNode group, Item *contact); + bool removeContact( Item *contact ); + bool removeContactFromGroup( ItemListPtr items, const QString &groupname ); + bool removeContactFromGroup( ItemListPtr items ); + + void getAllContactItems(); + void getAllContactItemsFromGroup( QString groupname ); + + QStringList getAllGroupNames(); + + +private: + static XmlControler* instance; + XmlControler( QObject *parent = 0 ); + + bool createAllContacts(); + QDomNode findGroup(const QString &groupname); + QDomNode findContact(const QString &groupname, Item *contact); + QDomNode findContact(QDomNode group, Item *contact); + + bool cleanAllContacts(); + bool cleanAllContactsGroup(); + +private: + ItemObserver *itemObserver; + ItemSelectObserver *itemSelectObserver; + + QDomDocument m_DomDoc; + + ItemListPtr all_contacts_items; + ItemListPtr all_contacts_items_group; + + QFile *m_XmlFileOut; + QFile *m_XmlFileIn; + QString m_filename; + + bool foundgroup; + bool foundcontact; + + QString old_groupname; + +Q_SIGNALS: + +public Q_SLOTS: + +}; + +#endif // XMLCONTROLER_H diff --git a/sms/xmlstring.h b/sms/xmlstring.h new file mode 100644 index 0000000..e11932c --- /dev/null +++ b/sms/xmlstring.h @@ -0,0 +1,20 @@ +#ifndef XMLSTRING_H +#define XMLSTRING_H + +#include + +const QString STR_XML_GROUPSMS = "GroupSMS"; +const QString STR_XML_VERSION = "Version"; +const QString STR_XML_VERSION_NUMBER = "0.1"; + +const QString STR_XML_GROUP = "Group"; +const QString STR_XML_GROUP_NAME = "GroupName"; +const QString STR_XML_ALLCONTACTS = "All_Contacts"; +const QString STR_XML_CONTACT = "Contact"; +const QString STR_XML_CONTACT_UID = "Uid"; +const QString STR_XML_CONTACT_FULL_NAME = "Full_Name"; +const QString STR_XML_CONTACT_MOBILE_NUMBER = "Mobile_Number"; +const QString STR_XML_CONTACT_GROUP_OWNER = "Group_Owner"; +const QString STR_XML_CONTACT_PIC_URI = "Pic_Uri"; + +#endif // XMLSTRING_H diff --git a/welcome b/welcome index e69de29..a0c312c 100644 --- a/welcome +++ b/welcome @@ -0,0 +1,3 @@ +It's a Qt application. It manage group contacts by personal XML file. it 's base on local contacts DB (libosso-abook). It could be add/remove group contacts. Another, It's could send SMS to group contacts. that's use TpSession and TelepathyQt4 lib. + +Author: Tom Chen