~ubuntu-branches/ubuntu/saucy/kopete/saucy-proposed

« back to all changes in this revision

Viewing changes to protocols/wlm/wlmaccount.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-06-21 02:22:39 UTC
  • Revision ID: package-import@ubuntu.com-20130621022239-63l3zc8p0nf26pt6
Tags: upstream-4.10.80
ImportĀ upstreamĀ versionĀ 4.10.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    wlmaccount.cpp - Kopete Wlm Protocol
 
3
 
 
4
    Copyright (c) 2008      by Tiago Salem Herrmann <tiagosh@gmail.com>
 
5
    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
 
6
 
 
7
    *************************************************************************
 
8
    *                                                                       *
 
9
    * This library is free software; you can redistribute it and/or         *
 
10
    * modify it under the terms of the GNU General Public                   *
 
11
    * License as published by the Free Software Foundation; either          *
 
12
    * version 2 of the License, or (at your option) any later version.      *
 
13
    *                                                                       *
 
14
    *************************************************************************
 
15
*/
 
16
 
 
17
#include "wlmaccount.h"
 
18
 
 
19
#include <QTextCodec>
 
20
#include <QFile>
 
21
#include <QFileInfo>
 
22
#include <QImage>
 
23
#include <QDomDocument>
 
24
#include <QtCore/QCryptographicHash>
 
25
 
 
26
#include <kaction.h>
 
27
#include <kactionmenu.h>
 
28
#include <kdebug.h>
 
29
#include <klocale.h>
 
30
#include <kmenu.h>
 
31
#include <kmessagebox.h>
 
32
#include <knotification.h>
 
33
#include <KCodecs>
 
34
#include <KInputDialog>
 
35
#include <KStandardDirs>
 
36
#include <KToolInvocation>
 
37
 
 
38
#include "kopetechatsessionmanager.h"
 
39
#include "kopetemetacontact.h"
 
40
#include "kopetecontactlist.h"
 
41
#include "kopetegroup.h"
 
42
#include "kopetepassword.h"
 
43
#include "kopeteuiglobal.h"
 
44
#include "kopetepicture.h"
 
45
#include "kopeteutils.h"
 
46
#include "kopetetransfermanager.h"
 
47
#include "kopeteidentity.h"
 
48
#include "kopeteavatarmanager.h"
 
49
#include "kopeteaddedinfoevent.h"
 
50
 
 
51
#include "wlmcontact.h"
 
52
#include "wlmprotocol.h"
 
53
#include "wlmchatsession.h"
 
54
 
 
55
WlmAccount::WlmAccount (WlmProtocol * parent, const QString & accountID):
 
56
Kopete::PasswordedAccount (parent, accountID.toLower ()),
 
57
m_server (NULL),
 
58
m_transferManager (NULL),
 
59
m_chatManager (NULL),
 
60
clientid (0),
 
61
m_lastMainConnectionError(Callbacks::NoError)
 
62
{
 
63
    // Init the myself contact
 
64
    setMyself (new
 
65
               WlmContact (this, accountId (), QString(),
 
66
                           accountId (),
 
67
                           Kopete::ContactList::self ()->myself ()));
 
68
    myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
 
69
    clientid += MSN::MSNC7;
 
70
    clientid += MSN::SupportWinks;
 
71
    clientid += MSN::VoiceClips;
 
72
    clientid += MSN::InkGifSupport;
 
73
    clientid += MSN::SIPInvitations;
 
74
    clientid += MSN::SupportMultiPacketMessaging;
 
75
 
 
76
    m_openInboxAction = new KAction(KIcon("mail-folder-inbox"), i18n("Open Inbo&x..."), this);
 
77
    QObject::connect(m_openInboxAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenInbox()));
 
78
 
 
79
    m_changeDNAction = new KAction(i18n("&Change Display Name..."), this);
 
80
    QObject::connect(m_changeDNAction, SIGNAL(triggered(bool)), this, SLOT(slotChangePublicName()));
 
81
 
 
82
//     m_startChatAction = new KAction(KIcon("mail-message-new"), i18n("&Start Chat..."), this);
 
83
//     QObject::connect(m_startChatAction, SIGNAL(triggered(bool)), this, SLOT(slotStartChat()));
 
84
    
 
85
    m_openStatusAction = new KAction(i18n("Open MS&N service status site..."), this);
 
86
    QObject::connect(m_openStatusAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenStatus()));
 
87
 
 
88
    tmpMailFile = 0L;
 
89
    m_tmpMailFileTimer = new QTimer();
 
90
    QObject::connect(m_tmpMailFileTimer, SIGNAL(timeout()), this, SLOT(slotRemoveTmpMailFile()));
 
91
}
 
92
 
 
93
WlmAccount::~WlmAccount ()
 
94
{
 
95
    slotRemoveTmpMailFile();
 
96
    delete m_tmpMailFileTimer;
 
97
    disconnect ();
 
98
}
 
99
 
 
100
void
 
101
WlmAccount::fillActionMenu (KActionMenu * actionMenu)
 
102
{
 
103
    Kopete::Account::fillActionMenu (actionMenu);
 
104
    const bool connected = isConnected();
 
105
    m_openInboxAction->setEnabled(connected);
 
106
//     m_startChatAction->setEnabled(connected);
 
107
    m_changeDNAction->setEnabled(connected);
 
108
 
 
109
    actionMenu->addSeparator();
 
110
 
 
111
    actionMenu->addAction(m_changeDNAction);
 
112
//     actionMenu->addAction(m_startChatAction);
 
113
 
 
114
    actionMenu->addAction(m_openInboxAction);
 
115
    actionMenu->addAction(m_openStatusAction);
 
116
}
 
117
 
 
118
bool
 
119
WlmAccount::createContact (const QString & contactId,
 
120
                           Kopete::MetaContact * parentContact)
 
121
{
 
122
    if ( !m_server )
 
123
        return false;
 
124
 
 
125
    kDebug() << "contact " << contactId;
 
126
    WlmContact *newContact = new WlmContact (this, contactId, QString(), parentContact->displayName (), parentContact);
 
127
 
 
128
    if (parentContact->isTemporary())
 
129
        return true;
 
130
 
 
131
    if (m_serverSideContactsPassports.contains(contactId))
 
132
    {
 
133
        kDebug() << "contact " << contactId << " already on server list. Do nothing.";
 
134
        return true;
 
135
    }
 
136
 
 
137
    QString groupName;
 
138
    Kopete::GroupList kopeteGroups = parentContact->groups(); //get the group list
 
139
 
 
140
    if (kopeteGroups.isEmpty() || kopeteGroups.first() == Kopete::Group::topLevel())
 
141
        groupName = i18n("Buddies");
 
142
    else
 
143
        groupName = kopeteGroups.first() ? kopeteGroups.first()->displayName() : i18n("Buddies");
 
144
 
 
145
    // emergency exit, should never occur
 
146
    if (groupName.isEmpty())
 
147
        return false;
 
148
 
 
149
    m_contactAddQueue.insert(contactId, groupName);
 
150
        if (!m_groupToGroupId.contains(groupName))
 
151
    {
 
152
        kDebug() << "group \'" << groupName << "\' not found adding group";
 
153
        m_server->cb.mainConnection->addGroup (groupName.toUtf8().constData());
 
154
    }
 
155
    else
 
156
    {
 
157
        kDebug() << "group \'" << groupName << "\' found adding contact";
 
158
        m_server->cb.mainConnection->addToAddressBook (contactId.toLatin1().constData(), contactId.toUtf8().constData());
 
159
    }
 
160
 
 
161
        return newContact != 0L;
 
162
}
 
163
 
 
164
void WlmAccount::setPersonalMessage (const Kopete::StatusMessage & reason)
 
165
{
 
166
    kDebug (14210) << k_funcinfo;
 
167
    myself()->setStatusMessage(reason);
 
168
    if (isConnected ())
 
169
    {
 
170
        MSN::personalInfo pInfo;
 
171
        pInfo.mediaIsEnabled = 0;
 
172
        if (reason.message().isEmpty ())
 
173
            pInfo.PSM = "";
 
174
        else
 
175
            pInfo.PSM = reason.message().toUtf8().constData();
 
176
 
 
177
        // we have both artist and title
 
178
        if( reason.hasMetaData("artist") && reason.hasMetaData("title") )
 
179
        {
 
180
            pInfo.mediaIsEnabled = 1;
 
181
            pInfo.mediaType="Music";
 
182
            pInfo.mediaLines.push_back( reason.metaData("artist").toString().toUtf8().constData() );
 
183
            pInfo.mediaLines.push_back( reason.metaData("title").toString().toUtf8().constData() );
 
184
            pInfo.mediaFormat="{0} - {1}";
 
185
            m_server->cb.mainConnection->setPersonalStatus (pInfo);
 
186
            return;
 
187
        }
 
188
    
 
189
        // we have only the title
 
190
        if( reason.hasMetaData("title") )
 
191
        {
 
192
            pInfo.mediaIsEnabled = 1;
 
193
            pInfo.mediaType="Music";
 
194
            pInfo.mediaFormat="{0}";
 
195
            pInfo.mediaLines.push_back( reason.metaData("title").toString().toUtf8().constData() );
 
196
            m_server->cb.mainConnection->setPersonalStatus (pInfo);
 
197
            return;
 
198
        }
 
199
        m_server->cb.mainConnection->setPersonalStatus (pInfo);
 
200
    }
 
201
}
 
202
 
 
203
void
 
204
WlmAccount::setOnlineStatus (const Kopete::OnlineStatus & status,
 
205
                             const Kopete::StatusMessage & reason,
 
206
                             const OnlineStatusOptions& /*options*/)
 
207
{
 
208
    kDebug (14210) << k_funcinfo;
 
209
 
 
210
    setPersonalMessage(reason);
 
211
 
 
212
    temporaryStatus = status;
 
213
 
 
214
    if (status == WlmProtocol::protocol ()->wlmConnecting &&
 
215
        myself ()->onlineStatus () == WlmProtocol::protocol ()->wlmOffline)
 
216
        slotGoOnline ();
 
217
    else if (status == WlmProtocol::protocol ()->wlmOnline || status.status () == Kopete::OnlineStatus::Online)
 
218
        slotGoOnline ();
 
219
    else if (status == WlmProtocol::protocol ()->wlmOffline)
 
220
        slotGoOffline ();
 
221
    else if (status == WlmProtocol::protocol ()->wlmInvisible)
 
222
        slotGoInvisible ();
 
223
    else if (status.status () == Kopete::OnlineStatus::Away ||
 
224
              status.status () == Kopete::OnlineStatus::Busy)
 
225
        slotGoAway (status);
 
226
}
 
227
 
 
228
void
 
229
WlmAccount::setStatusMessage (const Kopete::StatusMessage & statusMessage)
 
230
{
 
231
    setPersonalMessage(statusMessage);
 
232
}
 
233
 
 
234
void
 
235
WlmAccount::slotChangePublicName()
 
236
{
 
237
    if ( !isConnected() )
 
238
    {
 
239
        return;
 
240
        //TODO:  change it anyway, and sync at the next connection
 
241
    }
 
242
 
 
243
    bool ok;
 
244
    const QString name = KInputDialog::getText( i18n( "Change Display Name - MSN Plugin" ), //TODO rename MSN to WLM (see also following strings)
 
245
        i18n( "Enter the new display name by which you want to be visible to your friends on MSN:" ),
 
246
        myself()->property( Kopete::Global::Properties::self()->nickName()).value().toString(), &ok );
 
247
 
 
248
    if ( ok )
 
249
    {
 
250
        if ( name.length() > 387 )
 
251
        {
 
252
            KMessageBox::error( Kopete::UI::Global::mainWidget(),
 
253
                i18n( "<qt>The display name you entered is too long. Please use a shorter name.\n"
 
254
                    "Your display name has <b>not</b> been changed.</qt>" ),
 
255
                i18n( "Change Display Name - MSN Plugin" ) );
 
256
            return;
 
257
        }
 
258
 
 
259
        m_server->cb.mainConnection->setFriendlyName(name.toUtf8().constData(), true);
 
260
    }
 
261
}
 
262
 
 
263
void
 
264
WlmAccount::slotOpenInbox()
 
265
{
 
266
    if (isConnected ())
 
267
        m_server->cb.mainConnection->getInboxUrl ();
 
268
}
 
269
 
 
270
void
 
271
WlmAccount::slotOpenStatus()
 
272
{
 
273
    KToolInvocation::invokeBrowser(QLatin1String("http://messenger.msn.com/Status.aspx")) ;
 
274
}
 
275
 
 
276
void
 
277
WlmAccount::connectWithPassword (const QString & pass)
 
278
{
 
279
    kDebug (14210) << k_funcinfo;
 
280
    if (myself ()->onlineStatus () != WlmProtocol::protocol ()->wlmOffline)
 
281
        return;
 
282
 
 
283
    if (pass.isEmpty ())
 
284
    {
 
285
        // User has cancelled password prompt.
 
286
        return;
 
287
    }
 
288
 
 
289
    password ().setWrong (false);
 
290
 
 
291
    QString id = accountId ();
 
292
    QString pass1 = pass;
 
293
 
 
294
    enableInitialList ();
 
295
 
 
296
    m_lastMainConnectionError = Callbacks::NoError;
 
297
    m_server = new WlmServer (this, id, pass1);
 
298
    m_server->WlmConnect ( serverName(), serverPort() );
 
299
 
 
300
    m_transferManager = new WlmTransferManager (this);
 
301
 
 
302
    m_chatManager = new WlmChatManager (this);
 
303
 
 
304
    QObject::connect (&m_server->cb, SIGNAL (connectionCompleted()),
 
305
                      this, SLOT (connectionCompleted()));
 
306
    QObject::connect (&m_server->cb, SIGNAL (connectionFailed()),
 
307
                      this, SLOT (connectionFailed()));
 
308
    QObject::connect (&m_server->cb, SIGNAL(socketError(int)),
 
309
                      this, SLOT(error(int)));
 
310
    QObject::connect (&m_server->cb, SIGNAL(mainConnectionError(int)),
 
311
                      this, SLOT(mainConnectionError(int)));
 
312
    QObject::connect (&m_server->cb,
 
313
                      SIGNAL (gotDisplayName(QString)), this,
 
314
                      SLOT (gotDisplayName(QString)));
 
315
    QObject::connect (&m_server->cb,
 
316
                      SIGNAL (receivedOIMList
 
317
                              (std::vector < MSN::eachOIM > &)), this,
 
318
                      SLOT (receivedOIMList
 
319
                            (std::vector < MSN::eachOIM > &)));
 
320
    QObject::connect (&m_server->cb,
 
321
                      SIGNAL (receivedOIM(QString,QString)),
 
322
                      this,
 
323
                      SLOT (receivedOIM(QString,QString)));
 
324
 
 
325
    QObject::connect (&m_server->cb,
 
326
                      SIGNAL (deletedOIM(QString,bool)), this,
 
327
                      SLOT (deletedOIM(QString,bool)));
 
328
    QObject::connect (&m_server->cb,
 
329
                      SIGNAL (NotificationServerConnectionTerminated
 
330
                              (MSN::NotificationServerConnection *)), this,
 
331
                      SLOT (NotificationServerConnectionTerminated
 
332
                            (MSN::NotificationServerConnection *)));
 
333
    QObject::connect (&m_server->cb, SIGNAL (initialEmailNotification(int)), this,
 
334
                      SLOT (slotInitialEmailNotification(int)));
 
335
    QObject::connect (&m_server->cb, SIGNAL (newEmailNotification(QString,QString)), this,
 
336
                      SLOT (slotNewEmailNotification(QString,QString)));
 
337
    QObject::connect (&m_server->cb, SIGNAL (inboxUrl(MSN::hotmailInfo&)), this,
 
338
                      SLOT (slotInboxUrl(MSN::hotmailInfo&)));
 
339
 
 
340
    myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmConnecting);
 
341
}
 
342
 
 
343
QString WlmAccount::serverName() const
 
344
{
 
345
    return configGroup()->readEntry( "serverName" , "messenger.hotmail.com" );
 
346
}
 
347
 
 
348
uint WlmAccount::serverPort() const
 
349
{
 
350
    return configGroup()->readEntry( "serverPort" , 1863 );
 
351
}
 
352
 
 
353
QString WlmAccount::proxyUsername() const
 
354
{
 
355
    return configGroup()->readEntry( "proxyUsername" );
 
356
}
 
357
 
 
358
QString WlmAccount::proxyPassword() const
 
359
{
 
360
    return configGroup()->readEntry( "proxyPassword" );
 
361
}
 
362
 
 
363
QString WlmAccount::proxyHost() const
 
364
{
 
365
    return configGroup()->readEntry( "proxyHost" );
 
366
}
 
367
 
 
368
uint WlmAccount::proxyType() const
 
369
{
 
370
    return configGroup()->readEntry( "proxyType", 0 );
 
371
}
 
372
 
 
373
uint WlmAccount::proxyPort() const
 
374
{
 
375
    return configGroup()->readEntry( "proxyPort", 8080 );
 
376
}
 
377
 
 
378
bool WlmAccount::isProxyEnabled() const
 
379
{
 
380
    return configGroup()->readEntry( "enableProxy", false );
 
381
}
 
382
 
 
383
bool WlmAccount::doNotRequestEmoticons() const
 
384
{
 
385
    return configGroup()->readEntry( "doNotRequestEmoticons", false );
 
386
}
 
387
 
 
388
bool WlmAccount::doNotSendEmoticons() const
 
389
{
 
390
    return configGroup()->readEntry( "doNotSendEmoticons", false );
 
391
}
 
392
 
 
393
void
 
394
WlmAccount::gotNewContact (const MSN::ContactList & list,
 
395
                           const QString & passport,
 
396
                           const QString & friendlyname)
 
397
{
 
398
    kDebug() << "contact " << passport;
 
399
    if (list == MSN::LST_RL)
 
400
    {
 
401
        kDebug() << "contact " << passport << " added to reverse list";
 
402
        m_reverseList.insert(passport);
 
403
        Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent(passport, this);
 
404
        QObject::connect(event, SIGNAL(actionActivated(uint)), this, SLOT(addedInfoEventActionActivated(uint)));
 
405
 
 
406
        Kopete::AddedInfoEvent::ShowActionOptions actions = Kopete::AddedInfoEvent::AuthorizeAction;
 
407
        actions |= Kopete::AddedInfoEvent::BlockAction;
 
408
        //actions |= Kopete::AddedInfoEvent::InfoAction;
 
409
 
 
410
        WlmContact * ct = qobject_cast<WlmContact*>(contacts().value(passport));
 
411
        if (!ct || !ct->metaContact() || ct->metaContact()->isTemporary())
 
412
            actions |= Kopete::AddedInfoEvent::AddAction;
 
413
 
 
414
        event->setContactNickname(friendlyname);
 
415
        event->showActions(actions);
 
416
        event->sendEvent();
 
417
    }
 
418
    else if (list == MSN::LST_BL)
 
419
    {
 
420
        kDebug() << "contact " << passport << " added to block list";
 
421
        m_allowList.remove(passport);
 
422
        m_blockList.insert(passport);
 
423
        WlmContact * ct = qobject_cast<WlmContact*>(contacts().value(passport));
 
424
        if(ct)
 
425
            ct->setOnlineStatus(ct->onlineStatus());
 
426
    }
 
427
    else if (list == MSN::LST_AL)
 
428
    {
 
429
        kDebug() << "contact " << passport << " added to allow list";
 
430
        m_blockList.remove(passport);
 
431
        m_allowList.insert(passport);
 
432
            WlmContact * ct = qobject_cast<WlmContact*>(contacts().value(passport));
 
433
        if(ct)
 
434
            ct->setOnlineStatus(ct->onlineStatus());
 
435
    }
 
436
}
 
437
 
 
438
void WlmAccount::gotRemovedContactFromList (const MSN::ContactList & list, const QString & contact)
 
439
{
 
440
    kDebug() << "contact " << contact;
 
441
    if (list == MSN::LST_BL)
 
442
    {
 
443
        kDebug() << "contact " << contact << " removed from block list";
 
444
        m_blockList.remove( contact );
 
445
    }
 
446
    else if (list == MSN::LST_AL)
 
447
    {
 
448
        kDebug() << "contact " << contact << " removed from allow list";
 
449
        m_allowList.remove( contact );
 
450
    }
 
451
    else if (list == MSN::LST_RL)
 
452
    {
 
453
        kDebug() << "contact " << contact << " removed from reverse list";
 
454
        m_reverseList.remove( contact );
 
455
        // force overlayIcons to be updated
 
456
            WlmContact * ct = qobject_cast<WlmContact*>(contacts().value( contact ));
 
457
        if(ct)
 
458
            ct->setOnlineStatus(ct->onlineStatus());
 
459
    }
 
460
}
 
461
 
 
462
void WlmAccount::addedInfoEventActionActivated(uint actionId)
 
463
{
 
464
    Kopete::AddedInfoEvent *event = qobject_cast<Kopete::AddedInfoEvent *>(sender());
 
465
    if (!event || !isConnected())
 
466
        return;
 
467
 
 
468
    switch (actionId)
 
469
    {
 
470
    case Kopete::AddedInfoEvent::AddContactAction:
 
471
        event->addContact();
 
472
        break;
 
473
    case Kopete::AddedInfoEvent::AuthorizeAction:
 
474
        blockContact(event->contactId(), false);
 
475
        break;
 
476
    case Kopete::AddedInfoEvent::BlockAction:
 
477
        if (isOnAllowList(event->contactId()))
 
478
            server()->mainConnection->removeFromList(MSN::LST_AL, event->contactId().toLatin1().constData());
 
479
        if(!isOnBlockList(event->contactId()))
 
480
            server()->mainConnection->addToList(MSN::LST_BL, event->contactId().toLatin1().constData());
 
481
        break;
 
482
/*    case Kopete::AddedInfoEvent::InfoAction:
 
483
        break;*/
 
484
    }
 
485
}
 
486
 
 
487
void
 
488
WlmAccount::mainConnectionError(int errorCode)
 
489
{
 
490
    kDebug (14210) << k_funcinfo;
 
491
    m_lastMainConnectionError = errorCode;
 
492
}
 
493
 
 
494
void
 
495
WlmAccount::scheduleConnect ()
 
496
{
 
497
    connect (temporaryStatus);
 
498
}
 
499
 
 
500
void
 
501
WlmAccount::gotDisplayPicture (const QString & contactId,
 
502
                               const QString & filename)
 
503
{
 
504
    // FIXME: Why we get local file and not just QByteArray data?
 
505
    kDebug (14210) << k_funcinfo;
 
506
    WlmContact * contact = qobject_cast<WlmContact*>(contacts().value(contactId));
 
507
    if (contact)
 
508
    {
 
509
        // remove from pending display pictures list if applicable
 
510
        m_pendingDisplayPictureList.remove(contactId);
 
511
 
 
512
        // check file integrity (SHA1D)
 
513
        QDomDocument xmlobj;
 
514
        xmlobj.setContent (contact->getMsnObj());
 
515
        QString SHA1D_orig = xmlobj.documentElement ().attribute ("SHA1D");
 
516
 
 
517
        QFile f(filename);
 
518
        QByteArray avatarData;
 
519
        if (f.exists() && f.size() > 0 && f.open(QIODevice::ReadOnly))
 
520
        {
 
521
            avatarData = f.readAll();
 
522
            f.close();
 
523
        }
 
524
        QFile::remove(filename);
 
525
 
 
526
        if (!avatarData.isEmpty() && !SHA1D_orig.isEmpty() &&
 
527
            SHA1D_orig == QCryptographicHash::hash(avatarData, QCryptographicHash::Sha1).toBase64())
 
528
        {
 
529
            QImage img;
 
530
            img.loadFromData(avatarData);
 
531
 
 
532
            Kopete::AvatarManager::AvatarEntry entry;
 
533
            entry.name = contact->contactId();
 
534
            entry.category = Kopete::AvatarManager::Contact;
 
535
            entry.contact = contact;
 
536
            entry.image = img;
 
537
            entry = Kopete::AvatarManager::self()->add(entry);
 
538
            if (!entry.dataPath.isNull())
 
539
            {
 
540
                contact->removeProperty(Kopete::Global::Properties::self()->photo());
 
541
                contact->setProperty(Kopete::Global::Properties::self()->photo(), entry.dataPath);
 
542
                contact->setProperty(WlmProtocol::protocol()->displayPhotoSHA1, SHA1D_orig);
 
543
            }
 
544
        }
 
545
        else
 
546
        {
 
547
            contact->removeProperty(WlmProtocol::protocol()->displayPhotoSHA1);
 
548
            contact->removeProperty(Kopete::Global::Properties::self()->photo());
 
549
        }
 
550
    }
 
551
}
 
552
 
 
553
void
 
554
WlmAccount::gotDisplayName (const QString & displayName)
 
555
{
 
556
    kDebug (14210) << k_funcinfo;
 
557
    myself ()->setProperty (Kopete::Global::Properties::self ()->nickName (),
 
558
                            displayName);
 
559
}
 
560
 
 
561
void
 
562
WlmAccount::gotContactPersonalInfo (const QString & fromPassport,
 
563
                                    const MSN::personalInfo & pInfo)
 
564
{
 
565
    kDebug (14210) << k_funcinfo;
 
566
        WlmContact * contact = qobject_cast<WlmContact*>(contacts().value(fromPassport));
 
567
    if (contact)
 
568
    {
 
569
        // TODO - handle the other fields of pInfo
 
570
        contact->setStatusMessage(Kopete::StatusMessage(WlmUtils::utf8(pInfo.PSM)));
 
571
        QString type(WlmUtils::utf8(pInfo.mediaType));
 
572
        if (pInfo.mediaIsEnabled && type == "Music")
 
573
        {
 
574
            QString song_line (WlmUtils::utf8(pInfo.mediaFormat));
 
575
            int num = pInfo.mediaLines.size ();
 
576
            for (int i = 0; i < num; i++)
 
577
            {
 
578
                song_line.replace ('{' + QString::number (i) + '}', WlmUtils::utf8(pInfo.mediaLines[i]));
 
579
            }
 
580
            contact->setProperty (WlmProtocol::protocol ()->currentSong, song_line);
 
581
        }
 
582
        else
 
583
        {
 
584
            contact->removeProperty (WlmProtocol::protocol ()->currentSong);
 
585
        }
 
586
    }
 
587
}
 
588
 
 
589
void
 
590
WlmAccount::contactChangedStatus (const QString & buddy,
 
591
                                  const QString & friendlyname,
 
592
                                  const MSN::BuddyStatus & state,
 
593
                                  const unsigned int &clientID,
 
594
                                  const QString & msnobject)
 
595
{
 
596
    kDebug (14210) << k_funcinfo;
 
597
        WlmContact *contact = qobject_cast<WlmContact*>(contacts().value(buddy));
 
598
    if (contact)
 
599
    {
 
600
        contact->setProperty (Kopete::Global::Properties::self ()->
 
601
                              nickName (), friendlyname);
 
602
 
 
603
        // set contact properties
 
604
        contact->setProperty (WlmProtocol::protocol ()->contactCapabilities, QString::number(clientID));
 
605
 
 
606
        if (state == MSN::STATUS_AWAY)
 
607
            contact->setOnlineStatus (WlmProtocol::protocol ()->wlmAway);
 
608
        else if (state == MSN::STATUS_AVAILABLE)
 
609
            contact->setOnlineStatus (WlmProtocol::protocol ()->wlmOnline);
 
610
        else if (state == MSN::STATUS_INVISIBLE)
 
611
            contact->setOnlineStatus (WlmProtocol::protocol ()->wlmInvisible);
 
612
        else if (state == MSN::STATUS_BUSY)
 
613
            contact->setOnlineStatus (WlmProtocol::protocol ()->wlmBusy);
 
614
        else if (state == MSN::STATUS_OUTTOLUNCH)
 
615
            contact->setOnlineStatus (WlmProtocol::protocol ()->
 
616
                                      wlmOutToLunch);
 
617
        else if (state == MSN::STATUS_ONTHEPHONE)
 
618
            contact->setOnlineStatus (WlmProtocol::protocol ()->
 
619
                                      wlmOnThePhone);
 
620
        else if (state == MSN::STATUS_BERIGHTBACK)
 
621
            contact->setOnlineStatus (WlmProtocol::protocol ()->
 
622
                                      wlmBeRightBack);
 
623
        else if (state == MSN::STATUS_IDLE)
 
624
            contact->setOnlineStatus (WlmProtocol::protocol ()->wlmIdle);
 
625
 
 
626
        qobject_cast <WlmContact *>(contact)->setMsnObj(msnobject);
 
627
 
 
628
        if (msnobject.isEmpty () || msnobject == "0")   // no picture
 
629
        {
 
630
            contact->removeProperty(WlmProtocol::protocol()->displayPhotoSHA1);
 
631
            contact->removeProperty(Kopete::Global::Properties::self()->photo());
 
632
            return;
 
633
        }
 
634
 
 
635
        QDomDocument xmlobj;
 
636
        xmlobj.setContent (msnobject);
 
637
 
 
638
        // track display pictures by SHA1D field
 
639
        QString SHA1D = xmlobj.documentElement ().attribute ("SHA1D");
 
640
 
 
641
        if (SHA1D.isEmpty ())
 
642
            return;
 
643
 
 
644
        QString currentSHA1D = contact->property(WlmProtocol::protocol()->displayPhotoSHA1).value().toString();
 
645
        QString photoPath = contact->property(Kopete::Global::Properties::self()->photo().key()).value().toString();
 
646
        if (SHA1D == currentSHA1D && QFileInfo(photoPath).size() > 0)
 
647
            return;
 
648
 
 
649
        // do not request all pictures at once when you are just connected
 
650
        if (isInitialList ())
 
651
        {
 
652
            // schedule to retrieve this picture later
 
653
            m_pendingDisplayPictureList.insert(buddy);
 
654
            return;
 
655
        }
 
656
 
 
657
        if ((myself ()->onlineStatus () !=
 
658
                WlmProtocol::protocol ()->wlmOffline)
 
659
               && (myself ()->onlineStatus () !=
 
660
                   WlmProtocol::protocol ()->wlmInvisible)
 
661
               && (myself ()->onlineStatus () !=
 
662
                   WlmProtocol::protocol ()->wlmUnknown))
 
663
        {
 
664
            // do not open many switchboards in a short period of time
 
665
            if(!m_recentDPRequests.contains(buddy))
 
666
            {
 
667
                m_recentDPRequests.append(buddy);
 
668
                QTimer::singleShot(10 * 1000, this, SLOT(slotRemoveRecentDPRequests()));
 
669
                chatManager ()->requestDisplayPicture(buddy);
 
670
            }
 
671
        }
 
672
    }
 
673
}
 
674
 
 
675
void
 
676
WlmAccount::contactDisconnected (const QString & buddy)
 
677
{
 
678
    kDebug (14210) << k_funcinfo;
 
679
        WlmContact * contact = qobject_cast<WlmContact*>(contacts().value(buddy));
 
680
    if (contact)
 
681
    {
 
682
        contact->setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
 
683
    }
 
684
}
 
685
 
 
686
void
 
687
WlmAccount::groupListReceivedFromServer (std::map < std::string, MSN::Group > &list)
 
688
{
 
689
    kDebug (14210) << k_funcinfo;
 
690
    // add server groups on local list
 
691
    std::map < std::string, MSN::Group >::iterator it;
 
692
    for (it = list.begin (); it != list.end (); ++it)   // groups from server
 
693
    {
 
694
        MSN::Group * g = &(*it).second;
 
695
 
 
696
        QString gName = WlmUtils::utf8(g->name);
 
697
        Kopete::Group * b = Kopete::ContactList::self ()->findGroup(gName);
 
698
        if (!b)
 
699
        {
 
700
            b = new Kopete::Group(gName);
 
701
            Kopete::ContactList::self ()->addGroup( b );
 
702
        }
 
703
 
 
704
        m_groupToGroupId.insert(gName, WlmUtils::latin1(g->groupID));
 
705
    }
 
706
/*
 
707
        // remove local groups which are not on server
 
708
        QPtrList<Kopete::Group>::Iterator it1 =  Kopete::ContactList::self()->groups().begin();
 
709
        Kopete::Group *group;
 
710
        for ( group = Kopete::ContactList::self()->groups().first(); group; group = Kopete::ContactList::self()->groups().next() )
 
711
        {
 
712
                bool ok=false;
 
713
                std::map<std::string, MSN::Group>::iterator it;
 
714
                for ( it = list.begin(); it != list.end(); ++it ) // groups from server
 
715
                {
 
716
                        MSN::Group *g = &(*it).second;
 
717
                        if(Kopete::ContactList::self()->findGroup(WlmUtils::utf8(g->name)))
 
718
                                ok=true;
 
719
                }
 
720
                if(!ok)
 
721
                {
 
722
                        if(!group->members().count())
 
723
                                Kopete::ContactList::self()->removeGroup(group);
 
724
                }
 
725
        }
 
726
*/
 
727
}
 
728
 
 
729
void
 
730
WlmAccount::addressBookReceivedFromServer (std::map < std::string,
 
731
                                           MSN::Buddy * >&list)
 
732
{
 
733
    kDebug (14210) << k_funcinfo;
 
734
 
 
735
    // Clear server side passports
 
736
    m_serverSideContactsPassports.clear ();
 
737
    m_allowList.clear();
 
738
    m_blockList.clear();
 
739
    m_pendingList.clear();
 
740
    m_reverseList.clear();
 
741
 
 
742
    // local contacts which do not exist on server should be deleted
 
743
    std::map < std::string, MSN::Buddy * >::iterator it;
 
744
    for (it = list.begin (); it != list.end (); ++it)
 
745
    {
 
746
        Kopete::MetaContact * metacontact = 0L;
 
747
        MSN::Buddy * b = (*it).second;
 
748
        QString passport = WlmUtils::passport(b->userName);
 
749
 
 
750
        if (b->lists & MSN::LST_AB)
 
751
            m_serverSideContactsPassports.insert(passport);
 
752
        if ( b->lists & MSN::LST_AL )
 
753
            m_allowList.insert( passport );
 
754
        if ( b->lists & MSN::LST_BL )
 
755
            m_blockList.insert( passport );
 
756
        if ( b->lists & MSN::LST_PL )
 
757
            m_pendingList.insert( passport );
 
758
        if ( b->lists & MSN::LST_RL )
 
759
            m_reverseList.insert(passport);
 
760
 
 
761
        // disabled users (not in list)
 
762
        if(b->properties["isMessengerUser"] == "false")
 
763
        {
 
764
            // disable this contact
 
765
                WlmContact *contact = qobject_cast<WlmContact*>(contacts().value( passport ));
 
766
            if (!contact)
 
767
            {
 
768
                addContact (passport, QString(), Kopete::Group::topLevel (), Kopete::Account::DontChangeKABC);
 
769
                    contact = qobject_cast<WlmContact*>(contacts().value( passport ));
 
770
            }
 
771
            if(contact)
 
772
            {
 
773
                contact->setContactSerial(WlmUtils::latin1(b->properties["contactId"]));
 
774
                contact->setCurrentGroup(Kopete::Group::topLevel());
 
775
                contact->setDisabled(true, false);
 
776
            }
 
777
            continue;
 
778
        }
 
779
 
 
780
            if ( !contacts().value( passport ) )
 
781
        {
 
782
            if (!b->friendlyName.length ())
 
783
                b->friendlyName = b->userName;
 
784
 
 
785
            std::list < MSN::Group * >::iterator i = b->groups.begin ();
 
786
 
 
787
            // no groups, add to top level
 
788
            if (!b->groups.size ())
 
789
            {
 
790
                // only add users in forward list
 
791
                if (b->lists & MSN::LST_AB)
 
792
                {
 
793
                    metacontact = addContact (passport, QString(), Kopete::Group::topLevel (), Kopete::Account::DontChangeKABC);
 
794
 
 
795
                    WlmContact * newcontact = qobject_cast<WlmContact*>(contacts().value(passport));
 
796
                    if(!newcontact)
 
797
                        return;
 
798
 
 
799
                    newcontact->setProperty (Kopete::Global::Properties::self ()->nickName (), WlmUtils::utf8(b->friendlyName));
 
800
                }
 
801
 
 
802
                if (metacontact)
 
803
                {
 
804
                        WlmContact *contact = qobject_cast<WlmContact*>(contacts().value( passport ));
 
805
                    if (contact)
 
806
                    {
 
807
                        contact->setContactSerial(WlmUtils::latin1(b->properties["contactId"]));
 
808
                        kDebug (14210) << "ContactID: " << WlmUtils::latin1(b->properties["contactId"]);
 
809
                    }
 
810
                }
 
811
                continue;
 
812
            }
 
813
 
 
814
            for (; i != b->groups.end (); ++i)
 
815
            {
 
816
                Kopete::Group * g = Kopete::ContactList::self ()->findGroup (WlmUtils::utf8((*i)->name));
 
817
 
 
818
                if (g)
 
819
                    metacontact = addContact (passport, QString(), g, Kopete::Account::DontChangeKABC);
 
820
                else
 
821
                    metacontact = addContact (passport, QString(), Kopete::Group::topLevel (), Kopete::Account::DontChangeKABC);
 
822
 
 
823
                if (metacontact)
 
824
                {
 
825
                        WlmContact *contact = qobject_cast<WlmContact*>(contacts().value( passport ));
 
826
                    if (contact)
 
827
                    {
 
828
                        contact->setProperty(Kopete::Global::Properties::self ()->nickName (), WlmUtils::utf8(b->friendlyName));
 
829
                        contact->setContactSerial(WlmUtils::latin1(b->properties["contactId"]));
 
830
                        kDebug (14210) << "ContactID: " << WlmUtils::latin1(b->properties["contactId"]);
 
831
                    }
 
832
                }
 
833
            }
 
834
        }
 
835
        else
 
836
        {
 
837
            // check if this contact has changed groups while we were offline.
 
838
            // users in the toplevel group on server side
 
839
            if( b->groups.size() == 0)
 
840
            {
 
841
                    Kopete::Group *current = contacts().value( passport )->metaContact()->groups().first();
 
842
                // the contact has no group, so put it on top level group
 
843
                if(current != Kopete::Group::topLevel ())
 
844
                {
 
845
                        contacts().value( passport )->metaContact()->
 
846
                        moveToGroup(current, Kopete::Group::topLevel ());
 
847
                        qobject_cast<WlmContact*>(contacts().value( passport ))->setCurrentGroup(Kopete::Group::topLevel());
 
848
                }
 
849
                continue;
 
850
            }
 
851
            // users in only one group on server side
 
852
            if( b->groups.size() == 1)
 
853
            {
 
854
                // users in only one group in the local list
 
855
                if(contacts().value( passport )->metaContact()->groups().size() == 1) 
 
856
                {
 
857
                        Kopete::Group *current = contacts().value( passport )->metaContact()->groups().first();
 
858
                    Kopete::Group *newgroup = Kopete::ContactList::self ()->findGroup(WlmUtils::utf8(b->groups.front()->name));
 
859
 
 
860
                    if(!current || !newgroup)
 
861
                        continue;
 
862
 
 
863
                    if(current != newgroup)
 
864
                    {
 
865
                            contacts().value( passport )->metaContact()->moveToGroup(current, newgroup);
 
866
                            qobject_cast<WlmContact*>(contacts().value( passport ))->setCurrentGroup(newgroup);
 
867
                    }
 
868
                }
 
869
            }
 
870
        }
 
871
    }
 
872
}
 
873
 
 
874
void
 
875
WlmAccount::slotGlobalIdentityChanged (Kopete::PropertyContainer *,
 
876
                                       const QString & key, const QVariant &,
 
877
                                       const QVariant & newValue)
 
878
{
 
879
    kDebug (14210) << k_funcinfo;
 
880
    if (key == Kopete::Global::Properties::self ()->photo ().key ())
 
881
    {
 
882
        m_pictureFilename = newValue.toString ();
 
883
        // TODO - Set no photo on server
 
884
        if (m_pictureFilename.isEmpty ())
 
885
        {
 
886
            myself()->removeProperty(Kopete::Global::Properties::self()->photo ());
 
887
            if(m_server && isConnected ())
 
888
            {
 
889
                m_server->cb.mainConnection->change_DisplayPicture ("");
 
890
                setOnlineStatus (myself ()->onlineStatus ());
 
891
            }
 
892
            return;
 
893
        }
 
894
 
 
895
        QImage contactPhoto = QImage( m_pictureFilename );
 
896
        Kopete::AvatarManager::AvatarEntry entry;
 
897
        entry.name = myself ()->contactId();
 
898
        entry.image = contactPhoto;
 
899
        entry.category = Kopete::AvatarManager::Contact;
 
900
        entry.contact = myself();
 
901
        entry = Kopete::AvatarManager::self()->add(entry);
 
902
 
 
903
        kDebug (14140) << k_funcinfo << m_pictureFilename;
 
904
        if(!entry.path.isNull())
 
905
        {
 
906
            if(m_server)
 
907
                m_server->cb.mainConnection->change_DisplayPicture(QFile::encodeName(entry.path).constData());
 
908
 
 
909
            myself()->setProperty(Kopete::Global::Properties::self()->photo (), entry.path);
 
910
        }
 
911
        setOnlineStatus (myself ()->onlineStatus ());
 
912
    }
 
913
    else if (key == Kopete::Global::Properties::self ()->nickName ().key ())
 
914
    {
 
915
        QString oldNick =
 
916
            myself ()->property (Kopete::Global::Properties::self ()->
 
917
                                 nickName ()).value ().toString ();
 
918
        QString newNick = newValue.toString ();
 
919
 
 
920
        if (newNick != oldNick)
 
921
        {
 
922
            if(m_server && isConnected())
 
923
                m_server->cb.mainConnection->setFriendlyName (newNick.toUtf8().constData());
 
924
        }
 
925
    }
 
926
}
 
927
 
 
928
void
 
929
WlmAccount::changedStatus (MSN::BuddyStatus & state)
 
930
{
 
931
    kDebug (14210) << k_funcinfo;
 
932
    if (state == MSN::STATUS_AWAY)
 
933
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmAway);
 
934
    else if (state == MSN::STATUS_AVAILABLE)
 
935
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmOnline);
 
936
    else if (state == MSN::STATUS_INVISIBLE)
 
937
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmInvisible);
 
938
    else if (state == MSN::STATUS_BUSY)
 
939
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmBusy);
 
940
    else if (state == MSN::STATUS_OUTTOLUNCH)
 
941
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmOutToLunch);
 
942
    else if (state == MSN::STATUS_ONTHEPHONE)
 
943
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmOnThePhone);
 
944
    else if (state == MSN::STATUS_BERIGHTBACK)
 
945
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmBeRightBack);
 
946
    if (state == MSN::STATUS_IDLE)
 
947
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmIdle);
 
948
 
 
949
}
 
950
 
 
951
void
 
952
WlmAccount::connectionFailed ()
 
953
{
 
954
    kDebug (14210) << k_funcinfo;
 
955
    logOff( Kopete::Account::Unknown );
 
956
    Kopete::Utils::notifyCannotConnect (this);
 
957
}
 
958
 
 
959
void
 
960
WlmAccount::connectionCompleted ()
 
961
{
 
962
    kDebug (14210) << k_funcinfo;
 
963
 
 
964
    // set all users as offline
 
965
    foreach ( Kopete::Contact *kc , contacts() )
 
966
    {
 
967
        WlmContact *c = static_cast<WlmContact *>( kc );
 
968
        c->setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
 
969
    }
 
970
 
 
971
    if (identity ()->hasProperty (Kopete::Global::Properties::self ()->photo ().key()))
 
972
    {
 
973
        m_server->cb.mainConnection->change_DisplayPicture(QFile::encodeName(identity()->customIcon()).constData());
 
974
        QImage contactPhoto = QImage( identity ()->customIcon() );
 
975
        Kopete::AvatarManager::AvatarEntry entry;
 
976
        entry.name = myself ()->contactId();
 
977
        entry.image = contactPhoto;
 
978
        entry.category = Kopete::AvatarManager::Contact;
 
979
        entry.contact = myself();
 
980
        entry = Kopete::AvatarManager::self()->add(entry);
 
981
        if(!entry.path.isNull())
 
982
            myself()->setProperty(Kopete::Global::Properties::self()->photo (), entry.path);
 
983
    }
 
984
 
 
985
    if ( identity()->hasProperty( Kopete::Global::Properties::self()->nickName().key() ))
 
986
    {
 
987
        // use the identity nickname instead of the one stored on the server side
 
988
        QString nick = identity()->property(
 
989
                Kopete::Global::Properties::self()->nickName()).value().toString();
 
990
        m_server->cb.mainConnection->setFriendlyName(nick.toUtf8().constData());
 
991
    }
 
992
    else
 
993
    {
 
994
        // Set myself contact display name here
 
995
        // This information come along with the address book
 
996
        // Fix BUG 182366
 
997
        m_server->cb.mainConnection->setFriendlyName( m_server->mainConnection->myDisplayName );
 
998
    }
 
999
 
 
1000
    password ().setWrong (false);
 
1001
 
 
1002
    QObject::connect (&m_server->cb,
 
1003
                      SIGNAL (changedStatus(MSN::BuddyStatus&)), this,
 
1004
                      SLOT (changedStatus(MSN::BuddyStatus&)));
 
1005
 
 
1006
    QObject::connect (&m_server->cb,
 
1007
                      SIGNAL (contactChangedStatus
 
1008
                              (const QString &, const QString &,
 
1009
                               const MSN::BuddyStatus &, const unsigned int &,
 
1010
                               const QString &)), this,
 
1011
                      SLOT (contactChangedStatus
 
1012
                            (const QString &, const QString &,
 
1013
                             const MSN::BuddyStatus &, const unsigned int &,
 
1014
                             const QString &)));
 
1015
 
 
1016
    QObject::connect (&m_server->cb,
 
1017
                      SIGNAL (contactDisconnected(QString)),
 
1018
                      this,
 
1019
                      SLOT (contactDisconnected(QString)));
 
1020
 
 
1021
    QObject::connect (identity (),
 
1022
                      SIGNAL (propertyChanged
 
1023
                              (Kopete::PropertyContainer *, const QString &,
 
1024
                               const QVariant &, const QVariant &)),
 
1025
                      SLOT (slotGlobalIdentityChanged
 
1026
                            (Kopete::PropertyContainer *, const QString &,
 
1027
                             const QVariant &, const QVariant &)));
 
1028
 
 
1029
    QObject::connect (&m_server->cb,
 
1030
                      SIGNAL (gotDisplayPicture
 
1031
                              (const QString &, const QString &)),
 
1032
                      SLOT (gotDisplayPicture
 
1033
                            (const QString &, const QString &)));
 
1034
 
 
1035
    QObject::connect (&m_server->cb,
 
1036
                      SIGNAL (gotContactPersonalInfo
 
1037
                              (const QString &,
 
1038
                               const MSN::personalInfo &)),
 
1039
                      SLOT (gotContactPersonalInfo
 
1040
                            (const QString &,
 
1041
                             const MSN::personalInfo &)));
 
1042
 
 
1043
    QObject::connect (&m_server->cb, SIGNAL(gotNewContact(MSN::ContactList,QString,QString)),
 
1044
                      SLOT (gotNewContact(MSN::ContactList,QString,QString)));
 
1045
 
 
1046
    QObject::connect (&m_server->cb, SIGNAL(gotRemovedContactFromList(MSN::ContactList,QString)),
 
1047
                      this, SLOT(gotRemovedContactFromList(MSN::ContactList,QString)) );
 
1048
 
 
1049
    QObject::connect (&m_server->cb, SIGNAL(gotAddedContactToGroup(bool,QString,QString)),
 
1050
                      this, SLOT(gotAddedContactToGroup(bool,QString,QString)) );
 
1051
 
 
1052
    QObject::connect (&m_server->cb, SIGNAL(gotRemovedContactFromGroup(bool,QString,QString)),
 
1053
                      this, SLOT(gotRemovedContactFromGroup(bool,QString,QString)) );
 
1054
 
 
1055
    QObject::connect (&m_server->cb, SIGNAL(gotAddedGroup(bool,QString,QString)),
 
1056
                      this, SLOT(gotAddedGroup(bool,QString,QString)) );
 
1057
 
 
1058
    QObject::connect (&m_server->cb, SIGNAL(gotRemovedGroup(bool,QString)),
 
1059
                      this, SLOT(gotRemovedGroup(bool,QString)) );
 
1060
 
 
1061
 
 
1062
    QObject::connect (&m_server->cb, SIGNAL(gotAddedContactToAddressBook(bool,QString,QString,QString)),
 
1063
                      this, SLOT(gotAddedContactToAddressBook(bool,QString,QString,QString)));
 
1064
 
 
1065
    QObject::connect (&m_server->cb, SIGNAL(gotRemovedContactFromAddressBook(bool,QString,QString)),
 
1066
                      this, SLOT(gotRemovedContactFromAddressBook(bool,QString,QString)));
 
1067
 
 
1068
    MSN::BuddyStatus state = MSN::STATUS_AVAILABLE;
 
1069
 
 
1070
    if (temporaryStatus == WlmProtocol::protocol ()->wlmOnline)
 
1071
        state = MSN::STATUS_AVAILABLE;
 
1072
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmAway)
 
1073
        state = MSN::STATUS_AWAY;
 
1074
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmInvisible)
 
1075
        state = MSN::STATUS_INVISIBLE;
 
1076
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmBusy)
 
1077
        state = MSN::STATUS_BUSY;
 
1078
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmOutToLunch)
 
1079
        state = MSN::STATUS_OUTTOLUNCH;
 
1080
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmOnThePhone)
 
1081
        state = MSN::STATUS_ONTHEPHONE;
 
1082
    else if (temporaryStatus == WlmProtocol::protocol ()->wlmBeRightBack)
 
1083
        state = MSN::STATUS_BERIGHTBACK;
 
1084
 
 
1085
    m_server->cb.mainConnection->setState (state, clientid);
 
1086
    // this prevents our client from downloading display pictures
 
1087
    // when is just connected.
 
1088
    QTimer::singleShot (10 * 1000, this, SLOT (disableInitialList()));
 
1089
    setPersonalMessage(myself()->statusMessage());
 
1090
 
 
1091
    // download a pending picture every 20 seconds
 
1092
    m_pendingDisplayPicturesTimer = new QTimer(this);
 
1093
 
 
1094
    QObject::connect(m_pendingDisplayPicturesTimer, SIGNAL(timeout()), 
 
1095
            this, SLOT(downloadPendingDisplayPicture()));
 
1096
 
 
1097
    m_pendingDisplayPicturesTimer->start(30 * 1000);
 
1098
 
 
1099
    // manage pending list
 
1100
    foreach ( const QString &contact, pendingList() )
 
1101
    {
 
1102
        // if we do not have this contact yet, so ask for add it
 
1103
        if(!isOnServerSideList(contact) &&
 
1104
                !isOnAllowList(contact) &&
 
1105
                !isOnBlockList(contact))
 
1106
        {
 
1107
            // fake this contact in RL to prompt the user to add it
 
1108
            gotNewContact (MSN::LST_RL, contact, contact);
 
1109
        }
 
1110
    }
 
1111
}
 
1112
 
 
1113
void WlmAccount::downloadPendingDisplayPicture()
 
1114
{
 
1115
    if(!m_pendingDisplayPicturesTimer)
 
1116
        return;
 
1117
 
 
1118
    if (m_pendingDisplayPictureList.isEmpty())
 
1119
    {
 
1120
        m_pendingDisplayPicturesTimer->stop();
 
1121
        m_pendingDisplayPicturesTimer->deleteLater();
 
1122
        m_pendingDisplayPicturesTimer = NULL;
 
1123
        return;
 
1124
    }
 
1125
 
 
1126
    QString passport = m_pendingDisplayPictureList.toList().first();
 
1127
    m_pendingDisplayPictureList.remove(passport);
 
1128
 
 
1129
        WlmContact * contact = qobject_cast<WlmContact*>(contacts().value(passport));
 
1130
    if(!contact)
 
1131
        return;
 
1132
 
 
1133
    // we only download the display picture if we and the contact are online
 
1134
    if ((myself ()->onlineStatus () != WlmProtocol::protocol ()->wlmOffline)
 
1135
     && (myself ()->onlineStatus () != WlmProtocol::protocol ()->wlmInvisible)
 
1136
     && (myself ()->onlineStatus () != WlmProtocol::protocol ()->wlmUnknown)
 
1137
     && (contact->onlineStatus () != WlmProtocol::protocol ()->wlmOffline)
 
1138
     && (contact->onlineStatus () != WlmProtocol::protocol ()->wlmInvisible)
 
1139
     && (contact->onlineStatus () != WlmProtocol::protocol ()->wlmUnknown))
 
1140
 
 
1141
    {
 
1142
        // do not open many switchboards in a short period of time
 
1143
        if(!m_recentDPRequests.contains(passport))
 
1144
        {
 
1145
            m_recentDPRequests.append(passport);
 
1146
            QTimer::singleShot(10 * 1000, this, SLOT(slotRemoveRecentDPRequests()));
 
1147
            chatManager ()->requestDisplayPicture (passport);
 
1148
        }
 
1149
    }
 
1150
}
 
1151
 
 
1152
void
 
1153
WlmAccount::slotInitialEmailNotification (const int unread_inbox)
 
1154
{
 
1155
    if ( isBusy() )
 
1156
        return;
 
1157
 
 
1158
    KNotification *notification= new KNotification ("msn_mail", Kopete::UI::Global::mainWidget());
 
1159
 
 
1160
    notification->setText(i18np( "You have one unread message in your Hotmail inbox.",
 
1161
                                 "You have %1 unread messages in your Hotmail inbox.", unread_inbox));
 
1162
    notification->setActions(( QStringList() << i18nc("@action", "Open Inbox" ) << i18nc("@action", "Close" )) );
 
1163
    notification->setFlags(KNotification::Persistent);
 
1164
    notification->setPixmap(accountIcon(KIconLoader::SizeMedium));
 
1165
    QObject::connect(notification,SIGNAL(activated()), this , SLOT(slotOpenInbox()) );
 
1166
    QObject::connect(notification,SIGNAL(action1Activated()), this, SLOT(slotOpenInbox()) );
 
1167
    QObject::connect(notification,SIGNAL(action2Activated()), notification, SLOT(close()) );
 
1168
    QObject::connect(notification,SIGNAL(ignored()), notification, SLOT(close()) );
 
1169
    notification->sendEvent();
 
1170
}
 
1171
 
 
1172
void
 
1173
WlmAccount::slotNewEmailNotification (const QString from, const QString subject)
 
1174
{
 
1175
    if ( isBusy() )
 
1176
        return;
 
1177
 
 
1178
    KNotification *notification= new KNotification ("msn_mail", Kopete::UI::Global::mainWidget());
 
1179
 
 
1180
    notification->setText(i18n( "New message from %1 in your Hotmail inbox.<p>Subject: %2", from, subject));
 
1181
    notification->setActions(( QStringList() << i18nc("@action", "Open Inbox" ) << i18nc("@action", "Close" )) );
 
1182
    notification->setFlags(KNotification::Persistent);
 
1183
    notification->setPixmap(accountIcon(KIconLoader::SizeMedium));
 
1184
    QObject::connect(notification,SIGNAL(activated()), this , SLOT(slotOpenInbox()) );
 
1185
    QObject::connect(notification,SIGNAL(action1Activated()), this, SLOT(slotOpenInbox()) );
 
1186
    QObject::connect(notification,SIGNAL(action2Activated()), notification, SLOT(close()) );
 
1187
    QObject::connect(notification,SIGNAL(ignored()), notification, SLOT(close()) );
 
1188
    notification->sendEvent();
 
1189
}
 
1190
 
 
1191
void
 
1192
WlmAccount::slotInboxUrl (MSN::hotmailInfo & info)
 
1193
{
 
1194
    //write the tmp file
 
1195
    QString UserID = accountId();
 
1196
 
 
1197
    QString hotmailRequest = "<html>\n"
 
1198
        "<head>\n"
 
1199
            "<noscript>\n"
 
1200
                "<meta http-equiv=Refresh content=\"0; url=http://www.hotmail.com\">\n"
 
1201
            "</noscript>\n"
 
1202
        "</head>\n"
 
1203
        "<body onload=\"document.pform.submit(); \">\n"
 
1204
            "<form name=\"pform\" action=\"" + WlmUtils::utf8(info.url) + "\" method=\"POST\">\n"
 
1205
                "<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n"
 
1206
                "<input type=\"hidden\" name=\"login\" value=\"" + UserID.left( UserID.indexOf('@') ) + "\">\n"
 
1207
                "<input type=\"hidden\" name=\"username\" value=\"" + UserID + "\">\n"
 
1208
                "<input type=\"hidden\" name=\"sid\" value=\"" + WlmUtils::utf8(info.sid) + "\">\n"
 
1209
                "<input type=\"hidden\" name=\"kv\" value=\"" + WlmUtils::utf8(info.kv) + "\">\n"
 
1210
                "<input type=\"hidden\" name=\"id\" value=\""+ WlmUtils::utf8(info.id) +"\">\n"
 
1211
                "<input type=\"hidden\" name=\"sl\" value=\"" + WlmUtils::utf8(info.sl) +"\">\n"
 
1212
                "<input type=\"hidden\" name=\"rru\" value=\"" + WlmUtils::utf8(info.rru) + "\">\n"
 
1213
                "<input type=\"hidden\" name=\"auth\" value=\"" + WlmUtils::utf8(info.MSPAuth) + "\">\n"
 
1214
                "<input type=\"hidden\" name=\"creds\" value=\"" + WlmUtils::utf8(info.creds) + "\">\n"
 
1215
                "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n"
 
1216
                "<input type=\"hidden\" name=\"js\" value=\"yes\">\n"
 
1217
            "</form></body>\n</html>\n";
 
1218
 
 
1219
    slotRemoveTmpMailFile();
 
1220
    tmpMailFile = new KTemporaryFile();
 
1221
    tmpMailFile->setSuffix(".html");
 
1222
 
 
1223
    if (tmpMailFile->open())
 
1224
    {
 
1225
            tmpMailFile->write(hotmailRequest.toUtf8());
 
1226
        tmpMailFile->flush();
 
1227
 
 
1228
        /* tmpMailFile->close() erases tmpMailFile->fileName property(), so use it before closing file. */
 
1229
        KToolInvocation::invokeBrowser( tmpMailFile->fileName(), "0" ); // "0" means we don't need startup notification
 
1230
        tmpMailFile->close();
 
1231
        m_tmpMailFileTimer->start(30000);
 
1232
        m_tmpMailFileTimer->setSingleShot(true);
 
1233
    }
 
1234
    else
 
1235
        kDebug(14140) << "Error opening temporary file";
 
1236
}
 
1237
 
 
1238
void WlmAccount::slotRemoveTmpMailFile()
 
1239
{
 
1240
    if (tmpMailFile)
 
1241
    {
 
1242
        delete tmpMailFile;
 
1243
        tmpMailFile = 0L;
 
1244
    }
 
1245
 
 
1246
    m_tmpMailFileTimer->stop();
 
1247
}
 
1248
 
 
1249
void WlmAccount::gotAddedGroup (bool added,
 
1250
                                const QString & groupName,
 
1251
                                const QString & groupId)
 
1252
{
 
1253
    kDebug() << "groupName: " << groupName << "groupId: " << groupId << " added:" << added;
 
1254
    const QStringList contactIdList = m_contactAddQueue.keys (groupName);
 
1255
    if (!added)
 
1256
    {
 
1257
        // Remove contact from add queue. FIXME: We should somehow sync the contact list here
 
1258
        foreach ( const QString &contactId, contactIdList )
 
1259
            m_contactAddQueue.remove(contactId);
 
1260
 
 
1261
        return;
 
1262
    }
 
1263
 
 
1264
    // Insert new group
 
1265
    m_groupToGroupId.insert(groupName, groupId);
 
1266
 
 
1267
    // Add contact to the new group
 
1268
    foreach ( const QString &contactId, contactIdList )
 
1269
    {
 
1270
        kDebug() << "adding contact " << contactId;
 
1271
        m_server->cb.mainConnection->addToAddressBook (contactId.toLatin1().constData(), contactId.toUtf8().constData());
 
1272
    }
 
1273
 
 
1274
    // Sync contact belonging to the new group
 
1275
    foreach ( Kopete::Contact *kc , contacts() )
 
1276
    {
 
1277
        WlmContact *c = static_cast<WlmContact *>( kc );
 
1278
        if ( c->metaContact()->groups().first()->displayName() == groupName )
 
1279
            c->sync( Kopete::Contact::MovedBetweenGroup );
 
1280
    }
 
1281
}
 
1282
 
 
1283
void WlmAccount::gotRemovedGroup (bool removed,
 
1284
                      const QString & groupId)
 
1285
{
 
1286
    kDebug() << "groupId: " << groupId << " removed:" << removed;
 
1287
    if ( !removed )
 
1288
        return;
 
1289
 
 
1290
    // remove group
 
1291
    m_groupToGroupId.remove(m_groupToGroupId.key(groupId));
 
1292
}
 
1293
 
 
1294
void
 
1295
WlmAccount::gotAddedContactToGroup (bool added,
 
1296
                        const QString & groupId,
 
1297
                        const QString & contactId)
 
1298
{
 
1299
    kDebug() << "groupId: " << groupId << " contactId: " << contactId << " added:" << added;
 
1300
}
 
1301
 
 
1302
void
 
1303
WlmAccount::gotRemovedContactFromGroup (bool removed,
 
1304
                            const QString & groupId,
 
1305
                            const QString & contactId)
 
1306
{
 
1307
    kDebug() << "groupId: " << groupId << " contactId: " << contactId << " removed:" << removed;
 
1308
}
 
1309
 
 
1310
void
 
1311
WlmAccount::gotAddedContactToAddressBook (bool added, const QString & passport, const QString & displayName, const QString & guid)
 
1312
{
 
1313
    kDebug() << "contact: " << passport << " added:" << added << " guid: " << guid;
 
1314
    if (added)
 
1315
    {
 
1316
        m_serverSideContactsPassports.insert (passport);
 
1317
        addContact (passport, QString(), Kopete::Group::topLevel (), Kopete::Account::DontChangeKABC);
 
1318
 
 
1319
            WlmContact * newcontact = qobject_cast <WlmContact *>(contacts().value(passport));
 
1320
        if (!newcontact)
 
1321
            return;
 
1322
 
 
1323
        newcontact->setContactSerial (guid);
 
1324
        newcontact->setProperty (Kopete::Global::Properties::self()->nickName(), displayName);
 
1325
 
 
1326
        QString groupName = m_contactAddQueue.value (passport);
 
1327
        if( !groupName.isEmpty() && m_groupToGroupId.contains (groupName) )
 
1328
        {
 
1329
            kDebug() << "Adding contact \'" << passport << "\' to group \'" << groupName << "\'";
 
1330
            QString groupId = m_groupToGroupId.value (groupName);
 
1331
            m_server->cb.mainConnection->addToGroup (groupId.toLatin1().constData(), guid.toLatin1().constData());
 
1332
        }
 
1333
    }
 
1334
    else
 
1335
    {
 
1336
        // TODO: Raise an error
 
1337
    }
 
1338
 
 
1339
    // Remove contact from add queue
 
1340
    m_contactAddQueue.remove(passport);
 
1341
}
 
1342
 
 
1343
void
 
1344
WlmAccount::gotRemovedContactFromAddressBook (bool removed, const QString & passport, const QString & contactId)
 
1345
{
 
1346
    Q_UNUSED( contactId );
 
1347
 
 
1348
    kDebug() << "contact: " << passport << " removed:" << removed;
 
1349
    if (removed)
 
1350
        m_serverSideContactsPassports.remove( passport );
 
1351
 
 
1352
}
 
1353
 
 
1354
void
 
1355
WlmAccount::NotificationServerConnectionTerminated (MSN::
 
1356
                                                    NotificationServerConnection
 
1357
                                                    * conn)
 
1358
{
 
1359
    Q_UNUSED( conn );
 
1360
 
 
1361
    kDebug (14210) << k_funcinfo;
 
1362
 
 
1363
    if (m_lastMainConnectionError == Callbacks::WrongPassword)
 
1364
        logOff( Kopete::Account::BadPassword );
 
1365
    else if (m_lastMainConnectionError == Callbacks::OtherClient)
 
1366
        logOff( Kopete::Account::OtherClient );
 
1367
    else if (myself ()->onlineStatus () == WlmProtocol::protocol ()->wlmConnecting)
 
1368
        connectionFailed ();
 
1369
    else if (isConnected ())
 
1370
        logOff( Kopete::Account::Unknown );
 
1371
}
 
1372
 
 
1373
void WlmAccount::disconnect()
 
1374
{
 
1375
    logOff( Kopete::Account::Manual );
 
1376
}
 
1377
 
 
1378
void WlmAccount::error( int /*errCode*/ )
 
1379
{
 
1380
    logOff( Kopete::Account::ConnectionReset );
 
1381
}
 
1382
 
 
1383
 
 
1384
void WlmAccount::logOff( Kopete::Account::DisconnectReason reason )
 
1385
{
 
1386
    kDebug (14210) << k_funcinfo;
 
1387
    if (m_server)
 
1388
        m_server->WlmDisconnect ();
 
1389
 
 
1390
    if (myself ())
 
1391
        myself ()->setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
 
1392
 
 
1393
    foreach ( Kopete::Contact *kc , contacts() )
 
1394
    {
 
1395
        WlmContact *c = static_cast<WlmContact *>( kc );
 
1396
        c->setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
 
1397
    }
 
1398
 
 
1399
    delete m_transferManager;
 
1400
    m_transferManager = NULL;
 
1401
    delete m_chatManager;
 
1402
    m_chatManager = NULL;
 
1403
    if (m_server)
 
1404
    {
 
1405
        QObject::disconnect (&m_server->cb, 0, 0, 0);
 
1406
        m_server->deleteLater();
 
1407
        m_server = NULL;
 
1408
    }
 
1409
 
 
1410
    disconnected( reason );
 
1411
}
 
1412
 
 
1413
WlmServer *WlmAccount::server ()
 
1414
{
 
1415
    return m_server;
 
1416
}
 
1417
 
 
1418
bool WlmAccount::isContactBlocked(const QString& passport) const
 
1419
{
 
1420
    return (isOnBlockList(passport) || (blockUnknownUsers() && !isOnAllowList(passport)));
 
1421
}
 
1422
 
 
1423
void WlmAccount::blockContact(const QString& passport, bool block)
 
1424
{
 
1425
    if (!isConnected() || isContactBlocked(passport) == block)
 
1426
        return;
 
1427
 
 
1428
    if (block)
 
1429
    {
 
1430
        if (isOnAllowList(passport))
 
1431
            server()->mainConnection->removeFromList(MSN::LST_AL, passport.toLatin1().constData());
 
1432
 
 
1433
        server()->mainConnection->addToList(MSN::LST_BL, passport.toLatin1().constData());
 
1434
    }
 
1435
    else
 
1436
    {
 
1437
        if (isOnBlockList(passport))
 
1438
            server()->mainConnection->removeFromList(MSN::LST_BL, passport.toLatin1().constData());
 
1439
 
 
1440
        server()->mainConnection->addToList(MSN::LST_AL, passport.toLatin1().constData());
 
1441
    }
 
1442
}
 
1443
 
 
1444
void
 
1445
WlmAccount::slotGoOnline ()
 
1446
{
 
1447
    kDebug (14210) << k_funcinfo;
 
1448
 
 
1449
    if (!isConnected ())
 
1450
        connect (WlmProtocol::protocol ()->wlmOnline);
 
1451
    else
 
1452
        m_server->cb.mainConnection->setState (MSN::STATUS_AVAILABLE,
 
1453
                                               clientid);
 
1454
}
 
1455
 
 
1456
void
 
1457
WlmAccount::slotGoInvisible ()
 
1458
{
 
1459
    kDebug (14210) << k_funcinfo;
 
1460
 
 
1461
    if (!isConnected ())
 
1462
        connect (WlmProtocol::protocol ()->wlmInvisible);
 
1463
    else
 
1464
        m_server->cb.mainConnection->setState (MSN::STATUS_INVISIBLE,
 
1465
                                               clientid);
 
1466
}
 
1467
 
 
1468
void
 
1469
WlmAccount::slotGoAway (const Kopete::OnlineStatus & status)
 
1470
{
 
1471
    kDebug (14210) << k_funcinfo;
 
1472
 
 
1473
    if (!isConnected ())
 
1474
        connect (status);
 
1475
    else
 
1476
    {
 
1477
        if (status == WlmProtocol::protocol ()->wlmIdle)
 
1478
            m_server->cb.mainConnection->setState (MSN::STATUS_IDLE,
 
1479
                                                   clientid);
 
1480
        if (status == WlmProtocol::protocol ()->wlmAway)
 
1481
            m_server->cb.mainConnection->setState (MSN::STATUS_AWAY,
 
1482
                                                   clientid);
 
1483
        else if (status == WlmProtocol::protocol ()->wlmOutToLunch)
 
1484
            m_server->cb.mainConnection->setState (MSN::STATUS_OUTTOLUNCH,
 
1485
                                                   clientid);
 
1486
        else if (status == WlmProtocol::protocol ()->wlmBusy)
 
1487
            m_server->cb.mainConnection->setState (MSN::STATUS_BUSY,
 
1488
                                                   clientid);
 
1489
        else if (status == WlmProtocol::protocol ()->wlmOnThePhone)
 
1490
            m_server->cb.mainConnection->setState (MSN::STATUS_ONTHEPHONE,
 
1491
                                                   clientid);
 
1492
        else if (status == WlmProtocol::protocol ()->wlmBeRightBack)
 
1493
            m_server->cb.mainConnection->setState (MSN::STATUS_BERIGHTBACK,
 
1494
                                                   clientid);
 
1495
    }
 
1496
}
 
1497
 
 
1498
void
 
1499
WlmAccount::slotGoOffline ()
 
1500
{
 
1501
    kDebug (14210) << k_funcinfo;
 
1502
 
 
1503
    if ( isConnected() || myself ()->onlineStatus ().status () == Kopete::OnlineStatus::Connecting )
 
1504
        disconnect();
 
1505
}
 
1506
 
 
1507
void
 
1508
WlmAccount::updateContactStatus ()
 
1509
{
 
1510
}
 
1511
 
 
1512
void
 
1513
WlmAccount::receivedOIMList (std::vector < MSN::eachOIM > &oimlist)
 
1514
{
 
1515
    kDebug (14210) << k_funcinfo;
 
1516
    std::vector < MSN::eachOIM >::iterator i = oimlist.begin ();
 
1517
    for (; i != oimlist.end (); i++)
 
1518
    {
 
1519
        m_oimList[WlmUtils::latin1((*i).id)] = WlmUtils::passport((*i).from);
 
1520
        m_server->cb.mainConnection->get_oim((*i).id, true);
 
1521
    }
 
1522
}
 
1523
 
 
1524
void
 
1525
WlmAccount::deletedOIM(const QString& id, const bool deleted)
 
1526
{
 
1527
    kDebug() << " deleted OIM " << id << " " << deleted;
 
1528
}
 
1529
 
 
1530
void
 
1531
WlmAccount::receivedOIM (const QString & id, const QString & message)
 
1532
{
 
1533
    kDebug (14210) << k_funcinfo;
 
1534
    QString contactId = m_oimList[id];
 
1535
        WlmContact * contact = qobject_cast<WlmContact*>(contacts().value( contactId));
 
1536
 
 
1537
    Kopete::Message msg = Kopete::Message (contact, myself ());
 
1538
    msg.setPlainBody (message);
 
1539
    msg.setDirection (Kopete::Message::Inbound);
 
1540
 
 
1541
    if (contact)
 
1542
        contact->manager (Kopete::Contact::CanCreate)->appendMessage (msg);
 
1543
 
 
1544
    m_oimList.remove (id);
 
1545
    m_server->cb.mainConnection->delete_oim (id.toLatin1().constData ());
 
1546
}
 
1547
 
 
1548
void WlmAccount::slotRemoveRecentDPRequests()
 
1549
{
 
1550
    m_recentDPRequests.pop_front();
 
1551
}
 
1552
 
 
1553
#include "wlmaccount.moc"