1 /** \file TocMainWindow.cpp
2 * \brief Implementation of TocMainWindow class
4 * Tieto Open Communicator - Client for the Telepathy communications framework.
5 * Copyright (c) 2010, Tieto Corporation
8 * Redistribution and use in source and binary forms, with or without modification,
9 * are permitted provided that the following conditions are met:
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.
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.
32 #include "TocMainWindow"
34 #include "TocMainToolbar"
35 #include "TocContactListWidget"
36 #include "TocChatWidget"
37 #include "TocUserInfoWidget"
38 #include "TocSettingsWidget"
39 #include "TocGeneralSettingsWidget"
40 #include "TocAccountSettingsWidget"
41 #include "TocAccountIntermediateWidget"
42 #include "TocThemesSettingsWidget"
43 #include "TocSettings"
47 #include <QStackedLayout>
50 #include <QMessageBox>
53 #include <QCloseEvent>
56 Q_DECLARE_METATYPE(TocContact*);
58 TocMainWindow::TocMainWindow(TocBaseEngine* engine, QWidget * parent, Qt::WindowFlags flags) :
59 TocBaseMainWindow(engine, parent, flags), _register(false) {
61 setWindowTitle("Tieto Open Communicator");
62 setContentsMargins( -20, 0, -20, -5 );
63 _pCentralWidget = new QWidget( this );
64 _pCentralWidget->setObjectName("_pCentralWidget");
66 QAction* pAboutAct = new QAction(tr("About"), this);
67 pAboutAct->setStatusTip(tr("Show About info"));
68 CONNECT(pAboutAct, SIGNAL(triggered()), this, SLOT(showAbout()));
70 QAction* pExitAct = new QAction(tr("Exit"), this);
71 pExitAct->setStatusTip(tr("Close application"));
72 CONNECT(pExitAct, SIGNAL(triggered()), this, SLOT(close()));
74 menuBar()->addAction(pAboutAct);
75 menuBar()->addAction(pExitAct);
77 setCentralWidget( _pCentralWidget );
78 QVBoxLayout* verticalLayout = new QVBoxLayout( _pCentralWidget );
79 verticalLayout->setSpacing( 0 );
81 _pMainToolbar = new TocMainToolbar( _pCentralWidget );
82 CONNECT( _pMainToolbar, SIGNAL(contactsClicked()), this, SLOT(showContacts()) );
83 CONNECT( _pMainToolbar, SIGNAL(settingsClicked()), this, SLOT(showSettings()) );
84 CONNECT( _pMainToolbar, SIGNAL(finishedSession(const QString&)), this, SLOT(closeChat(const QString&)) );
85 CONNECT( _pMainToolbar, SIGNAL(finishedAllSessions()), this, SLOT(closeAllOpenChats()) );
86 CONNECT( _pMainToolbar, SIGNAL(activeSessionTriggered(QString,QString)), this, SLOT(showChat(QString,QString)) );
87 CONNECT( _pMainToolbar, SIGNAL(presenceUpdate(Presence,QString)), this, SIGNAL(presenceChanged(Presence,QString)) );
89 verticalLayout->addWidget( _pMainToolbar );
90 _pMainLayout = new QStackedLayout( verticalLayout );
91 _pMainLayout->setSpacing( 0 );
93 _pChatList = new QList<TocChatWidget*>();
94 _pOpenChatList = new QList<TocChatWidget*>();
96 _pSettingsWidget = new TocSettingsWidget( _pCentralWidget );
97 _pMainLayout->addWidget( _pSettingsWidget );
98 CONNECT(_pSettingsWidget, SIGNAL(triggered(int)), this, SLOT(showView(int)));
100 _pContactList = new TocContactListWidget( _pCentralWidget );
101 _pMainLayout->addWidget( _pContactList );
103 CONNECT( _pContactList, SIGNAL(triggered(QString,QString,Presence)), _pMainToolbar, SLOT(onNewSession(QString,QString,Presence)) );
104 CONNECT( _pContactList, SIGNAL(contactInfoRequest(QListWidgetItem*)), this, SLOT(showUserInfo(QListWidgetItem*)) );
105 CONNECT( _pContactList, SIGNAL(triggered(QString,QString,Presence)), this, SLOT(showChat(QString,QString,Presence)) );
106 CONNECT( _pContactList, SIGNAL(addContact(TocContact*)),
107 this, SIGNAL(addContact(TocContact*)));
108 CONNECT( _pContactList, SIGNAL(removedContact(QString)),
109 this, SIGNAL(removeContact(QString)));
110 CONNECT( _pContactList, SIGNAL(editContact(TocContact*,QString)),
111 this, SIGNAL(editContact(TocContact*,QString)));
112 CONNECT( _pContactList, SIGNAL(displayedNameChanged(QString,QString)),
113 this, SLOT(onDisplayedNameChange(QString,QString)) );
115 _pUserInfoWidget = 0;
118 _pIntermediateWidget = 0;
122 showView( static_cast<int>( FTU ) );
124 _pMainLayout->setCurrentWidget( _pContactList );
127 // "TocMainToolbar > QPushButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
128 // "stop: 0 #aa0, stop: 0.55 #bb0, stop: 0.56 #bb0, stop: 1 #ff0); }"
129 // "QPushButton#okButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
130 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
131 // "QPushButton#cancelButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
132 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
133 // "QPushButton#generalButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
134 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
135 // "QPushButton#themesButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
136 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
137 // "QPushButton#accountButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
138 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
139 // "QPushButton#networkButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
140 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
141 // "QPushButton#statusButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
142 // "stop: 0 #aaa, stop: 0.55 #bbb, stop: 0.56 #bbb, stop: 1 #fff); }"
143 // "QPushButton#settingsButton { background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
144 // "stop: 0 #0aa, stop: 0.55 #0bb, stop: 0.56 #0bb, stop: 1 #0ff); }"
145 // "*[mandatoryField=\"true\"] {background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,"
146 // "stop: 0 #aa0, stop: 0.55 #bb0, stop: 0.56 #bb0, stop: 1 #ff0); }"
148 "QMessageBox QPushButton {"
158 _defaultStyle = styleSheet();
162 TocMainWindow::~TocMainWindow() {
165 delete _pOpenChatList;
168 TocChatWidget* TocMainWindow::chatForUid(const QString& uid) {
169 foreach( TocChatWidget* chat, *_pChatList )
170 if ( chat->uid() == uid )
175 TocChatWidget* TocMainWindow::openChatForUid(const QString& uid) {
176 foreach( TocChatWidget* chat, *_pOpenChatList )
177 if ( chat->uid() == uid )
182 void TocMainWindow::onPresenceUpdate(Presence presence, QString desc) {
183 _pMainToolbar->onPresenceUpdate( presence, desc );
184 if( presence == Offline )
185 _pContactList->clearStatuses();
188 void TocMainWindow::onContactPresenceUpdate(QString uid, Presence presence, QString desc) {
189 if ( TocChatWidget* chat = openChatForUid( uid ) ) {
190 chat->onContactPresenceUpdate( presence, desc );
191 _pMainToolbar->onContactPresenceUpdate( uid, presence );
194 _pContactList->onContactPresenceUpdate( uid, presence, desc );
197 void TocMainWindow::onIncomingMessage(QString uid, Message message) {
200 if ( chat = chatForUid( uid ) ) {
201 _pOpenChatList->append( chat );
202 chat->appendMessage( message );
203 QListWidgetItem* pItem = _pContactList->findItem( uid );
205 QString name = pItem->data( DisplayRole ).toString();
206 TocContact *pContact = pItem->data(ContactRole).value<TocContact*>();
207 _pMainToolbar->onNewMessage( uid, name, pContact->presence );
209 _pMainToolbar->onNewMessage( uid, uid, static_cast<Presence>(0) );
212 QListWidgetItem* pItem = _pContactList->findItem( uid );
214 chat = new TocChatWidget( uid, uid, static_cast<Presence>(0), _pCentralWidget, message );
215 _pChatList->append( chat );
216 _pOpenChatList->append( chat );
217 _pMainLayout->addWidget( chat );
218 _pMainToolbar->onNewMessage( uid, uid, static_cast<Presence>(0) );
220 QString name = pItem->data( DisplayRole ).toString();
221 TocContact *pContact = pItem->data(ContactRole).value<TocContact*>();
222 chat = new TocChatWidget( uid, name, pContact->presence, _pCentralWidget, message );
223 _pChatList->append( chat );
224 _pOpenChatList->append( chat );
225 _pMainLayout->addWidget( chat );
226 _pMainToolbar->onNewMessage( uid, name, pContact->presence );
228 CONNECT(chat, SIGNAL(newMessageReady(QString,Message)), this, SIGNAL(newMessageReady(QString,Message)));
232 void TocMainWindow::closeChat(const QString& uid) {
234 if ( TocChatWidget* chat = openChatForUid( uid ) ) {
235 _pOpenChatList->removeOne( chat );
236 emit sessionClosed( uid );
240 void TocMainWindow::closeAllOpenChats() {
242 foreach( TocChatWidget* chat, *_pOpenChatList ) {
243 emit sessionClosed( chat->uid() );
245 _pOpenChatList->clear();
248 void TocMainWindow::clearAllChats() {
250 // First close open chats
253 foreach( TocChatWidget* chat, *_pChatList ) {
254 _pMainLayout->removeWidget( chat );
261 void TocMainWindow::showChat(const QString& uid, const QString& name, Presence presence) {
263 if ( TocChatWidget* chat = chatForUid( uid ) ) {
264 if(!openChatForUid(uid)) {
265 _pOpenChatList->append( chat );
266 chat->updateContactPresence( presence );
269 _pMainLayout->setCurrentWidget( chat );
271 chat = new TocChatWidget( uid, name, presence, _pCentralWidget );
272 _pChatList->append( chat );
273 _pOpenChatList->append( chat );
274 _pMainLayout->addWidget( chat );
275 _pMainLayout->setCurrentWidget( chat );
276 CONNECT(chat, SIGNAL(newMessageReady(QString,Message)), this, SIGNAL(newMessageReady(QString,Message)));
280 void TocMainWindow::showContacts() {
281 _pMainLayout->setCurrentWidget( _pContactList );
284 void TocMainWindow::returnToContacts() {
285 _pMainLayout->setCurrentWidget( _pContactList );
286 _pMainToolbar->onCurrentView( Contacts );
289 void TocMainWindow::showSettings() {
290 _pMainLayout->setCurrentWidget( _pSettingsWidget );
293 void TocMainWindow::returnToSettings() {
294 _pMainLayout->setCurrentWidget( _pSettingsWidget );
295 _pMainToolbar->onCurrentView( Settings, tr("Settings") );
298 void TocMainWindow::reloadTheme() {
299 QString current = styleSheet();
302 TocSettings* pSettings = TocSettings::getInstance();
304 QFile file(pSettings->currentTheme());
306 file.open(QIODevice::ReadOnly | QIODevice::Text);
308 theme = file.readAll();
313 if (theme + _defaultStyle != current) {
315 setStyleSheet(_defaultStyle);
317 setStyleSheet(theme + _defaultStyle);
321 void TocMainWindow::returnToIntermediate() {
323 showView( static_cast<int>( FTU ) );
325 showView( static_cast<int>( AccountIntermediate ) );
328 void TocMainWindow::showAccount() {
329 showView( static_cast<int>( Account ) );
332 void TocMainWindow::showAccountCreate() {
333 showView( static_cast<int>( AccountCreate ) );
336 void TocMainWindow::showView(int type) {
337 ViewType viewType = static_cast<ViewType>( type );
343 _pMainToolbar->onCurrentView( Contacts );
359 if( !_pGeneralWidget ) {
360 _pGeneralWidget = new TocGeneralSettingsWidget( _pCentralWidget );
361 CONNECT(_pGeneralWidget, SIGNAL(backClicked()), this, SLOT(returnToSettings()));
362 CONNECT(_pGeneralWidget, SIGNAL(finished()), this, SLOT(returnToContacts()));
363 _pMainLayout->addWidget( _pGeneralWidget );
365 _pMainToolbar->onCurrentView( viewType, tr("General Settings") );
366 _pMainLayout->setCurrentWidget( _pGeneralWidget );
370 if( !_pIntermediateWidget ) {
371 _pIntermediateWidget = new TocAccountIntermediateWidget( _pCentralWidget );
372 CONNECT(_pIntermediateWidget, SIGNAL(backClicked()), this, SLOT(returnToSettings()));
373 CONNECT(_pIntermediateWidget, SIGNAL(editClicked()), this, SLOT(showAccount()));
374 CONNECT(_pIntermediateWidget, SIGNAL(createClicked()), this, SLOT(showAccountCreate()));
375 _pMainLayout->addWidget( _pIntermediateWidget );
377 _pIntermediateWidget->enableFTUMode( true );
378 _pMainToolbar->onCurrentView( viewType, tr("Account Settings") );
379 _pMainLayout->setCurrentWidget( _pIntermediateWidget );
382 case AccountIntermediate:
383 if( !_pIntermediateWidget ) {
384 _pIntermediateWidget = new TocAccountIntermediateWidget( _pCentralWidget );
385 CONNECT(_pIntermediateWidget, SIGNAL(backClicked()), this, SLOT(returnToSettings()));
386 CONNECT(_pIntermediateWidget, SIGNAL(editClicked()), this, SLOT(showAccount()));
387 CONNECT(_pIntermediateWidget, SIGNAL(createClicked()), this, SLOT(showAccountCreate()));
388 _pMainLayout->addWidget( _pIntermediateWidget );
390 _pIntermediateWidget->enableFTUMode( false );
391 _pMainToolbar->onCurrentView( viewType, tr("Account Settings") );
392 _pMainLayout->setCurrentWidget( _pIntermediateWidget );
396 if( !_pAccountWidget ) {
397 _pAccountWidget = new TocAccountSettingsWidget( _pCentralWidget );
398 CONNECT(_pAccountWidget, SIGNAL(newAccountSettingsCreated()), this, SLOT(onAccountSettingsCreated()));
399 CONNECT(_pAccountWidget, SIGNAL(accountSettingsChanged()), this, SLOT(onAccountSettingsChanged())); CONNECT(_pAccountWidget, SIGNAL(finished()), this, SLOT(returnToContacts()));
400 CONNECT(_pAccountWidget, SIGNAL(finished()), this, SLOT(returnToContacts()));
401 CONNECT(_pAccountWidget, SIGNAL(backClicked()), this, SLOT(returnToIntermediate()));
402 _pMainLayout->addWidget( _pAccountWidget );
404 _pAccountWidget->setCreateMode(true);
405 _pMainToolbar->onCurrentView( viewType, tr("Create Account") );
406 _pMainLayout->setCurrentWidget( _pAccountWidget );
410 if( !_pAccountWidget ) {
411 _pAccountWidget = new TocAccountSettingsWidget( _pCentralWidget );
412 CONNECT(_pAccountWidget, SIGNAL(newAccountSettingsCreated()), this, SLOT(onAccountSettingsCreated()));
413 CONNECT(_pAccountWidget, SIGNAL(accountSettingsChanged()), this, SLOT(onAccountSettingsChanged()));
414 CONNECT(_pAccountWidget, SIGNAL(finished()), this, SLOT(returnToContacts()));
415 CONNECT(_pAccountWidget, SIGNAL(backClicked()), this, SLOT(returnToIntermediate()));
416 _pMainLayout->addWidget( _pAccountWidget );
418 _pAccountWidget->setCreateMode(false);
419 _pMainToolbar->onCurrentView( viewType, tr("Account Settings") );
420 _pMainLayout->setCurrentWidget( _pAccountWidget );
424 if( !_pThemesWidget ) {
425 _pThemesWidget = new TocThemesSettingsWidget( _pCentralWidget );
426 _pMainLayout->addWidget( _pThemesWidget );
427 CONNECT(_pThemesWidget, SIGNAL(backClicked()), this, SLOT(returnToSettings()));
428 CONNECT(_pThemesWidget, SIGNAL(currentThemeChanged()), this, SLOT(reloadTheme()));
430 _pMainToolbar->onCurrentView( viewType, tr("Themes Settings") );
431 _pMainLayout->setCurrentWidget( _pThemesWidget );
440 void TocMainWindow::showUserInfo(QListWidgetItem* item) {
442 _pMainLayout->removeWidget( _pUserInfoWidget );
443 delete _pUserInfoWidget;
445 _pUserInfoWidget = new TocUserInfoWidget( item, _pContactList );
448 CONNECT(_pUserInfoWidget, SIGNAL(contactChanged(QListWidgetItem*)),
449 _pContactList, SLOT(commitAdd(QListWidgetItem*)));
451 _pMainToolbar->onCurrentView( UserInfo, tr("Create Contact") );
454 CONNECT(_pUserInfoWidget, SIGNAL(contactChanged(QListWidgetItem*)),
455 _pContactList, SLOT(commitEdit(QListWidgetItem*)));
457 QString name = item->data( DisplayRole ).toString();
458 _pMainToolbar->onCurrentView( UserInfo, tr("Edit %1").arg( name ) );
461 CONNECT(_pUserInfoWidget, SIGNAL(finished()), this, SLOT(returnToContacts()));
463 _pMainLayout->addWidget( _pUserInfoWidget );
464 _pMainLayout->setCurrentWidget( _pUserInfoWidget );
467 void TocMainWindow::onDisplayedNameChange(const QString& uid, const QString& name) {
469 if ( TocChatWidget* chat = chatForUid( uid ) ) {
470 chat->onDisplayedNameChange( name );
471 _pMainToolbar->onDisplayedNameChange( uid, name );
475 void TocMainWindow::onContactListReceived(const TocContactList& cList)
477 _pContactList->onNewContactList(cList);
480 void TocMainWindow::onAuthorizationRequest(QString /*uid*/) {
481 //TODO: finish implementation
484 void TocMainWindow::onSubscriptionAccepted(QString /*uid*/) {
485 //TODO: finish implementation
488 void TocMainWindow::onStatusChange(Status status, Reason reason) {
491 if(reason != Requested)
493 QMessageBox::critical(this, tr("TEC"), errorString(reason) + "\nCannot create account");
496 QMessageBox::critical(this, tr("TEC"), errorString(reason));
498 _pMainToolbar->onPresenceUpdate( Offline, "" );
503 QMessageBox::information(this, tr("TEC"), tr("Account created successfully!"));
516 QString TocMainWindow::errorString(Reason reason) {
519 return tr("Disconnected because of unknown reason.");
522 return tr("Disconnected because it was requested.");
525 return tr("Disconnected because of network error.");
527 case AuthenticationFailed:
528 return tr("Disconnected because the username or password was invalid.");
530 case EncryptionError:
531 return tr("Disconnected because of encryption error.");
534 return tr("Could not create account or connect because username is already in use.");
536 case CertificateNotProvided:
537 return tr("Disconnected because certificate was not provided.");
539 case CertificateUntrusted:
540 return tr("Disconnected because certificate is untrusted.");
542 case CertificateExpired:
543 return tr("Disconnected because certificate has expired.");
545 case CertificateNotActivated:
546 return tr("Disconnected because certificate has not been activated.");
548 case CertificateHostnameMismatch:
549 return tr("Disconnected because of certificate hostname mismatch.");
551 case CertificateFingerPrintMismatch:
552 return tr("Disconnected because of certificate finger print mismatch.");
554 case CertificateSigned:
555 return tr("Disconnected because certificate was self-signed.");
557 case CertificateOtherError:
558 return tr("Disconnected because of non specified certificate error.");
561 return tr("Disconnected because of unknown reason.");
565 bool TocMainWindow::isFtu() {
566 TocSettings *set = TocSettings::getInstance();
567 if(!set->accountUid().length() && !set->accountPasswd().length())
572 void TocMainWindow::showAbout() {
573 QMessageBox::about(this, tr("About Tieto Open Communicator"), tr(
574 "Tieto Open Communicator %1 - Instant Message Communicator for Telepathy framework\n\n"
575 "Copyright: (c) 2010, Tieto Corporation\n"
576 "License: see `/usr/share/%2/licence/copyright`."
577 ).arg(VERSION).arg(TARGET));
580 void TocMainWindow::onAccountSettingsChanged() {
582 emit presenceChanged(Offline, "");
584 // Clear chat widgets and active sessions
586 _pMainToolbar->clearAllSessions();
588 // Empty the contact list
589 TocSettings *pSettings = TocSettings::getInstance();
590 pSettings->contactList()->clear();
591 _pContactList->onNewContactList(*pSettings->contactList());
594 void TocMainWindow::onAccountSettingsCreated() {
595 onAccountSettingsChanged();
597 _pMainToolbar->onCurrentView(AccountCreate, tr("Create Account"));
599 // Request to create account
600 emit presenceChanged(Available, "");
601 QMessageBox::information(this, tr("TEC"),
602 tr("To be able to fully use Your new account:\nplease reconnect."));
605 void TocMainWindow::closeEvent( QCloseEvent* event ) {
610 int TocMainWindow::top_application() {