28 #include <QApplication>
33 #include <QToolButton>
36 #include <QStyleOption>
38 #include <kapplication.h>
40 #include <ktabwidget.h>
46 #include <kiconloader.h>
47 #include <ktoolinvocation.h>
49 #include <kmimetype.h>
50 #include <kio/global.h>
64 class TabWidget::Private
70 explicit Private(
TabWidget * qq ) : q( qq ), currentMaxLength( 30 ), currentItem( 0 ), tabsClose( 0 ) {}
76 QToolButton* tabsClose;
78 QWidget* selectedWidget()
const {
79 return ( currentItem && q->indexOf(currentItem) != -1 ) ? currentItem : q->currentWidget();
82 uint tabBarWidthForMaxChars(
int maxLength);
83 void setTitle(
const QString &title ,
QWidget* sender);
84 void updateTabBarVisibility();
85 Frame* currentFrame();
88 void TabWidget::Private::updateTabBarVisibility()
92 q->tabBar()->tabButton(0, QTabBar::RightSide)->hide();
98 setMinimumSize(250,150);
100 setDocumentMode(
true);
101 connect(
this, SIGNAL(currentChanged(
int)),
102 this, SLOT(slotTabChanged(
int)) );
103 connect(
this, SIGNAL(closeRequest(
QWidget*)),
104 this, SLOT(slotCloseRequest(
QWidget*)));
107 d->tabsClose =
new QToolButton(
this);
108 connect( d->tabsClose, SIGNAL(clicked()),
this,
111 d->tabsClose->setIcon( KIcon(
"tab-close" ) );
112 d->tabsClose->setEnabled(
false );
113 d->tabsClose->adjustSize();
114 d->tabsClose->setToolTip( i18n(
"Close the current tab"));
116 #ifndef QT_NO_ACCESSIBILITY
117 d->tabsClose->setAccessibleName( i18n(
"Close tab" ) );
120 setCornerWidget( d->tabsClose, Qt::TopRightCorner );
121 d->updateTabBarVisibility();
133 d->updateTabBarVisibility();
138 setCurrentIndex((currentIndex()+1) % count());
143 if (currentIndex() == 0)
144 setCurrentIndex(count()-1);
146 setCurrentIndex(currentIndex()-1);
150 Frame* frame = d->framesById.value(frameId);
151 if (frame && frame != d->currentFrame())
153 setCurrentWidget(frame);
154 if (frame->
part() && frame->
part()->widget())
156 frame->
part()->widget()->setFocus();
169 d->frames.insert(frame, frame);
170 d->framesById.insert( frame->
id(), frame );
171 addTab(frame, frame->
title());
178 connect(frame, SIGNAL(signalPartDestroyed(
int)),
this, SLOT(
slotRemoveFrame(
int)));
182 Frame * TabWidget::Private::currentFrame()
184 QWidget* w = q->currentWidget();
185 assert( frames.value( w ) );
186 return w ? frames.value(w) : 0;
191 if ( !d->currentFrame() )
198 if ( !d->currentFrame() )
204 void TabWidget::slotTabChanged(
int index)
207 Frame* frame = d->frames.value(widget(index));
208 d->tabsClose->setEnabled(frame && frame->
isRemovable());
212 void TabWidget::tabInserted(
int )
214 d->updateTabBarVisibility();
218 void TabWidget::tabRemoved(
int )
220 d->updateTabBarVisibility();
225 Frame*
const frame = d->currentFrame();
232 if (!d->framesById.contains(frameId))
234 Frame* f = d->framesById.value(frameId);
236 d->framesById.remove(frameId);
237 f->disconnect(
this );
238 removeTab(indexOf(f));
240 if (d->currentFrame())
241 d->setTitle( d->currentFrame()->title(), currentWidget() );
245 uint TabWidget::Private::tabBarWidthForMaxChars(
int maxLength )
249 hframe = q->tabBar()->style()->pixelMetric( QStyle::PM_TabBarTabHSpace, &o, q );
251 QFontMetrics fm = q->tabBar()->fontMetrics();
253 for (
int i = 0; i < q->count(); ++i)
255 Frame* f = frames.value(q->widget(i));
259 QString newTitle = f->
title();
260 if ( newTitle.length() > maxLength )
261 newTitle = newTitle.left( maxLength-3 ) +
"...";
263 int lw = fm.width( newTitle );
264 int iw = q->tabBar()->tabIcon( i ).pixmap( q->tabBar()->style()->pixelMetric(
265 QStyle::PM_SmallIconSize ), QIcon::Normal
268 x += ( q->tabBar()->style()->sizeFromContents( QStyle::CT_TabBarTab, &o,
269 QSize( qMax( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), q ) ).width();
276 d->setTitle(title, frame);
281 const int idx = indexOf( frame );
284 setTabIcon( idx, icon );
287 void TabWidget::Private::setTitle(
const QString &title,
QWidget* sender)
289 int senderIndex = q->indexOf(sender);
291 q->setTabToolTip( senderIndex, QString() );
294 int tabBarHeight = q->tabBar()->sizeHint().height();
296 QWidget* leftCorner = q->cornerWidget( Qt::TopLeftCorner );
298 if ( leftCorner && leftCorner->isVisible() )
299 lcw = qMax( leftCorner->width(), tabBarHeight );
301 QWidget* rightCorner = q->cornerWidget( Qt::TopRightCorner );
303 if ( rightCorner && rightCorner->isVisible() )
304 rcw = qMax( rightCorner->width(), tabBarHeight );
305 uint maxTabBarWidth = q->width() - lcw - rcw;
307 int newMaxLength = 30;
309 for ( ; newMaxLength > 3; newMaxLength-- )
311 if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
315 QString newTitle = title;
316 if ( newTitle.length() > newMaxLength )
318 q->setTabToolTip( senderIndex, newTitle );
319 newTitle = newTitle.left( newMaxLength-3 ) +
"...";
322 newTitle.replace(
'&',
"&&" );
324 if ( q->tabText(senderIndex) != newTitle )
325 q->setTabText( senderIndex, newTitle );
327 if( newMaxLength != currentMaxLength )
329 for(
int i = 0; i < q->count(); ++i)
331 Frame* f = frames.value(q->widget(i));
335 newTitle = f->
title();
336 int index = q->indexOf(q->widget( i ));
337 q->setTabToolTip( index, QString() );
339 if ( newTitle.length() > newMaxLength )
341 q->setTabToolTip( index, newTitle );
342 newTitle = newTitle.left( newMaxLength-3 ) +
"...";
345 newTitle.replace(
'&',
"&&" );
346 if ( newTitle != q->tabText( index ) )
347 q->setTabText( index, newTitle );
349 currentMaxLength = newMaxLength;
353 void TabWidget::contextMenu(
int i,
const QPoint &p)
356 TemporaryValue<QWidget*> tmp( d->currentItem, widget( i ) );
359 if (w && indexOf(d->currentItem) != 0)
360 static_cast<QMenu *
>(w)->exec(p);
363 void TabWidget::slotDetachTab()
365 Frame* frame = d->frames.value( d->selectedWidget() );
367 if (frame && frame->url().isValid() && frame->isRemovable())
369 OpenUrlRequest request;
370 request.setUrl(frame->url());
377 void TabWidget::slotCopyLinkAddress()
379 Frame* frame = d->frames.value( d->selectedWidget() );
381 if (frame && frame->url().isValid())
383 KUrl url = frame->url();
386 kapp->clipboard()->setText(url.prettyUrl(), QClipboard::Clipboard);
390 void TabWidget::slotCloseTab()
392 QWidget* widget = d->selectedWidget();
393 Frame* frame = d->frames.value( widget );
395 if (frame == 0 || !frame->isRemovable() )
401 void TabWidget::initiateDrag(
int tab)
403 Frame* frame = d->frames.value(widget(tab));
405 if (frame && frame->url().isValid())
408 lst.append( frame->url() );
409 QDrag* drag =
new QDrag(
this );
410 QMimeData *md =
new QMimeData;
411 drag->setMimeData( md );
412 lst.populateMimeData( md );
413 drag->setPixmap( KIO::pixmapForUrl( lst.first(), 0, KIconLoader::Small ) );
420 Q_FOREACH(
Frame* frame,d->frames.values())
427 void TabWidget::slotCloseRequest(
QWidget* widget)
429 if (d->frames.value(widget))
435 setCurrentIndex( sender()->objectName().right( 2 ).toInt() -1 );
441 #include "tabwidget.moc"
bool isRemovable() const
Returns whether the frame can be removed from Akregator (via detach or close tab etc.) Usually all tabs but the main tab can be removed.
static bool alwaysShowTabBar()
Get Always show the tab bar.
static bool closeButtonOnTabs()
Get Show close buttons on tabs.
virtual KParts::ReadOnlyPart * part() const =0
virtual QWidget * container(const char *name)=0
virtual void slotReload()
reloads the current content, if possible.
static ActionManager * getInstance()