24 #include <QtCore/QTextStream>
25 #include <QtCore/QTimer>
26 #include <QtGui/QDockWidget>
27 #include <QtGui/QFrame>
28 #include <QtGui/QLabel>
29 #include <QtGui/QLayout>
30 #include <QtGui/QMenu>
31 #include <QtGui/QPixmap>
32 #include <QtGui/QCloseEvent>
33 #include <QtGui/QVBoxLayout>
39 #include <kactioncollection.h>
46 #include <kiconloader.h>
48 #include <kwindowsystem.h>
49 #include <ktemporaryfile.h>
50 #include <kedittoolbar.h>
51 #include <kstatusbar.h>
52 #include <kpushbutton.h>
53 #include <ktabwidget.h>
55 #include <kstringhandler.h>
56 #include <ksqueezedtextlabel.h>
57 #include <kstandardshortcut.h>
58 #include <kglobalsettings.h>
59 #include <kcolorscheme.h>
63 #include <kstandardaction.h>
64 #include <ktoggleaction.h>
65 #include <kactionmenu.h>
66 #include <ktoolbarspaceraction.h>
72 #include "kopetebehaviorsettings.h"
75 #include "kopetegroup.h"
76 #include "kopetechatsession.h"
77 #include "kopetemetacontact.h"
78 #include "kopetepluginmanager.h"
79 #include "kopeteprotocol.h"
80 #include "kopetestdaction.h"
81 #include "kopeteviewmanager.h"
83 #include "chatsessionmemberslistmodel.h"
85 #include <qtoolbutton.h>
86 #include <kxmlguifactory.h>
89 typedef QMap<Kopete::Account*,KopeteChatWindow*>
AccountMap;
90 typedef QMap<Kopete::Group*,KopeteChatWindow*>
GroupMap;
94 using Kopete::ChatSessionMembersListModel;
106 bool windowCreated =
false;
116 Kopete::GroupList gList = metaContact->groups();
117 group = gList.first();
120 switch( Kopete::BehaviorSettings::self()->chatWindowGroupPolicy() )
123 case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByAccount:
124 if( accountMap.contains( manager->account() ) )
125 myWindow = accountMap[ manager->account() ];
127 windowCreated =
true;
131 case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByGroup:
132 if( group && groupMap.contains( group ) )
133 myWindow = groupMap[ group ];
135 windowCreated =
true;
139 case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupByMetaContact:
140 if( mcMap.contains( metaContact ) )
141 myWindow = mcMap[ metaContact ];
143 windowCreated =
true;
147 case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::GroupAll:
148 if( windows.isEmpty() )
149 windowCreated =
true;
157 WindowList::iterator it;
158 for ( it = windows.begin(); it != windows.end(); ++it )
160 if( (*it)->chatViewCount() > viewCount )
170 case Kopete::BehaviorSettings::EnumChatWindowGroupPolicy::OpenNewWindow:
172 windowCreated =
true;
180 if ( !accountMap.contains( manager->account() ) )
181 accountMap.insert( manager->account(), myWindow );
183 if ( !mcMap.contains( metaContact ) )
184 mcMap.insert( metaContact, myWindow );
186 if ( group && !groupMap.contains( group ) )
187 groupMap.insert( group, myWindow );
195 KopeteChatWindow::KopeteChatWindow( Kopete::ChatSession::Form form,
QWidget *parent )
199 QTime chrono;chrono.start();
207 m_participantsWidget =
new QDockWidget(i18n(
"Participants"),
this);
208 m_participantsWidget->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
209 m_participantsWidget->setFeatures(QDockWidget::DockWidgetClosable);
210 m_participantsWidget->setTitleBarWidget(0L);
211 m_participantsWidget->setObjectName(
"Participants");
213 ChatSessionMembersListModel *members_model =
new ChatSessionMembersListModel(
this);
215 connect(
this, SIGNAL(
chatSessionChanged(Kopete::ChatSession*)), members_model, SLOT(setChatSession(Kopete::ChatSession*)));
218 chatmembers->setModel(members_model);
219 chatmembers->setWordWrap(
true);
220 m_participantsWidget->setWidget(chatmembers);
223 addDockWidget(Qt::RightDockWidgetArea, m_participantsWidget);
226 vBox->setLineWidth( 0 );
227 vBox->setSpacing( 0 );
228 vBox->setFrameStyle( QFrame::NoFrame );
230 if ( initialForm == Kopete::ChatSession::Chatroom ) {
233 m_participantsWidget->hide();
236 setCentralWidget( vBox );
238 mainArea =
new QFrame( vBox );
239 mainArea->setLineWidth( 0 );
240 mainArea->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
241 mainLayout =
new QVBoxLayout( mainArea );
242 mainLayout->setContentsMargins(0, 4, 0, 0);
244 if ( Kopete::BehaviorSettings::self()->chatWindowShowSendButton() )
247 m_button_send =
new KPushButton( i18nc(
"@action:button",
"Send"), statusBar() );
248 m_button_send->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
249 m_button_send->setEnabled(
false );
250 m_button_send->setFont( statusBar()->font() );
251 m_button_send->setFixedHeight( statusBar()->sizeHint().height() );
252 connect( m_button_send, SIGNAL(clicked()),
this, SLOT(slotSendMessage()) );
253 statusBar()->addPermanentWidget( m_button_send, 0 );
258 m_status_text =
new KSqueezedTextLabel( i18nc(
"@info:status",
"Ready."), statusBar() );
259 m_status_text->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
260 m_status_text->setFont( statusBar()->font() );
261 m_status_text->setFixedHeight( statusBar()->sizeHint().height() );
262 statusBar()->addWidget( m_status_text, 1 );
264 windows.append(
this );
267 m_alwaysShowTabs = KGlobal::config()->group(
"ChatWindowSettings" ).
268 readEntry( QLatin1String(
"AlwaysShowTabs"),
false );
271 setupGUI( static_cast<StandardWindowOptions>(ToolBar | Keys | StatusBar | Save | Create) ,
"kopetechatwindow.rc" );
276 kDebug()<<
"TIME: "<<chrono.elapsed();
286 for( AccountMap::Iterator it = accountMap.begin(); it != accountMap.end(); )
288 if( it.value() == this )
289 it=accountMap.erase( it );
294 for( GroupMap::Iterator it = groupMap.begin(); it != groupMap.end(); )
296 if( it.value() == this )
297 it=groupMap.erase( it );
302 for( MetaContactMap::Iterator it = mcMap.begin(); it != mcMap.end(); )
304 if( it.value() == this )
305 it=mcMap.erase( it );
310 windows.removeAt( windows.indexOf(
this ) );
322 void KopeteChatWindow::windowListChanged()
325 for ( WindowList::iterator it = windows.begin(); it != windows.end(); ++it )
326 (*it)->checkDetachEnable();
329 void KopeteChatWindow::slotTabContextMenu(
QWidget *tab,
const QPoint &pos )
331 m_popupView =
static_cast<ChatView*
>( tab );
334 popup.addTitle( KStringHandler::rsqueeze( m_popupView->
caption() ) );
335 popup.addAction( actionContactMenu );
336 popup.addSeparator();
337 popup.addAction( actionTabPlacementMenu );
338 popup.addAction( tabDetach );
339 popup.addAction( actionDetachMenu );
340 popup.addAction( tabCloseAllOthers );
341 popup.addAction( tabClose );
352 void KopeteChatWindow::updateSendKeySequence()
354 if ( !sendMessage || !m_activeView )
357 m_activeView->editPart()->textEdit()->setSendKeySequenceList( sendMessage->shortcuts() );
360 void KopeteChatWindow::initActions(
void)
362 KActionCollection *coll = actionCollection();
364 createStandardStatusBarAction();
366 chatSend =
new KAction( KIcon(
"mail-send"), i18n(
"&Send Message" ), coll );
368 sendMessage = coll->addAction(
"chat_send", chatSend );
370 connect( sendMessage, SIGNAL(changed()), SLOT(updateSendKeySequence()) );
372 connect( chatSend, SIGNAL(triggered(
bool)), SLOT(slotSendMessage()) );
376 KShortcut chatSendShortcut( QKeySequence((
int)Qt::Key_Return), QKeySequence((
int)Qt::Key_Enter) );
377 chatSend->setShortcut( chatSendShortcut );
378 chatSend->setEnabled(
false );
380 chatSendFile =
new KAction( KIcon(
"mail-attachment"), i18n(
"Send File..." ), coll );
381 coll->addAction(
"chat_send_file", chatSendFile );
382 connect( chatSendFile, SIGNAL(triggered(
bool)), SLOT(slotSendFile()) );
383 chatSendFile->setEnabled(
false );
385 KStandardAction::save (
this, SLOT(slotChatSave()), coll );
386 KStandardAction::print (
this, SLOT(slotChatPrint()), coll );
387 KAction* quitAction = KStandardAction::quit (
this, SLOT(close()), coll );
388 quitAction->setText( i18n(
"Close All Chats") );
390 tabClose = KStandardAction::close (
this, SLOT(slotChatClosed()), coll );
391 coll->addAction(
"tabs_close", tabClose );
393 tabActive=
new KAction( i18n(
"&Activate Next Active Tab" ), coll );
394 coll->addAction(
"tabs_active", tabActive );
396 tabActive->setEnabled(
false );
397 connect( tabActive, SIGNAL(triggered(
bool)),
this, SLOT(slotNextActiveTab()) );
399 tabRight=
new KAction( i18n(
"&Activate Next Tab" ), coll );
400 coll->addAction(
"tabs_right", tabRight );
401 tabRight->setShortcut( KStandardShortcut::tabNext() );
402 tabRight->setEnabled(
false );
403 connect( tabRight, SIGNAL(triggered(
bool)),
this, SLOT(slotNextTab()) );
405 tabLeft=
new KAction( i18n(
"&Activate Previous Tab" ), coll );
406 coll->addAction(
"tabs_left", tabLeft );
407 tabLeft->setShortcut( KStandardShortcut::tabPrev() );
408 tabLeft->setEnabled(
false );
409 connect( tabLeft, SIGNAL(triggered(
bool)),
this, SLOT(slotPreviousTab()) );
413 nickComplete =
new KAction( i18n(
"Nic&k Completion" ), coll );
414 coll->addAction(
"nick_complete", nickComplete );
415 nickComplete->setShortcut( QKeySequence( Qt::Key_Tab ) );
417 tabDetach =
new KAction( KIcon(
"tab-detach"), i18n(
"&Detach Chat" ), coll );
418 coll->addAction(
"tabs_detach", tabDetach );
419 tabDetach->setEnabled(
false );
420 connect( tabDetach, SIGNAL(triggered(
bool)),
this, SLOT(slotDetachChat()));
422 tabCloseAllOthers =
new KAction( KIcon(
"tab-close"), i18n(
"Close &All But This Tab" ), coll );
423 coll->addAction(
"tabs_close_others", tabCloseAllOthers );
424 tabCloseAllOthers->setEnabled(
true );
425 connect( tabCloseAllOthers, SIGNAL(triggered(
bool)),
this, SLOT(slotCloseAllOtherTabs()));
427 actionDetachMenu =
new KActionMenu( KIcon(
"tab-detach"), i18n(
"&Move Tab to Window" ), coll );
428 coll->addAction(
"tabs_detachmove", actionDetachMenu );
429 actionDetachMenu->setDelayed(
false );
431 connect ( actionDetachMenu->menu(), SIGNAL(aboutToShow()),
this, SLOT(slotPrepareDetachMenu()) );
432 connect ( actionDetachMenu->menu(), SIGNAL(triggered(QAction*)),
this, SLOT(slotDetachChat(QAction*)) );
434 actionTabPlacementMenu =
new KActionMenu( i18n(
"&Tab Placement" ), coll );
435 coll->addAction(
"tabs_placement", actionTabPlacementMenu );
436 connect ( actionTabPlacementMenu->menu(), SIGNAL(aboutToShow()),
this, SLOT(slotPreparePlacementMenu()) );
437 connect ( actionTabPlacementMenu->menu(), SIGNAL(triggered(QAction*)),
this, SLOT(slotPlaceTabs(QAction*)) );
439 tabDetach->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B) );
441 KStandardAction::cut(
this, SLOT(slotCut()), coll);
442 KStandardAction::copy(
this, SLOT(slotCopy()), coll);
443 KStandardAction::paste(
this, SLOT(slotPaste()), coll);
447 historyUp =
new KAction( i18n(
"Previous History" ), coll );
448 coll->addAction(
"history_up", historyUp );
449 historyUp->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_Up) );
450 connect( historyUp, SIGNAL(triggered(
bool)),
this, SLOT(slotHistoryUp()) );
452 historyDown =
new KAction( i18n(
"Next History" ), coll );
453 coll->addAction(
"history_down", historyDown );
454 historyDown->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_Down) );
455 connect( historyDown, SIGNAL(triggered(
bool)),
this, SLOT(slotHistoryDown()) );
457 action = KStandardAction::prior(
this, SLOT(slotPageUp()), coll );
458 coll->addAction(
"scroll_up", action );
459 action = KStandardAction::next(
this, SLOT(slotPageDown()), coll );
460 coll->addAction(
"scroll_down", action );
462 KStandardAction::showMenubar( menuBar(), SLOT(setVisible(
bool)), coll );
464 toggleAutoSpellCheck =
new KToggleAction( i18n(
"Automatic Spell Checking" ), coll );
465 coll->addAction(
"enable_auto_spell_check", toggleAutoSpellCheck );
466 toggleAutoSpellCheck->setChecked(
true );
467 connect( toggleAutoSpellCheck, SIGNAL(triggered(
bool)),
this, SLOT(toggleAutoSpellChecking()) );
469 QAction *toggleParticipantsAction = m_participantsWidget->toggleViewAction( );
470 toggleParticipantsAction->setText( i18n(
"Show Participants" ) );
471 toggleParticipantsAction->setIconText(i18n(
"Participants" ));
472 toggleParticipantsAction->setIcon(KIcon(
"system-users" ) );
473 coll->addAction (
"show_participants_widget", toggleParticipantsAction );
476 coll->addAction(
"format_smiley", actionSmileyMenu );
477 actionSmileyMenu->setDelayed(
false );
478 connect(actionSmileyMenu, SIGNAL(activated(QString)),
this, SLOT(
slotSmileyActivated(QString)));
480 actionContactMenu =
new KActionMenu(i18n(
"Co&ntacts"), coll );
481 coll->addAction(
"contacts_menu", actionContactMenu );
482 actionContactMenu->setDelayed(
false );
483 connect ( actionContactMenu->menu(), SIGNAL(aboutToShow()),
this, SLOT(slotPrepareContactMenu()) );
485 KopeteStdAction::preferences( coll ,
"settings_prefs" );
487 KToolBarSpacerAction * spacer =
new KToolBarSpacerAction( coll );
488 coll->addAction(
"spacer", spacer );
491 normalIcon = QPixmap( BarIcon( QLatin1String(
"kopete" ) ) );
494 anim =
new QLabel( QString::null, 0L );
495 anim->setObjectName( QLatin1String(
"kde toolbar widget") );
497 anim->setPixmap( normalIcon );
499 animIcon = KIconLoader::global()->loadMovie( QLatin1String(
"newmessage" ), KIconLoader::Toolbar);
501 animIcon->setPaused(
true);
503 KAction *animAction =
new KAction( i18n(
"Toolbar Animation"), coll );
504 coll->addAction(
"toolbar_animation", animAction );
505 animAction->setDefaultWidget( anim );
526 void KopeteChatWindow::slotStopAnimation(
ChatView* view )
528 if( view == m_activeView )
530 anim->setPixmap( normalIcon );
531 if( animIcon && animIcon->state() == QMovie::Running )
532 animIcon->setPaused(
true );
536 void KopeteChatWindow::slotUpdateSendEnabled()
538 if ( !m_activeView )
return;
540 bool enabled = m_activeView->canSend();
541 chatSend->setEnabled( enabled );
543 m_button_send->setEnabled( enabled );
546 void KopeteChatWindow::updateChatSendFileAction()
551 chatSendFile->setEnabled( m_activeView->canSendFile() );
554 void KopeteChatWindow::toggleAutoSpellChecking()
559 bool currentSetting = m_activeView->editPart()->checkSpellingEnabled();
560 m_activeView->editPart()->setCheckSpellingEnabled( !currentSetting );
561 updateSpellCheckAction();
564 void KopeteChatWindow::updateSpellCheckAction()
569 bool currentSetting = m_activeView->editPart()->checkSpellingEnabled();
570 toggleAutoSpellCheck->setChecked( currentSetting );
573 void KopeteChatWindow::enableSpellCheckAction(
bool enable)
575 toggleAutoSpellCheck->setChecked( enable );
578 void KopeteChatWindow::updateActions()
580 updateSpellCheckAction();
581 updateChatSendFileAction();
584 void KopeteChatWindow::slotHistoryUp()
587 m_activeView->editPart()->historyUp();
590 void KopeteChatWindow::slotHistoryDown()
593 m_activeView->editPart()->historyDown();
596 void KopeteChatWindow::slotPageUp()
599 m_activeView->messagePart()->pageUp();
602 void KopeteChatWindow::slotPageDown()
605 m_activeView->messagePart()->pageDown();
608 void KopeteChatWindow::slotCut()
613 void KopeteChatWindow::slotCopy()
615 m_activeView->copy();
618 void KopeteChatWindow::slotPaste()
620 m_activeView->paste();
623 void KopeteChatWindow::slotResetFontAndColor()
625 m_activeView->resetFontAndColor();
630 m_status_text->setText(text);
633 void KopeteChatWindow::testCanDecode(
const QDragMoveEvent *event,
bool &accept)
635 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 )) {
642 void KopeteChatWindow::receivedDropEvent(
QWidget *w, QDropEvent *e )
644 m_tabBar->setCurrentWidget( w );
648 void KopeteChatWindow::createTabBar()
652 KConfigGroup cg( KGlobal::config(), QLatin1String(
"ChatWindowSettings") );
654 m_tabBar =
new KTabWidget( mainArea );
655 m_tabBar->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
656 m_tabBar->setTabsClosable(cg.readEntry( QLatin1String(
"HoverClose"),
true ));
657 m_tabBar->setMovable(
true);
658 m_tabBar->setAutomaticResizeTabs(
true);
659 connect( m_tabBar, SIGNAL(closeRequest(
QWidget*)),
this, SLOT(slotCloseChat(
QWidget*)) );
661 m_UpdateChatLabel = cg.readEntry( QLatin1String(
"ShowContactName"),
true );
663 QToolButton* m_rightWidget =
new QToolButton( m_tabBar );
664 connect( m_rightWidget, SIGNAL(clicked()),
this, SLOT(slotChatClosed()) );
665 m_rightWidget->setIcon( SmallIcon(
"tab-close" ) );
666 m_rightWidget->adjustSize();
667 m_rightWidget->setToolTip( i18nc(
"@info:tooltip",
"Close the current tab") );
668 m_tabBar->setCornerWidget( m_rightWidget, Qt::TopRightCorner );
670 mainLayout->addWidget( m_tabBar );
676 connect ( m_tabBar, SIGNAL(testCanDecode(
const QDragMoveEvent*,
bool&)),
this, SLOT(testCanDecode(
const QDragMoveEvent*,
bool&)) );
677 connect ( m_tabBar, SIGNAL(receivedDropEvent(
QWidget*,QDropEvent*)),
this, SLOT(receivedDropEvent(
QWidget*,QDropEvent*)) );
679 connect ( m_tabBar, SIGNAL(contextMenu(
QWidget*,QPoint)),
this, SLOT(slotTabContextMenu(
QWidget*,QPoint)) );
682 m_tabBar->setCurrentWidget( m_activeView );
686 int tabPosition = cg.readEntry( QLatin1String(
"Tab Placement") , 0 );
688 QAction action(
this);
689 action.setData(tabPosition);
690 slotPlaceTabs( &action );
694 void KopeteChatWindow::slotCloseChat(
QWidget *chatView )
696 static_cast<ChatView*
>( chatView )->closeView();
700 void KopeteChatWindow::addTab(
ChatView *view )
702 QList<Kopete::Contact*> chatMembers=view->msgManager()->members();
703 Kopete::Contact *c=0L;
704 foreach( Kopete::Contact *contact , chatMembers )
706 if(!c || c->onlineStatus() < contact->onlineStatus())
709 QIcon pluginIcon = c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c) :
710 KIcon( view->msgManager()->protocol()->pluginIcon() );
712 view->setParent( m_tabBar );
713 view->setWindowFlags( 0 );
714 view->move( QPoint() );
717 m_tabBar->addTab( view, pluginIcon,
"");
718 view->setVisible(view == m_activeView);
719 connect( view, SIGNAL(updateStatusIcon(
ChatView*)),
this, SLOT(slotUpdateCaptionIcons(
ChatView*)) );
721 if (m_UpdateChatLabel) {
722 connect( view, SIGNAL(captionChanged(
bool)),
this, SLOT(updateChatLabel()) );
728 void KopeteChatWindow::setPrimaryChatView(
ChatView *view )
732 view->setParent( mainArea );
733 view->setWindowFlags( 0 );
734 view->move( QPoint() );
737 mainLayout->addWidget( view );
741 void KopeteChatWindow::deleteTabBar()
746 disconnect ( m_tabBar, SIGNAL(contextMenu(
QWidget*,QPoint)),
this, SLOT(slotTabContextMenu(
QWidget*,QPoint)) );
751 m_tabBar->deleteLater();
761 setPrimaryChatView( newView );
772 newView->
editWidget()->installEventFilter(
this );
774 KCursor::setAutoHideCursor( newView->
editWidget(),
true, true );
775 connect( newView, SIGNAL(captionChanged(
bool)),
this, SLOT(slotSetCaption(
bool)) );
776 connect( newView, SIGNAL(messageSuccess(
ChatView*)),
this, SLOT(slotStopAnimation(
ChatView*)) );
777 connect( newView, SIGNAL(updateStatusIcon(
ChatView*)),
this, SLOT(slotUpdateCaptionIcons(
ChatView*)) );
779 if (m_UpdateChatLabel) {
780 connect( newView, SIGNAL(updateChatState(
ChatView*,
int)),
this, SLOT(updateChatState(
ChatView*,
int)) );
785 connect( newView, SIGNAL(autoSpellCheckEnabled(
ChatView*,
bool)),
786 this, SLOT(slotAutoSpellCheckEnabled(
ChatView*,
bool)) );
789 void KopeteChatWindow::checkDetachEnable()
792 tabCloseAllOthers->setEnabled( haveTabs );
793 tabDetach->setEnabled( haveTabs );
794 tabLeft->setEnabled( haveTabs );
795 tabRight->setEnabled( haveTabs );
796 tabActive->setEnabled( haveTabs );
797 actionTabPlacementMenu->setEnabled( m_tabBar != 0 );
799 bool otherWindows = (windows.count() > 1);
800 actionDetachMenu->setEnabled( otherWindows );
807 disconnect( view, SIGNAL(captionChanged(
bool)),
this, SLOT(slotSetCaption(
bool)) );
808 disconnect( view, SIGNAL(updateStatusIcon(
ChatView*)),
this, SLOT(slotUpdateCaptionIcons(
ChatView*)) );
809 disconnect( view, SIGNAL(updateChatState(
ChatView*,
int)),
this, SLOT(updateChatState(
ChatView*,
int)) );
810 view->
editWidget()->removeEventFilter(
this );
814 int curPage = m_tabBar->currentIndex();
815 QWidget *page = m_tabBar->currentWidget();
821 m_tabBar->setCurrentIndex( curPage - 1 );
823 m_tabBar->setCurrentIndex( curPage + 1 );
826 m_tabBar->removePage( view );
828 if( m_tabBar->currentWidget() )
829 setActiveView( static_cast<ChatView*>(m_tabBar->currentWidget()) );
832 if( m_activeView == view )
837 else if( !m_alwaysShowTabs &&
chatViewList.count() == 1)
843 void KopeteChatWindow::slotDetachChat( QAction *action )
849 detachedView = m_popupView;
851 detachedView = m_activeView;
858 guiFactory()->removeClient(detachedView->msgManager());
863 newWindow->setObjectName( QLatin1String(
"KopeteChatWindow") );
866 newWindow = windows.at( action->data().toInt() );
875 void KopeteChatWindow::slotCloseAllOtherTabs()
880 detachedView = m_popupView;
882 detachedView = m_activeView;
885 if (view != detachedView)
890 void KopeteChatWindow::slotPreviousTab()
892 int curPage = m_tabBar->currentIndex();
894 m_tabBar->setCurrentIndex( curPage - 1 );
896 m_tabBar->setCurrentIndex( m_tabBar->count() - 1 );
899 void KopeteChatWindow::slotNextTab()
901 int curPage = m_tabBar->currentIndex();
902 if( curPage == ( m_tabBar->count() - 1 ) )
903 m_tabBar->setCurrentIndex( 0 );
905 m_tabBar->setCurrentIndex( curPage + 1 );
908 void KopeteChatWindow::slotNextActiveTab()
910 int curPage = m_tabBar->currentIndex();
911 for(
int i=(curPage+1) % m_tabBar->count(); i!=curPage; i = (i+1) % m_tabBar->count())
916 m_tabBar->setCurrentIndex( i );
922 void KopeteChatWindow::slotSetCaption(
bool active )
924 if( active && m_activeView )
926 setCaption( m_activeView->caption(), false );
941 QTimer::singleShot( 100,
this, SLOT(slotEnableUpdateBg()) );
949 if( m_activeView == view )
954 disconnect( m_activeView->editWidget(), SIGNAL(checkSpellingChanged(
bool)),
this, SLOT(enableSpellCheckAction(
bool)) );
955 disconnect( m_activeView, SIGNAL(canSendChanged(
bool)),
this, SLOT(slotUpdateSendEnabled()) );
956 disconnect( m_activeView, SIGNAL(canAcceptFilesChanged()),
this, SLOT(updateChatSendFileAction()) );
957 guiFactory()->removeClient(m_activeView->msgManager());
958 m_activeView->saveChatSettings();
962 guiFactory()->addClient(view->msgManager());
966 m_activeView->setActive(
false );
976 connect( m_activeView->editWidget(), SIGNAL(checkSpellingChanged(
bool)),
this, SLOT(enableSpellCheckAction(
bool)) );
977 connect( m_activeView, SIGNAL(canSendChanged(
bool)),
this, SLOT(slotUpdateSendEnabled()) );
978 connect( m_activeView, SIGNAL(canAcceptFilesChanged()),
this, SLOT(updateChatSendFileAction()) );
981 m_activeView->setActive(
true );
984 slotUpdateCaptionIcons( m_activeView );
986 if ( m_activeView->sendInProgress() && animIcon )
988 anim->setMovie( animIcon );
989 animIcon->setPaused(
false);
993 anim->setPixmap( normalIcon );
995 animIcon->setPaused(
true);
1003 m_tabBar->setCurrentWidget( m_activeView );
1006 setCaption( m_activeView->caption() );
1007 setStatus( m_activeView->statusText() );
1008 m_activeView->setFocus();
1010 slotUpdateSendEnabled();
1011 m_activeView->loadChatSettings();
1012 updateSendKeySequence();
1017 void KopeteChatWindow::slotUpdateCaptionIcons(
ChatView *view )
1022 QList<Kopete::Contact*> chatMembers=view->msgManager()->members();
1023 Kopete::Contact *c=0L;
1024 foreach ( Kopete::Contact *contact , chatMembers )
1026 if(!c || c->onlineStatus() < contact->onlineStatus())
1030 if ( view == m_activeView )
1032 setWindowIcon( c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c ) :
1033 KIcon(view->msgManager()->protocol()->pluginIcon()));
1037 m_tabBar->setTabIcon(m_tabBar->indexOf( view ), c ? view->msgManager()->contactOnlineStatus( c ).iconFor( c ) :
1038 KIcon( view->msgManager()->protocol()->pluginIcon() ) );
1041 void KopeteChatWindow::slotChatClosed()
1046 m_activeView->closeView();
1049 void KopeteChatWindow::slotPrepareDetachMenu(
void)
1051 QMenu *detachMenu = actionDetachMenu->menu();
1052 detachMenu->clear();
1055 for (
int id = 0;
id < windows.count();
id++ )
1060 action = detachMenu->addAction( win->windowIcon(), win->windowTitle() );
1061 action->setData(
id );
1066 void KopeteChatWindow::slotSendMessage()
1068 if ( m_activeView && m_activeView->canSend() )
1072 anim->setMovie( animIcon );
1073 animIcon->setPaused(
false);
1075 m_activeView->sendMessage();
1079 void KopeteChatWindow::slotSendFile()
1082 m_activeView->sendFile();
1085 void KopeteChatWindow::slotPrepareContactMenu(
void)
1087 KMenu *contactsMenu = actionContactMenu->menu();
1088 contactsMenu->clear();
1093 m_them = m_popupView->msgManager()->members();
1095 m_them = m_activeView->msgManager()->members();
1100 uint contactCount = 0;
1102 foreach(Kopete::Contact *contact, m_them)
1104 KMenu *p = contact->popupMenu();
1105 connect ( actionContactMenu->menu(), SIGNAL(aboutToHide()),
1106 p, SLOT(deleteLater()) );
1108 p->setIcon( contact->onlineStatus().iconFor( contact ) );
1109 if( contact->metaContact() )
1110 p->setTitle( contact->metaContact()->displayName() );
1112 p->setTitle( contact->contactId() );
1114 contactsMenu->addMenu( p );
1117 if( ++contactCount == 15 && contact != m_them.last() )
1120 connect ( actionContactMenu->menu(), SIGNAL(aboutToHide()),
1121 moreMenu, SLOT(deleteLater()) );
1122 contactsMenu->addAction( moreMenu );
1123 contactsMenu = moreMenu->menu();
1129 void KopeteChatWindow::slotPreparePlacementMenu()
1131 QMenu *placementMenu = actionTabPlacementMenu->menu();
1132 placementMenu->clear();
1135 action = placementMenu->addAction( i18n(
"Top") );
1136 action->setData( 0 );
1138 action = placementMenu->addAction( i18n(
"Bottom") );
1139 action->setData( 1 );
1141 action = placementMenu->addAction( i18n(
"Left") );
1142 action->setData( 2 );
1144 action = placementMenu->addAction( i18n(
"Right") );
1145 action->setData( 3 );
1148 void KopeteChatWindow::slotPlaceTabs( QAction *action )
1150 int placement = action->data().toInt();
1156 case 1 : m_tabBar->setTabPosition( QTabWidget::South );
break;
1157 case 2 : m_tabBar->setTabPosition( QTabWidget::West );
break;
1158 case 3 : m_tabBar->setTabPosition( QTabWidget::East );
break;
1159 default: m_tabBar->setTabPosition( QTabWidget::North );
1165 void KopeteChatWindow::readOptions()
1169 applyMainWindowSettings( KGlobal::config()->group( ( initialForm == Kopete::ChatSession::Chatroom ? QLatin1String(
"KopeteChatWindowGroupMode" ) : QLatin1String(
"KopeteChatWindowIndividualMode" ) ) ) );
1173 void KopeteChatWindow::saveOptions()
1177 KConfigGroup kopeteChatWindowMainWinSettings( KGlobal::config(), ( initialForm == Kopete::ChatSession::Chatroom ? QLatin1String(
"KopeteChatWindowGroupMode" ) : QLatin1String(
"KopeteChatWindowIndividualMode" ) ) );
1180 saveMainWindowSettings( kopeteChatWindowMainWinSettings );
1182 KConfigGroup chatWindowSettings( KGlobal::config(), QLatin1String(
"ChatWindowSettings") );
1183 chatWindowSettings.writeEntry ( QLatin1String(
"Tab Placement"), (
int)m_tabBar->tabPosition() );
1184 chatWindowSettings.sync();
1186 kopeteChatWindowMainWinSettings.sync();
1189 void KopeteChatWindow::slotChatSave()
1192 if( isActiveWindow() && m_activeView )
1193 m_activeView->messagePart()->save();
1198 if( e->type() == QEvent::ActivationChange && isActiveWindow() && m_activeView )
1199 m_activeView->setActive(
true );
1202 void KopeteChatWindow::slotChatPrint()
1204 m_activeView->messagePart()->print();
1211 m_activeView->addText(
' ' + sm +
' ' );
1215 void KopeteChatWindow::slotAutoSpellCheckEnabled(
ChatView* view,
bool isEnabled )
1217 if ( view != m_activeView )
1220 toggleAutoSpellCheck->setChecked( isEnabled );
1221 m_activeView->editPart()->setCheckSpellingEnabled( isEnabled );
1227 QTime chrono;chrono.start();
1229 bool canClose =
true;
1234 setUpdatesEnabled(
false);
1247 kDebug() <<
"Closing view failed!";
1251 setUpdatesEnabled(
true);
1253 kDebug()<<
"TIME: "<<chrono.elapsed();
1261 if ( app->sessionSaving()
1264 || !Kopete::BehaviorSettings::self()->showSystemTray()
1267 Kopete::PluginManager::self()->shutdown();
1279 if ( Kopete::BehaviorSettings::self()->showSystemTray() && !app->
isShuttingDown() && !app->sessionSaving() ) {
1283 if ( settingsDirty() && autoSaveSettings() )
1284 saveAutoSaveSettings();
1295 KXmlGuiWindow::closeEvent( e );
1299 void KopeteChatWindow::updateChatState(
ChatView* cv,
int newState )
1305 KColorScheme scheme(QPalette::Active, KColorScheme::Window);
1309 m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::LinkText).color());
1312 m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::ActiveText).color());
1315 m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::NeutralText).color());
1318 m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::PositiveText).color());
1322 m_tabBar->setTabTextColor( m_tabBar->indexOf(cv), scheme.foreground(KColorScheme::NormalText).color() );
1328 void KopeteChatWindow::updateChatTooltip(
ChatView* cv )
1331 m_tabBar->setTabToolTip( m_tabBar->indexOf( cv ), QString::fromLatin1(
"<qt>%1</qt>").arg( cv->
caption() ) );
1334 void KopeteChatWindow::updateChatLabel()
1337 if ( !chat || !m_tabBar )
1342 m_tabBar->setTabText( m_tabBar->indexOf( chat ), chat->
caption() );
1343 if ( m_tabBar->count() < 2 || m_tabBar->currentWidget() == chat )
1344 setCaption( chat->
caption() );
1350 KXmlGuiWindow::resizeEvent( e );
1351 if ( m_activeView && m_activeView->messagePart() )
1352 m_activeView->messagePart()->keepScrolledDown();
1357 if ( m_activeView && obj == m_activeView->editWidget() &&
event->type() == QEvent::KeyPress ) {
1358 QKeyEvent *keyEvent =
static_cast<QKeyEvent*
>(event);
1359 if (nickComplete->shortcut().primary() == QKeySequence(keyEvent->key())) {
1360 m_activeView->nickComplete();
1364 return KXmlGuiWindow::eventFilter(obj, event);
1367 #include "kopetechatwindow.moc"
virtual bool eventFilter(QObject *obj, QEvent *event)
void chatSessionChanged(Kopete::ChatSession *newSession)
void setCaption(const QString &text, bool modified)
Sets the text to be displayed on tab label and window caption.
QString & caption() const
ChatViewList chatViewList
virtual bool closeView(bool force=false)
void closing(KopeteChatWindow *)
int chatViewCount()
Returns the number of chat views attached to this window.
QMap< Kopete::MetaContact *, KopeteChatWindow * > MetaContactMap
KTemporaryFile * backgroundFile
virtual void resizeEvent(QResizeEvent *e)
KopeteTabState tabState() const
Retrieves the tab state.
virtual void dropEvent(QDropEvent *)
void detachChatView(ChatView *chat)
Detach a chat view from this window.
QMap< Kopete::Account *, KopeteChatWindow * > AccountMap
virtual Kopete::ChatSession * manager(Kopete::Contact::CanCreateFlags)
void slotSmileyActivated(const QString &)
void updateBackground(const QPixmap &pm)
void setActive(bool value)
Tells this view it is the active view.
virtual bool queryClose()
Reimplemented from KXmlGuiWindow - asks each ChatView in the window if it is ok to close the window...
virtual void changeEvent(QEvent *e)
static KopeteChatWindow * window(Kopete::ChatSession *manager)
Find the appropriate window for a ChatView of the given protocol to dock into.
virtual void closeEvent(QCloseEvent *e)
QList< KopeteChatWindow * > WindowList
bool isShuttingDown() const
Method to return whether or not we're shutting down or not at this point.
QMap< Kopete::Group *, KopeteChatWindow * > GroupMap
void setMainWindow(KopeteChatWindow *parent)
Changes the pointer to the chat window.
ChatView * activeView()
Returns the chatview in the currently active tab, or the only chat view if chatViewCount() == 1...
void attachChatView(ChatView *chat)
Attach an unattached chatview to this window.
void setActiveView(QWidget *active)
void setStatus(const QString &)
QList< Contact * > ContactPtrList