2
*insert new header here
6
/* This file is heavily based upon part of the KDE libraries
7
Copyright (C) 2003 Stephan Binner <binner@kde.org>
8
Copyright (C) 2003 Zack Rusin <zack@kde.org>
11
#include <qapplication.h>
14
#include "psitabwidget.h"
15
#include "psitabbar.h"
17
class KTabWidgetPrivate {
19
bool m_automaticResizeTabs;
22
unsigned int m_CurrentMaxLength;
24
//holds the full names of the tab, otherwise all we
25
//know about is the shortened name
26
QStringList m_tabNames;
29
m_automaticResizeTabs = false;
32
m_CurrentMaxLength = m_minLength;
36
KTabWidget::KTabWidget( QWidget *parent, const char *name, WFlags f )
37
: QTabWidget( parent, name, f )
39
d = new KTabWidgetPrivate;
40
setTabBar( new KTabBar(this, "tabbar") );
41
setAcceptDrops( true );
43
connect(tabBar(), SIGNAL(contextMenu( int, const QPoint & )), SLOT(contextMenu( int, const QPoint & )));
44
connect(tabBar(), SIGNAL(mouseDoubleClick( int )), SLOT(mouseDoubleClick( int )));
45
connect(tabBar(), SIGNAL(mouseMiddleClick( int )), SLOT(mouseMiddleClick( int )));
46
connect(tabBar(), SIGNAL(initiateDrag( int )), SLOT(initiateDrag( int )));
47
connect(tabBar(), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )));
48
connect(tabBar(), SIGNAL(receivedDropEvent( int, QDropEvent * )), SLOT(receivedDropEvent( int, QDropEvent * )));
49
connect(tabBar(), SIGNAL(moveTab( int, int )), SLOT(moveTab( int, int )));
50
connect(tabBar(), SIGNAL(closeRequest( int )), SLOT(closeRequest( int )));
51
#ifndef QT_NO_WHEELEVENT
52
connect(tabBar(), SIGNAL(wheelDelta( int )), SLOT(wheelDelta( int )));
56
KTabWidget::~KTabWidget()
61
void KTabWidget::setCloseIcon(const QIconSet& icon)
63
static_cast<KTabBar*>(tabBar())->setCloseIcon(icon);
66
void KTabWidget::insertTab( QWidget *child, const QString &label, int index )
68
QTabWidget::insertTab( child, label, index );
71
void KTabWidget::insertTab( QWidget *child, const QIconSet& iconset, const QString &label, int index )
73
QTabWidget::insertTab( child, iconset, label, index );
76
void KTabWidget::insertTab( QWidget *child, QTab *tab, int index )
78
QTabWidget::insertTab( child, tab, index);
79
if ( d->m_automaticResizeTabs ) {
80
if ( index < 0 || index >= count() ) {
81
d->m_tabNames.append( tab->text() );
82
resizeTabs( d->m_tabNames.count()-1 );
85
d->m_tabNames.insert( d->m_tabNames.at( index ), tab->text() );
91
void KTabWidget::setTabBarHidden( bool hide )
93
QWidget *rightcorner = this->cornerWidget( TopRight );
94
QWidget *leftcorner = this->cornerWidget( TopLeft );
97
if ( leftcorner ) leftcorner->hide();
98
if ( rightcorner ) rightcorner->hide();
102
if ( leftcorner ) leftcorner->show();
103
if ( rightcorner ) rightcorner->show();
107
bool KTabWidget::isTabBarHidden() const
109
return !( tabBar()->isVisible() );
112
void KTabWidget::setTabColor( QWidget *w, const QColor& color )
114
QTab *t = tabBar()->tabAt( indexOf( w ) );
116
static_cast<KTabBar*>(tabBar())->setTabColor( t->identifier(), color );
120
QColor KTabWidget::tabColor( QWidget *w ) const
122
QTab *t = tabBar()->tabAt( indexOf( w ) );
124
return static_cast<KTabBar*>(tabBar())->tabColor( t->identifier() );
130
void KTabWidget::setTabReorderingEnabled( bool on)
132
static_cast<KTabBar*>(tabBar())->setTabReorderingEnabled( on );
135
bool KTabWidget::isTabReorderingEnabled() const
137
return static_cast<KTabBar*>(tabBar())->isTabReorderingEnabled();
140
void KTabWidget::setTabCloseActivatePrevious( bool previous)
142
static_cast<KTabBar*>(tabBar())->setTabCloseActivatePrevious( previous );
145
bool KTabWidget::tabCloseActivatePrevious() const
147
return static_cast<KTabBar*>(tabBar())->tabCloseActivatePrevious();
150
unsigned int KTabWidget::tabBarWidthForMaxChars( uint maxLength )
154
hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, tabBar() );
155
overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, tabBar() );
157
QFontMetrics fm = tabBar()->fontMetrics();
159
for( int i=0; i < count(); ++i ) {
160
QString newTitle = d->m_tabNames[ i ];
161
//newTitle = KStringHandler::rsqueeze( newTitle, maxLength ).leftJustify( d->m_minLength, ' ' );
163
QTab* tab = tabBar()->tabAt( i );
164
int lw = fm.width( newTitle );
166
if ( tab->iconSet() )
167
iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;
168
x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this,
169
QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ),
170
QStyleOption( tab ) ) ).width();
175
void KTabWidget::changeTab( QWidget *w, const QString &label )
177
QTabWidget::changeTab( w, label );
178
if ( d->m_automaticResizeTabs ) {
179
int index = indexOf( w );
181
d->m_tabNames[ index ] = label;
187
void KTabWidget::changeTab( QWidget *w, const QIconSet &iconset, const QString &label )
189
QTabWidget::changeTab( w, iconset, label );
190
if ( d->m_automaticResizeTabs ) {
191
int index = indexOf( w );
193
d->m_tabNames[ index ] = label;
199
QString KTabWidget::label( int index ) const
201
if ( d->m_automaticResizeTabs ) {
202
if ( index >= 0 && index < count() )
203
return d->m_tabNames[ index ];
205
return QString::null;
208
return QTabWidget::label( index );
211
QString KTabWidget::tabLabel( QWidget * w ) const
213
if ( d->m_automaticResizeTabs ) {
214
int index = indexOf( w );
216
return QString::null;
218
return d->m_tabNames[ index ];
221
return QTabWidget::tabLabel( w );
224
void KTabWidget::setTabLabel( QWidget *w, const QString &l )
226
QTabWidget::setTabLabel( w, l );
227
if ( d->m_automaticResizeTabs ) {
228
int index = indexOf( w );
230
d->m_tabNames[ index ] = l;
236
void KTabWidget::resizeTabs( int changeTabIndex )
239
if ( d->m_automaticResizeTabs ) {
240
// Calculate new max length
241
newMaxLength=d->m_maxLength;
244
int tabBarHeight = tabBar()->sizeHint().height();
245
if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
246
lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
247
if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
248
rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
250
uint maxTabBarWidth = width() - lcw - rcw;
252
for ( ; newMaxLength > (uint)d->m_minLength; newMaxLength-- ) {
253
if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
260
// Update hinted or all tabs
261
if ( d->m_CurrentMaxLength != newMaxLength ) {
262
d->m_CurrentMaxLength = newMaxLength;
263
for( int i = 0; i < count(); ++i )
266
else if ( changeTabIndex != -1 )
267
updateTab( changeTabIndex );
270
void KTabWidget::updateTab( int index )
272
QString title = d->m_automaticResizeTabs ? d->m_tabNames[ index ] : QTabWidget::label( index );
273
removeTabToolTip( page( index ) );
274
if ( title.length() > d->m_CurrentMaxLength )
275
setTabToolTip( page( index ), title );
277
//title = KStringHandler::rsqueeze( title, d->m_CurrentMaxLength ).leftJustify( d->m_minLength, ' ' );
278
title.replace( '&', "&&" );
280
if ( QTabWidget::label( index ) != title )
281
QTabWidget::setTabLabel( page( index ), title );
284
void KTabWidget::dragMoveEvent( QDragMoveEvent *e )
286
if ( isEmptyTabbarSpace( e->pos() ) ) {
288
// The receivers of the testCanDecode() signal has to adjust
289
// 'accept' accordingly.
290
emit testCanDecode( e, accept);
295
QTabWidget::dragMoveEvent( e );
298
void KTabWidget::dropEvent( QDropEvent *e )
300
if ( isEmptyTabbarSpace( e->pos() ) ) {
301
emit ( receivedDropEvent( e ) );
304
QTabWidget::dropEvent( e );
307
#ifndef QT_NO_WHEELEVENT
308
void KTabWidget::wheelEvent( QWheelEvent *e )
310
if ( e->orientation() == Horizontal )
313
if ( isEmptyTabbarSpace( e->pos() ) )
314
wheelDelta( e->delta() );
319
void KTabWidget::wheelDelta( int delta )
324
int page = currentPageIndex();
326
page = (page + 1) % count();
332
setCurrentPage( page );
336
void KTabWidget::mouseDoubleClickEvent( QMouseEvent *e )
338
if( e->button() != LeftButton )
341
if ( isEmptyTabbarSpace( e->pos() ) ) {
342
emit( mouseDoubleClick() );
345
QTabWidget::mouseDoubleClickEvent( e );
348
void KTabWidget::mousePressEvent( QMouseEvent *e )
350
if ( e->button() == RightButton ) {
351
if ( isEmptyTabbarSpace( e->pos() ) ) {
352
emit( contextMenu( mapToGlobal( e->pos() ) ) );
355
} else if ( e->button() == MidButton ) {
356
if ( isEmptyTabbarSpace( e->pos() ) ) {
357
emit( mouseMiddleClick() );
361
QTabWidget::mousePressEvent( e );
364
void KTabWidget::receivedDropEvent( int index, QDropEvent *e )
366
emit( receivedDropEvent( page( index ), e ) );
369
void KTabWidget::initiateDrag( int index )
371
emit( initiateDrag( page( index ) ) );
374
void KTabWidget::contextMenu( int index, const QPoint &p )
376
emit( contextMenu( page( index ), p ) );
379
void KTabWidget::mouseDoubleClick( int index )
381
emit( mouseDoubleClick( page( index ) ) );
384
void KTabWidget::mouseMiddleClick( int index )
386
emit( mouseMiddleClick( page( index ) ) );
389
void KTabWidget::moveTab( int from, int to )
391
QString tablabel = label( from );
392
QWidget *w = page( from );
393
QColor color = tabColor( w );
394
QIconSet tabiconset = tabIconSet( w );
395
QString tabtooltip = tabToolTip( w );
396
bool current = ( w == currentPage() );
397
bool enabled = isTabEnabled( w );
401
// Work-around kmdi brain damage which calls showPage() in insertTab()
402
QTab * t = new QTab();
403
t->setText(tablabel);
404
QTabWidget::insertTab( w, t, to );
405
if ( d->m_automaticResizeTabs ) {
406
if ( to < 0 || to >= count() )
407
d->m_tabNames.append( QString::null );
409
d->m_tabNames.insert( d->m_tabNames.at( to ), QString::null );
413
changeTab( w, tabiconset, tablabel );
414
setTabToolTip( w, tabtooltip );
415
setTabColor( w, color );
418
setTabEnabled( w, enabled );
421
emit ( movedTab( from, to ) );
424
void KTabWidget::removePage( QWidget * w ) {
425
if ( d->m_automaticResizeTabs ) {
426
int index = indexOf( w );
428
d->m_tabNames.remove( d->m_tabNames.at( index ) );
430
QTabWidget::removePage( w );
431
if ( d->m_automaticResizeTabs )
436
bool KTabWidget::isEmptyTabbarSpace( const QPoint &p ) const
439
QSize size( tabBar()->sizeHint() );
440
if ( ( tabPosition()==Top && point.y()< size.height() ) || ( tabPosition()==Bottom && point.y()>(height()-size.height() ) ) ) {
441
QWidget *rightcorner = cornerWidget( TopRight );
443
if ( point.x()>=width()-rightcorner->width() )
446
QWidget *leftcorner = cornerWidget( TopLeft );
448
if ( point.x()<=leftcorner->width() )
450
point.setX( point.x()-size.height() );
452
if ( tabPosition()==Bottom )
453
point.setY( point.y()-( height()-size.height() ) );
454
QTab *tab = tabBar()->selectTab( point);
461
void KTabWidget::setHoverCloseButton( bool button )
463
static_cast<KTabBar*>(tabBar())->setHoverCloseButton( button );
466
bool KTabWidget::hoverCloseButton() const
468
return static_cast<KTabBar*>(tabBar())->hoverCloseButton();
471
void KTabWidget::setHoverCloseButtonDelayed( bool delayed )
473
static_cast<KTabBar*>(tabBar())->setHoverCloseButtonDelayed( delayed );
476
bool KTabWidget::hoverCloseButtonDelayed() const
478
return static_cast<KTabBar*>(tabBar())->hoverCloseButtonDelayed();
481
void KTabWidget::setAutomaticResizeTabs( bool enabled )
483
if ( d->m_automaticResizeTabs==enabled )
486
d->m_automaticResizeTabs = enabled;
488
d->m_tabNames.clear();
489
for( int i = 0; i < count(); ++i )
490
d->m_tabNames.append( tabBar()->tabAt( i )->text() );
493
for( int i = 0; i < count(); ++i )
494
tabBar()->tabAt( i )->setText( d->m_tabNames[ i ] );
498
bool KTabWidget::automaticResizeTabs() const
500
return d->m_automaticResizeTabs;
503
void KTabWidget::closeRequest( int index )
505
emit( closeRequest( page( index ) ) );
508
void KTabWidget::resizeEvent( QResizeEvent *e )
510
QTabWidget::resizeEvent( e );