~ubuntu-branches/ubuntu/karmic/choqok/karmic

« back to all changes in this revision

Viewing changes to choqok/timelinewidget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Christian Mangold
  • Date: 2009-08-11 22:29:59 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090811222959-7tnr98ptcnyx3pjg
Tags: 0.6.6-0ubuntu1
[Alessandro Ghersi]
* New upstream release
  - Bump Standards-Version to 3.8.2
  - Long description formatted to fit in 80 characters

[Christian Mangold]
* Improve long description
* Update Maintainer, package is in main now
* Add a watch file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of Choqok, the KDE micro-blogging client
 
3
 
 
4
    Copyright (C) 2008-2009 Mehrdad Momeny <mehrdad.momeny@gmail.com>
 
5
 
 
6
    This program is free software; you can redistribute it and/or
 
7
    modify it under the terms of the GNU General Public License as
 
8
    published by the Free Software Foundation; either version 2 of
 
9
    the License or (at your option) version 3 or any later version
 
10
    accepted by the membership of KDE e.V. (or its successor approved
 
11
    by the membership of KDE e.V.), which shall act as a proxy
 
12
    defined in Section 14 of version 3 of the license.
 
13
 
 
14
 
 
15
    This program is distributed in the hope that it will be useful,
 
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
18
    GNU General Public License for more details.
 
19
 
 
20
    You should have received a copy of the GNU General Public License
 
21
    along with this program; if not, see http://www.gnu.org/licenses/
 
22
 
 
23
*/
 
24
#include "timelinewidget.h"
 
25
#include "statustextedit.h"
 
26
#include "settings.h"
 
27
#include "statuswidget.h"
 
28
#include "constants.h"
 
29
#include "accountmanager.h"
 
30
#include <kdebug.h>
 
31
#include <QTimer>
 
32
#include <KDE/KLocale>
 
33
#include <KDE/KMessageBox>
 
34
#include <QProcess>
 
35
#include <KDE/KNotification>
 
36
#include <KFileDialog>
 
37
#include <KUrl>
 
38
#include <QKeyEvent>
 
39
 
 
40
TimeLineWidget::TimeLineWidget( const Account &userAccount, QWidget* parent ) :
 
41
        QWidget( parent )
 
42
{
 
43
    kDebug();
 
44
    setupUi( this );
 
45
    mCurrentAccount = userAccount;
 
46
    twitter = new Backend( &mCurrentAccount, this );
 
47
    latestHomeStatusId = latestReplyStatusId = 0;
 
48
 
 
49
    homeLayout->setDirection( QBoxLayout::TopToBottom );
 
50
    replyLayout->setDirection( QBoxLayout::TopToBottom );
 
51
    txtNewStatus = new StatusTextEdit( this );
 
52
    lblCounter = new QLabel( this );
 
53
    tabs->setCornerWidget( lblCounter, Qt::TopRightCorner );
 
54
    txtNewStatus->setObjectName( "txtNewStatus" );
 
55
    inputFrame->layout()->addWidget( txtNewStatus );
 
56
 
 
57
    btnAttachMedia->setIcon(KIcon("mail-attachment"));
 
58
    attachMediaFrame->hide();
 
59
    if(mCurrentAccount.serviceType() == Account::Twitter) {
 
60
        mediaToAttach.clear();
 
61
        btnClearMedia->setIcon(KIcon("edit-clear"));
 
62
        connect(btnAttachMedia, SIGNAL(clicked(bool)), SLOT(attachMedia()));
 
63
        connect(btnClearMedia, SIGNAL(clicked(bool)), SLOT(clearMedia()));
 
64
    } else {
 
65
        btnAttachMedia->setEnabled(false);
 
66
    }
 
67
 
 
68
//     connect ( toggleArrow, SIGNAL ( clicked() ), this, SLOT ( toggleTwitFieldVisible() ) );
 
69
    connect( txtNewStatus, SIGNAL( charsLeft( int ) ), this, SLOT( checkNewStatusCharactersCount( int ) ) );
 
70
    connect( txtNewStatus, SIGNAL( returnPressed( QString& ) ), this, SLOT( postStatus( QString& ) ) );
 
71
    connect( txtNewStatus, SIGNAL( cleared() ), this, SLOT( txtNewStatusCleared() ) );
 
72
    connect( qApp, SIGNAL( aboutToQuit() ), this, SLOT( aboutQuit() ) );
 
73
    QTimer::singleShot( 0, this, SLOT( initObjects() ) );
 
74
}
 
75
 
 
76
TimeLineWidget::~TimeLineWidget()
 
77
{
 
78
    kDebug();
 
79
}
 
80
 
 
81
void TimeLineWidget::aboutQuit()
 
82
{
 
83
    kDebug();
 
84
    AccountManager::self()->saveFriendsList( mCurrentAccount.alias(), friendsList );
 
85
    saveStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(), Backend::HomeTimeLine ),
 
86
                  listHomeStatus.values() );
 
87
    saveStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(), Backend::ReplyTimeLine ),
 
88
                  listReplyStatus.values() );
 
89
    saveStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(), Backend::InboxTimeLine ),
 
90
                  listInboxStatus.values() );
 
91
    saveStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(), Backend::OutboxTimeLine ),
 
92
                  listOutboxStatus.values() );
 
93
    deleteLater();
 
94
}
 
95
 
 
96
void TimeLineWidget::initObjects()
 
97
{
 
98
    kDebug();
 
99
 
 
100
    txtNewStatus->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );
 
101
    txtNewStatus->setTabChangesFocus( true );
 
102
    btnReloadFriends->setIcon( KIcon( "view-refresh" ) );
 
103
    connect( btnReloadFriends, SIGNAL( clicked( bool ) ), this, SLOT( reloadFriendsList() ) );
 
104
 
 
105
    QFont counterF;
 
106
    counterF.setBold( true );
 
107
    counterF.setPointSize( 12 );
 
108
    lblCounter->setFont( counterF );
 
109
    checkNewStatusCharactersCount( 140 );
 
110
 
 
111
    connect( twitter, SIGNAL( homeTimeLineReceived( QList< Status >& ) ),
 
112
             this, SLOT( homeTimeLinesReceived( QList< Status >& ) ) );
 
113
    connect( twitter, SIGNAL( replyTimeLineReceived( QList< Status >& ) ),
 
114
             this, SLOT( replyTimeLineReceived( QList< Status >& ) ) );
 
115
    connect( twitter, SIGNAL( directMessagesReceived( QList< Status >& ) ),
 
116
             this, SLOT( directMessagesReceived( QList< Status >& ) ) );
 
117
    connect( twitter, SIGNAL( outboxMessagesReceived( QList< Status >& ) ),
 
118
             this, SLOT( outboxMessagesReceived( QList< Status >& ) ) );
 
119
    connect( twitter, SIGNAL( sigPostNewStatusDone( bool ) ),
 
120
             this, SLOT( postingNewStatusDone( bool ) ) );
 
121
    connect( twitter, SIGNAL( sigFavoritedDone( bool ) ),
 
122
             this, SLOT( requestFavoritedDone( bool ) ) );
 
123
    connect( twitter, SIGNAL( sigDestroyDone( bool ) ),
 
124
             this, SLOT( requestDestroyDone( bool ) ) );
 
125
    connect( twitter, SIGNAL( sigError( const QString& ) ),
 
126
             this, SLOT( error( const QString& ) ) );
 
127
    connect( twitter, SIGNAL( friendsListed( const QStringList& ) ),
 
128
             this, SLOT( friendsListed( const QStringList& ) ) );
 
129
    connect( twitter, SIGNAL( followersListed( const QStringList& ) ),
 
130
             this, SLOT( friendsListed( const QStringList& ) ) );
 
131
 
 
132
    replyToStatusId = unreadStatusCount = unreadStatusInReply = unreadStatusInHome =
 
133
                                              unreadStatusInInbox = unreadStatusInOutbox = latestInboxStatusId =
 
134
                                                                        latestOutboxStatusId = 0;
 
135
 
 
136
    setTabOrder( chkDMessage, comboFriendList );
 
137
    setTabOrder( comboFriendList, btnReloadFriends );
 
138
    setTabOrder( btnReloadFriends, txtNewStatus );
 
139
    setTabOrder( txtNewStatus, chkDMessage );
 
140
 
 
141
    loadConfigurations();
 
142
    txtNewStatus->setFocus( Qt::OtherFocusReason );
 
143
    settingsChanged();
 
144
}
 
145
 
 
146
void TimeLineWidget::checkNewStatusCharactersCount( int numOfChars )
 
147
{
 
148
    if ( numOfChars < 0 ) {
 
149
        lblCounter->setStyleSheet( "QLabel {color: red;}" );
 
150
    } else if ( numOfChars < 30 ) {
 
151
        lblCounter->setStyleSheet( "QLabel {color: rgb(242, 179, 19);}" );
 
152
    } else {
 
153
        lblCounter->setStyleSheet( "QLabel {color: green;}" );
 
154
    }
 
155
 
 
156
    if ( numOfChars == 140 ) {
 
157
        txtNewStatus->setMaximumHeight( 28 );
 
158
        lblCounter->setVisible(false);
 
159
    } else {
 
160
        txtNewStatus->setMaximumHeight( 80 );
 
161
        lblCounter->setVisible(true);
 
162
    }
 
163
 
 
164
    lblCounter->setText( KGlobal::locale()->formatNumber( numOfChars, 0 ) );
 
165
}
 
166
 
 
167
void TimeLineWidget::settingsChanged()
 
168
{
 
169
    kDebug();
 
170
    setDefaultDirection();
 
171
    twitter->settingsChanged();
 
172
    updateUi();
 
173
    foreach(StatusWidget * s,listHomeStatus)
 
174
      s->setUiStyle();
 
175
    foreach(StatusWidget * s,listInboxStatus)
 
176
      s->setUiStyle();
 
177
    foreach(StatusWidget * s,listOutboxStatus)
 
178
      s->setUiStyle();
 
179
    foreach(StatusWidget * s,listReplyStatus)
 
180
      s->setUiStyle();
 
181
}
 
182
 
 
183
void TimeLineWidget::updateTimeLines()
 
184
{
 
185
    kDebug();
 
186
    twitter->requestTimeLine( latestHomeStatusId, Backend::HomeTimeLine );
 
187
    twitter->requestTimeLine( latestReplyStatusId, Backend::ReplyTimeLine );
 
188
    twitter->requestDMessages( latestInboxStatusId, Backend::Inbox );
 
189
    twitter->requestDMessages( latestOutboxStatusId, Backend::Outbox );
 
190
 
 
191
    if ( latestHomeStatusId == 0 || latestReplyStatusId == 0 )
 
192
        isStartMode = true;
 
193
    else
 
194
        isStartMode = false;
 
195
 
 
196
    emit notify( i18n( "Loading timelines..." ), true );
 
197
}
 
198
 
 
199
void TimeLineWidget::directMessagesReceived( QList< Status > & msgList )
 
200
{
 
201
    kDebug();
 
202
    emit notify( i18n( "Latest direct messages received." ) );
 
203
    int count = msgList.count();
 
204
 
 
205
    if ( count == 0 ) {
 
206
        kDebug() << "Message list is empty";
 
207
        emit notify( i18n( "No new messages received. The list is up to date." ) );
 
208
        return;
 
209
    } else {
 
210
        addNewStatusesToUi( msgList, inboxLayout, &listInboxStatus, Backend::InboxTimeLine );
 
211
//         inboxScroll->verticalScrollBar()->setSliderPosition( 0 );
 
212
        kDebug() << count << " Statuses received.";
 
213
        if ( !isStartMode ) {
 
214
            unreadStatusInInbox += count;
 
215
            if ( unreadStatusInInbox > 0 )
 
216
                tabs->setTabText( 2, i18n( "Inbox(%1)", unreadStatusInInbox ) );
 
217
        }
 
218
    }
 
219
}
 
220
 
 
221
void TimeLineWidget::outboxMessagesReceived( QList< Status > & msgList )
 
222
{
 
223
    kDebug();
 
224
    emit notify( i18n( "Latest sent messages received." ) );
 
225
    int count = msgList.count();
 
226
 
 
227
    if ( count == 0 ) {
 
228
        kDebug() << "Message list is empty";
 
229
        emit notify( i18n( "No new messages received. The list is up to date." ) );
 
230
        return;
 
231
    } else {
 
232
        addNewStatusesToUi( msgList, outboxLayout, &listOutboxStatus, Backend::OutboxTimeLine );
 
233
//         outboxScroll->verticalScrollBar()->setSliderPosition( 0 );
 
234
 
 
235
        kDebug() << count << " Statuses received.";
 
236
 
 
237
//         if ( !isStartMode ) {
 
238
//             unreadStatusInOutbox += count;
 
239
//             if( unreadStatusInOutbox > 0 )
 
240
//                 tabs->setTabText ( 3, i18n ( "Outbox(%1)", unreadStatusInOutbox ) );
 
241
//         }
 
242
    }
 
243
}
 
244
 
 
245
void TimeLineWidget::homeTimeLinesReceived( QList< Status > & statusList )
 
246
{
 
247
    kDebug();
 
248
    emit notify( i18n( "Latest friend timelines received." ) );
 
249
    int count = statusList.count();
 
250
 
 
251
    if ( count == 0 ) {
 
252
        kDebug() << "Status list is empty";
 
253
        emit notify( i18n( "No new statuses received. The list is up to date." ) );
 
254
        return;
 
255
    } else {
 
256
        addNewStatusesToUi( statusList, homeLayout, &listHomeStatus );
 
257
//         homeScroll->verticalScrollBar()->setSliderPosition( 0 );
 
258
 
 
259
//         int count = statusList.count();
 
260
        kDebug() << count << " Statuses received.";
 
261
 
 
262
        if ( !isStartMode ) {
 
263
            unreadStatusInHome += count;
 
264
            if ( unreadStatusInHome > 0 )
 
265
                tabs->setTabText( 0, i18n( "Home(%1)", unreadStatusInHome ) );
 
266
        }
 
267
    }
 
268
}
 
269
 
 
270
void TimeLineWidget::replyTimeLineReceived( QList< Status > & statusList )
 
271
{
 
272
    kDebug();
 
273
    emit notify( i18n( "Latest reply timelines received." ) );
 
274
    int count = statusList.count();
 
275
    if ( count == 0 ) {
 
276
        kDebug() << "Status list is empty";
 
277
        emit notify( i18n( "No new statuses received. The list is up to date." ) );
 
278
        return;
 
279
    } else {
 
280
        addNewStatusesToUi( statusList, replyLayout, &listReplyStatus, Backend::ReplyTimeLine );
 
281
//         replyScroll->verticalScrollBar()->setSliderPosition( 0 );
 
282
 
 
283
//         int count = statusList.count();
 
284
        kDebug() << count << " Statuses received.";
 
285
 
 
286
        if ( !isStartMode ) {
 
287
            unreadStatusInReply += count;
 
288
            if ( unreadStatusInReply > 0 )
 
289
                tabs->setTabText( 1, i18n( "Reply(%1)", unreadStatusInReply ) );
 
290
        }
 
291
    }
 
292
}
 
293
 
 
294
void TimeLineWidget::addNewStatusesToUi( QList< Status > & statusList, QBoxLayout * layoutToAddStatuses,
 
295
        QMap<qulonglong, StatusWidget*> *list, Backend::TimeLineType type )
 
296
{
 
297
    kDebug();
 
298
    bool allInOne = Settings::showAllNotifiesInOne();
 
299
    QString notifyStr;
 
300
    int numOfNewStatuses = statusList.count();
 
301
    QList<Status>::const_iterator it = statusList.constBegin();
 
302
    QList<Status>::const_iterator endIt = statusList.constEnd();
 
303
    bool isThereAnyNewStatusToNotify = false;
 
304
    if ( allInOne && Settings::notifyType() != SettingsBase::LibNotify )
 
305
        notifyStr = ( mCurrentAccount.direction() == Qt::RightToLeft ) ? "<div dir='rtl'>" : "<div dir='ltr'>";
 
306
    for ( ;it != endIt; ++it ) {
 
307
        if ( Settings::doNotShowRepliesOnHome() ) {
 
308
            if ( it->replyToUserId == mCurrentAccount.userId() && type == Backend::HomeTimeLine ) {
 
309
                --numOfNewStatuses;
 
310
                --unreadStatusInHome;
 
311
                continue;
 
312
            }
 
313
        }
 
314
        if(list->keys().contains(it->statusId)) 
 
315
            continue;
 
316
        
 
317
 
 
318
        StatusWidget *wt = new StatusWidget( &mCurrentAccount, this );
 
319
        wt->setAttribute( Qt::WA_DeleteOnClose );
 
320
        wt->setCurrentStatus( *it );
 
321
        connect( wt, SIGNAL( sigReply( const QString&, qulonglong, bool ) ),
 
322
                 this, SLOT( prepareReply( const QString&, qulonglong, bool ) ) );
 
323
        connect( wt, SIGNAL( sigFavorite( qulonglong, bool ) ),
 
324
                 twitter, SLOT( requestFavorited( qulonglong, bool ) ) );
 
325
        connect( wt, SIGNAL( sigDestroy( qulonglong ) ),
 
326
                 this, SLOT( requestDestroy( qulonglong ) ) );
 
327
        connect(wt,SIGNAL(sigSearch(int,QString)),this,SIGNAL(sigSearch(int,QString)));
 
328
        connect(wt, SIGNAL(sigReTweet(const QString&)), this, SLOT(reTweet(const QString&)));
 
329
 
 
330
        list->insert( it->statusId, wt );
 
331
        layoutToAddStatuses->insertWidget( 0, wt );
 
332
 
 
333
        if ( !isStartMode ) {
 
334
            if ( it->user.userId == mCurrentAccount.userId() ) {
 
335
                --numOfNewStatuses;
 
336
                wt->setUnread( StatusWidget::WithoutNotify );
 
337
            } else {
 
338
                if ( type == Backend::OutboxTimeLine ) {
 
339
                    wt->setUnread( StatusWidget::WithoutNotify );
 
340
                } else if ( allInOne ) {
 
341
                    notifyStr += "<b>" + it->user.screenName + " : </b>" + it->content + "<br/>";
 
342
                    isThereAnyNewStatusToNotify = true;
 
343
                    wt->setUnread( StatusWidget::WithoutNotify );
 
344
                } else {
 
345
                    wt->setUnread( StatusWidget::WithNotify );
 
346
                }
 
347
            }
 
348
            listUnreadStatuses.append( wt );
 
349
        }
 
350
    }
 
351
    if ( allInOne && Settings::notifyType() != SettingsBase::LibNotify )
 
352
        notifyStr += "</div>";
 
353
    qulonglong latestId = statusList.last().statusId;
 
354
    if ( type == Backend::HomeTimeLine && latestId > latestHomeStatusId ) {
 
355
        kDebug() << "Latest home statusId sets to: " << latestId;
 
356
        latestHomeStatusId = latestId;
 
357
    } else if ( type == Backend::ReplyTimeLine && latestId > latestReplyStatusId ) {
 
358
        kDebug() << "Latest reply statusId sets to: " << latestId;
 
359
        latestReplyStatusId = latestId;
 
360
    } else if ( type == Backend::InboxTimeLine && latestId > latestInboxStatusId ) {
 
361
        kDebug() << "Latest inbox statusId sets to: " << latestId;
 
362
        latestInboxStatusId = latestId;
 
363
    } else if ( type == Backend::OutboxTimeLine && latestId > latestOutboxStatusId ) {
 
364
        kDebug() << "Latest outbox statusId sets to: " << latestId;
 
365
        latestOutboxStatusId = latestId;
 
366
    }
 
367
    if ( !isStartMode && type != Backend::OutboxTimeLine )
 
368
        checkUnreadStatuses( numOfNewStatuses );
 
369
 
 
370
    if ( isThereAnyNewStatusToNotify ) {
 
371
        showNotify( i18n( "New statuses" ), notifyStr );
 
372
    }
 
373
 
 
374
    updateStatusList( list );
 
375
}
 
376
 
 
377
void TimeLineWidget::abortPostNewStatus()
 
378
{
 
379
    kDebug();
 
380
    twitter->abortPostNewStatus();
 
381
}
 
382
 
 
383
void TimeLineWidget::setDefaultDirection()
 
384
{
 
385
//     tabs->widget( 0 )->setLayoutDirection( mCurrentAccount.direction() );
 
386
//     tabs->widget( 1 )->setLayoutDirection( mCurrentAccount.direction() );
 
387
//     tabs->widget( 2 )->setLayoutDirection( mCurrentAccount.direction() );
 
388
//     tabs->widget( 3 )->setLayoutDirection( mCurrentAccount.direction() );
 
389
//     tabs->widget ( 4 )->setLayoutDirection ( mCurrentAccount.direction() );
 
390
 
 
391
    txtNewStatus->setDefaultDirection( mCurrentAccount.direction() );
 
392
}
 
393
 
 
394
void TimeLineWidget::error( const QString & errMsg )
 
395
{
 
396
    emit notify( i18n( "Failed: %1", errMsg ), true );
 
397
}
 
398
 
 
399
void TimeLineWidget::postStatus( QString & status )
 
400
{
 
401
    kDebug();
 
402
 
 
403
    if ( status.size() > MAX_STATUS_SIZE && status.indexOf( QRegExp( "https?://" ) ) == -1 ) {
 
404
        QString err = i18n( "Message text size is greater than the server limit: \
 
405
the server may truncate or drop it.\nAre you sure you want to post this message?" );
 
406
        if(KMessageBox::warningContinueCancel( this, err ) == KMessageBox::Cancel)
 
407
            return;
 
408
    }
 
409
    txtNewStatus->setEnabled( false );
 
410
    if( mediaToAttach.isEmpty() ) {
 
411
        if ( chkDMessage->isChecked() ) {
 
412
            emit notify( i18n( "Sending direct message...." ), true );
 
413
            twitter->sendDMessage( comboFriendList->currentText(), status );
 
414
            chkDMessage->setChecked( false );
 
415
        } else {
 
416
            emit notify( i18n( "Posting new status...." ), true );
 
417
            twitter->postNewStatus( status, replyToStatusId );
 
418
        }
 
419
    } else {
 
420
        emit notify( i18n( "Posting new status...." ), true );
 
421
        twitter->twitPicCreatePost( mediaToAttach, status );
 
422
        mediaToAttach.clear();
 
423
    }
 
424
}
 
425
 
 
426
void TimeLineWidget::postingNewStatusDone( bool isError )
 
427
{
 
428
    kDebug();
 
429
//     emit sigStatusUpdated( isError );
 
430
    if ( !isError ) {
 
431
        clearMedia();
 
432
        txtNewStatus->clearContentsAndSetDirection( mCurrentAccount.direction() );
 
433
        QString successMsg = i18n( "New status posted successfully" );
 
434
        emit systemNotify( i18n( "Success." ), successMsg, APPNAME );
 
435
        notify( successMsg );
 
436
        replyToStatusId = 0;
 
437
        lblCounter->setPixmap(KIcon("dialog-ok").pixmap(22));
 
438
        twitter->requestTimeLine(latestHomeStatusId, Backend::HomeTimeLine);
 
439
    } else {
 
440
        lblCounter->setPixmap(KIcon("dialog-cancel").pixmap(22));
 
441
        error( twitter->latestErrorString() );
 
442
    }
 
443
    QTimer::singleShot( 3000, this, SLOT( revertCounterLabelShape() ) );
 
444
    lblCounter->show();
 
445
    lblCounter->setText(QString());
 
446
    txtNewStatus->setFocus( Qt::OtherFocusReason );
 
447
    txtNewStatus->setEnabled( true );
 
448
 
 
449
}
 
450
 
 
451
bool TimeLineWidget::saveStatuses( QString fileName, QList<StatusWidget*> list )
 
452
{
 
453
    kDebug();
 
454
    KConfig statusesBackup( "choqok/" + fileName, KConfig::NoGlobals, "data" );
 
455
 
 
456
    ///Clear previous data:
 
457
    QStringList prevList = statusesBackup.groupList();
 
458
    int c = prevList.count();
 
459
 
 
460
    if ( c > 0 ) {
 
461
        for ( int i = 0; i < c; ++i ) {
 
462
            statusesBackup.deleteGroup( prevList[i] );
 
463
        }
 
464
    }
 
465
 
 
466
    int count = list.count();
 
467
 
 
468
    for ( int i = 0; i < count; ++i ) {
 
469
//   QString str = ;
 
470
        KConfigGroup grp( &statusesBackup, QString::number( list[i]->currentStatus().statusId ) );
 
471
        grp.writeEntry( "created_at", list[i]->currentStatus().creationDateTime );
 
472
        grp.writeEntry( "id", list[i]->currentStatus().statusId );
 
473
        grp.writeEntry( "text", list[i]->currentStatus().content );
 
474
        grp.writeEntry( "source", list[i]->currentStatus().source );
 
475
        grp.writeEntry( "truncated", list[i]->currentStatus().isTruncated );
 
476
        grp.writeEntry( "in_reply_to_status_id", list[i]->currentStatus().replyToStatusId );
 
477
        grp.writeEntry( "in_reply_to_user_id", list[i]->currentStatus().replyToUserId );
 
478
        grp.writeEntry( "favorited", list[i]->currentStatus().isFavorited );
 
479
        grp.writeEntry( "in_reply_to_screen_name", list[i]->currentStatus().replyToUserScreenName );
 
480
        grp.writeEntry( "userId", list[i]->currentStatus().user.userId );
 
481
        grp.writeEntry( "screen_name", list[i]->currentStatus().user.screenName );
 
482
        grp.writeEntry( "name", list[i]->currentStatus().user.name );
 
483
        grp.writeEntry( "profile_image_url", list[i]->currentStatus().user.profileImageUrl );
 
484
        grp.writeEntry( "description" , list[i]->currentStatus().user.description );
 
485
        grp.writeEntry( "isDMessage" , list[i]->currentStatus().isDMessage );
 
486
        grp.writeEntry( "location" , list[i]->currentStatus().user.location );
 
487
        grp.writeEntry( "url" , list[i]->currentStatus().user.homePageUrl );
 
488
        grp.writeEntry( "followers_count" , list[i]->currentStatus().user.followersCount );
 
489
        grp.writeEntry( "friends_count" , list[i]->currentStatus().user.friendsCount );
 
490
    }
 
491
 
 
492
    statusesBackup.sync();
 
493
 
 
494
    return true;
 
495
}
 
496
 
 
497
QList< Status > TimeLineWidget::loadStatuses( QString fileName )
 
498
{
 
499
    kDebug();
 
500
    KConfig statusesBackup( "choqok/" + fileName, KConfig::NoGlobals, "data" );
 
501
//  KConfigGroup entries(&statusesBackup, "Statuses");
 
502
    QList< Status > list;
 
503
    QStringList groupList = statusesBackup.groupList();
 
504
//  kDebug()<<groupList;
 
505
    int count = groupList.count();
 
506
 
 
507
    for ( int i = 0; i < count; ++i ) {
 
508
        KConfigGroup grp( &statusesBackup, groupList[i] );
 
509
        Status st;
 
510
        st.creationDateTime = grp.readEntry( "created_at", QDateTime::currentDateTime() );
 
511
        st.statusId = grp.readEntry( "id", ( qulonglong ) 0 );
 
512
        st.content = grp.readEntry( "text", QString() );
 
513
        st.source = grp.readEntry( "source", QString() );
 
514
        st.isTruncated = grp.readEntry( "truncated", false );
 
515
        st.replyToStatusId = grp.readEntry( "in_reply_to_status_id", ( qulonglong ) 0 );
 
516
        st.replyToUserId = grp.readEntry( "in_reply_to_user_id", ( qulonglong ) 0 );
 
517
        st.isFavorited = grp.readEntry( "favorited", false );
 
518
        st.replyToUserScreenName = grp.readEntry( "in_reply_to_screen_name", QString() );
 
519
        st.user.userId = grp.readEntry( "userId", ( qulonglong ) 0 );
 
520
        st.user.screenName = grp.readEntry( "screen_name", QString() );
 
521
        st.user.name = grp.readEntry( "name", QString() );
 
522
        st.user.profileImageUrl = grp.readEntry( "profile_image_url", QString() );
 
523
        st.user.description = grp.readEntry( "description" , QString() );
 
524
        st.isDMessage = grp.readEntry( "isDMessage" , false );
 
525
        st.user.location = grp.readEntry("location", QString());
 
526
        st.user.homePageUrl = grp.readEntry("url", QString());
 
527
        st.user.followersCount = grp.readEntry("followers_count", 0);
 
528
        st.user.friendsCount = grp.readEntry("friends_count", 0);
 
529
 
 
530
        //Sorting The new statuses:
 
531
        int j = 0;
 
532
        int count = list.count();
 
533
        while (( j < count ) && ( st.statusId > list[ j ].statusId ) ) {
 
534
            ++j;
 
535
        }
 
536
        list.insert( j, st );
 
537
    }
 
538
 
 
539
    return list;
 
540
}
 
541
 
 
542
void TimeLineWidget::prepareReply( const QString &userName, qulonglong statusId, bool dMsg )
 
543
{
 
544
    kDebug();
 
545
    emit showMe();
 
546
    if ( dMsg ) {
 
547
        chkDMessage->setChecked( true );
 
548
        comboFriendList->setCurrentItem( userName, true, 0 );
 
549
    } else {
 
550
        QString current = txtNewStatus->toPlainText();
 
551
        txtNewStatus->setText( '@' + userName + ' ' + current );
 
552
        replyToStatusId = statusId;
 
553
        txtNewStatus->setDefaultDirection( mCurrentAccount.direction() );
 
554
    }
 
555
    txtNewStatus->moveCursor( QTextCursor::End );
 
556
    txtNewStatus->setFocus( Qt::OtherFocusReason );
 
557
}
 
558
 
 
559
void TimeLineWidget::updateStatusList( QMap<qulonglong, StatusWidget*> *list )
 
560
{
 
561
    kDebug();
 
562
    int toBeDelete = list->count() - Settings::countOfStatusesOnMain();
 
563
 
 
564
    if ( toBeDelete > 0 ) {
 
565
        QMap<qulonglong, StatusWidget*>::const_iterator it = list->constBegin();
 
566
        QMap<qulonglong, StatusWidget*>::const_iterator endIt = list->constEnd();
 
567
        for ( ; it != endIt && toBeDelete > 0; ++it ) {
 
568
            StatusWidget* wt = it.value();
 
569
            if( !wt )
 
570
                continue;
 
571
            if ( !wt->isRead() )
 
572
                break;
 
573
            wt->close();
 
574
            list->remove( it.key() );
 
575
            --toBeDelete;
 
576
        }
 
577
    }
 
578
}
 
579
 
 
580
void TimeLineWidget::clearTimeLineList( QMap<qulonglong, StatusWidget * > * list )
 
581
{
 
582
    kDebug();
 
583
    qDeleteAll(*list);
 
584
}
 
585
 
 
586
void TimeLineWidget::loadConfigurations()
 
587
{
 
588
    kDebug();
 
589
    setDefaultDirection();
 
590
    friendsList = AccountManager::self()->listFriends( mCurrentAccount.alias() );
 
591
    friendsList.sort();
 
592
//     txtNewStatus->setFriendsList( friendsList );
 
593
    comboFriendList->addItems( friendsList );
 
594
    KCompletion *c = comboFriendList->completionObject( true );;
 
595
    c->setItems( friendsList );
 
596
    c->setCompletionMode( KGlobalSettings::CompletionPopupAuto );
 
597
 
 
598
    isStartMode = true;
 
599
 
 
600
    QList< Status > lstHome =
 
601
        loadStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(),
 
602
                                                                    Backend::HomeTimeLine ) );
 
603
    if ( lstHome.count() > 0 )
 
604
        homeTimeLinesReceived( lstHome );
 
605
 
 
606
    QList< Status > lstReply =
 
607
        loadStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(),
 
608
                                                                    Backend::ReplyTimeLine ) );
 
609
    if ( lstReply.count() > 0 )
 
610
        replyTimeLineReceived( lstReply );
 
611
 
 
612
    QList< Status > lstInbox =
 
613
        loadStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(),
 
614
                                                                    Backend::InboxTimeLine ) );
 
615
    if ( lstInbox.count() > 0 )
 
616
        directMessagesReceived( lstInbox );
 
617
 
 
618
    QList< Status > lstOutbox =
 
619
        loadStatuses( AccountManager::generateStatusBackupFileName( mCurrentAccount.alias(),
 
620
                                                                    Backend::OutboxTimeLine ) );
 
621
    if ( lstOutbox.count() > 0 )
 
622
        outboxMessagesReceived( lstOutbox );
 
623
 
 
624
}
 
625
 
 
626
void TimeLineWidget::checkUnreadStatuses( int numOfNewStatusesReciened )
 
627
{
 
628
    kDebug();
 
629
//  if(this->isVisible()){
 
630
//   unreadStatusCount = 0;
 
631
//  } else {
 
632
    unreadStatusCount += numOfNewStatusesReciened;
 
633
//  }
 
634
    emit sigSetUnread( numOfNewStatusesReciened );
 
635
    emit sigSetUnreadOnMainWin( unreadStatusCount );
 
636
}
 
637
 
 
638
void TimeLineWidget::setUnreadStatusesToReadState()
 
639
{
 
640
    kDebug();
 
641
    tabs->setTabText( 0, i18nc( "@title:tab", "Home" ) );
 
642
    tabs->setTabText( 1, i18nc( "@title:tab", "Reply" ) );
 
643
    tabs->setTabText( 2, i18nc( "@title:tab", "Inbox" ) );
 
644
    tabs->setTabText( 3, i18nc( "@title:tab", "Outbox" ) );
 
645
    int count = listUnreadStatuses.count();
 
646
 
 
647
    for ( int i = 0;i < count; ++i ) {
 
648
        listUnreadStatuses[i]->setRead();
 
649
    }
 
650
 
 
651
    listUnreadStatuses.clear();
 
652
//     if(unreadStatusCount) {
 
653
//       QString s = qApp->styleSheet();
 
654
//       qApp->setStyleSheet(s);
 
655
//     }
 
656
//     qApp->setStyleSheet( StatusWidget::getColoredStyle() );
 
657
 
 
658
    emit sigSetUnread( -unreadStatusCount );
 
659
    emit sigSetUnreadOnMainWin( 0 );
 
660
    unreadStatusCount = unreadStatusInReply = unreadStatusInHome = 0;
 
661
}
 
662
 
 
663
void TimeLineWidget::requestFavoritedDone( bool isError )
 
664
{
 
665
    kDebug() << "is Error: " << isError;
 
666
    notify( "Done!" );
 
667
}
 
668
 
 
669
void TimeLineWidget::requestDestroyDone( bool isError )
 
670
{
 
671
    kDebug() << "is Error: " << isError;
 
672
    notify( "Done!" );
 
673
    toBeDestroied->close();
 
674
}
 
675
 
 
676
void TimeLineWidget::requestDestroy( qulonglong statusId )
 
677
{
 
678
    if ( KMessageBox::warningYesNo( this, i18n( "Are you sure you wish to destroy this status?" ) ) == KMessageBox::Yes ) {
 
679
        toBeDestroied = qobject_cast<StatusWidget*> ( sender() );
 
680
        if ( toBeDestroied->currentStatus().isDMessage ) {
 
681
            twitter->requestDestroyDMessage( statusId );
 
682
        } else {
 
683
            twitter->requestDestroy( statusId );
 
684
        }
 
685
        setUnreadStatusesToReadState();
 
686
    }
 
687
}
 
688
 
 
689
void TimeLineWidget::disableApp()
 
690
{
 
691
    kDebug();
 
692
    txtNewStatus->setEnabled( false );
 
693
}
 
694
 
 
695
void TimeLineWidget::enableApp()
 
696
{
 
697
    kDebug();
 
698
    txtNewStatus->setEnabled( true );
 
699
}
 
700
 
 
701
Account TimeLineWidget::currentAccount() const
 
702
{
 
703
    return mCurrentAccount;
 
704
}
 
705
 
 
706
void TimeLineWidget::setCurrentAccount( const Account & account )
 
707
{
 
708
    mCurrentAccount = account;
 
709
}
 
710
 
 
711
void TimeLineWidget::reloadFriendsList()
 
712
{
 
713
    kDebug();
 
714
    friendsList.clear();
 
715
    comboFriendList->setCurrentItem( i18n("Please wait...."), true, 0);
 
716
//     twitter->listFollowersScreenName();
 
717
    twitter->listFriendsScreenName();
 
718
}
 
719
 
 
720
void TimeLineWidget::friendsListed( const QStringList & list )
 
721
{
 
722
    friendsList<<list;
 
723
    friendsList.removeDuplicates();
 
724
    friendsList.sort();
 
725
 
 
726
    comboFriendList->clear();
 
727
    comboFriendList->addItems( friendsList );
 
728
    KCompletion *c = comboFriendList->completionObject( true );
 
729
    c->setItems( friendsList );
 
730
    c->setCompletionMode( KGlobalSettings::CompletionPopupAuto );
 
731
}
 
732
 
 
733
void TimeLineWidget::showNotify( const QString &title, const QString &message )
 
734
{
 
735
    if ( Settings::notifyType() == SettingsBase::KNotify ) {//KNotify
 
736
        KNotification *notif = new KNotification( "new-status-arrived", parentWidget() );
 
737
        notif->setText( message );
 
738
        notif->setFlags( KNotification::RaiseWidgetOnActivation | KNotification::Persistent );
 
739
        notif->sendEvent();
 
740
        QTimer::singleShot( Settings::notifyInterval()*1000, notif, SLOT( close() ) );
 
741
    } else if ( Settings::notifyType() == SettingsBase::LibNotify ) {//Libnotify!
 
742
        QString msg = message;
 
743
        msg = msg.replace( "<br/>", "\n" );
 
744
        QString libnotifyCmd = QString( "notify-send -t " ) + QString::number( Settings::notifyInterval() * 1000 )
 
745
                               + QString( " -u low \"" ) + title + QString( "\" \"" ) + msg + QString( "\"" );
 
746
        QProcess::execute( libnotifyCmd );
 
747
    }
 
748
}
 
749
 
 
750
void TimeLineWidget::txtNewStatusCleared()
 
751
{
 
752
    replyToStatusId = 0;
 
753
}
 
754
 
 
755
void TimeLineWidget::updateUi()
 
756
{
 
757
    if(Settings::showIconsOnTimelineTabs()) {
 
758
        tabs->setTabIcon(0, KIcon( "user-home" ));
 
759
        tabs->setTabIcon(1, KIcon( "edit-undo" ));
 
760
        tabs->setTabIcon(2, KIcon( "mail-folder-inbox" ));
 
761
        tabs->setTabIcon(3, KIcon( "mail-folder-outbox" ));
 
762
    } else {
 
763
        tabs->setTabIcon(0, KIcon());
 
764
        tabs->setTabIcon(1, KIcon());
 
765
        tabs->setTabIcon(2, KIcon());
 
766
        tabs->setTabIcon(3, KIcon());
 
767
    }
 
768
}
 
769
 
 
770
void TimeLineWidget::revertCounterLabelShape()
 
771
{
 
772
    lblCounter->setPixmap( QPixmap() );
 
773
    checkNewStatusCharactersCount( txtNewStatus->countOfRemainsChar() );
 
774
}
 
775
 
 
776
Backend* TimeLineWidget::getBackend()
 
777
{
 
778
    return twitter;
 
779
}
 
780
 
 
781
void TimeLineWidget::reTweet( const QString &text )
 
782
{
 
783
    replyToStatusId = 0;
 
784
    txtNewStatus->setText( text );
 
785
    txtNewStatus->setFocus(Qt::OtherFocusReason);
 
786
}
 
787
 
 
788
void TimeLineWidget::attachMedia()
 
789
{
 
790
    kDebug();
 
791
    QString mediaPath = KFileDialog::getOpenFileName( KUrl("kfiledialog:///image?global"),
 
792
                                                      "image/png image/jpeg image/gif", this,
 
793
                                                      i18n("Select media to attach"));
 
794
    if( !mediaPath.isEmpty() ) {
 
795
        mediaToAttach.setPath(mediaPath);
 
796
        lblMediaName->setText( mediaToAttach.fileName() );
 
797
        lblMediaName->setToolTip(mediaPath);
 
798
        attachMediaFrame->show();
 
799
    }
 
800
    txtNewStatus->setFocus(Qt::OtherFocusReason);
 
801
}
 
802
 
 
803
void TimeLineWidget::clearMedia()
 
804
{
 
805
    lblMediaName->clear();
 
806
    mediaToAttach.clear();
 
807
    attachMediaFrame->hide();
 
808
}
 
809
 
 
810
void TimeLineWidget::keyPressEvent( QKeyEvent *event )
 
811
{
 
812
    if(event->key() == Qt::Key_Escape){
 
813
        twitter->abortPostNewStatus();
 
814
        txtNewStatus->setEnabled(true);
 
815
        txtNewStatus->setFocus();
 
816
    }
 
817
}
 
818
 
 
819
#include "timelinewidget.moc"