00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qxttabwidget.h"
00026 #include "qxttabwidget_p.h"
00027 #include "qxttabbar.h"
00028 #include <QContextMenuEvent>
00029 #include <QApplication>
00030 #include <QTabBar>
00031 #include <QAction>
00032 #include <QMovie>
00033 #include <QMenu>
00034
00035 QxtTabWidgetPrivate::QxtTabWidgetPrivate() : always(true), policy(Qt::DefaultContextMenu)
00036 {
00037 }
00038
00039 int QxtTabWidgetPrivate::tabIndexAt(const QPoint& pos) const
00040 {
00041 const int count = qxt_p().count();
00042 const QTabBar* tabBar = qxt_p().tabBar();
00043 for (int i = 0; i < count; ++i)
00044 if (tabBar->tabRect(i).contains(pos))
00045 return i;
00046 return -1;
00047 }
00048
00049 void QxtTabWidgetPrivate::setMovieFrame(int frame)
00050 {
00051 Q_UNUSED(frame);
00052 QMovie* movie = static_cast<QMovie*>(sender());
00053 if (movie)
00054 {
00055 int index = animations.indexOf(movie);
00056 if (index != -1)
00057 qxt_p().setTabIcon(index, movie->currentPixmap());
00058 }
00059 }
00060
00100 QxtTabWidget::QxtTabWidget(QWidget* parent) : QTabWidget(parent)
00101 {
00102 QXT_INIT_PRIVATE(QxtTabWidget);
00103 QTabWidget::setTabBar(new QxtTabBar);
00104 }
00105
00109 QxtTabWidget::~QxtTabWidget()
00110 {
00111 }
00112
00123 bool QxtTabWidget::alwaysShowTabBar() const
00124 {
00125 return qxt_d().always;
00126 }
00127
00128 void QxtTabWidget::setAlwaysShowTabBar(bool always)
00129 {
00130 qxt_d().always = always;
00131 tabBar()->setVisible(always || count() > 1);
00132 }
00133
00142 QxtTabWidget::TabMovementMode QxtTabWidget::tabMovementMode() const
00143 {
00144 return TabMovementMode(tabBar()->tabMovementMode());
00145 }
00146
00147 void QxtTabWidget::setTabMovementMode(TabMovementMode mode)
00148 {
00149 tabBar()->setTabMovementMode(QxtTabBar::TabMovementMode(mode));
00150 }
00151
00165 Qt::ContextMenuPolicy QxtTabWidget::tabContextMenuPolicy() const
00166 {
00167 return qxt_d().policy;
00168 }
00169
00170 void QxtTabWidget::setTabContextMenuPolicy(Qt::ContextMenuPolicy policy)
00171 {
00172 qxt_d().policy = policy;
00173 }
00174
00181 void QxtTabWidget::addTabAction(int index, QAction* action)
00182 {
00183 insertTabAction(index, 0, action);
00184 }
00185
00193 QAction* QxtTabWidget::addTabAction(int index, const QString& text)
00194 {
00195 return addTabAction(index, QIcon(), text, 0, 0);
00196 }
00197
00205 QAction* QxtTabWidget::addTabAction(int index, const QIcon& icon, const QString& text)
00206 {
00207 return addTabAction(index, icon, text, 0, 0);
00208 }
00209
00230 QAction* QxtTabWidget::addTabAction(int index, const QString& text, const QObject* receiver, const char* member, const QKeySequence& shortcut)
00231 {
00232 return addTabAction(index, QIcon(), text, receiver, member, shortcut);
00233 }
00234
00243 QAction* QxtTabWidget::addTabAction(int index, const QIcon& icon, const QString& text, const QObject* receiver, const char* member, const QKeySequence& shortcut)
00244 {
00245 QAction* action = new QAction(icon, text, this);
00246 addTabAction(index, action);
00247 if (receiver && member)
00248 connect(action, SIGNAL(triggered()), receiver, member);
00249 action->setShortcut(shortcut);
00250 return action;
00251 }
00252
00259 void QxtTabWidget::addTabActions(int index, QList<QAction*> actions)
00260 {
00261 foreach(QAction* action, actions)
00262 {
00263 insertTabAction(index, 0, action);
00264 }
00265 }
00266
00274 void QxtTabWidget::clearTabActions(int index)
00275 {
00276 Q_ASSERT(index >= 0 && index < qxt_d().actions.count());
00277
00278 while (qxt_d().actions[index].count())
00279 {
00280 QAction* action = qxt_d().actions[index].last();
00281 removeTabAction(index, action);
00282 if (action->parent() == this)
00283 delete action;
00284 }
00285 }
00286
00294 void QxtTabWidget::insertTabAction(int index, QAction* before, QAction* action)
00295 {
00296 Q_ASSERT(index >= 0 && index < qxt_d().actions.count());
00297
00298 if (!action)
00299 {
00300 qWarning("QxtTabWidget::insertTabAction: Attempt to insert a null action");
00301 return;
00302 }
00303
00304 const Actions& actions = qxt_d().actions.at(index);
00305 if (actions.contains(action))
00306 removeTabAction(index, action);
00307
00308 int pos = actions.indexOf(before);
00309 if (pos < 0)
00310 {
00311 before = 0;
00312 pos = actions.count();
00313 }
00314 qxt_d().actions[index].insert(pos, action);
00315
00316 QActionEvent e(QEvent::ActionAdded, action, before);
00317 QApplication::sendEvent(this, &e);
00318 }
00319
00327 void QxtTabWidget::insertTabActions(int index, QAction* before, QList<QAction*> actions)
00328 {
00329 foreach(QAction* action, actions)
00330 {
00331 insertTabAction(index, before, action);
00332 }
00333 }
00334
00343 void QxtTabWidget::removeTabAction(int index, QAction* action)
00344 {
00345 Q_ASSERT(index >= 0 && index < qxt_d().actions.count());
00346
00347 if (!action)
00348 {
00349 qWarning("QxtTabWidget::removeTabAction: Attempt to remove a null action");
00350 return;
00351 }
00352
00353 if (qxt_d().actions[index].removeAll(action))
00354 {
00355 QActionEvent e(QEvent::ActionRemoved, action);
00356 QApplication::sendEvent(this, &e);
00357 }
00358 }
00359
00366 QList<QAction*> QxtTabWidget::tabActions(int index) const
00367 {
00368 Q_ASSERT(index >= 0 && index < qxt_d().actions.count());
00369 return qxt_d().actions.at(index);
00370 }
00371
00378 QMovie* QxtTabWidget::tabAnimation(int index) const
00379 {
00380 Q_ASSERT(index >= 0 && index < qxt_d().animations.count());
00381 return qxt_d().animations.at(index);
00382 }
00383
00390 void QxtTabWidget::setTabAnimation(int index, QMovie* animation, bool start)
00391 {
00392 Q_ASSERT(index >= 0 && index < qxt_d().animations.count());
00393 delete takeTabAnimation(index);
00394 qxt_d().animations[index] = animation;
00395 if (animation)
00396 {
00397 connect(animation, SIGNAL(frameChanged(int)), &qxt_d(), SLOT(setMovieFrame(int)));
00398 if (start)
00399 animation->start();
00400 }
00401 }
00402
00410 void QxtTabWidget::setTabAnimation(int index, const QString& fileName, bool start)
00411 {
00412 setTabAnimation(index, new QMovie(fileName, QByteArray(), this), start);
00413 }
00414
00420 QMovie* QxtTabWidget::takeTabAnimation(int index)
00421 {
00422 Q_ASSERT(index >= 0 && index < qxt_d().animations.count());
00423 QMovie* animation = qxt_d().animations.at(index);
00424 qxt_d().animations[index] = 0;
00425 return animation;
00426 }
00427
00428 QxtTabBar* QxtTabWidget::tabBar() const
00429 {
00430 return qobject_cast<QxtTabBar*>(QTabWidget::tabBar());
00431 }
00432
00436 void QxtTabWidget::tabInserted(int index)
00437 {
00438 Q_ASSERT(index >= 0);
00439 Q_ASSERT(index <= qxt_d().actions.count());
00440 Q_ASSERT(index <= qxt_d().animations.count());
00441 qxt_d().actions.insert(index, Actions());
00442 qxt_d().animations.insert(index, 0);
00443 tabBar()->setVisible(qxt_d().always || count() > 1);
00444 }
00445
00449 void QxtTabWidget::tabRemoved(int index)
00450 {
00451 Q_ASSERT(index >= 0);
00452 Q_ASSERT(index < qxt_d().actions.count());
00453 Q_ASSERT(index < qxt_d().animations.count());
00454 qxt_d().actions.removeAt(index);
00455 qxt_d().animations.removeAt(index);
00456 tabBar()->setVisible(qxt_d().always || count() > 1);
00457 }
00458
00462 void QxtTabWidget::contextMenuEvent(QContextMenuEvent* event)
00463 {
00464 const QPoint& pos = event->pos();
00465 if (!tabBar()->geometry().contains(pos))
00466 return QTabWidget::contextMenuEvent(event);
00467
00468 const int index = qxt_d().tabIndexAt(event->pos());
00469 switch (qxt_d().policy)
00470 {
00471 case Qt::NoContextMenu:
00472 event->ignore();
00473 break;
00474
00475 #if QT_VERSION >= 0x040200
00476 case Qt::PreventContextMenu:
00477 event->accept();
00478 break;
00479 #endif // QT_VERSION
00480
00481 case Qt::ActionsContextMenu:
00482 if (index != -1 && qxt_d().actions.at(index).count())
00483 {
00484 QMenu::exec(qxt_d().actions.at(index), event->globalPos());
00485 }
00486 break;
00487
00488 case Qt::CustomContextMenu:
00489 if (index != -1)
00490 {
00491 emit tabContextMenuRequested(index, event->globalPos());
00492 }
00493 break;
00494
00495 case Qt::DefaultContextMenu:
00496 default:
00497 if (index != -1)
00498 {
00499 tabContextMenuEvent(index, event);
00500 }
00501 break;
00502 }
00503 }
00504
00516 void QxtTabWidget::tabContextMenuEvent(int index, QContextMenuEvent* event)
00517 {
00518 Q_UNUSED(index);
00519 event->ignore();
00520 }