diff --exclude='*orig' -Naur psi-0.10-test3-orig/iconsets/system/default/icondef.xml psi-0.10-test3/iconsets/system/default/icondef.xml --- psi-0.10-test3-orig/iconsets/system/default/icondef.xml 2005-12-04 23:38:32.000000000 +0000 +++ psi-0.10-test3/iconsets/system/default/icondef.xml 2005-12-04 23:39:30.000000000 +0000 @@ -317,6 +317,11 @@ + psi/rosteritem + add.png + + + psi/eye eye_blue.png diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/adduserdlg.cpp psi-0.10-test3/src/adduserdlg.cpp --- psi-0.10-test3-orig/src/adduserdlg.cpp 2005-08-21 17:44:28.000000000 +0000 +++ psi-0.10-test3/src/adduserdlg.cpp 2005-12-04 23:39:30.000000000 +0000 @@ -108,6 +108,24 @@ delete d; } +void AddUserDlg::setJid(const QString& jid) +{ + le_jid->setText(jid); +} + +void AddUserDlg::setName(const QString& name) +{ + le_nick->setText(name); +} + +void AddUserDlg::setGroups(const QStringList& groups) +{ + // FIXME: Add it to all groups when Psi supports multiple groups per contact + if (!groups.isEmpty()) { + cb_group->setCurrentText(groups.first()); + } +} + void AddUserDlg::pa_updatedActivity() { if(!d->pa->loggedIn()) diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/adduserdlg.h psi-0.10-test3/src/adduserdlg.h --- psi-0.10-test3-orig/src/adduserdlg.h 2005-08-21 17:44:28.000000000 +0000 +++ psi-0.10-test3/src/adduserdlg.h 2005-12-04 23:39:30.000000000 +0000 @@ -37,6 +37,11 @@ AddUserDlg(const QStringList &services, const QStringList &names, const QStringList &groups, PsiAccount *); ~AddUserDlg(); +public slots: + void setJid(const QString&); + void setName(const QString&); + void setGroups(const QStringList&); + signals: void add(const Jid &, const QString &, const QStringList &, bool authReq); diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/eventdlg.cpp psi-0.10-test3/src/eventdlg.cpp --- psi-0.10-test3-orig/src/eventdlg.cpp 2005-12-04 23:38:30.000000000 +0000 +++ psi-0.10-test3/src/eventdlg.cpp 2005-12-04 23:39:36.000000000 +0000 @@ -21,6 +21,7 @@ #include"eventdlg.h" #include +#include #include #include #include @@ -289,6 +290,7 @@ class AttachViewItem : public QListViewItem { public: + typedef enum { UrlAttach, RosterItemAttach } AttachType; static const int RTTI = 9200; AttachViewItem(AttachView *par, const char *icon) @@ -297,6 +299,7 @@ if(icon) setPixmap(0, IconsetFactory::icon(icon)); + type = UrlAttach; setMultiLinesEnabled(true); } @@ -307,6 +310,9 @@ virtual void contextMenuRequested(const QPoint &pos) = 0; virtual void doubleClicked() = 0; + + AttachType type; + RosterItem ri; }; class AttachViewUrl: public AttachViewItem @@ -317,10 +323,28 @@ AttachViewUrl(const QString &_url, const QString &_desc, AttachView *par) : AttachViewItem(par, "psi/www") { + type = UrlAttach; url = _url; desc = _desc; - setText(0, url + " (" + desc + ')'); + if (!desc.isEmpty()) { + setText(0, url + " (" + desc + ')'); + } + else { + setText(0, url); + } + } + + AttachViewUrl(const RosterItem &rosterItem, AttachView *par) + : AttachViewItem(par, "psi/rosteritem") + { + type = RosterItemAttach; + ri = rosterItem; + + QString text = ri.jid().full(); + if (!ri.name().isEmpty()) + text += " (" + ri.name() + ")"; + setText(0, text); } int rtti() const @@ -330,19 +354,29 @@ void contextMenuRequested(const QPoint &pos) { + AttachView *lv = (AttachView *)listView(); QPopupMenu pm(listView()); - pm.insertItem(AttachView::tr("Go to &URL..."), 0); - pm.insertItem(AttachView::tr("Copy location"), 1); - pm.insertSeparator(); - pm.insertItem(AttachView::tr("Remove"), 2); + if(type == AttachViewItem::RosterItemAttach) { + pm.insertItem(AttachView::tr("&Add Contact..."), 0); + if (!lv->readOnly ()) + pm.setItemEnabled(0, false); + } + else { + pm.insertItem(AttachView::tr("Go to &URL..."), 0); + pm.insertItem(AttachView::tr("Copy location"), 1); + pm.insertSeparator(); + pm.insertItem(AttachView::tr("Remove"), 2); - AttachView *lv = (AttachView *)listView(); - if(lv->readOnly()) - pm.setItemEnabled(2, false); + if(lv->readOnly()) + pm.setItemEnabled(2, false); + } switch(pm.exec(pos)) { case 0: - lv->goURL(url); + if(type == AttachViewItem::RosterItemAttach) + lv->actionAddContact(ri); + else + lv->goURL(url); break; case 1: QApplication::clipboard()->setText(url, QClipboard::Clipboard); @@ -359,7 +393,10 @@ void doubleClicked() { AttachView *lv = (AttachView *)listView(); - lv->goURL(url); + if(type != AttachViewItem::RosterItemAttach) + lv->goURL(url); + else + lv->actionAddContact(ri); } QString url, desc; @@ -374,15 +411,50 @@ connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), SLOT(qlv_context(QListViewItem *, const QPoint &, int))); connect(this, SIGNAL(doubleClicked(QListViewItem *)), SLOT(qlv_doubleClicked(QListViewItem *))); + setAcceptDrops(TRUE); }; AttachView::~AttachView() { } +void AttachView::dragEnterEvent(QDragEnterEvent *e) +{ + e->accept(QTextDrag::canDecode(e)); +} + +void AttachView::dropEvent(QDropEvent *e) +{ + QString str; + + if(QTextDrag::decode(e, str)) { + Jid jid(str); + if (jid.isValid() && !jid.node().isEmpty()) { + /* Try to find roster item */ + EventDlg *e = (EventDlg *)parent(); + QPtrList ul = e->psiAccount()->findRelavent(jid); + + if(!ul.isEmpty()) { + /* Add roster item */ + UserListItem *u = ul.first(); + rosterItemAdd(*u); + } + else { + /* Add new roster item */ + rosterItemAdd(RosterItem(jid)); + } + } + else { + /* Add as URL */ + urlAdd(str,""); + } + } +} + void AttachView::setReadOnly(bool b) { v_readOnly = b; + setAcceptDrops(!b); } void AttachView::urlAdd(const QString &url, const QString &desc) @@ -416,6 +488,11 @@ openURL(url); } +void AttachView::actionAddContact(const RosterItem& ri) +{ + ((EventDlg*)parent())->psiAccount()->openAddUserDlg(ri.jid(),ri.name(),ri.groups()); +} + UrlList AttachView::urlList() const { UrlList list; @@ -423,7 +500,8 @@ for(AttachViewItem *i = (AttachViewItem *)firstChild(); i; i = (AttachViewItem *)i->nextSibling()) { if(i->rtti() == AttachViewUrl::RTTI) { AttachViewUrl *i_url = (AttachViewUrl *)i; - list += Url(i_url->url, i_url->desc); + if (i_url->type == AttachViewItem::UrlAttach) + list += Url(i_url->url, i_url->desc); } } @@ -449,6 +527,12 @@ childCountChanged(); } +void AttachView::rosterItemAdd(const RosterItem& ri) +{ + new AttachViewUrl(ri, this); + childCountChanged(); +} + void AttachView::takeItem(QListViewItem *i) { QListView::takeItem(i); @@ -460,6 +544,25 @@ emit childCountChanged(); } + +RosterItemList AttachView::rosterItemList() const +{ + RosterItemList list; + + for(AttachViewItem *i = (AttachViewItem *)firstChild(); i; i = (AttachViewItem *)i->nextSibling()) + if (i->type == AttachViewItem::RosterItemAttach) + list += i->ri; + + return list; +} + +void AttachView::addRosterItemList(const RosterItemList &list) +{ + for(QValueList::ConstIterator it = list.begin(); it != list.end(); ++it) { + rosterItemAdd(*it); + } +} + //---------------------------------------------------------------------------- // AddUrlDlg //---------------------------------------------------------------------------- @@ -514,6 +617,7 @@ IconButton *pb_join, *pb_decline; // invitation buttons ChatView *mle; AttachView *attachView; + QTimer *attachHide; QTimer *whois; QString lastWhois; Jid jid, realJid; @@ -585,6 +689,7 @@ d->mayShowReplyingBtns = false; d->psi = psi; d->pa = 0; + d->attachView = 0; d->psi->dialogRegister(this); d->anim = 0; @@ -597,6 +702,9 @@ d->whois = new QTimer; connect(d->whois, SIGNAL(timeout()), SLOT(doWhois())); + d->attachHide = new QTimer; + connect(d->attachHide, SIGNAL(timeout()), SLOT(showHideAttachView())); + init(); d->cb_ident->setAccount(pa); @@ -642,6 +750,8 @@ if(u && u->isSecure(d->jid.resource())) d->tb_pgp->setOn(true); } + + setAcceptDrops(TRUE); } EventDlg::EventDlg(const Jid &j, PsiAccount *pa, bool unique) @@ -685,6 +795,7 @@ { if(d->composing) { delete d->whois; + delete d->attachHide; d->psi->dialogUnregister(this); } else { @@ -1332,6 +1443,18 @@ return QSize(420, 280); } +void EventDlg::dragEnterEvent(QDragEnterEvent *) +{ + d->attachHide->stop(); + if(d->attachView->isHidden()) + d->attachView->show(); +} + +void EventDlg::dragLeaveEvent(QDragLeaveEvent *) +{ + d->attachHide->start(3000,true); +} + void EventDlg::showEvent(QShowEvent *e) { QWidget::showEvent(e); @@ -1416,6 +1539,7 @@ m.setBody(d->mle->text()); m.setSubject(d->le_subj->text()); + m.setRosterItemList(d->attachView->rosterItemList()); m.setUrlList(d->attachView->urlList()); m.setTimeStamp(QDateTime::currentDateTime()); m.setThread(d->thread); @@ -1769,6 +1893,7 @@ d->attachView->clear(); d->attachView->addUrlList(m.urlList()); + d->attachView->addRosterItemList(m.rosterItemList()); showHideAttachView(); } diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/eventdlg.h psi-0.10-test3/src/eventdlg.h --- psi-0.10-test3-orig/src/eventdlg.h 2005-12-04 23:38:26.000000000 +0000 +++ psi-0.10-test3/src/eventdlg.h 2005-12-04 23:39:34.000000000 +0000 @@ -84,12 +84,19 @@ AttachView(QWidget *parent=0, const char *name=0); ~AttachView(); + void dragEnterEvent(QDragEnterEvent *); + void dropEvent(QDropEvent *); + void setReadOnly(bool); void urlAdd(const QString &, const QString &); + void rosterItemAdd(const RosterItem & ri); UrlList urlList() const; void addUrlList(const UrlList &); + RosterItemList rosterItemList() const; + void addRosterItemList(const RosterItemList &); + void goURL(const QString &); bool readOnly() const; @@ -98,6 +105,7 @@ virtual void takeItem(QListViewItem *); void emitChildCountChanged(); + void actionAddContact(const RosterItem & ri); signals: void childCountChanged(); @@ -140,6 +148,9 @@ static QSize defaultSize(); + void dragEnterEvent(QDragEnterEvent *); + void dragLeaveEvent(QDragLeaveEvent *); + signals: void aChat(const Jid& jid); void aCompose(const Jid &jid, const QString &body, const QString &subject, const QString &thread, ComposeType ct, const Jid &originalJid_Sender, const Jid &originalJid_Me, const QDateTime &originalMessageTime, const UrlList &originalMessageAttachements); diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/psiaccount.cpp psi-0.10-test3/src/psiaccount.cpp --- psi-0.10-test3-orig/src/psiaccount.cpp 2005-12-04 23:38:32.000000000 +0000 +++ psi-0.10-test3/src/psiaccount.cpp 2005-12-04 23:39:30.000000000 +0000 @@ -1580,7 +1580,7 @@ void PsiAccount::processIncomingMessage(const Message &_m) { // skip empty messages - if(_m.body().isEmpty() && _m.urlList().isEmpty() && !_m.containsEvents() && + if(_m.body().isEmpty() && _m.rosterItemList().isEmpty() && _m.urlList().isEmpty() && !_m.containsEvents() && _m.invitationFrom().isEmpty()) return; @@ -2120,12 +2120,23 @@ void PsiAccount::openAddUserDlg() { + Jid j; + QStringList sl; + openAddUserDlg(j, "", sl); +} + +void PsiAccount::openAddUserDlg(const Jid& jid, const QString& name, const QStringList& groups) +{ if(!checkConnected()) return; AddUserDlg *w = (AddUserDlg *)dialogFind("AddUserDlg"); - if(w) + if(w) { bringToFront(w); + w->setJid(jid.full()); + w->setName(name); + w->setGroups(groups); + } else { QStringList gl, services, names; UserListIt it(d->userList); @@ -2144,6 +2155,9 @@ } w = new AddUserDlg(services, names, gl, this); + w->setJid(jid.full()); + w->setName(name); + w->setGroups(groups); connect(w, SIGNAL(add(const Jid &, const QString &, const QStringList &, bool)), SLOT(dj_add(const Jid &, const QString &, const QStringList &, bool))); w->show(); } diff --exclude='*orig' -Naur psi-0.10-test3-orig/src/psiaccount.h psi-0.10-test3/src/psiaccount.h --- psi-0.10-test3-orig/src/psiaccount.h 2005-12-04 23:38:32.000000000 +0000 +++ psi-0.10-test3/src/psiaccount.h 2005-12-04 23:39:30.000000000 +0000 @@ -179,6 +179,7 @@ void showXmlConsole(); void openAddUserDlg(); + void openAddUserDlg(const Jid&, const QString& name, const QStringList&); void openGroupChat(const Jid &, const QString &); bool groupChatJoin(const QString &host, const QString &room, const QString &nick, const QString &pass = ""); void groupChatSetStatus(const QString &host, const QString &room, const Status &);