• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdenetwork API Reference
  • KDE Home
  • Contact Us
 

kopete/kopete

  • sources
  • kde-4.14
  • kdenetwork
  • kopete
  • kopete
  • chatwindow
kopetechatwindow.cpp
Go to the documentation of this file.
1 /*
2  kopetechatwindow.cpp - Chat Window
3 
4  Copyright (c) 2008 by Benson Tsai <btsai@vrwarp.com>
5  Copyright (c) 2007 by Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
6  Copyright (c) 2002-2006 by Olivier Goffart <ogoffart@kde.org>
7  Copyright (c) 2003-2004 by Richard Smith <kde@metafoo.co.uk>
8  Copyright (C) 2002 by James Grant
9  Copyright (c) 2002 by Stefan Gehn <metz@gehn.net>
10  Copyright (c) 2002-2004 by Martijn Klingens <klingens@kde.org>
11 
12  Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
13 
14  *************************************************************************
15  * *
16  * This program is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU General Public License as published by *
18  * the Free Software Foundation; either version 2 of the License, or *
19  * (at your option) any later version. *
20  * *
21  *************************************************************************
22 */
23 
24 #include "kopetechatwindow.h"
25 
26 #include <QtCore/QTextStream>
27 #include <QtCore/QTimer>
28 #include <QtGui/QDockWidget>
29 #include <QtGui/QFrame>
30 #include <QtGui/QLabel>
31 #include <QtGui/QLayout>
32 #include <QtGui/QMenu>
33 #include <QtGui/QPixmap>
34 #include <QtGui/QCloseEvent>
35 #include <QtGui/QVBoxLayout>
36 
37 #ifdef CHRONO
38 #include <QTime>
39 #endif
40 
41 #include <kactioncollection.h>
42 #include <kcursor.h>
43 #include <klocale.h>
44 #include <kmenubar.h>
45 #include <kconfig.h>
46 #include <kmenu.h>
47 #include <kicon.h>
48 #include <kiconloader.h>
49 #include <kdebug.h>
50 #include <kwindowsystem.h>
51 #include <ktemporaryfile.h>
52 #include <kedittoolbar.h>
53 #include <kstatusbar.h>
54 #include <kpushbutton.h>
55 #include <ktabwidget.h>
56 #include <kdialog.h>
57 #include <kstringhandler.h>
58 #include <ksqueezedtextlabel.h>
59 #include <kstandardshortcut.h>
60 #include <kglobalsettings.h>
61 #include <kcolorscheme.h>
62 #include <khbox.h>
63 #include <kvbox.h>
64 #include <ktoolbar.h>
65 #include <kstandardaction.h>
66 #include <ktoggleaction.h>
67 #include <kactionmenu.h>
68 #include <ktoolbarspaceraction.h>
69 
70 #include "chatmessagepart.h"
71 #include "chattexteditpart.h"
72 #include "chatview.h"
73 #include "kopeteapplication.h"
74 #include "kopetebehaviorsettings.h"
75 #include "kopeteemoticonaction.h"
76 #include "kopetegroup.h"
77 #include "kopetechatsession.h"
78 #include "kopetemetacontact.h"
79 #include "kopetepluginmanager.h"
80 #include "kopeteprotocol.h"
81 #include "kopetestdaction.h"
82 #include "kopeteviewmanager.h"
83 #include "chatmemberslistview.h"
84 #include "chatsessionmemberslistmodel.h"
85 
86 #include <qtoolbutton.h>
87 #include <kxmlguifactory.h>
88 #include <KTabBar>
89 
90 typedef QMap<Kopete::Account*,KopeteChatWindow*> AccountMap;
91 typedef QMap<Kopete::Group*,KopeteChatWindow*> GroupMap;
92 typedef QMap<Kopete::MetaContact*,KopeteChatWindow*> MetaContactMap;
93 typedef QList<KopeteChatWindow*> WindowList;
94 
95 using Kopete::ChatSessionMembersListModel;
96 
97 namespace
98 {
99  AccountMap accountMap;
100  GroupMap groupMap;
101  MetaContactMap mcMap;
102  WindowList windows;
103 }
104 
105 KopeteChatWindow *KopeteChatWindow::window( Kopete::ChatSession *manager )
106 {
107  bool windowCreated = false;
108  KopeteChatWindow *myWindow = 0;
109 
110  //Take the first and the first? What else?
111  Kopete::Group *group = 0L;
112  Kopete::ContactPtrList members = manager->members();
113  Kopete::MetaContact *metaContact = members.first()->metaContact();
114 
115  if ( metaContact )
116  {
117  Kopete::GroupList gList = metaContact->groups();
118  group = gList.first();
119  }
120 
121  switch( Kopete::BehaviorSettings::self()->chatWindowGroupPolicy() )
122  {
123  //Open chats from the same protocol in the same window
124  case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByAccount:
125  if( accountMap.contains( manager->account() ) )
126  myWindow = accountMap[ manager->account() ];
127  else
128  windowCreated = true;
129  break;
130 
131  //Open chats from the same group in the same window
132  case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByGroup:
133  if( group && groupMap.contains( group ) )
134  myWindow = groupMap[ group ];
135  else
136  windowCreated = true;
137  break;
138 
139  //Open chats from the same metacontact in the same window
140  case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByMetaContact:
141  if( mcMap.contains( metaContact ) )
142  myWindow = mcMap[ metaContact ];
143  else
144  windowCreated = true;
145  break;
146 
147  //Open all chats in the same window
148  case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupAll:
149  if( windows.isEmpty() )
150  windowCreated = true;
151  else
152  {
153  //Here we are finding the window with the most tabs and
154  //putting it there. Need this for the cases where config changes
155  //midstream
156 
157  int viewCount = -1;
158  WindowList::iterator it;
159  for ( it = windows.begin(); it != windows.end(); ++it )
160  {
161  if( (*it)->chatViewCount() > viewCount )
162  {
163  myWindow = (*it);
164  viewCount = (*it)->chatViewCount();
165  }
166  }
167  }
168  break;
169 
170  //Open every chat in a new window
171  case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::OpenNewWindow:
172  default:
173  windowCreated = true;
174  break;
175  }
176 
177  if ( windowCreated )
178  {
179  myWindow = new KopeteChatWindow( manager->form() );
180 
181  if ( !accountMap.contains( manager->account() ) )
182  accountMap.insert( manager->account(), myWindow );
183 
184  if ( !mcMap.contains( metaContact ) )
185  mcMap.insert( metaContact, myWindow );
186 
187  if ( group && !groupMap.contains( group ) )
188  groupMap.insert( group, myWindow );
189  }
190 
191 // kDebug( 14010 ) << "Open Windows: " << windows.count();
192 
193  return myWindow;
194 }
195 
196 KopeteChatWindow::KopeteChatWindow( Kopete::ChatSession::Form form, QWidget *parent )
197  : KXmlGuiWindow( parent ), initialForm( form )
198 {
199 #ifdef CHRONO
200  QTime chrono;chrono.start();
201 #endif
202  m_activeView = 0L;
203  m_popupView = 0L;
204  backgroundFile = 0L;
205  updateBg = true;
206  m_tabBar = 0L;
207 
208  m_participantsWidget = new QDockWidget(i18n("Participants"), this);
209  m_participantsWidget->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
210  m_participantsWidget->setFeatures(QDockWidget::DockWidgetClosable);
211  m_participantsWidget->setTitleBarWidget(0L);
212  m_participantsWidget->setObjectName("Participants"); //object name is required for automatic position and settings save.
213 
214  ChatSessionMembersListModel *members_model = new ChatSessionMembersListModel(this);
215 
216  connect(this, SIGNAL(chatSessionChanged(Kopete::ChatSession*)), members_model, SLOT(setChatSession(Kopete::ChatSession*)));
217 
218  ChatMembersListView *chatmembers = new ChatMembersListView(m_participantsWidget);
219  chatmembers->setModel(members_model);
220  chatmembers->setWordWrap(true);
221  m_participantsWidget->setWidget(chatmembers);
222  initActions();
223 
224  addDockWidget(Qt::RightDockWidgetArea, m_participantsWidget);
225 
226  KVBox *vBox = new KVBox( this );
227  vBox->setLineWidth( 0 );
228  vBox->setSpacing( 0 );
229  vBox->setFrameStyle( QFrame::NoFrame );
230  // set default window size. This could be removed by fixing the size hints of the contents
231  if ( initialForm == Kopete::ChatSession::Chatroom ) {
232  resize( 650, 400 );
233  } else {
234  m_participantsWidget->hide();
235  resize( 400, 400 );
236  }
237  setCentralWidget( vBox );
238 
239  mainArea = new QFrame( vBox );
240  mainArea->setLineWidth( 0 );
241  mainArea->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
242  mainLayout = new QVBoxLayout( mainArea );
243  mainLayout->setContentsMargins(0, 4, 0, 0);
244 
245  if ( Kopete::BehaviorSettings::self()->chatWindowShowSendButton() )
246  {
247  //Send Button
248  m_button_send = new KPushButton( i18nc("@action:button", "Send"), statusBar() );
249  m_button_send->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
250  m_button_send->setEnabled( false );
251  m_button_send->setFont( statusBar()->font() );
252  m_button_send->setFixedHeight( statusBar()->sizeHint().height() );
253  connect( m_button_send, SIGNAL(clicked()), this, SLOT(slotSendMessage()) );
254  statusBar()->addPermanentWidget( m_button_send, 0 );
255  }
256  else
257  m_button_send = 0L;
258 
259  m_status_text = new KSqueezedTextLabel( i18nc("@info:status","Ready."), statusBar() );
260  m_status_text->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
261  m_status_text->setFont( statusBar()->font() );
262  m_status_text->setFixedHeight( statusBar()->sizeHint().height() );
263  statusBar()->addWidget( m_status_text, 1 );
264 
265  windows.append( this );
266  windowListChanged();
267 
268  m_alwaysShowTabs = KGlobal::config()->group( "ChatWindowSettings" ).
269  readEntry( QLatin1String("AlwaysShowTabs"), false );
270 // kDebug( 14010 ) << "Open Windows: " << windows.count();
271 
272  setupGUI( static_cast<StandardWindowOptions>(ToolBar | Keys | StatusBar | Save | Create) , "kopetechatwindow.rc" );
273 
274  //has to be done after the setupGUI, in order to have the toolbar set up to restore window settings.
275  readOptions();
276 #ifdef CHRONO
277  kDebug()<<"TIME: "<<chrono.elapsed();
278 #endif
279 }
280 
281 KopeteChatWindow::~KopeteChatWindow()
282 {
283  kDebug( 14010 ) ;
284 
285  emit( closing( this ) );
286 
287  for( AccountMap::Iterator it = accountMap.begin(); it != accountMap.end(); )
288  {
289  if( it.value() == this )
290  it=accountMap.erase( it );
291  else
292  ++it;
293  }
294 
295  for( GroupMap::Iterator it = groupMap.begin(); it != groupMap.end(); )
296  {
297  if( it.value() == this )
298  it=groupMap.erase( it );
299  else
300  ++it;
301  }
302 
303  for( MetaContactMap::Iterator it = mcMap.begin(); it != mcMap.end(); )
304  {
305  if( it.value() == this )
306  it=mcMap.erase( it );
307  else
308  ++it;
309  }
310 
311  windows.removeAt( windows.indexOf( this ) );
312  windowListChanged();
313 
314 // kDebug( 14010 ) << "Open Windows: " << windows.count();
315 
316  saveOptions();
317 
318  delete backgroundFile;
319  delete anim;
320  delete animIcon;
321 }
322 
323 void KopeteChatWindow::windowListChanged()
324 {
325  // update all windows' Move Tab to Window action
326  for ( WindowList::iterator it = windows.begin(); it != windows.end(); ++it )
327  (*it)->checkDetachEnable();
328 }
329 
330 void KopeteChatWindow::slotTabContextMenu( QWidget *tab, const QPoint &pos )
331 {
332  m_popupView = static_cast<ChatView*>( tab );
333 
334  KMenu popup;
335  popup.addTitle( KStringHandler::rsqueeze( m_popupView->caption() ) );
336  popup.addAction( actionContactMenu );
337  popup.addSeparator();
338  popup.addAction( actionTabPlacementMenu );
339  popup.addAction( tabDetach );
340  popup.addAction( actionDetachMenu );
341  popup.addAction( tabCloseAllOthers );
342  popup.addAction( tabClose );
343  popup.exec( pos );
344 
345  m_popupView = 0;
346 }
347 
348 ChatView *KopeteChatWindow::activeView()
349 {
350  return m_activeView;
351 }
352 
353 void KopeteChatWindow::updateSendKeySequence()
354 {
355  if ( !sendMessage || !m_activeView )
356  return;
357 
358  m_activeView->editPart()->textEdit()->setSendKeySequenceList( sendMessage->shortcuts() );
359 }
360 
361 void KopeteChatWindow::initActions(void)
362 {
363  KActionCollection *coll = actionCollection();
364 
365  createStandardStatusBarAction();
366 
367  chatSend = new KAction( KIcon("mail-send"), i18n( "&Send Message" ), coll );
368  //Recuperate the qAction for later
369  sendMessage = coll->addAction( "chat_send", chatSend );
370  //Set up change signal in case the user changer the shortcut later
371  connect( sendMessage, SIGNAL(changed()), SLOT(updateSendKeySequence()) );
372 
373  connect( chatSend, SIGNAL(triggered(bool)), SLOT(slotSendMessage()) );
374  //Default to 'Return' and 'Enter' for sending messages
375  //'Return' is the key in the main part of the keyboard
376  //'Enter' is on the Numpad
377  KShortcut chatSendShortcut( QKeySequence((int)Qt::Key_Return), QKeySequence((int)Qt::Key_Enter) );
378  chatSend->setShortcut( chatSendShortcut );
379  chatSend->setEnabled( false );
380 
381  chatSendFile = new KAction( KIcon("mail-attachment"), i18n( "Send File..." ), coll );
382  coll->addAction( "chat_send_file", chatSendFile );
383  connect( chatSendFile, SIGNAL(triggered(bool)), SLOT(slotSendFile()) );
384  chatSendFile->setEnabled( false );
385 
386  KStandardAction::save ( this, SLOT(slotChatSave()), coll );
387  KStandardAction::print ( this, SLOT(slotChatPrint()), coll );
388  KAction* quitAction = KStandardAction::quit ( this, SLOT(close()), coll );
389  quitAction->setText( i18n("Close All Chats") );
390 
391  tabClose = KStandardAction::close ( this, SLOT(slotChatClosed()), coll );
392  coll->addAction( "tabs_close", tabClose );
393 
394  tabActive=new KAction( i18n( "&Activate Next Active Tab" ), coll );
395  coll->addAction( "tabs_active", tabActive );
396 // tabActive->setShortcut( KStandardShortcut::tabNext() );
397  tabActive->setEnabled( false );
398  connect( tabActive, SIGNAL(triggered(bool)), this, SLOT(slotNextActiveTab()) );
399 
400  tabRight=new KAction( i18n( "&Activate Next Tab" ), coll );
401  coll->addAction( "tabs_right", tabRight );
402  tabRight->setShortcut( KStandardShortcut::tabNext() );
403  tabRight->setEnabled( false );
404  connect( tabRight, SIGNAL(triggered(bool)), this, SLOT(slotNextTab()) );
405 
406  tabLeft=new KAction( i18n( "&Activate Previous Tab" ), coll );
407  coll->addAction( "tabs_left", tabLeft );
408  tabLeft->setShortcut( KStandardShortcut::tabPrev() );
409  tabLeft->setEnabled( false );
410  connect( tabLeft, SIGNAL(triggered(bool)), this, SLOT(slotPreviousTab()) );
411 
412  // This action exists mostly so that the shortcut is configurable.
413  // The actual "slot" is the eventFilter.
414  nickComplete = new KAction( i18n( "Nic&k Completion" ), coll );
415  coll->addAction( "nick_complete", nickComplete );
416  nickComplete->setShortcut( QKeySequence( Qt::Key_Tab ) );
417 
418  tabDetach = new KAction( KIcon("tab-detach"), i18n( "&Detach Chat" ), coll );
419  coll->addAction( "tabs_detach", tabDetach );
420  tabDetach->setEnabled( false );
421  connect( tabDetach, SIGNAL(triggered(bool)), this, SLOT(slotDetachChat()));
422 
423  tabCloseAllOthers = new KAction( KIcon("tab-close"), i18n( "Close &All But This Tab" ), coll );
424  coll->addAction( "tabs_close_others", tabCloseAllOthers );
425  tabCloseAllOthers->setEnabled( true );
426  connect( tabCloseAllOthers, SIGNAL(triggered(bool)), this, SLOT(slotCloseAllOtherTabs()));
427 
428  actionDetachMenu = new KActionMenu( KIcon("tab-detach"), i18n( "&Move Tab to Window" ), coll );
429  coll->addAction( "tabs_detachmove", actionDetachMenu );
430  actionDetachMenu->setDelayed( false );
431 
432  connect ( actionDetachMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotPrepareDetachMenu()) );
433  connect ( actionDetachMenu->menu(), SIGNAL(triggered(QAction*)), this, SLOT(slotDetachChat(QAction*)) );
434 
435  actionTabPlacementMenu = new KActionMenu( i18n( "&Tab Placement" ), coll );
436  coll->addAction( "tabs_placement", actionTabPlacementMenu );
437  connect ( actionTabPlacementMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotPreparePlacementMenu()) );
438  connect ( actionTabPlacementMenu->menu(), SIGNAL(triggered(QAction*)), this, SLOT(slotPlaceTabs(QAction*)) );
439 
440  tabDetach->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B) );
441 
442  KStandardAction::cut( this, SLOT(slotCut()), coll);
443  KStandardAction::copy( this, SLOT(slotCopy()), coll);
444  KStandardAction::paste( this, SLOT(slotPaste()), coll);
445 
446  KAction* action;
447 
448  historyUp = new KAction( i18n( "Previous History" ), coll );
449  coll->addAction( "history_up", historyUp );
450  historyUp->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_Up) );
451  connect( historyUp, SIGNAL(triggered(bool)), this, SLOT(slotHistoryUp()) );
452 
453  historyDown = new KAction( i18n( "Next History" ), coll );
454  coll->addAction( "history_down", historyDown );
455  historyDown->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_Down) );
456  connect( historyDown, SIGNAL(triggered(bool)), this, SLOT(slotHistoryDown()) );
457 
458  action = KStandardAction::prior( this, SLOT(slotPageUp()), coll );
459  coll->addAction( "scroll_up", action );
460  action = KStandardAction::next( this, SLOT(slotPageDown()), coll );
461  coll->addAction( "scroll_down", action );
462 
463  KStandardAction::showMenubar( menuBar(), SLOT(setVisible(bool)), coll );
464 
465  toggleAutoSpellCheck = new KToggleAction( i18n( "Automatic Spell Checking" ), coll );
466  coll->addAction( "enable_auto_spell_check", toggleAutoSpellCheck );
467  toggleAutoSpellCheck->setChecked( true );
468  connect( toggleAutoSpellCheck, SIGNAL(triggered(bool)), this, SLOT(toggleAutoSpellChecking()) );
469 
470  QAction *toggleParticipantsAction = m_participantsWidget->toggleViewAction( );
471  toggleParticipantsAction->setText( i18n( "Show Participants" ) );
472  toggleParticipantsAction->setIconText(i18n( "Participants" ));
473  toggleParticipantsAction->setIcon(KIcon( "system-users" ) );
474  coll->addAction ( "show_participants_widget", toggleParticipantsAction );
475 
476  actionSmileyMenu = new KopeteEmoticonAction( coll );
477  coll->addAction( "format_smiley", actionSmileyMenu );
478  actionSmileyMenu->setDelayed( false );
479  connect(actionSmileyMenu, SIGNAL(activated(QString)), this, SLOT(slotSmileyActivated(QString)));
480 
481  actionContactMenu = new KActionMenu(i18n("Co&ntacts"), coll );
482  coll->addAction( "contacts_menu", actionContactMenu );
483  actionContactMenu->setDelayed( false );
484  connect ( actionContactMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(slotPrepareContactMenu()) );
485 
486  KopeteStdAction::preferences( coll , "settings_prefs" );
487 
488  KToolBarSpacerAction * spacer = new KToolBarSpacerAction( coll );
489  coll->addAction( "spacer", spacer );
490 
491  //The Sending movie
492  normalIcon = QPixmap( BarIcon( QLatin1String( "kopete" ) ) );
493 
494  // we can't set the tool bar as parent, if we do, it will be deleted when we configure toolbars
495  anim = new QLabel( QString::null, 0L ); //krazy:exclude=nullstrassign for old broken gcc
496  anim->setObjectName( QLatin1String("kde toolbar widget") );
497  anim->setMargin(5);
498  anim->setPixmap( normalIcon );
499 
500  animIcon = KIconLoader::global()->loadMovie( QLatin1String( "newmessage" ), KIconLoader::Toolbar);
501  if ( animIcon )
502  animIcon->setPaused(true);
503 
504  KAction *animAction = new KAction( i18n("Toolbar Animation"), coll );
505  coll->addAction( "toolbar_animation", animAction );
506  animAction->setDefaultWidget( anim );
507 
508  //toolBar()->insertWidget( 99, anim->width(), anim );
509  //toolBar()->alignItemRight( 99 );
510 }
511 
512 /*
513 const QString KopeteChatWindow::fileContents( const QString &path ) const
514 {
515  QString contents;
516  QFile file( path );
517  if ( file.open( QIODevice::ReadOnly ) )
518  {
519  QTextStream stream( &file );
520  contents = stream.readAll();
521  file.close();
522  }
523 
524  return contents;
525 }
526 */
527 void KopeteChatWindow::slotStopAnimation( ChatView* view )
528 {
529  if( view == m_activeView )
530  {
531  anim->setPixmap( normalIcon );
532  if( animIcon && animIcon->state() == QMovie::Running )
533  animIcon->setPaused( true );
534  }
535 }
536 
537 void KopeteChatWindow::slotUpdateSendEnabled()
538 {
539  if ( !m_activeView ) return;
540 
541  bool enabled = m_activeView->canSend();
542  chatSend->setEnabled( enabled );
543  if(m_button_send)
544  m_button_send->setEnabled( enabled );
545 }
546 
547 void KopeteChatWindow::updateChatSendFileAction()
548 {
549  if ( !m_activeView )
550  return;
551 
552  chatSendFile->setEnabled( m_activeView->canSendFile() );
553 }
554 
555 void KopeteChatWindow::toggleAutoSpellChecking()
556 {
557  if ( !m_activeView )
558  return;
559 
560  bool currentSetting = m_activeView->editPart()->checkSpellingEnabled();
561  m_activeView->editPart()->setCheckSpellingEnabled( !currentSetting );
562  updateSpellCheckAction();
563 }
564 
565 void KopeteChatWindow::updateSpellCheckAction()
566 {
567  if ( !m_activeView )
568  return;
569 
570  bool currentSetting = m_activeView->editPart()->checkSpellingEnabled();
571  toggleAutoSpellCheck->setChecked( currentSetting );
572 }
573 
574 void KopeteChatWindow::enableSpellCheckAction(bool enable)
575 {
576  toggleAutoSpellCheck->setChecked( enable );
577 }
578 
579 void KopeteChatWindow::updateActions()
580 {
581  updateSpellCheckAction();
582  updateChatSendFileAction();
583 }
584 
585 void KopeteChatWindow::slotHistoryUp()
586 {
587  if( m_activeView )
588  m_activeView->editPart()->historyUp();
589 }
590 
591 void KopeteChatWindow::slotHistoryDown()
592 {
593  if( m_activeView )
594  m_activeView->editPart()->historyDown();
595 }
596 
597 void KopeteChatWindow::slotPageUp()
598 {
599  if( m_activeView )
600  m_activeView->messagePart()->pageUp();
601 }
602 
603 void KopeteChatWindow::slotPageDown()
604 {
605  if( m_activeView )
606  m_activeView->messagePart()->pageDown();
607 }
608 
609 void KopeteChatWindow::slotCut()
610 {
611  m_activeView->cut();
612 }
613 
614 void KopeteChatWindow::slotCopy()
615 {
616  m_activeView->copy();
617 }
618 
619 void KopeteChatWindow::slotPaste()
620 {
621  m_activeView->paste();
622 }
623 
624 void KopeteChatWindow::slotResetFontAndColor()
625 {
626  m_activeView->resetFontAndColor();
627 }
628 
629 void KopeteChatWindow::setStatus(const QString &text)
630 {
631  m_status_text->setText(text);
632 }
633 
634 void KopeteChatWindow::testCanDecode(const QDragMoveEvent *event, bool &accept)
635 {
636  if ( m_tabBar && qobject_cast<KTabBar*>(m_tabBar->childAt( event->pos() )) && chatViewList[static_cast<KTabBar*>(m_tabBar->childAt( event->pos()))->selectTab( event->pos() )]->isDragEventAccepted( event )) {
637  accept = true;
638  } else {
639  accept = false;
640  }
641 }
642 
643 void KopeteChatWindow::receivedDropEvent( QWidget *w, QDropEvent *e )
644 {
645  m_tabBar->setCurrentWidget( w );
646  activeView()->dropEvent( e );
647 }
648 
649 void KopeteChatWindow::createTabBar()
650 {
651  if( !m_tabBar )
652  {
653  KConfigGroup cg( KGlobal::config(), QLatin1String("ChatWindowSettings") );
654 
655  m_tabBar = new KTabWidget( mainArea );
656  m_tabBar->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
657  m_tabBar->setTabsClosable(cg.readEntry( QLatin1String("HoverClose"), true ));
658  m_tabBar->setMovable(true);
659  m_tabBar->setAutomaticResizeTabs(true);
660  connect( m_tabBar, SIGNAL(closeRequest(QWidget*)), this, SLOT(slotCloseChat(QWidget*)) );
661 
662  m_UpdateChatLabel = cg.readEntry( QLatin1String("ShowContactName"), true );
663 
664  QToolButton* m_rightWidget = new QToolButton( m_tabBar );
665  connect( m_rightWidget, SIGNAL(clicked()), this, SLOT(slotChatClosed()) );
666  m_rightWidget->setIcon( SmallIcon( "tab-close" ) );
667  m_rightWidget->adjustSize();
668  m_rightWidget->setToolTip( i18nc("@info:tooltip","Close the current tab") );
669  m_tabBar->setCornerWidget( m_rightWidget, Qt::TopRightCorner );
670 
671  mainLayout->addWidget( m_tabBar );
672  m_tabBar->show();
673 
674  for( ChatViewList::iterator it = chatViewList.begin(); it != chatViewList.end(); ++it )
675  addTab( *it );
676 
677  connect ( m_tabBar, SIGNAL(testCanDecode(const QDragMoveEvent*,bool&)), this, SLOT(testCanDecode(const QDragMoveEvent*,bool&)) );
678  connect ( m_tabBar, SIGNAL(receivedDropEvent(QWidget*,QDropEvent*)), this, SLOT(receivedDropEvent(QWidget*,QDropEvent*)) );
679  connect ( m_tabBar, SIGNAL(currentChanged(QWidget*)), this, SLOT(setActiveView(QWidget*)) );
680  connect ( m_tabBar, SIGNAL(contextMenu(QWidget*,QPoint)), this, SLOT(slotTabContextMenu(QWidget*,QPoint)) );
681 
682  if( m_activeView )
683  m_tabBar->setCurrentWidget( m_activeView );
684  else
685  setActiveView( chatViewList.first() );
686 
687  int tabPosition = cg.readEntry( QLatin1String("Tab Placement") , 0 );
688 
689  QAction action(this);
690  action.setData(tabPosition);
691  slotPlaceTabs( &action );
692  }
693 }
694 
695 void KopeteChatWindow::slotCloseChat( QWidget *chatView )
696 {
697  static_cast<ChatView*>( chatView )->closeView();
698  //FIXME: check if we need to remove from the chatViewList
699 }
700 
701 void KopeteChatWindow::addTab( ChatView *view )
702 {
703  QList<Kopete::Contact*> chatMembers=view->msgManager()->members();
704  Kopete::Contact *c=0L;
705  foreach( Kopete::Contact *contact , chatMembers )
706  {
707  if(!c || c->onlineStatus() < contact->onlineStatus())
708  c=contact;
709  }
710  QIcon pluginIcon = c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c) :
711  KIcon( view->msgManager()->protocol()->pluginIcon() );
712 
713  view->setParent( m_tabBar );
714  view->setWindowFlags( 0 );
715  view->move( QPoint() );
716  //view->show();
717 
718  m_tabBar->addTab( view, pluginIcon, "");
719  view->setVisible(view == m_activeView);
720  connect( view, SIGNAL(updateStatusIcon(ChatView*)), this, SLOT(slotUpdateCaptionIcons(ChatView*)) );
721 
722  if (m_UpdateChatLabel) {
723  connect( view, SIGNAL(captionChanged(bool)), this, SLOT(updateChatLabel()) );
724  view->setCaption( view->caption(), false );
725  }
726 
727 }
728 
729 void KopeteChatWindow::setPrimaryChatView( ChatView *view )
730 {
731  //TODO figure out what else we have to save here besides the font
732  //reparent clears a lot of stuff out
733  view->setParent( mainArea );
734  view->setWindowFlags( 0 );
735  view->move( QPoint() );
736  view->show();
737 
738  mainLayout->addWidget( view );
739  setActiveView( view );
740 }
741 
742 void KopeteChatWindow::deleteTabBar()
743 {
744  if( m_tabBar )
745  {
746  disconnect ( m_tabBar, SIGNAL(currentChanged(QWidget*)), this, SLOT(setActiveView(QWidget*)) );
747  disconnect ( m_tabBar, SIGNAL(contextMenu(QWidget*,QPoint)), this, SLOT(slotTabContextMenu(QWidget*,QPoint)) );
748 
749  if( !chatViewList.isEmpty() )
750  setPrimaryChatView( chatViewList.first() );
751 
752  m_tabBar->deleteLater();
753  m_tabBar = 0L;
754  }
755 }
756 
757 void KopeteChatWindow::attachChatView( ChatView* newView )
758 {
759  chatViewList.append( newView );
760 
761  if ( !m_alwaysShowTabs && chatViewList.count() == 1 )
762  setPrimaryChatView( newView );
763  else
764  {
765  if ( !m_tabBar )
766  createTabBar();
767  else
768  addTab( newView );
769  newView->setActive( false );
770  }
771 
772  newView->setMainWindow( this );
773  newView->editWidget()->installEventFilter( this );
774 
775  KCursor::setAutoHideCursor( newView->editWidget(), true, true );
776  connect( newView, SIGNAL(captionChanged(bool)), this, SLOT(slotSetCaption(bool)) );
777  connect( newView, SIGNAL(messageSuccess(ChatView*)), this, SLOT(slotStopAnimation(ChatView*)) );
778  connect( newView, SIGNAL(updateStatusIcon(ChatView*)), this, SLOT(slotUpdateCaptionIcons(ChatView*)) );
779 
780  if (m_UpdateChatLabel) {
781  connect( newView, SIGNAL(updateChatState(ChatView*,int)), this, SLOT(updateChatState(ChatView*,int)) );
782  }
783 
784  updateActions();
785  checkDetachEnable();
786  connect( newView, SIGNAL(autoSpellCheckEnabled(ChatView*,bool)),
787  this, SLOT(slotAutoSpellCheckEnabled(ChatView*,bool)) );
788 }
789 
790 void KopeteChatWindow::checkDetachEnable()
791 {
792  bool haveTabs = (chatViewList.count() > 1);
793  tabCloseAllOthers->setEnabled( haveTabs );
794  tabDetach->setEnabled( haveTabs );
795  tabLeft->setEnabled( haveTabs );
796  tabRight->setEnabled( haveTabs );
797  tabActive->setEnabled( haveTabs );
798  actionTabPlacementMenu->setEnabled( m_tabBar != 0 );
799 
800  bool otherWindows = (windows.count() > 1);
801  actionDetachMenu->setEnabled( otherWindows );
802 }
803 
804 void KopeteChatWindow::detachChatView( ChatView *view )
805 {
806  chatViewList.removeAt( chatViewList.indexOf( view ) );
807 
808  disconnect( view, SIGNAL(captionChanged(bool)), this, SLOT(slotSetCaption(bool)) );
809  disconnect( view, SIGNAL(updateStatusIcon(ChatView*)), this, SLOT(slotUpdateCaptionIcons(ChatView*)) );
810  disconnect( view, SIGNAL(updateChatState(ChatView*,int)), this, SLOT(updateChatState(ChatView*,int)) );
811  view->editWidget()->removeEventFilter( this );
812 
813  if( m_tabBar )
814  {
815  int curPage = m_tabBar->currentIndex();
816  QWidget *page = m_tabBar->currentWidget();
817 
818  // if the current view is to be detached, switch to a different one
819  if( page == view )
820  {
821  if( curPage > 0 )
822  m_tabBar->setCurrentIndex( curPage - 1 );
823  else
824  m_tabBar->setCurrentIndex( curPage + 1 );
825  }
826 
827  m_tabBar->removePage( view );
828 
829  if( m_tabBar->currentWidget() )
830  setActiveView( static_cast<ChatView*>(m_tabBar->currentWidget()) );
831  }
832 
833  if( m_activeView == view )
834  m_activeView = 0;
835 
836  if( chatViewList.isEmpty() )
837  close();
838  else if( !m_alwaysShowTabs && chatViewList.count() == 1)
839  deleteTabBar();
840 
841  checkDetachEnable();
842 }
843 
844 void KopeteChatWindow::slotDetachChat( QAction *action )
845 {
846  KopeteChatWindow *newWindow = 0L;
847  ChatView *detachedView;
848 
849  if( m_popupView )
850  detachedView = m_popupView;
851  else
852  detachedView = m_activeView;
853 
854  if( !detachedView )
855  return;
856 
857  //if we don't do this, we might crash
858 // createGUI(0L);
859  guiFactory()->removeClient(detachedView->msgManager());
860 
861  if( !action )
862  {
863  newWindow = new KopeteChatWindow( detachedView->msgManager()->form() );
864  newWindow->setObjectName( QLatin1String("KopeteChatWindow") );
865  }
866  else
867  newWindow = windows.at( action->data().toInt() );
868 
869  newWindow->show();
870  newWindow->raise();
871 
872  detachChatView( detachedView );
873  newWindow->attachChatView( detachedView );
874 }
875 
876 void KopeteChatWindow::slotCloseAllOtherTabs()
877 {
878  ChatView *detachedView;
879 
880  if( m_popupView )
881  detachedView = m_popupView;
882  else
883  detachedView = m_activeView;
884 
885  foreach(ChatView *view, chatViewList) {
886  if (view != detachedView)
887  view->closeView();
888  }
889 }
890 
891 void KopeteChatWindow::slotPreviousTab()
892 {
893  int curPage = m_tabBar->currentIndex();
894  if( curPage > 0 )
895  m_tabBar->setCurrentIndex( curPage - 1 );
896  else
897  m_tabBar->setCurrentIndex( m_tabBar->count() - 1 );
898 }
899 
900 void KopeteChatWindow::slotNextTab()
901 {
902  int curPage = m_tabBar->currentIndex();
903  if( curPage == ( m_tabBar->count() - 1 ) )
904  m_tabBar->setCurrentIndex( 0 );
905  else
906  m_tabBar->setCurrentIndex( curPage + 1 );
907 }
908 
909 void KopeteChatWindow::slotNextActiveTab()
910 {
911  int curPage = m_tabBar->currentIndex();
912  for(int i=(curPage+1) % m_tabBar->count(); i!=curPage; i = (i+1) % m_tabBar->count())
913  {
914  ChatView *v = static_cast<ChatView*>(m_tabBar->widget(i)); //We assume we only have ChatView's
915  if(v->tabState()==ChatView::Highlighted || v->tabState()==ChatView::Message)
916  {
917  m_tabBar->setCurrentIndex( i );
918  break;
919  }
920  }
921 }
922 
923 void KopeteChatWindow::slotSetCaption( bool active )
924 {
925  if( active && m_activeView )
926  {
927  setCaption( m_activeView->caption(), false );
928  }
929 }
930 
931 void KopeteChatWindow::updateBackground( const QPixmap &pm )
932 {
933  if( updateBg )
934  {
935  updateBg = false;
936  delete backgroundFile;
937 
938  backgroundFile = new KTemporaryFile();
939  backgroundFile->setSuffix(".bmp");
940  backgroundFile->open();
941  pm.save( backgroundFile, "BMP" );
942  QTimer::singleShot( 100, this, SLOT(slotEnableUpdateBg()) );
943  }
944 }
945 
946 void KopeteChatWindow::setActiveView( QWidget *widget )
947 {
948  ChatView *view = static_cast<ChatView*>(widget);
949 
950  if( m_activeView == view )
951  return;
952 
953  if(m_activeView)
954  {
955  disconnect( m_activeView->editWidget(), SIGNAL(checkSpellingChanged(bool)), this, SLOT(enableSpellCheckAction(bool)) );
956  disconnect( m_activeView, SIGNAL(canSendChanged(bool)), this, SLOT(slotUpdateSendEnabled()) );
957  disconnect( m_activeView, SIGNAL(canAcceptFilesChanged()), this, SLOT(updateChatSendFileAction()) );
958  guiFactory()->removeClient(m_activeView->msgManager());
959  m_activeView->saveChatSettings();
960  }
961 
962  if ( view != 0 )
963  guiFactory()->addClient(view->msgManager());
964 // createGUI( view->editPart() );
965 
966  if( m_activeView )
967  m_activeView->setActive( false );
968 
969  m_activeView = view;
970 
971  if ( view == 0 )
972  return;
973 
974  if( chatViewList.indexOf( view ) == -1)
975  attachChatView( view );
976 
977  connect( m_activeView->editWidget(), SIGNAL(checkSpellingChanged(bool)), this, SLOT(enableSpellCheckAction(bool)) );
978  connect( m_activeView, SIGNAL(canSendChanged(bool)), this, SLOT(slotUpdateSendEnabled()) );
979  connect( m_activeView, SIGNAL(canAcceptFilesChanged()), this, SLOT(updateChatSendFileAction()) );
980 
981  //Tell it it is active
982  m_activeView->setActive( true );
983 
984  //Update icons to match
985  slotUpdateCaptionIcons( m_activeView );
986 
987  if ( m_activeView->sendInProgress() && animIcon )
988  {
989  anim->setMovie( animIcon );
990  animIcon->setPaused(false);
991  }
992  else
993  {
994  anim->setPixmap( normalIcon );
995  if( animIcon )
996  animIcon->setPaused(true);
997  }
998 
999  if ( m_alwaysShowTabs || chatViewList.count() > 1 )
1000  {
1001  if( !m_tabBar )
1002  createTabBar();
1003 
1004  m_tabBar->setCurrentWidget( m_activeView );
1005  }
1006 
1007  setCaption( m_activeView->caption() );
1008  setStatus( m_activeView->statusText() );
1009  m_activeView->setFocus();
1010  updateActions();
1011  slotUpdateSendEnabled();
1012  m_activeView->loadChatSettings();
1013  updateSendKeySequence();
1014 
1015  emit chatSessionChanged(m_activeView->msgManager());
1016 }
1017 
1018 void KopeteChatWindow::slotUpdateCaptionIcons( ChatView *view )
1019 {
1020  if ( !view )
1021  return; //(pas de charité)
1022 
1023  QList<Kopete::Contact*> chatMembers=view->msgManager()->members();
1024  Kopete::Contact *c=0L;
1025  foreach ( Kopete::Contact *contact , chatMembers )
1026  {
1027  if(!c || c->onlineStatus() < contact->onlineStatus())
1028  c=contact;
1029  }
1030 
1031  if ( view == m_activeView )
1032  {
1033  setWindowIcon( c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c ) :
1034  KIcon(view->msgManager()->protocol()->pluginIcon()));
1035  }
1036 
1037  if ( m_tabBar )
1038  m_tabBar->setTabIcon(m_tabBar->indexOf( view ), c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c ) :
1039  KIcon( view->msgManager()->protocol()->pluginIcon() ) );
1040 }
1041 
1042 void KopeteChatWindow::slotChatClosed()
1043 {
1044  if( m_popupView )
1045  m_popupView->closeView();
1046  else
1047  m_activeView->closeView();
1048 }
1049 
1050 void KopeteChatWindow::slotPrepareDetachMenu(void)
1051 {
1052  QMenu *detachMenu = actionDetachMenu->menu();
1053  detachMenu->clear();
1054 
1055  QAction *action;
1056  for ( int id = 0; id < windows.count(); id++ )
1057  {
1058  KopeteChatWindow *win = windows.at( id );
1059  if( win != this )
1060  {
1061  action = detachMenu->addAction( win->windowIcon(), win->windowTitle() );
1062  action->setData( id );
1063  }
1064  }
1065 }
1066 
1067 void KopeteChatWindow::slotSendMessage()
1068 {
1069  if ( m_activeView && m_activeView->canSend() )
1070  {
1071  if( animIcon )
1072  {
1073  anim->setMovie( animIcon );
1074  animIcon->setPaused(false);
1075  }
1076  m_activeView->sendMessage();
1077  }
1078 }
1079 
1080 void KopeteChatWindow::slotSendFile()
1081 {
1082  if ( m_activeView )
1083  m_activeView->sendFile();
1084 }
1085 
1086 void KopeteChatWindow::slotPrepareContactMenu(void)
1087 {
1088  KMenu *contactsMenu = actionContactMenu->menu();
1089  contactsMenu->clear();
1090 
1091  Kopete::ContactPtrList m_them;
1092 
1093  if( m_popupView )
1094  m_them = m_popupView->msgManager()->members();
1095  else
1096  m_them = m_activeView->msgManager()->members();
1097 
1098  //TODO: don't display a menu with one contact in it, display that
1099  // contact's menu instead. Will require changing text and icon of
1100  // 'Contacts' action, or something cleverer.
1101  uint contactCount = 0;
1102 
1103  foreach(Kopete::Contact *contact, m_them)
1104  {
1105  KMenu *p = contact->popupMenu();
1106  connect ( actionContactMenu->menu(), SIGNAL(aboutToHide()),
1107  p, SLOT(deleteLater()) );
1108 
1109  p->setIcon( contact->onlineStatus().iconFor( contact ) );
1110  if( contact->metaContact() )
1111  p->setTitle( contact->metaContact()->displayName() );
1112  else
1113  p->setTitle( contact->contactId() );
1114 
1115  contactsMenu->addMenu( p );
1116 
1117  //FIXME: This number should be a config option
1118  if( ++contactCount == 15 && contact != m_them.last() )
1119  {
1120  KActionMenu *moreMenu = new KActionMenu( KIcon("folder-open"), i18n("More..."), this);
1121  connect ( actionContactMenu->menu(), SIGNAL(aboutToHide()),
1122  moreMenu, SLOT(deleteLater()) );
1123  contactsMenu->addAction( moreMenu );
1124  contactsMenu = moreMenu->menu();
1125  contactCount = 0;
1126  }
1127  }
1128 }
1129 
1130 void KopeteChatWindow::slotPreparePlacementMenu()
1131 {
1132  QMenu *placementMenu = actionTabPlacementMenu->menu();
1133  placementMenu->clear();
1134 
1135  QAction *action;
1136  action = placementMenu->addAction( i18n("Top") );
1137  action->setData( 0 );
1138 
1139  action = placementMenu->addAction( i18n("Bottom") );
1140  action->setData( 1 );
1141 
1142  action = placementMenu->addAction( i18n("Left") );
1143  action->setData( 2 );
1144 
1145  action = placementMenu->addAction( i18n("Right") );
1146  action->setData( 3 );
1147 }
1148 
1149 void KopeteChatWindow::slotPlaceTabs( QAction *action )
1150 {
1151  int placement = action->data().toInt();
1152 
1153  if( m_tabBar )
1154  {
1155  switch( placement )
1156  {
1157  case 1 : m_tabBar->setTabPosition( QTabWidget::South ); break;
1158  case 2 : m_tabBar->setTabPosition( QTabWidget::West ); break;
1159  case 3 : m_tabBar->setTabPosition( QTabWidget::East ); break;
1160  default: m_tabBar->setTabPosition( QTabWidget::North );
1161  }
1162  saveOptions();
1163  }
1164 }
1165 
1166 void KopeteChatWindow::readOptions()
1167 {
1168  // load and apply config file settings affecting the appearance of the UI
1169 // kDebug(14010) ;
1170  applyMainWindowSettings( KGlobal::config()->group( ( initialForm == Kopete::ChatSession::Chatroom ? QLatin1String( "KopeteChatWindowGroupMode" ) : QLatin1String( "KopeteChatWindowIndividualMode" ) ) ) );
1171  //config->setGroup( QLatin1String("ChatWindowSettings") );
1172 }
1173 
1174 void KopeteChatWindow::saveOptions()
1175 {
1176 // kDebug(14010) ;
1177 
1178  KConfigGroup kopeteChatWindowMainWinSettings( KGlobal::config(), ( initialForm == Kopete::ChatSession::Chatroom ? QLatin1String( "KopeteChatWindowGroupMode" ) : QLatin1String( "KopeteChatWindowIndividualMode" ) ) );
1179 
1180  // saves menubar,toolbar and statusbar setting
1181  saveMainWindowSettings( kopeteChatWindowMainWinSettings );
1182  if ( m_tabBar ) {
1183  KConfigGroup chatWindowSettings( KGlobal::config(), QLatin1String("ChatWindowSettings") );
1184  chatWindowSettings.writeEntry ( QLatin1String("Tab Placement"), (int)m_tabBar->tabPosition() );
1185  chatWindowSettings.sync();
1186  }
1187  kopeteChatWindowMainWinSettings.sync();
1188 }
1189 
1190 void KopeteChatWindow::slotChatSave()
1191 {
1192 // kDebug(14010) << "KopeteChatWindow::slotChatSave()";
1193  if( isActiveWindow() && m_activeView )
1194  m_activeView->messagePart()->save();
1195 }
1196 
1197 void KopeteChatWindow::changeEvent( QEvent *e )
1198 {
1199  if( e->type() == QEvent::ActivationChange && isActiveWindow() && m_activeView )
1200  m_activeView->setActive( true );
1201 }
1202 
1203 void KopeteChatWindow::slotChatPrint()
1204 {
1205  m_activeView->messagePart()->print();
1206 }
1207 
1208 
1209 void KopeteChatWindow::slotSmileyActivated(const QString &sm)
1210 {
1211  if ( !sm.isNull() )
1212  m_activeView->addText( ' ' + sm + ' ' );
1213  //we are adding space around the emoticon becasue our parser only display emoticons not in a word.
1214 }
1215 
1216 void KopeteChatWindow::slotAutoSpellCheckEnabled( ChatView* view, bool isEnabled )
1217 {
1218  if ( view != m_activeView )
1219  return;
1220 
1221  toggleAutoSpellCheck->setChecked( isEnabled );
1222  m_activeView->editPart()->setCheckSpellingEnabled( isEnabled );
1223 }
1224 
1225 bool KopeteChatWindow::queryClose()
1226 {
1227 #ifdef CHRONO
1228  QTime chrono;chrono.start();
1229 #endif
1230  bool canClose = true;
1231 
1232 // kDebug( 14010 ) << " Windows left open:";
1233 // for( QPtrListIterator<ChatView> it( chatViewList ); it; ++it)
1234 // kDebug( 14010 ) << " " << *it << " (" << (*it)->caption() << ")";
1235  setUpdatesEnabled(false);//hide the crazyness from users
1236  while (!chatViewList.isEmpty())
1237  {
1238 
1239  ChatView *view = chatViewList.takeFirst();
1240 
1241  // FIXME: This should only check if it *can* close
1242  // and not start closing if the close can be aborted halfway, it would
1243  // leave us with half the chats open and half of them closed. - Martijn
1244 
1245  // if the view is closed, it is removed from chatViewList for us
1246  if ( !view->closeView() )
1247  {
1248  kDebug() << "Closing view failed!";
1249  canClose = false;
1250  }
1251  }
1252  setUpdatesEnabled(true);
1253 #ifdef CHRONO
1254  kDebug()<<"TIME: "<<chrono.elapsed();
1255 #endif
1256  return canClose;
1257 }
1258 
1259 bool KopeteChatWindow::queryExit()
1260 {
1261  KopeteApplication *app = static_cast<KopeteApplication *>( kapp );
1262  if ( app->sessionSaving()
1263  || app->isShuttingDown() /* only set if KopeteApplication::quitKopete() or
1264  KopeteApplication::commitData() called */
1265  || !Kopete::BehaviorSettings::self()->showSystemTray() /* also close if our tray icon is hidden! */
1266  || isHidden() )
1267  {
1268  Kopete::PluginManager::self()->shutdown();
1269  return true;
1270  }
1271  else
1272  return false;
1273 }
1274 
1275 void KopeteChatWindow::closeEvent( QCloseEvent * e )
1276 {
1277  // if there's a system tray applet and we are not shutting down then just do what needs to be done if a
1278  // window is closed.
1279  KopeteApplication *app = static_cast<KopeteApplication *>( kapp );
1280  if ( Kopete::BehaviorSettings::self()->showSystemTray() && !app->isShuttingDown() && !app->sessionSaving() ) {
1281 // hide();
1282  // BEGIN of code borrowed from KMainWindow::closeEvent
1283  // Save settings if auto-save is enabled, and settings have changed
1284  if ( settingsDirty() && autoSaveSettings() )
1285  saveAutoSaveSettings();
1286 
1287  if ( queryClose() ) {
1288  e->accept();
1289  }
1290  else {
1291  e->ignore();
1292  }
1293  // END of code borrowed from KMainWindow::closeEvent
1294  }
1295  else
1296  KXmlGuiWindow::closeEvent( e );
1297 }
1298 
1299 
1300 void KopeteChatWindow::updateChatState( ChatView* cv, int newState )
1301 {
1302  Q_UNUSED(cv);
1303 
1304  if ( m_tabBar )
1305  {
1306  KColorScheme scheme(QPalette::Active, KColorScheme::Window);
1307  switch( newState )
1308  {
1309  case ChatView::Highlighted:
1310  m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::LinkText).color());
1311  break;
1312  case ChatView::Message:
1313  m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::ActiveText).color());
1314  break;
1315  case ChatView::Changed:
1316  m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::NeutralText).color());
1317  break;
1318  case ChatView::Typing:
1319  m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::PositiveText).color());
1320  break;
1321  case ChatView::Normal:
1322  default:
1323  m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::NormalText).color() );
1324  break;
1325  }
1326  }
1327 }
1328 
1329 void KopeteChatWindow::updateChatTooltip( ChatView* cv )
1330 {
1331  if ( m_tabBar )
1332  m_tabBar->setTabToolTip( m_tabBar->indexOf( cv ), QString::fromLatin1("<qt>%1</qt>").arg( cv->caption() ) );
1333 }
1334 
1335 void KopeteChatWindow::updateChatLabel()
1336 {
1337  ChatView* chat = dynamic_cast<ChatView*>( sender() );
1338  if ( !chat || !m_tabBar )
1339  return;
1340 
1341  if ( m_tabBar )
1342  {
1343  m_tabBar->setTabText( m_tabBar->indexOf( chat ), chat->caption() );
1344  if ( m_tabBar->count() < 2 || m_tabBar->currentWidget() == chat )
1345  setCaption( chat->caption() );
1346  }
1347 }
1348 
1349 void KopeteChatWindow::resizeEvent( QResizeEvent *e )
1350 {
1351  KXmlGuiWindow::resizeEvent( e );
1352  if ( m_activeView && m_activeView->messagePart() )
1353  m_activeView->messagePart()->keepScrolledDown();
1354 }
1355 
1356 bool KopeteChatWindow::eventFilter( QObject *obj, QEvent *event )
1357 {
1358  if ( m_activeView && obj == m_activeView->editWidget() && event->type() == QEvent::KeyPress ) {
1359  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
1360  if (nickComplete->shortcut().primary() == QKeySequence(keyEvent->key())) {
1361  m_activeView->nickComplete();
1362  return true;
1363  }
1364  }
1365  return KXmlGuiWindow::eventFilter(obj, event);
1366 }
1367 
1368 #include "kopetechatwindow.moc"
1369 
1370 // vim: set noet ts=4 sts=4 sw=4:
QAction::setText
void setText(const QString &text)
KopeteChatWindow::eventFilter
virtual bool eventFilter(QObject *obj, QEvent *event)
Definition: kopetechatwindow.cpp:1356
ChatView
Definition: chatview.h:62
KPushButton
KopeteChatWindow::chatSessionChanged
void chatSessionChanged(Kopete::ChatSession *newSession)
QEvent
QResizeEvent
ChatView::setCaption
void setCaption(const QString &text, bool modified)
Sets the text to be displayed on tab label and window caption.
Definition: chatview.cpp:659
QWidget
QEvent::type
Type type() const
QLayout::setContentsMargins
void setContentsMargins(int left, int top, int right, int bottom)
ChatView::caption
QString & caption() const
Definition: chatview.cpp:654
KVBox
KopeteChatWindow::chatViewList
ChatViewList chatViewList
Definition: kopetechatwindow.h:111
ChatView::closeView
virtual bool closeView(bool force=false)
Definition: chatview.cpp:345
KopeteChatWindow::closing
void closing(KopeteChatWindow *)
KopeteChatWindow::chatViewCount
int chatViewCount()
Returns the number of chat views attached to this window.
Definition: kopetechatwindow.h:93
MetaContactMap
QMap< Kopete::MetaContact *, KopeteChatWindow * > MetaContactMap
Definition: kopetechatwindow.cpp:92
QDockWidget
KopeteChatWindow::backgroundFile
KTemporaryFile * backgroundFile
Definition: kopetechatwindow.h:110
KopeteChatWindow::resizeEvent
virtual void resizeEvent(QResizeEvent *e)
Definition: kopetechatwindow.cpp:1349
ChatView::tabState
KopeteTabState tabState() const
Retrieves the tab state.
Definition: chatview.cpp:390
QDragMoveEvent
ChatView::dropEvent
virtual void dropEvent(QDropEvent *)
Definition: chatview.cpp:965
kopeteapplication.h
QAction::setIconText
void setIconText(const QString &text)
QAction::data
QVariant data() const
QAbstractItemView::setModel
virtual void setModel(QAbstractItemModel *model)
QLabel::setPixmap
void setPixmap(const QPixmap &)
KopeteChatWindow::detachChatView
void detachChatView(ChatView *chat)
Detach a chat view from this window.
Definition: kopetechatwindow.cpp:804
AccountMap
QMap< Kopete::Account *, KopeteChatWindow * > AccountMap
Definition: kopetechatwindow.cpp:90
kopetechatwindow.h
QSizePolicy
QAction::setIcon
void setIcon(const QIcon &icon)
QMap
manager
virtual Kopete::ChatSession * manager(Kopete::Contact::CanCreateFlags)
Definition: chatwindowconfig.cpp:94
QMenu::addAction
void addAction(QAction *action)
KopeteChatWindow::queryExit
virtual bool queryExit()
Definition: kopetechatwindow.cpp:1259
QList::removeAt
void removeAt(int i)
QDropEvent::pos
const QPoint & pos() const
QAction::shortcuts
QList< QKeySequence > shortcuts() const
KopeteEmoticonAction
Definition: kopeteemoticonaction.h:28
KopeteChatWindow::slotSmileyActivated
void slotSmileyActivated(const QString &)
Definition: kopetechatwindow.cpp:1209
KopeteChatWindow::updateBackground
void updateBackground(const QPixmap &pm)
Definition: kopetechatwindow.cpp:931
QDockWidget::setAllowedAreas
void setAllowedAreas(QFlags< Qt::DockWidgetArea > areas)
ChatView::Normal
Definition: chatview.h:70
QPoint
chatview.h
QListView::setWordWrap
void setWordWrap(bool on)
ChatView::editWidget
KTextEdit * editWidget()
Definition: chatview.cpp:187
QFrame::setLineWidth
void setLineWidth(int)
ChatView::Highlighted
Definition: chatview.h:70
QWidget::adjustSize
void adjustSize()
QTime
ChatView::setActive
void setActive(bool value)
Tells this view it is the active view.
Definition: chatview.cpp:873
QAbstractButton::setIcon
void setIcon(const QIcon &icon)
KopeteChatWindow::queryClose
virtual bool queryClose()
Reimplemented from KXmlGuiWindow - asks each ChatView in the window if it is ok to close the window...
Definition: kopetechatwindow.cpp:1225
KopeteChatWindow::changeEvent
virtual void changeEvent(QEvent *e)
Definition: kopetechatwindow.cpp:1197
QString::isNull
bool isNull() const
QList::indexOf
int indexOf(const T &value, int from) const
chatmemberslistview.h
QCloseEvent
QMenu::clear
void clear()
Kopete::Items::MetaContact
Definition: kopeteitembase.h:57
QMovie::setPaused
void setPaused(bool paused)
QTime::elapsed
int elapsed() const
chattexteditpart.h
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QPixmap::save
bool save(const QString &fileName, const char *format, int quality) const
Kopete::Items::Group
Definition: kopeteitembase.h:57
QEvent::ignore
void ignore()
QDockWidget::setFeatures
void setFeatures(QFlags< QDockWidget::DockWidgetFeature > features)
KXmlGuiWindow
QVariant::toInt
int toInt(bool *ok) const
ChatMembersListView
Definition: chatmemberslistview.h:36
QObject
QLabel::setMovie
void setMovie(QMovie *movie)
QDropEvent
QList::isEmpty
bool isEmpty() const
QObject::setObjectName
void setObjectName(const QString &name)
KopeteChatWindow::window
static KopeteChatWindow * window(Kopete::ChatSession *manager)
Find the appropriate window for a ChatView of the given protocol to dock into.
Definition: kopetechatwindow.cpp:105
QVBoxLayout
KopeteChatWindow::~KopeteChatWindow
~KopeteChatWindow()
Definition: kopetechatwindow.cpp:281
KopeteChatWindow::closeEvent
virtual void closeEvent(QCloseEvent *e)
Definition: kopetechatwindow.cpp:1275
QList::first
T & first()
QString
QList
QWidget::hide
void hide()
WindowList
QList< KopeteChatWindow * > WindowList
Definition: kopetechatwindow.cpp:93
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
QList::iterator
chatmessagepart.h
ChatView::Typing
Definition: chatview.h:70
KopeteApplication::isShuttingDown
bool isShuttingDown() const
Method to return whether or not we're shutting down or not at this point.
Definition: kopeteapplication.h:51
QPixmap
QAction::setData
void setData(const QVariant &userData)
QList::end
iterator end()
QToolButton
QKeyEvent::key
int key() const
QMenu
QEvent::accept
void accept()
QFrame
GroupMap
QMap< Kopete::Group *, KopeteChatWindow * > GroupMap
Definition: kopetechatwindow.cpp:91
QDockWidget::setWidget
void setWidget(QWidget *widget)
QKeyEvent
KActionMenu
QDockWidget::toggleViewAction
QAction * toggleViewAction() const
KopeteApplication
Definition: kopeteapplication.h:39
QList::takeFirst
T takeFirst()
QLatin1String
QKeySequence
ChatView::setMainWindow
void setMainWindow(KopeteChatWindow *parent)
Changes the pointer to the chat window.
Definition: chatview.cpp:417
KopeteChatWindow::activeView
ChatView * activeView()
Returns the chatview in the currently active tab, or the only chat view if chatViewCount() == 1...
Definition: kopetechatwindow.cpp:348
QAction
KAction
KopeteChatWindow::attachChatView
void attachChatView(ChatView *chat)
Attach an unattached chatview to this window.
Definition: kopetechatwindow.cpp:757
QList::last
T & last()
KopeteChatWindow::setActiveView
void setActiveView(QWidget *active)
Definition: kopetechatwindow.cpp:946
ChatView::Message
Definition: chatview.h:70
KopeteChatWindow::setStatus
void setStatus(const QString &)
Definition: kopetechatwindow.cpp:629
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QTime::start
void start()
QMap::Iterator
typedef Iterator
QWidget::setToolTip
void setToolTip(const QString &)
KopeteChatWindow
Definition: kopetechatwindow.h:61
QLabel
QMovie::state
MovieState state() const
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QLabel::setMargin
void setMargin(int)
QList::begin
iterator begin()
QDockWidget::setTitleBarWidget
void setTitleBarWidget(QWidget *widget)
kopeteemoticonaction.h
QIcon
QTimer::singleShot
singleShot
ChatView::Changed
Definition: chatview.h:70
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:29:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kopete/kopete

Skip menu "kopete/kopete"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdenetwork API Reference

Skip menu "kdenetwork API Reference"
  • kget
  • kopete
  •   kopete
  •   libkopete
  • krdc
  • krfb

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal