~ubuntu-branches/ubuntu/natty/kdenetwork/natty-proposed

« back to all changes in this revision

Viewing changes to .pc/kubuntu_01_fix_kopete_notifications_away.diff/kopete/libkopete/private/kopeteviewmanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-08-04 23:20:06 UTC
  • mfrom: (1.1.48 upstream)
  • Revision ID: james.westby@ubuntu.com-20100804232006-dccz6pliwwbrzz4u
Tags: 4:4.5.0b-0ubuntu1
New tar from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    kopeteviewmanager.cpp - View Manager
 
3
 
 
4
    Copyright (c) 2003      by Jason Keirstead       <jason@keirstead.org>
 
5
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
 
6
 
 
7
    *************************************************************************
 
8
    *                                                                       *
 
9
    * This program is free software; you can redistribute it and/or modify  *
 
10
    * it under the terms of the GNU General Public License as published by  *
 
11
    * the Free Software Foundation; either version 2 of the License, or     *
 
12
    * (at your option) any later version.                                   *
 
13
    *                                                                       *
 
14
    *************************************************************************
 
15
*/
 
16
 
 
17
#include "kopeteviewmanager.h"
 
18
 
 
19
#include <QList>
 
20
#include <QTextDocument>
 
21
#include <QtAlgorithms>
 
22
 
 
23
#include <kconfig.h>
 
24
#include <kdebug.h>
 
25
#include <klocale.h>
 
26
#include <kplugininfo.h>
 
27
#include <knotification.h>
 
28
#include <kglobal.h>
 
29
#include <kwindowsystem.h>
 
30
 
 
31
#include "kopetebehaviorsettings.h"
 
32
#include "kopeteaccount.h"
 
33
#include "kopetepluginmanager.h"
 
34
#include "kopeteviewplugin.h"
 
35
#include "kopetechatsessionmanager.h"
 
36
#include "kopetemetacontact.h"
 
37
#include "kopetecontact.h"
 
38
#include "kopetemessageevent.h"
 
39
#include "kopeteview.h"
 
40
#include "kopetechatsession.h"
 
41
#include "kopetegroup.h"
 
42
#include "kopetepicture.h"
 
43
#include "kopeteemoticons.h"
 
44
#include "kopeteactivenotification.h"
 
45
 
 
46
/**
 
47
 * Used to exrtract the message that will be shown in the notification popup.
 
48
 *
 
49
 * Was in KopeteSystemTray::squashMessage in KDE3
 
50
 */
 
51
 
 
52
static QString squashMessage( const Kopete::Message& msg )
 
53
{
 
54
        QString msgText = msg.parsedBody();
 
55
 
 
56
        QRegExp rx( "(<a.*>((http://)?(.+))</a>)" );
 
57
        rx.setMinimal( true );
 
58
        if ( rx.indexIn( msgText ) == -1 )
 
59
        {
 
60
                // no URLs in text, just pick the first 30 chars of
 
61
                // the parsed text if necessary. We used parsed text
 
62
                // so that things like "<knuff>" show correctly
 
63
                //  Escape it after snipping it to not snip entities
 
64
                msgText = msg.plainBody();
 
65
                if( msgText.length() > 30 )
 
66
                        msgText = msgText.left( 30 ) + QString::fromLatin1( " ..." );
 
67
                msgText=Kopete::Emoticons::parseEmoticons(Qt::escape(msgText));
 
68
        }
 
69
        else
 
70
        {
 
71
                QString plainText = msg.plainBody();
 
72
                if ( plainText.length() > 30 )
 
73
                {
 
74
                        QString fullUrl = rx.cap( 2 );
 
75
                        QString shorterUrl;
 
76
                        if ( fullUrl.length() > 30 )
 
77
                        {
 
78
                                QString urlWithoutProtocol = rx.cap( 4 );
 
79
                                shorterUrl = urlWithoutProtocol.left( 27 )
 
80
                                                + QString::fromLatin1( "... " );
 
81
                        }
 
82
                        else
 
83
                        {
 
84
                                shorterUrl = fullUrl.left( 27 )
 
85
                                                + QString::fromLatin1( "... " );
 
86
                        }
 
87
                        // remove message text
 
88
                        msgText = QString::fromLatin1( "... " ) +
 
89
                                        rx.cap( 1 ) +
 
90
                                        QString::fromLatin1( " ..." );
 
91
                        // find last occurrence of URL (the one inside the <a> tag)
 
92
                        int revUrlOffset = msgText.lastIndexOf( fullUrl );
 
93
                        msgText.replace( revUrlOffset,
 
94
                                                fullUrl.length(), shorterUrl );
 
95
                }
 
96
        }
 
97
        kDebug(14000) << msgText;
 
98
        return msgText;
 
99
}
 
100
 
 
101
typedef QMap<Kopete::ChatSession*, KopeteView*> SessionMap;
 
102
typedef QList<Kopete::MessageEvent*> EventList;
 
103
 
 
104
struct KopeteViewManagerPrivate
 
105
{
 
106
    ~KopeteViewManagerPrivate()
 
107
    {
 
108
        qDeleteAll(sessionMap);
 
109
        sessionMap.clear();
 
110
        qDeleteAll(eventList);
 
111
        eventList.clear();
 
112
    }
 
113
 
 
114
    SessionMap sessionMap;
 
115
    EventList eventList;
 
116
    KopeteView *activeView;
 
117
 
 
118
    bool useQueue;
 
119
    bool raiseWindow;
 
120
    bool queueUnreadMessages;
 
121
    bool queueOnlyHighlightedMessagesInGroupChats;
 
122
    bool queueOnlyMessagesOnAnotherDesktop;
 
123
    bool balloonNotifyIgnoreClosesChatView;
 
124
    bool balloonGroupMessageNotificationsPerSender;
 
125
    bool foreignMessage;
 
126
    bool animateOnMessageWithOpenChat;
 
127
    bool enableEventsWhileAway;
 
128
    Kopete::ActiveNotifications activeNotifications;
 
129
};
 
130
 
 
131
KopeteViewManager *KopeteViewManager::s_viewManager = 0L;
 
132
 
 
133
KopeteViewManager *KopeteViewManager::viewManager()
 
134
{
 
135
    if( !s_viewManager )
 
136
            s_viewManager = new KopeteViewManager();
 
137
    return s_viewManager;
 
138
}
 
139
 
 
140
KopeteViewManager::KopeteViewManager()
 
141
{
 
142
    s_viewManager=this;
 
143
    d = new KopeteViewManagerPrivate;
 
144
    d->activeView = 0L;
 
145
    d->foreignMessage=false;
 
146
 
 
147
    connect( Kopete::BehaviorSettings::self(), SIGNAL( configChanged() ), this, SLOT( slotPrefsChanged() ) );
 
148
 
 
149
    connect( Kopete::ChatSessionManager::self() , SIGNAL( display( Kopete::Message &, Kopete::ChatSession *) ),
 
150
            this, SLOT ( messageAppended( Kopete::Message &, Kopete::ChatSession *) ) );
 
151
 
 
152
    connect( Kopete::ChatSessionManager::self() , SIGNAL( readMessage() ),
 
153
            this, SLOT ( nextEvent() ) );
 
154
 
 
155
    slotPrefsChanged();
 
156
}
 
157
 
 
158
KopeteViewManager::~KopeteViewManager()
 
159
{
 
160
//      kDebug(14000) ;
 
161
 
 
162
    //delete all open chatwindow.
 
163
    SessionMap::Iterator it;
 
164
    for ( it = d->sessionMap.begin(); it != d->sessionMap.end(); ++it )
 
165
    {
 
166
        it.value()->closeView( true ); //this does not clean the map, but we don't care
 
167
    }
 
168
 
 
169
    delete d;
 
170
}
 
171
 
 
172
void KopeteViewManager::slotPrefsChanged()
 
173
{
 
174
        Kopete::BehaviorSettings *const bs = Kopete::BehaviorSettings::self();
 
175
 
 
176
        d->useQueue = bs->useMessageQueue();
 
177
        d->raiseWindow = bs->raiseMessageWindow();
 
178
        d->queueUnreadMessages = bs->queueUnreadMessages();
 
179
        d->queueOnlyHighlightedMessagesInGroupChats = bs->queueOnlyHighlightedMessagesInGroupChats();
 
180
        d->queueOnlyMessagesOnAnotherDesktop = bs->queueOnlyMessagesOnAnotherDesktop();
 
181
        d->balloonNotifyIgnoreClosesChatView = bs->balloonNotifyIgnoreClosesChatView();
 
182
        d->balloonGroupMessageNotificationsPerSender = bs->balloonGroupMessageNotificationsPerSender();
 
183
        d->animateOnMessageWithOpenChat = bs->animateOnMessageWithOpenChat();
 
184
        d->enableEventsWhileAway = bs->enableEventsWhileAway();
 
185
}
 
186
 
 
187
KopeteView *KopeteViewManager::view( Kopete::ChatSession* session, const QString &requestedPlugin )
 
188
{
 
189
    // kDebug(14000) ;
 
190
 
 
191
    if( d->sessionMap.contains( session ) && d->sessionMap[ session ] )
 
192
    {
 
193
        return d->sessionMap[ session ];
 
194
    }
 
195
    else
 
196
    {
 
197
        Kopete::PluginManager *pluginManager = Kopete::PluginManager::self();
 
198
        Kopete::ViewPlugin *viewPlugin = 0L;
 
199
 
 
200
        QString pluginName = requestedPlugin.isEmpty() ? Kopete::BehaviorSettings::self()->viewPlugin() : requestedPlugin;
 
201
        if( !pluginName.isEmpty() )
 
202
        {
 
203
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( pluginName );
 
204
 
 
205
            if( !viewPlugin )
 
206
            {
 
207
                kWarning(14000) << "Requested view plugin, " << pluginName
 
208
                                << ", was not found. Falling back to chat window plugin" << endl;
 
209
            }
 
210
        }
 
211
 
 
212
        if( !viewPlugin )
 
213
        {
 
214
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( QLatin1String("kopete_chatwindow") );
 
215
        }
 
216
 
 
217
        if( viewPlugin )
 
218
        {
 
219
            KopeteView *newView = viewPlugin->createView(session);
 
220
 
 
221
            d->foreignMessage = false;
 
222
            d->sessionMap.insert( session, newView );
 
223
 
 
224
            connect( session, SIGNAL( closing(Kopete::ChatSession *) ),
 
225
                     this, SLOT(slotChatSessionDestroyed(Kopete::ChatSession*)) );
 
226
 
 
227
            return newView;
 
228
        }
 
229
        else
 
230
        {
 
231
            kError(14000) << "Could not create a view, no plugins available!" << endl;
 
232
            return 0L;
 
233
        }
 
234
    }
 
235
}
 
236
 
 
237
 
 
238
void KopeteViewManager::messageAppended( Kopete::Message &msg, Kopete::ChatSession *session)
 
239
{
 
240
        const bool isOutboundMessage = msg.direction() == Kopete::Message::Outbound;
 
241
 
 
242
        if ( isOutboundMessage && !d->sessionMap.contains( session ) )
 
243
                return;
 
244
 
 
245
        // Get an early copy of the plain message body before the chat view works on it
 
246
        // Otherwise toPlainBody() will ignore smileys if they were turned into images during
 
247
        // the html conversion. See bug 161651.
 
248
        const QString squashedMessage = squashMessage( msg );
 
249
 
 
250
        d->foreignMessage = !isOutboundMessage; // for the view we are about to create
 
251
        session->view( true, msg.requestedPlugin() )->appendMessage( msg );
 
252
        d->foreignMessage = false; // the view has been created, reset the flag
 
253
 
 
254
        bool appendMessageEvent = d->useQueue;
 
255
        bool isViewOnCurrentDesktop = true;
 
256
 
 
257
        QWidget *w = dynamic_cast< QWidget * >( view( session ) );
 
258
#ifdef Q_WS_X11
 
259
        if ( w )
 
260
        {
 
261
                isViewOnCurrentDesktop = KWindowSystem::windowInfo( w->topLevelWidget()->winId(),
 
262
                                                                    NET::WMDesktop ).isOnCurrentDesktop();
 
263
        }
 
264
#endif
 
265
 
 
266
        if ( w && d->queueUnreadMessages )
 
267
        {
 
268
                // append msg event to queue if chat window is active but not the chat view in it...
 
269
                appendMessageEvent = appendMessageEvent && !( w->isActiveWindow()
 
270
                                                              && session->view() == d->activeView );
 
271
                // ...and chat window is on another desktop
 
272
                appendMessageEvent = appendMessageEvent && !( d->queueOnlyMessagesOnAnotherDesktop
 
273
                                                              && isViewOnCurrentDesktop );
 
274
        }
 
275
        else
 
276
        {
 
277
                // append if no chat window exists already
 
278
                appendMessageEvent = appendMessageEvent && !view( session )->isVisible();
 
279
        }
 
280
 
 
281
        // in groupchats, don't notify on non-highlighted messages if configured that way.
 
282
        const bool isIgnoredGroupChatMessage = session->members().count() > 1
 
283
                                               && d->queueOnlyHighlightedMessagesInGroupChats
 
284
                                               && msg.importance() != Kopete::Message::Highlight;
 
285
 
 
286
        appendMessageEvent = appendMessageEvent && !isIgnoredGroupChatMessage;
 
287
 
 
288
        QWidget *viewWidget = 0;
 
289
        bool showNotification = false;
 
290
        bool isActiveWindow = false;
 
291
        Kopete::MessageEvent *event = 0;
 
292
 
 
293
        if ( !isOutboundMessage )
 
294
        {
 
295
                if ( ( !session->account()->isAway() || d->enableEventsWhileAway )
 
296
                 && msg.direction() != Kopete::Message::Internal )
 
297
                {
 
298
                        viewWidget = dynamic_cast< QWidget * >( session->view( false ) );
 
299
                        // note that session->view( true [default value] ) can create a view, so watch the
 
300
                        // side-effects...
 
301
                        isActiveWindow = session->view( false ) && viewWidget
 
302
                                         && session->view() == d->activeView && viewWidget->isActiveWindow();
 
303
                        showNotification = msg.from() != 0;
 
304
                }
 
305
 
 
306
                if ( appendMessageEvent || showNotification )
 
307
                {
 
308
                        if ( msg.from() && d->eventList.isEmpty() ) // may happen for internal messages
 
309
                                showNotification = true;
 
310
 
 
311
                        event = new Kopete::MessageEvent( msg, session );
 
312
                        d->eventList.append( event );
 
313
 
 
314
                        // Don't call readMessages twice. We call it later in this method. Fixes bug 168978.
 
315
                        if ( d->useQueue )
 
316
                                connect( event, SIGNAL(done(Kopete::MessageEvent *)),
 
317
                                         this, SLOT(slotEventDeleted(Kopete::MessageEvent *)) );
 
318
                }
 
319
        }
 
320
 
 
321
        if ( msg.delayed() )
 
322
                showNotification = false;
 
323
 
 
324
        if ( showNotification )
 
325
                createNotification( msg, squashedMessage, session, event, viewWidget,
 
326
                                    isActiveWindow, isViewOnCurrentDesktop );
 
327
 
 
328
        if (!d->useQueue)
 
329
        {
 
330
                // "Open messages instantly" setting
 
331
                readMessages( session, isOutboundMessage );
 
332
        }
 
333
 
 
334
        KopeteView *view = session->view( false );
 
335
        if ( d->raiseWindow && view && view->isVisible() )
 
336
        {
 
337
                // "Raise window on incoming message" setting
 
338
                view->raise();
 
339
        }
 
340
 
 
341
        if ( event && ( appendMessageEvent || ( d->animateOnMessageWithOpenChat && !isActiveWindow ) )
 
342
             && !isIgnoredGroupChatMessage )
 
343
                Kopete::ChatSessionManager::self()->postNewEvent(event);
 
344
}
 
345
 
 
346
void KopeteViewManager::createNotification( Kopete::Message &msg, const QString &squashedMessage,
 
347
                                            Kopete::ChatSession *session, Kopete::MessageEvent *event,
 
348
                                                QWidget *viewWidget,
 
349
                                                bool isActiveWindow, bool isViewOnCurrentDesktop )
 
350
{
 
351
    if ( d->balloonGroupMessageNotificationsPerSender )
 
352
        {
 
353
                Kopete::ActiveNotifications::iterator notifyIt =
 
354
                        d->activeNotifications.find( msg.from()->account()->accountLabel() + msg.from()->contactId() );
 
355
                if (notifyIt != d->activeNotifications.end())
 
356
                {
 
357
                        ( *notifyIt )->incrementMessages();
 
358
                        return;
 
359
                }
 
360
        }
 
361
 
 
362
        const QString msgFrom = msg.from()->metaContact() ? msg.from()->metaContact()->displayName()
 
363
                                                          : msg.from()->contactId();
 
364
 
 
365
        QString eventId;
 
366
        KLocalizedString body = ki18n( "Incoming message from %1<br />\"%2\"" );
 
367
        switch( msg.importance() )
 
368
        {
 
369
        case Kopete::Message::Low:
 
370
                eventId = QLatin1String( "kopete_contact_lowpriority" );
 
371
                break;
 
372
        case Kopete::Message::Highlight:
 
373
                eventId = QLatin1String( "kopete_contact_highlight" );
 
374
                body = ki18n( "A highlighted message arrived from %1<br />\"%2\"" );
 
375
                break;
 
376
        default:
 
377
                if ( isActiveWindow || (d->queueOnlyMessagesOnAnotherDesktop
 
378
                     && isViewOnCurrentDesktop ) )
 
379
                {
 
380
                        eventId = QLatin1String( "kopete_contact_incoming_active_window" );
 
381
                }
 
382
                else
 
383
                {
 
384
                        eventId = QLatin1String( "kopete_contact_incoming" );
 
385
                }
 
386
        }
 
387
 
 
388
        KNotification *notify = new KNotification(eventId, viewWidget, isActiveWindow
 
389
                                                                       ? KNotification::CloseOnTimeout
 
390
                                                                       : KNotification::Persistent);
 
391
        notify->setPixmap( QPixmap::fromImage( msg.from()->metaContact()->picture().image() ) );
 
392
        notify->setActions( QStringList() << i18nc( "@action", "View" )
 
393
                                          << i18nc( "@action", "Ignore" ) );
 
394
 
 
395
        QString bodyString = body.subs( Qt::escape(msgFrom) ).subs( squashedMessage ).toString();
 
396
        if ( d->balloonGroupMessageNotificationsPerSender )
 
397
        {
 
398
                // notify is parent, will die with it
 
399
                new Kopete::ActiveNotification( notify,
 
400
                                msg.from()->account()->accountLabel() + msg.from()->contactId(),
 
401
                                d->activeNotifications,
 
402
                                bodyString );
 
403
        }
 
404
        else
 
405
        {
 
406
                notify->setText( "<qt>" + bodyString + "</qt>" );
 
407
        }
 
408
 
 
409
        foreach ( const QString& cl , msg.classes() )
 
410
                notify->addContext( qMakePair( QString::fromLatin1("class"), cl ) );
 
411
 
 
412
        Kopete::MetaContact *mc= msg.from()->metaContact();
 
413
        if ( mc )
 
414
        {
 
415
                notify->addContext( qMakePair( QString::fromLatin1("contact"),
 
416
                                               mc->metaContactId().toString()) );
 
417
                foreach( Kopete::Group *g , mc->groups() )
 
418
                {
 
419
                        notify->addContext( qMakePair( QString::fromLatin1("group"),
 
420
                                                       QString::number(g->groupId())) );
 
421
                }
 
422
        }
 
423
        connect( notify, SIGNAL(activated()), session, SLOT(raiseView()) );
 
424
        connect( notify, SIGNAL(action1Activated()), session, SLOT(raiseView()) );
 
425
        connect( notify, SIGNAL(action2Activated()), event, SLOT(discard()) );
 
426
        connect( event, SIGNAL(done(Kopete::MessageEvent*)), notify, SLOT(close()) );
 
427
        notify->sendEvent();
 
428
}
 
429
 
 
430
void KopeteViewManager::readMessages( Kopete::ChatSession *session, bool isOutboundMessage, bool activate )
 
431
{
 
432
    // kDebug( 14000 ) ;
 
433
    d->foreignMessage = !isOutboundMessage; //for the view we are about to create
 
434
    KopeteView *thisView = session->view( true );
 
435
    d->foreignMessage = false; //the view is created, reset the flag
 
436
    if ( ( isOutboundMessage && !thisView->isVisible() ) || d->raiseWindow || activate )
 
437
            thisView->raise( activate );
 
438
    else if ( !thisView->isVisible() )
 
439
            thisView->makeVisible();
 
440
 
 
441
    foreach ( Kopete::MessageEvent *event, d->eventList )
 
442
    {
 
443
        if ( event->message().manager() == session )
 
444
        {
 
445
            event->apply();
 
446
            d->eventList.removeAll( event );
 
447
        }
 
448
    }
 
449
}
 
450
 
 
451
void KopeteViewManager::slotEventDeleted( Kopete::MessageEvent *event )
 
452
{
 
453
    // d->eventList.remove( event );
 
454
    d->eventList.removeAll(event);
 
455
 
 
456
//    kDebug(14000) ;
 
457
    Kopete::ChatSession *kmm=event->message().manager();
 
458
    if(!kmm)
 
459
    {
 
460
            // this can be NULL for example if KopeteViewManager::slotViewActivated()
 
461
            // got called which does deleteLater() the event what may result in the
 
462
            // case, that the QPointer<ChatSession> in Message::Private got removed
 
463
            // aka set to NULL already.
 
464
            return;
 
465
    }
 
466
 
 
467
    if ( event->state() == Kopete::MessageEvent::Applied )
 
468
    {
 
469
        readMessages( kmm, false, true );
 
470
    }
 
471
    else if ( event->state() == Kopete::MessageEvent::Ignored && d->balloonNotifyIgnoreClosesChatView )
 
472
    {
 
473
        bool bAnotherWithThisManager = false;
 
474
        foreach (Kopete::MessageEvent *event, d->eventList)
 
475
        {
 
476
            if ( event->message().manager() == kmm )
 
477
            {
 
478
                bAnotherWithThisManager = true;
 
479
            }
 
480
        }
 
481
        if ( !bAnotherWithThisManager && kmm->view( false ) )
 
482
            kmm->view()->closeView( true );
 
483
    }
 
484
}
 
485
 
 
486
void KopeteViewManager::nextEvent()
 
487
{
 
488
    // kDebug( 14000 ) ;
 
489
 
 
490
    if( d->eventList.isEmpty() )
 
491
        return;
 
492
 
 
493
    Kopete::MessageEvent* event = d->eventList.first();
 
494
 
 
495
    if ( event )
 
496
        event->apply();
 
497
}
 
498
 
 
499
void KopeteViewManager::slotViewActivated( KopeteView *view )
 
500
{
 
501
    // kDebug( 14000 ) ;
 
502
    d->activeView = view;
 
503
 
 
504
    foreach (Kopete::MessageEvent *event, d->eventList)
 
505
    {
 
506
        if ( event->message().manager() == view->msgManager() )
 
507
        {
 
508
            event->deleteLater();
 
509
        }
 
510
    }
 
511
}
 
512
 
 
513
void KopeteViewManager::slotViewDestroyed( KopeteView *closingView )
 
514
{
 
515
    // kDebug( 14000 ) ;
 
516
 
 
517
    if ( d->sessionMap.contains( closingView->msgManager() ) )
 
518
    {
 
519
        d->sessionMap.remove( closingView->msgManager() );
 
520
        // closingView->msgManager()->setCanBeDeleted( true );
 
521
    }
 
522
 
 
523
    if( closingView == d->activeView )
 
524
        d->activeView = 0L;
 
525
}
 
526
 
 
527
void KopeteViewManager::slotChatSessionDestroyed( Kopete::ChatSession *session )
 
528
{
 
529
        // kDebug( 14000 ) ;
 
530
 
 
531
        if ( d->sessionMap.contains( session ) )
 
532
        {
 
533
                KopeteView *v = d->sessionMap[ session ];
 
534
                v->closeView( true );
 
535
                delete v;   //closeView call deleteLater,  but in this case this is not enough, because some signal are called that case crash
 
536
                d->sessionMap.remove( session );
 
537
        }
 
538
}
 
539
 
 
540
KopeteView* KopeteViewManager::activeView() const
 
541
{
 
542
    return d->activeView;
 
543
}
 
544
 
 
545
 
 
546
QList<Kopete::MessageEvent*> KopeteViewManager::pendingMessages( Kopete::Contact *contact )
 
547
{
 
548
        QList<Kopete::MessageEvent*> pending;
 
549
        foreach (Kopete::MessageEvent *event, d->eventList)
 
550
        {
 
551
                const Kopete::Message &message = event->message();
 
552
                if ( event->state() == Kopete::MessageEvent::Nothing
 
553
                         && message.direction() == Kopete::Message::Inbound
 
554
                         && message.from() == contact )
 
555
                {
 
556
                        pending << event;
 
557
                }
 
558
        }
 
559
 
 
560
        return pending;
 
561
}
 
562
 
 
563
#include "kopeteviewmanager.moc"
 
564
 
 
565
// vim: set noet ts=4 sts=4 sw=4:
 
566