Initial commit
[tietoopcom] / src / TocUi / TocMainToolbar.cpp
1 /** \file TocMainToolbar.cpp
2  * \brief Implementation of TocMainToolbar class
3  * 
4  * Tieto Open Communicator - Client for the Telepathy communications framework.
5  * Copyright (c) 2010, Tieto Corporation
6  *
7  * All rights reserved.
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  *      Redistributions of source code must retain the above copyright notice,
12  *      this list of conditions and the following disclaimer.
13  *      Redistributions in binary form must reproduce the above copyright notice,
14  *      this list of conditions and the following disclaimer in the documentation
15  *      and/or other materials provided with the distribution.
16  *      Neither the name of the Tieto Corporation nor the names of its contributors 
17  *      may be used to endorse or promote products derived from this software without
18  *      specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  * 
30  */
31  
32 #include "TocMainToolbar"
33 #include "macros.h"
34 #include <QPushButton> 
35 #include <QHBoxLayout>
36 #include <QMenu>
37 #include <QLabel>
38 #include <QEvent>
39 #include <QDebug>
40 #include <QThread>
41
42
43 TocMainToolbar::TocMainToolbar(QWidget * parent, Qt::WindowFlags flags)
44         : QWidget(parent, flags) {
45         
46         setObjectName("mainToolbar");
47         QHBoxLayout* horizontalLayout = new QHBoxLayout( this );
48         horizontalLayout->setSpacing( 0 );
49         setContentsMargins( -10, -10, -10, -10 );
50
51         statusButton = new QPushButton( QIcon(":/offline.png"), "", this );
52         statusButton->setObjectName("statusButton");
53         statusButton->setIconSize( QSize( 72, 72 ) );
54         horizontalLayout->addWidget( statusButton );
55         statusMenu = new QMenu( this );
56         statusMenu->setObjectName("statusMenu");
57         onlineAction = statusMenu->addAction( QIcon(":/online.png"), tr("Online") );
58         onlineAction->setData( QVariant::fromValue( Available ) );
59         awayAction = statusMenu->addAction( QIcon(":/away.png"), tr("Away") );
60         awayAction->setData( QVariant::fromValue( Away ) );
61         busyAction = statusMenu->addAction( QIcon(":/busy.png"), tr("Do not Disturb") );
62         busyAction->setData( QVariant::fromValue( Busy ) );
63         hiddenAction = statusMenu->addAction( QIcon(":/hidden.png"), tr("Hidden") );
64         hiddenAction->setData( QVariant::fromValue( Hidden ) );
65         offlineAction = statusMenu->addAction( QIcon(":/offline.png"), tr("Offline") );
66         offlineAction->setData( QVariant::fromValue( Offline ) );
67         statusButton->setMenu( statusMenu );
68         CONNECT( statusMenu, SIGNAL(triggered(QAction*)), this, SLOT(onTriggeredPresence(QAction*)) );
69
70         statusAreaLabel = new QLabel( this );
71         statusAreaLabel->setObjectName("statusAreaLabel");
72         statusAreaLabel->setWordWrap( true );
73         statusAreaLabel->setProperty("checked", false);
74         statusAreaLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
75         horizontalLayout->addWidget( statusAreaLabel );
76
77         statusAreaButton = new QPushButton( this );
78         statusAreaButton->setObjectName("statusAreaButton");
79         statusAreaButton->setEnabled( false );
80         statusAreaButton->setCheckable( true );
81         horizontalLayout->addWidget( statusAreaButton );
82
83         activeSessionsButton = new QPushButton( QIcon(":/activesessions.png"), "", this );
84         activeSessionsButton->setObjectName("activeSessionsButton");
85         activeSessionsButton->setIconSize( QSize( 72, 72 ) );
86         activeSessionsButton->setEnabled(false);
87         horizontalLayout->addWidget( activeSessionsButton );
88         
89
90         _pActiveSessions = new ActiveSessions(this);
91         
92         activeSessionsButton->setMenu( _pActiveSessions->menu() );
93         activeSessionsButton->setObjectName("activeSessionsButton");
94         
95         settingsButton = new QPushButton( QIcon(":/settings.png"), "", this );
96         settingsButton->setObjectName("settingsButton");
97         settingsButton->setIconSize( QSize( 72, 72 ) );
98         settingsButton->setCheckable( true );
99         horizontalLayout->addWidget( settingsButton );
100         CONNECT( settingsButton, SIGNAL(clicked()), this, SLOT(onSettingsClicked()) );
101
102         contactsButton = new QPushButton( QIcon(":/contacts.png"), "", this );
103         contactsButton->setObjectName("contactsButton");
104         contactsButton->setIconSize( QSize( 72, 72 ) );
105         contactsButton->setCheckable( true );
106
107         horizontalLayout->addWidget( contactsButton );
108         CONNECT( contactsButton, SIGNAL(clicked()), this, SLOT(onContactsClicked()) );
109         highlightButton(contactsButton);
110
111         setupStyles();
112 }
113
114 TocMainToolbar::~TocMainToolbar() {
115 }
116
117 void TocMainToolbar::highlightButton(const QPushButton* button) {
118         
119         contactsButton->setChecked(button == contactsButton);
120         settingsButton->setChecked(button == settingsButton);
121         statusAreaButton->setChecked(button == statusAreaButton);
122         statusAreaLabel->setEnabled(button == statusAreaButton);
123 }
124
125 void TocMainToolbar::restoreCurrentSession() {
126         
127         if( QAction* action = _pActiveSessions->disabledAction() ) {
128                 
129                 highlightButton(statusAreaButton);
130                 
131                 emit activeSessionTriggered( action->data().toString(), action->text() );
132                 
133                 statusAreaButton->setIcon( QIcon(":/close.png"));
134                 
135                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
136                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
137                 CONNECT( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
138         }
139 }
140
141 void TocMainToolbar::closeCurrentSession() {
142         qDebug() << __PRETTY_FUNCTION__;
143         
144         QAction* pAction = _pActiveSessions->disabledAction();
145         
146         if( pAction ) {
147         
148                 QAction *pNewCurrentAction = _pActiveSessions->closeCurrentSession();
149         
150                 if( pNewCurrentAction ) {
151                 
152                         statusAreaButton->setChecked(true);
153                         statusAreaLabel->setText( pNewCurrentAction->text() );
154                 
155                         emit activeSessionTriggered( pNewCurrentAction->data().toString(), pNewCurrentAction->text() );
156         
157                 } else {
158                 
159                         activeSessionsButton->setEnabled(false);
160                         statusAreaLabel->setText("");
161                         statusAreaButton->setIcon( QIcon() );
162                         statusAreaButton->setEnabled( false );
163                         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
164                         highlightButton(contactsButton);
165                         emit contactsClicked();
166                 }
167                 
168                 emit finishedSession( pAction->data().toString() );
169         }
170                 
171 }
172
173 void TocMainToolbar::closeAllSessions() {
174         
175         activeSessionsButton->setEnabled(false);
176                 
177         _pActiveSessions->clear();
178         
179         statusAreaLabel->setText("");
180         
181         statusAreaButton->setIcon( QIcon() );
182         statusAreaButton->setEnabled( false );
183         
184         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
185         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
186         
187         emit finishedAllSessions();
188         
189         highlightButton(contactsButton);
190         
191         emit contactsClicked();
192 }
193
194 void TocMainToolbar::clearAllSessions() {
195
196         activeSessionsButton->setEnabled(false);
197         _pActiveSessions->clear();
198
199         statusAreaLabel->setText("");
200         statusAreaButton->setIcon( QIcon() );
201         statusAreaButton->setEnabled( false );
202         
203         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
204         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );   
205 }
206
207
208 void TocMainToolbar::onTriggeredPresence(QAction* action) {
209         
210         emit presenceUpdate( action->data().value<Presence>(), "opisik" );
211 }
212
213 void TocMainToolbar::onPresenceUpdate(Presence presence, const QString& description) {
214         
215         Q_UNUSED(description);
216         
217         if( presence == onlineAction->data().value<Presence>() )
218                 statusButton->setIcon( onlineAction->icon() );
219         
220         else if( presence == awayAction->data().value<Presence>() )
221                 statusButton->setIcon( awayAction->icon() );
222         
223         else if( presence == busyAction->data().value<Presence>() )
224                 statusButton->setIcon( busyAction->icon() );
225         
226         else if( presence == hiddenAction->data().value<Presence>() )
227                 statusButton->setIcon( hiddenAction->icon() );
228         
229         else if( presence == offlineAction->data().value<Presence>() )
230                 statusButton->setIcon( offlineAction->icon() );
231 }
232
233 void TocMainToolbar::onContactPresenceUpdate(const QString& uid, Presence presence) {
234         
235         _pActiveSessions->onContactPresenceUpdate(uid, presence);
236
237 }
238
239 void TocMainToolbar::onNewMessage(const QString& uid, const QString& name, Presence presence) {
240         
241         qDebug()<<__PRETTY_FUNCTION__;
242         
243         if( QAction* pAction = _pActiveSessions->action( uid ) ) {
244                 
245                 if( pAction != _pActiveSessions->disabledAction() ) {
246
247                         activeSessionsButton->setChecked( true );
248                         //TODO: activeSessionsButton->startBlinking()
249                         
250                 } else {
251                         
252                         if( statusAreaButton->icon().cacheKey() == QIcon( ":/restore.png" ).cacheKey() )//
253                                 statusAreaButton->setChecked( true );
254                 }
255                 
256         } else {
257                 
258                 activeSessionsButton->setEnabled(true);
259                 //TODO: activeSessionsButton->startBlinking()
260         }
261         
262         _pActiveSessions->onNewMessage( uid, name, presence );
263 }
264
265 void TocMainToolbar::onNewSession(const QString& uid, const QString& name, Presence presence) {
266
267         qDebug()<<__PRETTY_FUNCTION__;
268         
269         highlightButton(statusAreaButton);
270
271         QAction* pDisabledAction = _pActiveSessions->disabledAction(); 
272         
273         if( QAction* pAction = _pActiveSessions->action( uid ) ) {
274                 if( pAction != pDisabledAction ) {
275
276                         statusAreaLabel->setText( pAction->text() );
277                         statusAreaButton->setIcon( QIcon(":/close.png"));
278                         statusAreaButton->setEnabled( true );
279                         
280                         disconnect( statusAreaButton, SIGNAL(clicked()), 
281                                                                         this, SLOT(restoreCurrentSession()) );
282                         disconnect( statusAreaButton, SIGNAL(clicked()),
283                                                                         this, SLOT(closeCurrentSession()) );
284                         CONNECT( statusAreaButton, SIGNAL(clicked()),
285                                                                         this, SLOT(closeCurrentSession()) );
286
287                 } else {
288
289                         statusAreaButton->setIcon( QIcon(":/close.png"));
290                         
291                         disconnect( statusAreaButton, SIGNAL(clicked()),
292                                                                         this, SLOT(restoreCurrentSession()) );
293                         disconnect( statusAreaButton, SIGNAL(clicked()),
294                                                                         this, SLOT(closeCurrentSession()) );
295                         CONNECT( statusAreaButton, SIGNAL(clicked()),
296                                                                         this, SLOT(closeCurrentSession()) );
297                 }
298                 
299         } else {
300
301                 statusAreaLabel->setText( name );
302                 
303                 statusAreaButton->setIcon( QIcon(":/close.png"));
304                 statusAreaButton->setEnabled( true );
305                 activeSessionsButton->setEnabled(true);
306                 
307                 disconnect( statusAreaButton, SIGNAL(clicked()),
308                                                                 this, SLOT(restoreCurrentSession()) );
309                 disconnect( statusAreaButton, SIGNAL(clicked()),
310                                                                 this, SLOT(closeCurrentSession()) );
311                 CONNECT( statusAreaButton, SIGNAL(clicked()),
312                                                                 this, SLOT(closeCurrentSession()) );
313         }
314         
315         _pActiveSessions->onNewSession( uid, name, presence );
316         
317 }
318
319 void TocMainToolbar::onCurrentView(ViewType viewType, const QString& text) {
320         
321         if( QAction* pAction = _pActiveSessions->disabledAction() ) { // If there is an active window
322                 
323                 if( viewType == Contacts ) {
324                         
325                         statusAreaButton->setIcon( QIcon(":/restore.png") );
326                         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
327                         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
328                         CONNECT( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
329                         highlightButton(contactsButton);
330                         
331                 } else {
332                         pAction->setEnabled( true );
333                         statusAreaLabel->setText( text );
334                         statusAreaButton->setIcon( QIcon() );
335                         statusAreaButton->setEnabled( false );
336                         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
337                         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
338                         // Deselect highlight from all buttons but leave settingsButton as is (highlighted or not)
339                         contactsButton->setChecked(false);
340                         contactsButton->setChecked(false);
341                         statusAreaButton->setChecked(false);
342                         statusAreaLabel->setEnabled(false);
343                 }
344         } else if( viewType == Contacts ) {
345                 highlightButton(contactsButton);
346                 statusAreaLabel->setText( text );       
347         }
348         else { // If there is no conversation at that time and the viewType != contacts
349                 statusAreaLabel->setText( text );
350                 statusAreaButton->setIcon( QIcon() );
351                 statusAreaButton->setEnabled( false );
352                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
353                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
354                 // Deselect highlight from all buttons but leave settingsButton as is (highlighted or not)
355                 contactsButton->setChecked(false);
356                 contactsButton->setChecked(false);
357                 statusAreaButton->setChecked(false);
358                 statusAreaLabel->setEnabled(false);
359         }
360 }
361
362 void TocMainToolbar::onDisplayedNameChange(const QString& uid, const QString& name) {
363         
364         if( QAction* pAction = _pActiveSessions->action( uid ) )
365                 pAction->setText( name );
366 }
367
368 void TocMainToolbar::onContactsClicked() {
369         
370         highlightButton(contactsButton);
371
372         if( _pActiveSessions->disabledAction() ) {
373                 
374                 statusAreaButton->setIcon( QIcon(":/restore.png") );
375                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
376                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
377                 CONNECT( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
378                 
379         } else {
380                 
381                 statusAreaLabel->setText("");
382                 statusAreaButton->setIcon( QIcon() );
383                 statusAreaButton->setEnabled( false );
384         }
385
386         emit contactsClicked();
387 }
388
389 void TocMainToolbar::onSettingsClicked() {
390         
391         highlightButton(settingsButton);
392
393         if( QAction* pAction = _pActiveSessions->disabledAction() ) {
394                 
395                 pAction->setEnabled( true );
396                 
397                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
398                 disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );           
399         }
400
401         statusAreaLabel->setText( tr("Settings") );
402         statusAreaButton->setIcon( QIcon() );
403         statusAreaButton->setEnabled( false );
404
405         emit settingsClicked();
406 }
407
408 void TocMainToolbar::onActiveSessionTriggered(QAction* pAction)
409 {
410         if(pAction->text() == "")
411                 return;
412
413         if( QAction* pDisabledAction = _pActiveSessions->disabledAction() )
414                 pDisabledAction->setEnabled( true );
415         
416         pAction->setChecked( false );
417         pAction->setEnabled( false );
418         
419         statusAreaLabel->setText( pAction->text() );
420         statusAreaButton->setIcon( QIcon(":/close.png"));
421         statusAreaButton->setEnabled( true );
422         
423         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(restoreCurrentSession()) );
424         disconnect( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
425         CONNECT( statusAreaButton, SIGNAL(clicked()), this, SLOT(closeCurrentSession()) );
426         
427         highlightButton(statusAreaButton);
428         
429         emit activeSessionTriggered( pAction->data().toString(), pAction->text() );     
430 }
431
432
433 void TocMainToolbar::setupStyles() {
434
435         statusButton->setStyleSheet(
436                         "QPushButton {\
437     border: none;\
438         min-height: 80px;\
439         min-width: 100px;\
440         max-height: 80px;\
441         max-width: 100px;\
442  }"
443         );
444
445         statusAreaLabel->setStyleSheet(" QLabel {\
446         font: bold 20px; \
447         border: none;\
448         border-radius: 0px;\
449         min-height: 80px;\
450         min-width: 100px;\
451         max-height: 80px;\
452  }");
453         
454         statusAreaButton->setStyleSheet(" QPushButton {\
455     border: none;\
456         border-radius: 0px;\
457         min-height: 80px;\
458         min-width: 80px;\
459         max-height: 80px;\
460         max-width: 80px;\
461  }");
462
463         activeSessionsButton->setStyleSheet(" QPushButton {\
464     border: none;\
465         min-height: 80px;\
466         min-width: 100px;\
467         max-height: 80px;\
468         max-width: 100px;"
469 "}"
470         " QPushButton:checked {\
471                         background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,\
472                                                 stop: 0 #999900, stop: 0.55 #aaaa00,\
473                                                             stop: 0.56 #bbbb00, stop: 1 #ffff00);}"
474         );
475
476         settingsButton->setStyleSheet(" QPushButton {\
477     border: none;\
478         min-height: 80px;\
479         min-width: 100px;\
480         max-height: 80px;\
481         max-width: 100px;\
482  }"
483         );
484
485         contactsButton->setStyleSheet(" QPushButton {\
486     border: none;\
487         min-height: 80px;\
488         min-width: 100px;\
489         max-height: 80px;\
490         max-width: 100px;\
491  }"
492         );
493
494         statusMenu->setStyleSheet("QMenu {\
495                         margin-left: 0px;\
496                         margin-top: 0px;\
497                         margin-right: 0px;\
498                         margin-bottom: 0px;\
499                 font: bold 16px; \
500  }\
501  QMenu::item {\
502                         margin-left: 0px;\
503                         margin-top: 0px;\
504                         margin-right: 0px;\
505                         margin-bottom: 0px;\
506                         padding: 0px 10px 0px 40px;\
507                         min-height: 68px;\
508                         min-width: 80px;\
509                         max-height: 68px;\
510                         border-radius: 5px;\
511  }"
512         );
513
514         setStyleSheet(
515                 "QMenu {\
516                         margin-left: 0px;\
517                         margin-top: 0px;\
518                         margin-right: 0px;\
519                         margin-bottom: 0px;"
520                 "       color: none; "
521                 "       font: bold 16px; "
522                 "       min-width: 180px; "
523                 "}\
524 \
525                 QMenu::item {\
526                         margin-left: 0px;\
527                         margin-top: 0px;\
528                         margin-right: 0px;\
529                         margin-bottom: 0px;\
530                         padding: 0px 10px 0px 20px;\
531                         min-height: 68px;\
532                         min-width: 180px;\
533                         max-height: 68px;\
534                         border-radius: 5px;\
535                 }\
536 \
537 QMenu::item:checked {\
538                         background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,\
539                                        stop: 0 #999900, stop: 0.55 #aaaa00,\
540                                                    stop: 0.56 #bbbb00, stop: 1 #ffff00);}\
541  QMenu::item:disabled {\
542                         background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,\
543                                        stop: 0 #999, stop: 0.55 #aaa,\
544                                        stop: 0.56 #bbb, stop: 1 #fff);}\
545  QMenu::separator {\
546              height: 10px;\
547              margin-left: 5px;\
548              margin-right: 5px;\
549          }"
550         );
551
552         _pActiveSessions->setStyleSheet(
553                 "QPushButton {"
554                         "font: bold 16px;"
555                         "border: none;"
556                         "border-radius: 5px;"
557                         "min-height: 60px;"
558                         "min-width: 100px;"
559                         "max-height: 60px;"
560                         "max-width: 100px;"
561                 "}"
562         );      
563         
564         
565 }
566
567
568 //--------------------------------------------------------
569 //ActiveStatusesMenu
570 //--------------------------------------------------------
571
572 ActiveSessions::ActiveSessions(QWidget * parent):
573         QWidget(parent),
574         _visibleActionsAllowed(3),
575         _firstVisibleAction(0),
576         _lastVisibleAction(0)
577 {
578         _pActiveSessionsMenu = new QMenu( this );
579         _pActiveSessionsMenu->setObjectName("activeSessionsMenu");
580
581         _pSeparatorAction = new QAction(this);
582         _pSeparatorAction->setSeparator(true);
583
584         _pCloseAllSessionsAction = new QAction( QIcon(":/close.png"), tr("Close all"), this );
585         
586         CONNECT( _pCloseAllSessionsAction, SIGNAL(triggered()), parent, SLOT(closeAllSessions()) );
587         CONNECT( _pActiveSessionsMenu, SIGNAL(triggered(QAction*)), parent, SLOT(onActiveSessionTriggered(QAction*)) );
588         
589         _pScrollAction = new QWidgetAction(this);
590         _pScrollWidget = new ScrollWidget(this);
591         _pScrollAction->setDefaultWidget( _pScrollWidget );
592         
593         CONNECT( _pScrollWidget->scrollUpButton(), SIGNAL(clicked()), this, SLOT(scrollUp()) );
594         CONNECT( _pScrollWidget->scrollDownButton(), SIGNAL(clicked()), this, SLOT(scrollDown()) );
595 }
596
597
598 QAction* ActiveSessions::closeCurrentSession() {
599
600         qDebug()<<__PRETTY_FUNCTION__;
601         
602         QAction* pAction = disabledAction();
603         
604         if( pAction ) 
605         {
606                 removeAction( pAction );
607                                 
608                 QAction* pNewCurrentAction = 0;
609
610                 
611                 if( _actionsList.count() > 0 ) 
612                 {
613                         pNewCurrentAction = _actionsList.last();
614                         pNewCurrentAction->setEnabled( false );
615                 }
616                 
617                 if( _actionsList.size() == 1 ) 
618                 {
619                         _pActiveSessionsMenu->removeAction( _pCloseAllSessionsAction );
620                         _pActiveSessionsMenu->removeAction( _pSeparatorAction );
621                 }
622
623                 return pNewCurrentAction;
624         }
625         else 
626                 return 0;
627 }
628
629
630 void ActiveSessions::clear() {
631                 
632         _pActiveSessionsMenu->clear();
633         _actionsList.clear();
634
635
636 QList<QAction*> ActiveSessions::actions() const {
637         
638         return _pActiveSessionsMenu->actions();
639 }
640
641 QAction* ActiveSessions::disabledAction() const {
642                 
643         foreach( QAction* pAction, _actionsList ) {
644         
645                 if( !pAction->isEnabled() )
646                         return pAction;
647         }
648         return 0;
649 }
650
651 QAction* ActiveSessions::action( const QString& uid ) const {
652         
653         if(uid.isEmpty()) return 0;
654         
655         QList<QAction*> actionsList = _pActiveSessionsMenu->actions();
656         
657         foreach( QAction* pAction, actionsList ) {
658                 
659                 if( pAction->data().toString() == uid )
660                         return pAction;
661         }
662         return 0;
663 }
664
665 void ActiveSessions::onContactPresenceUpdate(const QString& uid, Presence presence) {
666         
667         if( QAction* pAction = action( uid ) ) {
668                 
669                 switch( presence ) {
670                 
671                         case Available:
672                                 pAction->setIcon( QIcon(":/online.png") );
673                                 break;
674                         case XA:
675                         case Away:
676                                 pAction->setIcon( QIcon(":/away.png") );
677                                 break;
678                         case Busy:
679                                 pAction->setIcon( QIcon(":/busy.png") );
680                                 break;
681                         case Hidden:
682                                 pAction->setIcon( QIcon(":/hidden.png") );
683                                 break;
684                         case Offline:
685                                 pAction->setIcon( QIcon(":/offline.png") );
686                                 break;
687                         default:
688                                 pAction->setIcon( QIcon() );
689                 }
690         }
691 }
692
693 void ActiveSessions::onNewMessage(const QString& uid, const QString& name, Presence presence) {
694
695         //If such action already exists - set it checked
696         if( QAction* pAction = action( uid ) ) {
697                 
698                 if( pAction != disabledAction() )
699                         pAction->setChecked( true );
700                                                 
701         } else { //create a new one
702                 
703                 QIcon icon;
704
705                 switch( presence ) {
706                 
707                         case Available:
708                                 icon = QIcon(":/online.png");
709                                 break;
710                         case XA:
711                         case Away:
712                                 icon = QIcon(":/away.png");
713                                 break;
714                         case Busy:
715                                 icon = QIcon(":/busy.png");
716                                 break;
717                         case Hidden:
718                                 icon = QIcon(":/hidden.png");
719                                 break;
720                         case Offline:
721                                 icon = QIcon(":/offline.png");
722                                 break;
723                 }
724
725                 pAction = new QAction( icon, name, this );
726                 pAction->setData( QVariant::fromValue( uid ) );
727                 pAction->setCheckable( true );
728                 pAction->setChecked( true );
729                 
730                 addAction( pAction );
731
732                 
733                 if( _pActiveSessionsMenu->actions().count() == 2) {
734
735                         _pActiveSessionsMenu->addAction( _pSeparatorAction );
736                         _pActiveSessionsMenu->addAction( _pCloseAllSessionsAction );
737                 }
738         }
739
740 }
741         
742 void ActiveSessions::onNewSession(const QString& uid, const QString& name, Presence presence) {
743
744         QAction* pDisabledAction = disabledAction(); 
745         
746         if( QAction* pAction = action( uid ) ) {
747
748                 if( pAction != pDisabledAction ) {
749
750                         if(pDisabledAction)
751                                 pDisabledAction->setEnabled( true );
752                         
753                         pAction->setChecked( false );
754                         pAction->setEnabled( false );
755                 }
756
757         } else {
758
759                 QIcon icon;
760                 switch( presence ) {
761                         
762                         case Available:
763                                 icon = QIcon(":/online.png");
764                                 break;
765                         case XA:
766                         case Away:
767                                 icon = QIcon(":/away.png");
768                                 break;
769                         case Busy:
770                                 icon = QIcon(":/busy.png");
771                                 break;
772                         case Hidden:
773                                 icon = QIcon(":/hidden.png");
774                                 break;
775                         case Offline:
776                                 icon = QIcon(":/offline.png");
777                                 break;
778                         default: 
779                                 icon = QIcon(":/offline.png");
780                 }
781                 
782                 if( pDisabledAction )
783                         pDisabledAction->setEnabled( true );
784                 
785                 pAction = new QAction( icon, name, this );
786                 pAction->setData( QVariant::fromValue( uid ) );
787                 pAction->setCheckable( true );
788                 pAction->setEnabled( false );
789                 
790                 addAction( pAction );
791
792                 _pActiveSessionsMenu->setEnabled(true);
793                 
794
795                 if( _pActiveSessionsMenu->actions().count() == 2) {
796                         
797                         _pActiveSessionsMenu->addAction( _pSeparatorAction );
798                         _pActiveSessionsMenu->addAction( _pCloseAllSessionsAction );
799                 }
800
801         }       
802 }
803
804 void ActiveSessions::addAction(QAction *pAction) {
805                 
806         QList<QAction*> currentlyVisibleActions = _pActiveSessionsMenu->actions();
807         
808         if( currentlyVisibleActions.count( _pScrollAction ) )
809                 _pActiveSessionsMenu->insertAction( _pScrollAction, pAction );
810
811         else if( currentlyVisibleActions.count( _pSeparatorAction ) )
812                 _pActiveSessionsMenu->insertAction( _pSeparatorAction, pAction );
813         else
814                 _pActiveSessionsMenu->addAction( pAction );
815         
816         _actionsList.append(pAction);
817         
818         //set iterators
819         _lastVisibleAction = _actionsList.end() - 1;
820
821         if( _actionsList.size() > _visibleActionsAllowed )
822                 _firstVisibleAction = _actionsList.end() - _visibleActionsAllowed;
823         else
824                 _firstVisibleAction = _actionsList.begin();
825
826         
827         if( _actionsList.size() > _visibleActionsAllowed )
828         {
829                 //add scroll action
830                 _pActiveSessionsMenu->insertAction( _pSeparatorAction, _pScrollAction );        
831                 
832                 //remove one action from top to keep constant menu size
833                 if( _actionsList.size() > _visibleActionsAllowed )
834                 {
835                         QAction *pRemoveMe = *( _firstVisibleAction - 1 );
836                         if(pRemoveMe)
837                                 _pActiveSessionsMenu->removeAction( pRemoveMe );
838                 }
839                 
840                 checkScrollButtonsState();
841         }
842
843 }
844
845 void ActiveSessions::removeAction(QAction *pAction) {
846                 
847         _actionsList.removeOne(pAction);
848                 
849         _lastVisibleAction = _actionsList.end() - 1;
850         
851         //Reset iterators
852         if( _actionsList.size() > _visibleActionsAllowed )
853                 _firstVisibleAction = _actionsList.end() - _visibleActionsAllowed;
854         else
855                 _firstVisibleAction = _actionsList.begin();
856
857         //Remove all stuff above _pScrollAction or _pSeparatorAction
858         QList<QAction*> visibleItems = _pActiveSessionsMenu->actions();
859         QList<QAction*>::iterator it = visibleItems.begin();
860
861         while( it != visibleItems.end() )
862         {
863                 if( *it == _pScrollAction || *it == _pSeparatorAction) break;
864                         
865                 _pActiveSessionsMenu->removeAction((*it));
866                 
867                 ++it;
868         }
869         
870         //...and add it back again
871         it = _firstVisibleAction;
872         
873         while( it != (_lastVisibleAction + 1) )
874         {
875                 if( visibleItems.count( _pScrollAction ) )
876                         _pActiveSessionsMenu->insertAction( _pScrollAction, *it );
877
878                 else if( visibleItems.count( _pSeparatorAction ) )
879                         _pActiveSessionsMenu->insertAction( _pSeparatorAction, *it );
880                 else
881                         _pActiveSessionsMenu->addAction( *it );         
882                         
883                 ++it;
884         }
885         
886         if( _actionsList.count() <= _visibleActionsAllowed  && _pScrollAction->isVisible())
887                 _pActiveSessionsMenu->removeAction( _pScrollAction );
888
889         
890         if( _actionsList.isEmpty() ) return;
891
892         //Reset visible actions
893         QList<QAction*> visibleActions = _pActiveSessionsMenu->actions();
894         QAction *pFirstVisible = visibleActions[0];
895
896
897         _firstVisibleAction = _actionsList.begin() + _actionsList.indexOf(pFirstVisible);
898         
899         if(_actionsList.count() >= _visibleActionsAllowed )
900                 _lastVisibleAction = _firstVisibleAction + _visibleActionsAllowed - 1;
901         else
902                 _lastVisibleAction = _firstVisibleAction + _actionsList.size() - 1;
903         
904         checkScrollButtonsState();
905 }
906
907
908 void ActiveSessions::scrollDown() {
909         
910         //Is there something below?
911         if( _lastVisibleAction == (_actionsList.end() - 1) ) return;
912
913         _pActiveSessionsMenu->removeAction( *_firstVisibleAction );
914         
915         //Add an item from the bottom
916         if( _pScrollAction->isVisible() )
917                 _pActiveSessionsMenu->insertAction( _pScrollAction, *(_lastVisibleAction + 1) );
918         else
919                 _pActiveSessionsMenu->addAction( *(_lastVisibleAction + 1) );
920         
921         //adjust iterators
922         ++_firstVisibleAction;
923         ++_lastVisibleAction;
924         
925         checkScrollButtonsState();
926 }
927
928 void ActiveSessions::scrollUp() {
929         
930         //Is there something above?
931         if( _firstVisibleAction == _actionsList.begin() ) return;
932
933         //Add an item from the top
934         _pActiveSessionsMenu->insertAction(*_firstVisibleAction, *(_firstVisibleAction - 1) );
935         
936         //Hide an item from the bottom
937         _pActiveSessionsMenu->removeAction( *_lastVisibleAction );
938         
939         //adjust iterators
940         --_firstVisibleAction;
941         --_lastVisibleAction;
942         
943         checkScrollButtonsState();
944 }
945
946 void ActiveSessions::checkScrollButtonsState() {
947         
948         if( _firstVisibleAction != _actionsList.begin() )
949                 _pScrollWidget->scrollUpButton()->setEnabled( true );
950         else
951                 _pScrollWidget->scrollUpButton()->setEnabled( false );
952         
953         
954         if( _lastVisibleAction != _actionsList.end() - 1)
955                 _pScrollWidget->scrollDownButton()->setEnabled( true );
956         else
957                 _pScrollWidget->scrollDownButton()->setEnabled( false );
958 }
959
960 //--------------------------------------------------------
961 //      ScrollWidget
962 //--------------------------------------------------------
963 ScrollWidget::ScrollWidget(QWidget* parent):
964         QWidget(parent)
965 {
966         setObjectName("scrollWidget");
967         setContentsMargins( -10, -10, -10, -10 );
968
969         _pLayout = new QHBoxLayout(this);
970         _pLayout->setSpacing(0);
971         _pScrollUpButton = new QPushButton(tr("up"), this);
972         _pScrollUpButton->setObjectName("scrollUpButton");
973         _pScrollDownButton = new QPushButton(tr("down"), this);
974         _pScrollDownButton->setObjectName("scrollDownButton");
975                 
976         _pLayout->addWidget(_pScrollUpButton);
977         _pLayout->addWidget(_pScrollDownButton);
978         
979         show();
980 }