24 #include <QtGui/QApplication>
25 #include <QtGui/QDragMoveEvent>
26 #include <QtGui/QDropEvent>
27 #include <QtGui/QMouseEvent>
28 #include <QtGui/QStyle>
29 #include <QtGui/QStyleOption>
30 #include <QtGui/QTextDocument>
31 #include <QtGui/QWheelEvent>
32 #include <QtCore/QList>
43 class KTabWidget::Private
53 : m_resizeSuspend(ResizeEnabled),
55 m_automaticResizeTabs( false ),
56 m_tabBarHidden( false )
60 m_maxLength = cg.readEntry(
"MaximumTabLength", 30);
61 m_minLength = cg.readEntry(
"MinimumTabLength", 3);
62 Q_ASSERT(m_maxLength >= m_minLength);
63 m_currentTabLength = m_minLength;
67 bool m_automaticResizeTabs;
71 int m_currentTabLength;
77 bool isEmptyTabbarSpace(
const QPoint & )
const;
78 void resizeTabs(
int changedTabIndex = -1 );
79 void updateTab(
int index );
82 void slotTabMoved(
int from,
int to );
85 bool KTabWidget::Private::isEmptyTabbarSpace(
const QPoint &point )
const
87 if (m_parent->count() == 0) {
90 if (m_parent->tabBar()->isHidden()) {
93 QSize size( m_parent->tabBar()->sizeHint() );
94 if ( ( m_parent->tabPosition() == QTabWidget::North && point.y() < size.height() ) ||
95 ( m_parent->tabPosition() == QTabWidget::South && point.y() > (m_parent->height() - size.height() ) ) ) {
97 QWidget *rightcorner = m_parent->cornerWidget( Qt::TopRightCorner );
98 if ( rightcorner && rightcorner->isVisible() ) {
99 if ( point.x() >= m_parent->width()-rightcorner->width() )
103 QWidget *leftcorner = m_parent->cornerWidget( Qt::TopLeftCorner );
104 if ( leftcorner && leftcorner->isVisible() ) {
105 if ( point.x() <= leftcorner->width() )
109 for (
int i = 0; i < m_parent->count(); ++i )
110 if ( m_parent->tabBar()->tabRect( i ).contains( m_parent->tabBar()->mapFromParent( point ) ) )
123 m_resizeSuspend = ResizeDisabled;
130 m_tabNames.removeAt( index );
132 m_parent->QTabWidget::removeTab( index );
134 const bool doResize = (m_resizeSuspend == ResizeLater) || m_automaticResizeTabs;
135 m_resizeSuspend = ResizeEnabled;
142 void KTabWidget::Private::resizeTabs(
int changeTabIndex )
144 if (m_resizeSuspend != ResizeEnabled) {
145 m_resizeSuspend = ResizeLater;
149 int newTabLength = m_maxLength;
151 if (m_automaticResizeTabs) {
153 int lcw = 0, rcw = 0;
155 const int tabBarHeight = m_parent->tabBar()->sizeHint().height();
156 if (m_parent->cornerWidget(Qt::TopLeftCorner) &&
157 m_parent->cornerWidget( Qt::TopLeftCorner )->isVisible()) {
158 lcw = qMax(m_parent->cornerWidget(Qt::TopLeftCorner)->width(), tabBarHeight);
160 if (m_parent->cornerWidget(Qt::TopRightCorner) &&
161 m_parent->cornerWidget(Qt::TopRightCorner)->isVisible()) {
162 rcw = qMax( m_parent->cornerWidget(Qt::TopRightCorner)->width(), tabBarHeight);
165 const int maxTabBarWidth = m_parent->width() - lcw - rcw;
169 int newTabLengthHi = m_maxLength + 1;
170 int newTabLengthLo = m_minLength;
171 int prevTabLengthMid = -1;
173 int newTabLengthMid = (newTabLengthHi + newTabLengthLo) / 2;
174 if (prevTabLengthMid == newTabLengthMid) {
178 prevTabLengthMid = newTabLengthMid;
180 if (m_parent->tabBarWidthForMaxChars(newTabLengthMid) > maxTabBarWidth) {
181 newTabLengthHi = newTabLengthMid;
183 newTabLengthLo = newTabLengthMid;
186 newTabLength = qMin(newTabLengthLo, m_maxLength);
190 if (m_currentTabLength != newTabLength) {
191 m_currentTabLength = newTabLength;
192 for (
int i = 0; i < m_parent->count(); i++) {
195 }
else if (changeTabIndex != -1) {
196 updateTab(changeTabIndex);
200 void KTabWidget::Private::updateTab(
int index )
202 QString title = m_automaticResizeTabs ? m_tabNames[ index ] : m_parent->QTabWidget::tabText( index );
203 m_parent->setTabToolTip( index,
QString() );
205 if ( title.length() > m_currentTabLength ) {
208 for (
int i = toolTipText.indexOf(
'&' ); i >= 0 && i < toolTipText.length(); i = toolTipText.indexOf(
'&', i + 1 ) )
209 toolTipText.remove( i, 1 );
211 if ( Qt::mightBeRichText( toolTipText ) )
212 m_parent->setTabToolTip( index, Qt::escape( toolTipText ) );
214 m_parent->setTabToolTip( index, toolTipText );
219 if ( m_parent->QTabWidget::tabText( index ) != title )
220 m_parent->QTabWidget::setTabText( index, title );
223 void KTabWidget::Private::slotTabMoved(
int from,
int to)
227 if (m_automaticResizeTabs) {
228 QString movedName = m_tabNames.takeAt(from);
229 m_tabNames.insert(to, movedName);
235 d( new Private( this ) )
237 setWindowFlags( flags );
238 setTabBar(
new KTabBar(
this ) );
239 setObjectName(
"tabbar" );
240 setAcceptDrops(
true );
243 connect(tabBar(), SIGNAL(tabDoubleClicked(
int)), SLOT(
mouseDoubleClick(
int)));
244 connect(tabBar(), SIGNAL(newTabRequest()),
this, SIGNAL(
mouseDoubleClick()));
249 connect(tabBar(), SIGNAL(
moveTab(
int,
int)), SLOT(
moveTab(
int,
int)));
250 connect(tabBar(), SIGNAL(tabMoved(
int,
int)), SLOT(slotTabMoved(
int,
int)));
251 connect(tabBar(), SIGNAL(tabCloseRequested(
int)), SLOT(
closeRequest(
int)));
289 QWidget *rightcorner = cornerWidget( Qt::TopRightCorner );
290 QWidget *leftcorner = cornerWidget( Qt::TopLeftCorner );
292 d->m_tabBarHidden = hide;
294 if ( leftcorner ) leftcorner->hide();
295 if ( rightcorner ) rightcorner->hide();
299 if ( leftcorner ) leftcorner->show();
300 if ( rightcorner ) rightcorner->show();
306 return d->m_tabBarHidden;
311 tabBar()->setTabTextColor( index, color );
316 return tabBar()->tabTextColor( index );
319 #ifndef KDE_NO_DEPRECATED
326 #ifndef KDE_NO_DEPRECATED
333 #ifndef KDE_NO_DEPRECATED
340 #ifndef KDE_NO_DEPRECATED
350 hframe = tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, 0L, tabBar() );
351 overlap = tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabOverlap, 0L, tabBar() );
353 const QFontMetrics fm = tabBar()->fontMetrics();
355 for (
int i = 0; i < count(); ++i ) {
356 QString newTitle = d->m_tabNames.value( i );
359 int lw = fm.width( newTitle );
361 if ( !tabBar()->tabIcon( i ).isNull() ) {
362 iw = tabBar()->tabIcon( i ).pixmap( style()->pixelMetric( QStyle::PM_SmallIconSize ), QIcon::Normal ).width() + 4;
364 #ifndef KDE_NO_DEPRECATED
370 x += ( tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, 0L,
371 QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ),
380 if ( d->m_automaticResizeTabs ) {
381 if (index >= 0 && index < count()) {
382 if (index >= d->m_tabNames.count()) {
389 return d->m_tabNames[ index ];
403 if ( d->m_automaticResizeTabs ) {
405 tabBar()->setUpdatesEnabled(
false);
410 if (index >= d->m_tabNames.count()) {
411 kWarning(240) <<
"setTabText(" << index <<
") called but d->m_tabNames has only" << d->m_tabNames.count() <<
"entries";
412 while (index >= d->m_tabNames.count()) {
413 d->m_tabNames.append(
QString());
416 d->m_tabNames[ index ] = text;
417 d->resizeTabs( index );
420 tabBar()->setUpdatesEnabled(
true);
430 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
436 event->setAccepted( accept );
445 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
451 event->setAccepted( accept );
460 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
468 #ifndef QT_NO_WHEELEVENT
471 if ( d->isEmptyTabbarSpace( event->pos() ) )
472 QCoreApplication::sendEvent( tabBar(), event );
482 int page = currentIndex();
484 page = (page + 1) % count();
490 setCurrentIndex( page );
496 if ( event->button() != Qt::LeftButton )
499 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
509 if ( event->button() == Qt::RightButton ) {
510 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
511 emit(
contextMenu( mapToGlobal( event->pos() ) ) );
521 if ( event->button() == Qt::MidButton ) {
522 if ( d->isEmptyTabbarSpace( event->pos() ) ) {
558 setUpdatesEnabled(
false);
563 const QIcon tabiconset = tabIcon( from );
564 const QString tabtooltip = tabToolTip( from );
565 const bool current = ( from == currentIndex() );
566 const bool enabled = isTabEnabled( from );
568 const bool blocked = blockSignals(
true );
570 QWidget *fw = QApplication::focusWidget();
573 insertTab( to, w, tablabel );
577 if (w->isAncestorOf(fw)) {
581 setTabIcon( to, tabiconset );
583 setTabToolTip( to, tabtooltip );
586 setCurrentIndex( to );
587 setTabEnabled( to, enabled );
588 if ( d->m_automaticResizeTabs ) {
591 blockSignals( blocked );
593 setUpdatesEnabled(
true);
595 #ifndef KDE_NO_DEPRECATED
603 const int index = indexOf(widget);
604 if ( d->m_automaticResizeTabs ) {
605 setUpdatesEnabled(
false);
607 setUpdatesEnabled(
true);
615 if ( d->m_automaticResizeTabs ) {
616 const bool wasUpdatesEnabled = updatesEnabled();
617 setUpdatesEnabled(
false);
618 d->removeTab( index );
619 setUpdatesEnabled(wasUpdatesEnabled);
621 d->removeTab( index );
625 #ifndef KDE_NO_DEPRECATED
629 setTabsClosable( button );
633 #ifndef KDE_NO_DEPRECATED
641 #ifndef KDE_NO_DEPRECATED
649 #ifndef KDE_NO_DEPRECATED
653 return tabsClosable();
657 #ifndef KDE_NO_DEPRECATED
660 static_cast<KTabBar*
>( tabBar() )->setTabsClosable( enable );
664 #ifndef KDE_NO_DEPRECATED
667 return static_cast<KTabBar*
>( tabBar() )->tabsClosable();
673 if ( d->m_automaticResizeTabs == enabled )
676 setUpdatesEnabled(
false);
678 d->m_automaticResizeTabs = enabled;
680 d->m_tabNames.clear();
681 for (
int i = 0; i < count(); ++i )
682 d->m_tabNames.append( tabBar()->
tabText( i ) );
684 for (
int i = 0; i < count(); ++i )
685 tabBar()->setTabText( i, d->m_tabNames[ i ] );
689 setUpdatesEnabled(
true);
694 return d->m_automaticResizeTabs;
710 d->m_tabNames.insert( idx, tabBar()->
tabText( idx ) );
720 #ifndef KDE_NO_DEPRECATED
726 #include "ktabwidget.moc"