1 /*
2     kopetegroup.cpp - Kopete (Meta)Contact Group
3 
4     Copyright (c) 2002-2005 by Olivier Goffart       <ogoffart@kde.org>
5     Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>
6 
7     Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
8 
9     *************************************************************************
10     *                                                                       *
11     * This library is free software; you can redistribute it and/or         *
12     * modify it under the terms of the GNU Lesser General Public            *
13     * License as published by the Free Software Foundation; either          *
14     * version 2 of the License, or (at your option) any later version.      *
15     *                                                                       *
16     *************************************************************************
17 */
18 
19 #include "kopetegroup.h"
20 #include "kopetegroup_p.h"
21 
22 #include "kopetecontactlist.h"
23 #include "kopetemetacontact.h"
24 #include "kopetecontact.h"
25 #include "kopetechatsession.h"
26 
27 #include <KLocalizedString>
28 
29 namespace Kopete {
30 Group *Group::s_topLevel = nullptr;
31 Group *Group::s_temporary = nullptr;
32 Group *Group::s_offline = nullptr;
topLevel()33 Group *Group::topLevel()
34 {
35     if (!s_topLevel) {
36         s_topLevel = new Group(i18n("Top Level"), Group::TopLevel);
37     }
38 
39     return s_topLevel;
40 }
41 
temporary()42 Group *Group::temporary()
43 {
44     if (!s_temporary) {
45         s_temporary = new Group(i18n("Not in your contact list"), Group::Temporary);
46     }
47 
48     return s_temporary;
49 }
50 
offline()51 Group *Group::offline()
52 {
53     if (!s_offline) {
54         s_offline = new Group(i18n("Offline Users"), Group::Offline);
55     }
56 
57     return s_offline;
58 }
59 
60 uint Group::Private::uniqueGroupId = 0;
61 
Group(const QString & _name)62 Group::Group(const QString &_name)
63     : ContactListElement(ContactList::self())
64     , d(new Private())
65 {
66     d->displayName = _name;
67     d->type = Normal;
68     d->expanded = true;
69     d->groupId = 0;
70 }
71 
Group(const QString & _name,GroupType _type)72 Group::Group(const QString &_name, GroupType _type)
73     : ContactListElement(ContactList::self())
74     , d(new Private())
75 {
76     d->displayName = _name;
77     d->type = _type;
78     d->expanded = true;
79     d->groupId = 0;
80 }
81 
Group()82 Group::Group()
83     : ContactListElement(ContactList::self())
84     , d(new Private())
85 {
86     d->expanded = true;
87     d->type = Normal;
88     d->groupId = 0;
89 }
90 
~Group()91 Group::~Group()
92 {
93     if (d->type == TopLevel) {
94         s_topLevel = nullptr;
95     }
96     if (d->type == Temporary) {
97         s_temporary = nullptr;
98     }
99     if (d->type == Offline) {
100         s_offline = nullptr;
101     }
102     delete d;
103 }
104 
members() const105 QList<MetaContact *> Group::members() const
106 {
107     QList<MetaContact *> groupMembers;
108     foreach (MetaContact *mc, ContactList::self()->metaContacts()) {
109         if (mc->groups().contains(const_cast<Group *>(this))) {
110             groupMembers.append(mc);
111         }
112     }
113 
114     return groupMembers;
115 }
116 
setDisplayName(const QString & s)117 void Group::setDisplayName(const QString &s)
118 {
119     if (d->displayName != s) {
120         QString oldname = d->displayName;
121         d->displayName = s;
122         // Don't emit the signal in loading state
123         if (!loading()) {
124             emit displayNameChanged(this, oldname);
125         }
126     }
127 }
128 
displayName() const129 QString Group::displayName() const
130 {
131     return d->displayName;
132 }
133 
type() const134 Group::GroupType Group::type() const
135 {
136     return d->type;
137 }
138 
setExpanded(bool isExpanded)139 void Group::setExpanded(bool isExpanded)
140 {
141     d->expanded = isExpanded;
142 }
143 
isExpanded() const144 bool Group::isExpanded() const
145 {
146     return d->expanded;
147 }
148 
groupId() const149 uint Group::groupId() const
150 {
151     if (d->groupId == 0) {
152         d->groupId = ++d->uniqueGroupId;
153     }
154 
155     return d->groupId;
156 }
157 
setGroupId(uint groupId)158 void Group::setGroupId(uint groupId)
159 {
160     d->groupId = groupId;
161 }
162 
uniqueGroupId() const163 uint Group::uniqueGroupId() const
164 {
165     return d->uniqueGroupId;
166 }
167 
setUniqueGroupId(uint uniqueGroupId)168 void Group::setUniqueGroupId(uint uniqueGroupId)
169 {
170     d->uniqueGroupId = uniqueGroupId;
171 }
172 
sendMessage()173 void Group::sendMessage()
174 {
175     Kopete::Contact *c;
176 
177     if (onlineMembers().isEmpty()) {
178         return;
179     }
180     c = onlineMembers().first()->preferredContact();
181     c->sendMessage();
182     if (c->manager(Contact::CanCreate)) {
183         connect(c->manager(), SIGNAL(messageSent(Kopete::Message&,Kopete::ChatSession*)), this, SLOT(sendMessage(Kopete::Message&)));
184     }
185 }
186 
sendMessage(Message & msg)187 void Group::sendMessage(Message &msg)
188 {
189     QList<MetaContact *> list = onlineMembers();
190     ChatSession *cs = msg.manager();
191     if (cs) {
192         disconnect(cs, SIGNAL(messageSent(Kopete::Message&,Kopete::ChatSession*)), this, SLOT(sendMessage(Kopete::Message&)));
193     } else {
194         return;
195     }
196 
197     if (list.isEmpty()) {
198         return;
199     }
200     list.removeAll(msg.to().first()->metaContact());
201     QListIterator<MetaContact *> it(list);
202     while (it.hasNext())
203     {
204         MetaContact *mc = it.next();
205         if (mc->isReachable()) {
206             Contact *kcontact = mc->preferredContact();
207             if (kcontact->manager(Contact::CanCreate)) {
208                 //This is hack and stupid.    send message to group should never exist anyway - Olivier 2005-09-11
209                 // changing the "to" is require, because jabber use it to send the messgae.  Cf BUG 111514
210                 Message msg2(cs->myself(), kcontact);
211                 msg2.setPlainBody(msg.plainBody());
212                 msg2.setDirection(msg.direction());
213                 msg2.setRequestedPlugin(msg.requestedPlugin());
214 
215                 kcontact->manager(Contact::CanCreate)->sendMessage(msg2);
216             }
217         }
218     }
219 }
220 
onlineMembers() const221 QList<MetaContact *> Group::onlineMembers() const
222 {
223     QList<MetaContact *> list = members();
224     QList<MetaContact *>::iterator it = list.begin();
225     while (it != list.end())
226     {
227         if ((*it)->isReachable() && (*it)->isOnline()) {
228             ++it;
229         } else {
230             it = list.erase(it);
231         }
232     }
233     return list;
234 }
235 } //END namespace Kopete
236