2
* tabdlg.cpp - dialog for handling tabbed chats
3
* Copyright (C) 2005 Kevin Smith
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#include "iconwidget.h"
29
#include <qdragobject.h>
30
#include "psitabwidget.h"
36
//----------------------------------------------------------------------------
38
//----------------------------------------------------------------------------
39
TabDlg::TabDlg(PsiCon *psiCon)
43
//this->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
45
tabMenu = new QPopupMenu( this );
46
connect( tabMenu, SIGNAL( aboutToShow() ), SLOT( buildTabMenu() ) );
48
tabs = new KTabWidget (this);
50
closeCross = new QPushButton(this);
51
//closeCross->setText("x");
52
closeCross->setIconSet(IconsetFactory::icon("psi/closetab").iconSet());
54
if (option.usePerTabCloseButton)
55
tabs->setHoverCloseButton(true);
58
tabs->setHoverCloseButton(false);
59
tabs->setCornerWidget( closeCross );
63
tabs->setHoverCloseButtonDelayed(false); //people may want this enabled, but it's currently horribly broken.
64
tabs->setTabReorderingEnabled(true);
65
tabs->setCloseIcon(IconsetFactory::icon("psi/closetab").iconSet());
66
connect (tabs, SIGNAL( mouseDoubleClick( QWidget* ) ), SLOT( detachChat( QWidget* ) ) );
67
connect (tabs, SIGNAL( testCanDecode(const QDragMoveEvent*, bool&) ), SLOT( tabTestCanDecode(const QDragMoveEvent*, bool&) ) );
68
connect (tabs, SIGNAL( receivedDropEvent( QDropEvent* ) ), SLOT( tabReceivedDropEvent( QDropEvent* ) ) );
69
connect (tabs, SIGNAL( receivedDropEvent( QWidget*, QDropEvent* ) ), SLOT( tabReceivedDropEvent( QWidget*, QDropEvent* ) ) );
70
connect (tabs, SIGNAL( initiateDrag( QWidget* ) ), SLOT( startDrag( QWidget* ) ) );
71
connect (tabs, SIGNAL( closeRequest( QWidget* ) ), SLOT( closeChat( QWidget* ) ) );
74
QVBoxLayout *vert1 = new QVBoxLayout( this, 1);
75
vert1->addWidget(tabs);
76
chats.setAutoDelete( FALSE );
79
connect( closeCross, SIGNAL( clicked() ), SLOT( closeChat() ) );
80
connect( tabs, SIGNAL( currentChanged( QWidget* ) ), SLOT( tabSelected( QWidget* ) ) );
89
resize(option.sizeTabDlg);
97
void TabDlg::resizeEvent(QResizeEvent *e)
100
option.sizeTabDlg = e->size();
103
void TabDlg::buildTabMenu()
106
tabMenu->insertItem( tr("Detach Current Tab"), this, SLOT( detachChat() ) );
107
tabMenu->insertItem( tr("Close Current Tab"), this, SLOT( closeChat() ) );
109
QPopupMenu* sendTo = new QPopupMenu(tabMenu);
110
for (uint i = 0; i < psi->getTabSets()->count(); ++i)
112
TabDlg* tabSet= psi->getTabSets()->at(i);
113
sendTo->insertItem( tabSet->getName(), this, SLOT( sendChatTo( tabSet ) ) );
115
tabMenu->insertItem( tr("Sent Current Tab to"), sendTo);
118
void TabDlg::sendChatTo(QWidget* chatw, TabDlg* otherTabs)
122
ChatDlg* chat = (ChatDlg*)chatw;
123
closeChat(chat, false);
124
otherTabs->addChat(chat);
127
void TabDlg::setLooks()
129
//set the widget icon
131
setIcon(IconsetFactory::icon("psi/start-chat"));
133
tabs->setTabPosition(QTabWidget::Top);
134
if (option.putTabsAtBottom)
135
tabs->setTabPosition(QTabWidget::Bottom);
137
#if QT_VERSION >= 0x030300
138
setWindowOpacity(double(option.chatOpacity)/100);
142
QString TabDlg::getName()
144
return ((ChatDlg*)(tabs->currentPage()))->getDisplayNick();
147
void TabDlg::tabSelected(QWidget* chat)
149
((ChatDlg*)chat)->activated(); //is this still necessary?
153
bool TabDlg::managesChat(ChatDlg* chat)
155
if ( chats.contains(chat) )
160
bool TabDlg::chatOnTop(ChatDlg* chat)
162
if ( tabs->currentPage() == chat )
167
void TabDlg::addChat(ChatDlg* chat)
170
tabs->addTab(chat, chat->getDisplayNick());
171
tabs->setTabIconSet(chat, IconsetFactory::icon("psi/start-chat"));
173
tabs->showPage(chat);
174
connect ( chat, SIGNAL( captionChanged( ChatDlg*) ), SLOT( updateTab( ChatDlg* ) ) );
175
connect ( chat, SIGNAL( contactIsComposing(ChatDlg*, bool) ), SLOT( setTabComposing( ChatDlg*, bool) ) );
176
connect ( chat, SIGNAL( unreadMessageUpdate(ChatDlg*, int) ), SLOT( setTabHasMessages(ChatDlg*, int) ) );
182
void TabDlg::detachChat()
184
detachChat(tabs->currentPage());
187
void TabDlg::detachChat(QWidget* chat)
189
//don't detach singleton chats, fix for flyspray #477
190
if (tabs->count()==1)
193
TabDlg *newTab = psi->newTabs();
194
sendChatTo(chat, newTab);
197
void TabDlg::closeChat()
199
ChatDlg* chat = (ChatDlg*)(tabs->currentPage());
203
void TabDlg::closeChat(ChatDlg* chat, bool doclose=true)
206
disconnect ( chat, SIGNAL( captionChanged( ChatDlg*) ), this, SLOT( updateTab( ChatDlg* ) ) );
207
disconnect ( chat, SIGNAL( contactIsComposing(ChatDlg*, bool) ), this, SLOT( setTabComposing( ChatDlg*, bool) ) );
208
disconnect ( chat, SIGNAL( unreadMessageUpdate(ChatDlg*, int) ), this, SLOT( setTabHasMessages(ChatDlg*, int) ) );
209
tabs->removePage(chat);
210
tabIsComposing.erase(chat);
211
tabHasMessages.erase(chat);
213
chat->reparent(0,QPoint());
221
void TabDlg::closeChat(QWidget* chat)
223
closeChat((ChatDlg*)chat);
226
void TabDlg::selectTab(ChatDlg* chat)
228
tabs->showPage(chat);
231
void TabDlg::checkHasChats()
238
void TabDlg::windowActivationChange(bool oldstate)
240
QWidget::windowActivationChange(oldstate);
242
// if we're bringing it to the front, get rid of the '*' if necessary
243
if( isActiveWindow() ) {
248
void TabDlg::activated()
254
void TabDlg::updateCaption()
258
for ( uint i=0; i<tabHasMessages.count(); ++i)
260
pending+=tabHasMessages.values()[i];
265
cap += QString("[%1] ").arg(pending);
272
void TabDlg::closeEvent(QCloseEvent* closeEvent)
274
Q_UNUSED(closeEvent);
275
int count=tabs->count();
276
for (int i=0;i<count;++i) {
281
void TabDlg::closeMe()
284
//we do not delete it here, let the PsiCon do that, they create, they destroy.
287
ChatDlg* TabDlg::getChatPointer(QString fullJid)
289
for (int i=0; i < tabs->count() ; i++)
291
if (((ChatDlg*)tabs->page(i))->jid().full()==fullJid)
293
return (ChatDlg*)(tabs->page(i));
299
void TabDlg::updateTab( ChatDlg* chat)
301
QString label, prefix;
302
int num=tabHasMessages[chat];
313
prefix=QString("[%1] ").arg(num);
316
label=prefix+chat->getDisplayNick();
317
tabs->setTabLabel( chat, label );
318
//now set text colour based upon whether there are new messages/composing etc
319
if (tabIsComposing[chat])
320
tabs->setTabColor( chat, Qt::darkGreen );
321
else if (tabHasMessages[chat])
323
tabs->setTabColor( chat, Qt::red );
327
tabs->setTabColor( chat, Qt::black );
331
void TabDlg::setTabComposing(ChatDlg* chat, bool composing)
333
tabIsComposing[chat]=composing;
337
void TabDlg::setTabHasMessages(ChatDlg* chat, int messages)
339
tabHasMessages[chat]=messages;
343
void TabDlg::nextTab()
345
int page = tabs->currentPageIndex()+1;
346
if ( page >= tabs->count() )
348
tabs->setCurrentPage( page );
351
void TabDlg::previousTab()
353
int page = tabs->currentPageIndex()-1;
355
page = tabs->count() - 1;
356
tabs->setCurrentPage( page );
359
void TabDlg::tabTestCanDecode(const QDragMoveEvent* e, bool &b){
362
if ( QTextDrag::canDecode(e) && QTextDrag::decode(e, jid, type) && type=="psichatwindow" )
372
void TabDlg::tabReceivedDropEvent(QDropEvent* e){
376
if ( QTextDrag::decode(e, jid, type) && type=="psichatwindow" ) {
377
chat=psi->getChatInTabs(jid);
380
TabDlg *dlg=psi->getManagingTabs(chat);
381
dlg->sendChatTo(chat, this);
386
void TabDlg::tabReceivedDropEvent(QWidget* w, QDropEvent* e){
388
tabReceivedDropEvent(e);
392
void TabDlg::startDrag(QWidget* w)
394
QDragObject *d = new QTextDrag( ((ChatDlg*)w)->jid().full(), this );
395
((QTextDrag*)d)->setSubtype("psichatwindow");
400
void TabDlg::keyPressEvent(QKeyEvent *e)
402
if (e->key() == Key_Escape)
406
else if ( e->key() == Key_W && (e->state() & ControlButton) )
410
else if ( e->key() == Key_PageUp && (e->state() & ControlButton) )
414
else if ( e->key() == Key_PageDown && (e->state() & ControlButton) )