source: psi/trunk/libpsi/psiwidgets/psitabwidget.cpp@ 5

Last change on this file since 5 was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 13.9 KB
Line 
1/* Kevin Smith 2005
2 *insert new header here
3
4 */
5
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>
9*/
10
11#include <qapplication.h>
12#include <qstyle.h>
13
14#include "psitabwidget.h"
15#include "psitabbar.h"
16
17class KTabWidgetPrivate {
18public:
19 bool m_automaticResizeTabs;
20 int m_maxLength;
21 int m_minLength;
22 unsigned int m_CurrentMaxLength;
23
24 //holds the full names of the tab, otherwise all we
25 //know about is the shortened name
26 QStringList m_tabNames;
27
28 KTabWidgetPrivate() {
29 m_automaticResizeTabs = false;
30 m_maxLength = 30;
31 m_minLength = 3;
32 m_CurrentMaxLength = m_minLength;
33 }
34};
35
36KTabWidget::KTabWidget( QWidget *parent, const char *name, WFlags f )
37 : QTabWidget( parent, name, f )
38{
39 d = new KTabWidgetPrivate;
40 setTabBar( new KTabBar(this, "tabbar") );
41 setAcceptDrops( true );
42
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 )));
53#endif
54}
55
56KTabWidget::~KTabWidget()
57{
58 delete d;
59}
60
61void KTabWidget::setCloseIcon(const QIconSet& icon)
62{
63 static_cast<KTabBar*>(tabBar())->setCloseIcon(icon);
64}
65
66void KTabWidget::insertTab( QWidget *child, const QString &label, int index )
67{
68 QTabWidget::insertTab( child, label, index );
69}
70
71void KTabWidget::insertTab( QWidget *child, const QIconSet& iconset, const QString &label, int index )
72{
73 QTabWidget::insertTab( child, iconset, label, index );
74}
75
76void KTabWidget::insertTab( QWidget *child, QTab *tab, int index )
77{
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 );
83 }
84 else {
85 d->m_tabNames.insert( d->m_tabNames.at( index ), tab->text() );
86 resizeTabs( index );
87 }
88 }
89}
90
91void KTabWidget::setTabBarHidden( bool hide )
92{
93 QWidget *rightcorner = this->cornerWidget( TopRight );
94 QWidget *leftcorner = this->cornerWidget( TopLeft );
95
96 if ( hide ) {
97 if ( leftcorner ) leftcorner->hide();
98 if ( rightcorner ) rightcorner->hide();
99 tabBar()->hide();
100 } else {
101 tabBar()->show();
102 if ( leftcorner ) leftcorner->show();
103 if ( rightcorner ) rightcorner->show();
104 }
105}
106
107bool KTabWidget::isTabBarHidden() const
108{
109 return !( tabBar()->isVisible() );
110}
111
112void KTabWidget::setTabColor( QWidget *w, const QColor& color )
113{
114 QTab *t = tabBar()->tabAt( indexOf( w ) );
115 if (t) {
116 static_cast<KTabBar*>(tabBar())->setTabColor( t->identifier(), color );
117 }
118}
119
120QColor KTabWidget::tabColor( QWidget *w ) const
121{
122 QTab *t = tabBar()->tabAt( indexOf( w ) );
123 if (t) {
124 return static_cast<KTabBar*>(tabBar())->tabColor( t->identifier() );
125 } else {
126 return QColor();
127 }
128}
129
130void KTabWidget::setTabReorderingEnabled( bool on)
131{
132 static_cast<KTabBar*>(tabBar())->setTabReorderingEnabled( on );
133}
134
135bool KTabWidget::isTabReorderingEnabled() const
136{
137 return static_cast<KTabBar*>(tabBar())->isTabReorderingEnabled();
138}
139
140void KTabWidget::setTabCloseActivatePrevious( bool previous)
141{
142 static_cast<KTabBar*>(tabBar())->setTabCloseActivatePrevious( previous );
143}
144
145bool KTabWidget::tabCloseActivatePrevious() const
146{
147 return static_cast<KTabBar*>(tabBar())->tabCloseActivatePrevious();
148}
149
150unsigned int KTabWidget::tabBarWidthForMaxChars( uint maxLength )
151{
152 Q_UNUSED(maxLength);
153 int hframe, overlap;
154 hframe = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, tabBar() );
155 overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, tabBar() );
156
157 QFontMetrics fm = tabBar()->fontMetrics();
158 int x = 0;
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, ' ' );
162
163 QTab* tab = tabBar()->tabAt( i );
164 int lw = fm.width( newTitle );
165 int iw = 0;
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();
171 }
172 return x;
173}
174
175void KTabWidget::changeTab( QWidget *w, const QString &label )
176{
177 QTabWidget::changeTab( w, label );
178 if ( d->m_automaticResizeTabs ) {
179 int index = indexOf( w );
180 if ( index != -1 ) {
181 d->m_tabNames[ index ] = label;
182 resizeTabs( index );
183 }
184 }
185}
186
187void KTabWidget::changeTab( QWidget *w, const QIconSet &iconset, const QString &label )
188{
189 QTabWidget::changeTab( w, iconset, label );
190 if ( d->m_automaticResizeTabs ) {
191 int index = indexOf( w );
192 if ( index != -1 ) {
193 d->m_tabNames[ index ] = label;
194 resizeTabs( index );
195 }
196 }
197}
198
199QString KTabWidget::label( int index ) const
200{
201 if ( d->m_automaticResizeTabs ) {
202 if ( index >= 0 && index < count() )
203 return d->m_tabNames[ index ];
204 else
205 return QString::null;
206 }
207 else
208 return QTabWidget::label( index );
209}
210
211QString KTabWidget::tabLabel( QWidget * w ) const
212{
213 if ( d->m_automaticResizeTabs ) {
214 int index = indexOf( w );
215 if ( index == -1 )
216 return QString::null;
217 else
218 return d->m_tabNames[ index ];
219 }
220 else
221 return QTabWidget::tabLabel( w );
222}
223
224void KTabWidget::setTabLabel( QWidget *w, const QString &l )
225{
226 QTabWidget::setTabLabel( w, l );
227 if ( d->m_automaticResizeTabs ) {
228 int index = indexOf( w );
229 if ( index != -1 ) {
230 d->m_tabNames[ index ] = l;
231 resizeTabs( index );
232 }
233 }
234}
235
236void KTabWidget::resizeTabs( int changeTabIndex )
237{
238 uint newMaxLength;
239 if ( d->m_automaticResizeTabs ) {
240 // Calculate new max length
241 newMaxLength=d->m_maxLength;
242 uint lcw=0, rcw=0;
243
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 );
249
250 uint maxTabBarWidth = width() - lcw - rcw;
251
252 for ( ; newMaxLength > (uint)d->m_minLength; newMaxLength-- ) {
253 if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
254 break;
255 }
256 }
257 else
258 newMaxLength = 4711;
259
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 )
264 updateTab( i );
265 }
266 else if ( changeTabIndex != -1 )
267 updateTab( changeTabIndex );
268}
269
270void KTabWidget::updateTab( int index )
271{
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 );
276
277 //title = KStringHandler::rsqueeze( title, d->m_CurrentMaxLength ).leftJustify( d->m_minLength, ' ' );
278 title.replace( '&', "&&" );
279
280 if ( QTabWidget::label( index ) != title )
281 QTabWidget::setTabLabel( page( index ), title );
282}
283
284void KTabWidget::dragMoveEvent( QDragMoveEvent *e )
285{
286 if ( isEmptyTabbarSpace( e->pos() ) ) {
287 bool accept = false;
288 // The receivers of the testCanDecode() signal has to adjust
289 // 'accept' accordingly.
290 emit testCanDecode( e, accept);
291 e->accept( accept );
292 return;
293 }
294 e->accept( false );
295 QTabWidget::dragMoveEvent( e );
296}
297
298void KTabWidget::dropEvent( QDropEvent *e )
299{
300 if ( isEmptyTabbarSpace( e->pos() ) ) {
301 emit ( receivedDropEvent( e ) );
302 return;
303 }
304 QTabWidget::dropEvent( e );
305}
306
307#ifndef QT_NO_WHEELEVENT
308void KTabWidget::wheelEvent( QWheelEvent *e )
309{
310 if ( e->orientation() == Horizontal )
311 return;
312
313 if ( isEmptyTabbarSpace( e->pos() ) )
314 wheelDelta( e->delta() );
315 else
316 e->ignore();
317}
318
319void KTabWidget::wheelDelta( int delta )
320{
321 if ( count() < 2 )
322 return;
323
324 int page = currentPageIndex();
325 if ( delta < 0 )
326 page = (page + 1) % count();
327 else {
328 page--;
329 if ( page < 0 )
330 page = count() - 1;
331 }
332 setCurrentPage( page );
333}
334#endif
335
336void KTabWidget::mouseDoubleClickEvent( QMouseEvent *e )
337{
338 if( e->button() != LeftButton )
339 return;
340
341 if ( isEmptyTabbarSpace( e->pos() ) ) {
342 emit( mouseDoubleClick() );
343 return;
344 }
345 QTabWidget::mouseDoubleClickEvent( e );
346}
347
348void KTabWidget::mousePressEvent( QMouseEvent *e )
349{
350 if ( e->button() == RightButton ) {
351 if ( isEmptyTabbarSpace( e->pos() ) ) {
352 emit( contextMenu( mapToGlobal( e->pos() ) ) );
353 return;
354 }
355 } else if ( e->button() == MidButton ) {
356 if ( isEmptyTabbarSpace( e->pos() ) ) {
357 emit( mouseMiddleClick() );
358 return;
359 }
360 }
361 QTabWidget::mousePressEvent( e );
362}
363
364void KTabWidget::receivedDropEvent( int index, QDropEvent *e )
365{
366 emit( receivedDropEvent( page( index ), e ) );
367}
368
369void KTabWidget::initiateDrag( int index )
370{
371 emit( initiateDrag( page( index ) ) );
372}
373
374void KTabWidget::contextMenu( int index, const QPoint &p )
375{
376 emit( contextMenu( page( index ), p ) );
377}
378
379void KTabWidget::mouseDoubleClick( int index )
380{
381 emit( mouseDoubleClick( page( index ) ) );
382}
383
384void KTabWidget::mouseMiddleClick( int index )
385{
386 emit( mouseMiddleClick( page( index ) ) );
387}
388
389void KTabWidget::moveTab( int from, int to )
390{
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 );
398 blockSignals(true);
399 removePage( w );
400
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 );
408 else
409 d->m_tabNames.insert( d->m_tabNames.at( to ), QString::null );
410 }
411
412 w = page( to );
413 changeTab( w, tabiconset, tablabel );
414 setTabToolTip( w, tabtooltip );
415 setTabColor( w, color );
416 if ( current )
417 showPage( w );
418 setTabEnabled( w, enabled );
419 blockSignals(false);
420
421 emit ( movedTab( from, to ) );
422}
423
424void KTabWidget::removePage( QWidget * w ) {
425 if ( d->m_automaticResizeTabs ) {
426 int index = indexOf( w );
427 if ( index != -1 )
428 d->m_tabNames.remove( d->m_tabNames.at( index ) );
429 }
430 QTabWidget::removePage( w );
431 if ( d->m_automaticResizeTabs )
432 resizeTabs();
433}
434
435
436bool KTabWidget::isEmptyTabbarSpace( const QPoint &p ) const
437{
438 QPoint point( p );
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 );
442 if ( rightcorner ) {
443 if ( point.x()>=width()-rightcorner->width() )
444 return false;
445 }
446 QWidget *leftcorner = cornerWidget( TopLeft );
447 if ( leftcorner ) {
448 if ( point.x()<=leftcorner->width() )
449 return false;
450 point.setX( point.x()-size.height() );
451 }
452 if ( tabPosition()==Bottom )
453 point.setY( point.y()-( height()-size.height() ) );
454 QTab *tab = tabBar()->selectTab( point);
455 if( !tab )
456 return true;
457 }
458 return false;
459}
460
461void KTabWidget::setHoverCloseButton( bool button )
462{
463 static_cast<KTabBar*>(tabBar())->setHoverCloseButton( button );
464}
465
466bool KTabWidget::hoverCloseButton() const
467{
468 return static_cast<KTabBar*>(tabBar())->hoverCloseButton();
469}
470
471void KTabWidget::setHoverCloseButtonDelayed( bool delayed )
472{
473 static_cast<KTabBar*>(tabBar())->setHoverCloseButtonDelayed( delayed );
474}
475
476bool KTabWidget::hoverCloseButtonDelayed() const
477{
478 return static_cast<KTabBar*>(tabBar())->hoverCloseButtonDelayed();
479}
480
481void KTabWidget::setAutomaticResizeTabs( bool enabled )
482{
483 if ( d->m_automaticResizeTabs==enabled )
484 return;
485
486 d->m_automaticResizeTabs = enabled;
487 if ( enabled ) {
488 d->m_tabNames.clear();
489 for( int i = 0; i < count(); ++i )
490 d->m_tabNames.append( tabBar()->tabAt( i )->text() );
491 }
492 else
493 for( int i = 0; i < count(); ++i )
494 tabBar()->tabAt( i )->setText( d->m_tabNames[ i ] );
495 resizeTabs();
496}
497
498bool KTabWidget::automaticResizeTabs() const
499{
500 return d->m_automaticResizeTabs;
501}
502
503void KTabWidget::closeRequest( int index )
504{
505 emit( closeRequest( page( index ) ) );
506}
507
508void KTabWidget::resizeEvent( QResizeEvent *e )
509{
510 QTabWidget::resizeEvent( e );
511 resizeTabs();
512}
513
Note: See TracBrowser for help on using the repository browser.