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 "kmultitabbar.h"
00026 #include "kmultitabbar_p.h"
00027 #include "kmultitabbar.moc"
00028 #include "kmultitabbar_p.moc"
00029
00030 #include <QtGui/QActionEvent>
00031 #include <QtGui/QLayout>
00032 #include <QtGui/QPainter>
00033 #include <QtGui/QFontMetrics>
00034 #include <QtGui/QStyle>
00035 #include <QStyleOptionButton>
00036
00037 #include <kiconloader.h>
00038 #include <kdebug.h>
00039 #include <QtGui/QApplication>
00040 #include <math.h>
00041
00049 class KMultiTabBarPrivate
00050 {
00051 public:
00052 class KMultiTabBarInternal *m_internal;
00053 QBoxLayout *m_l;
00054 QFrame *m_btnTabSep;
00055 QList<KMultiTabBarButton*> m_buttons;
00056 KMultiTabBar::KMultiTabBarPosition m_position;
00057 };
00058
00059
00060 KMultiTabBarInternal::KMultiTabBarInternal(QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos):QFrame(parent)
00061 {
00062 m_position = pos;
00063 if (pos == KMultiTabBar::Left || pos == KMultiTabBar::Right)
00064 mainLayout=new QVBoxLayout(this);
00065 else
00066 mainLayout=new QHBoxLayout(this);
00067 mainLayout->setMargin(0);
00068 mainLayout->setSpacing(0);
00069 mainLayout->addStretch();
00070 setFrameStyle(NoFrame);
00071 setBackgroundRole(QPalette::Background);
00072 }
00073
00074 KMultiTabBarInternal::~KMultiTabBarInternal()
00075 {
00076 qDeleteAll(m_tabs);
00077 m_tabs.clear();
00078 }
00079
00080 void KMultiTabBarInternal::setStyle(enum KMultiTabBar::KMultiTabBarStyle style)
00081 {
00082 m_style=style;
00083 for (int i=0;i<m_tabs.count();i++)
00084 m_tabs.at(i)->setStyle(m_style);
00085
00086 updateGeometry();
00087 }
00088
00089 void KMultiTabBarInternal::contentsMousePressEvent(QMouseEvent *ev)
00090 {
00091 ev->ignore();
00092 }
00093
00094 void KMultiTabBarInternal::mousePressEvent(QMouseEvent *ev)
00095 {
00096 ev->ignore();
00097 }
00098
00099 KMultiTabBarTab* KMultiTabBarInternal::tab(int id) const
00100 {
00101 QListIterator<KMultiTabBarTab*> it(m_tabs);
00102 while (it.hasNext()) {
00103 KMultiTabBarTab *tab = it.next();
00104 if (tab->id()==id) return tab;
00105 }
00106 return 0;
00107 }
00108
00109 int KMultiTabBarInternal::appendTab(const QPixmap &pic, int id, const QString& text)
00110 {
00111 KMultiTabBarTab *tab;
00112 m_tabs.append(tab= new KMultiTabBarTab(pic,text,id,this,m_position,m_style));
00113
00114
00115 mainLayout->insertWidget(m_tabs.size()-1, tab);
00116 tab->show();
00117 return 0;
00118 }
00119
00120 void KMultiTabBarInternal::removeTab(int id)
00121 {
00122 for (int pos=0;pos<m_tabs.count();pos++)
00123 {
00124 if (m_tabs.at(pos)->id()==id)
00125 {
00126
00127 delete m_tabs.takeAt(pos);
00128 break;
00129 }
00130 }
00131 }
00132
00133 void KMultiTabBarInternal::setPosition(enum KMultiTabBar::KMultiTabBarPosition pos)
00134 {
00135 m_position=pos;
00136 for (int i=0;i<m_tabs.count();i++)
00137 m_tabs.at(i)->setPosition(m_position);
00138 updateGeometry();
00139 }
00140
00141
00143
00144 KMultiTabBarButton::KMultiTabBarButton(const QPixmap& pic, const QString& text,
00145 int id, QWidget *parent)
00146 : QPushButton(QIcon(pic), text, parent), m_id(id), d(0)
00147 {
00148 connect(this,SIGNAL(clicked()),this,SLOT(slotClicked()));
00149 setFlat(true);
00150
00151
00152
00153
00154 setFocusPolicy(Qt::NoFocus);
00155 }
00156
00157 KMultiTabBarButton::~KMultiTabBarButton()
00158 {
00159 }
00160
00161 void KMultiTabBarButton::setText(const QString &text)
00162 {
00163 QPushButton::setText(text);
00164 }
00165
00166 void KMultiTabBarButton::slotClicked()
00167 {
00168 updateGeometry();
00169 emit clicked(m_id);
00170 }
00171
00172 int KMultiTabBarButton::id() const
00173 {
00174 return m_id;
00175 }
00176
00177 void KMultiTabBarButton::hideEvent( QHideEvent* he) {
00178 QPushButton::hideEvent(he);
00179 KMultiTabBar *tb=dynamic_cast<KMultiTabBar*>(parentWidget());
00180 if (tb) tb->updateSeparator();
00181 }
00182
00183 void KMultiTabBarButton::showEvent( QShowEvent* he) {
00184 QPushButton::showEvent(he);
00185 KMultiTabBar *tb=dynamic_cast<KMultiTabBar*>(parentWidget());
00186 if (tb) tb->updateSeparator();
00187 }
00188
00189
00191
00192 KMultiTabBarTab::KMultiTabBarTab(const QPixmap& pic, const QString& text,
00193 int id, QWidget *parent,
00194 KMultiTabBar::KMultiTabBarPosition pos,
00195 KMultiTabBar::KMultiTabBarStyle style)
00196 : KMultiTabBarButton(pic, text, id, parent), m_style(style), d(0)
00197 {
00198 m_position=pos;
00199 setToolTip(text);
00200 setCheckable(true);
00201 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
00202
00203 }
00204
00205 KMultiTabBarTab::~KMultiTabBarTab()
00206 {
00207 }
00208
00209 void KMultiTabBarTab::setPosition(KMultiTabBar::KMultiTabBarPosition pos)
00210 {
00211 m_position=pos;
00212 updateGeometry();
00213 }
00214
00215 void KMultiTabBarTab::setStyle(KMultiTabBar::KMultiTabBarStyle style)
00216 {
00217 m_style=style;
00218 updateGeometry();
00219 }
00220
00221 QPixmap KMultiTabBarTab::iconPixmap() const
00222 {
00223 int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
00224 return icon().pixmap(iconSize);
00225 }
00226
00227 void KMultiTabBarTab::initStyleOption(QStyleOptionToolButton* opt) const
00228 {
00229 opt->initFrom(this);
00230
00231
00232 if (!icon().isNull()) {
00233 opt->iconSize = iconPixmap().size();
00234 opt->icon = icon();
00235 }
00236
00237
00238 if (shouldDrawText())
00239 opt->text = text();
00240
00241 if (underMouse())
00242 opt->state |= QStyle::State_AutoRaise | QStyle::State_MouseOver | QStyle::State_Raised;
00243
00244 if (isChecked())
00245 opt->state |= QStyle::State_Sunken | QStyle::State_On;
00246
00247 opt->font = font();
00248 opt->toolButtonStyle = shouldDrawText() ? Qt::ToolButtonTextBesideIcon : Qt::ToolButtonIconOnly;
00249 opt->subControls = QStyle::SC_ToolButton;
00250 }
00251
00252 QSize KMultiTabBarTab::sizeHint() const
00253 {
00254 return computeSizeHint(shouldDrawText());
00255 }
00256
00257 QSize KMultiTabBarTab::minimumSizeHint() const
00258 {
00259 return computeSizeHint(false);
00260 }
00261
00262 void KMultiTabBarTab::computeMargins(int* hMargin, int* vMargin) const
00263 {
00264
00265
00266 QStyleOptionToolButton opt;
00267 initStyleOption(&opt);
00268
00269 QPixmap iconPix = iconPixmap();
00270 QSize trialSize = iconPix.size();
00271 QSize expandSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, trialSize, this);
00272
00273 *hMargin = (expandSize.width() - trialSize.width())/2;
00274 *vMargin = (expandSize.height() - trialSize.height())/2;
00275 }
00276
00277 QSize KMultiTabBarTab::computeSizeHint(bool withText) const
00278 {
00279
00280 QStyleOptionToolButton opt;
00281 initStyleOption(&opt);
00282
00283 int hMargin, vMargin;
00284 computeMargins(&hMargin, &vMargin);
00285
00286
00287 QPixmap iconPix = iconPixmap();
00288 QSize size = iconPix.size();
00289
00290
00291
00292 QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text());
00293 size.setHeight(qMax(size.height(), textSize.height()));
00294
00295
00296 int majorMargin = isVertical() ? vMargin : hMargin;
00297 int minorMargin = isVertical() ? hMargin : vMargin;
00298
00299 size.setWidth (size.width() + 2*majorMargin);
00300 size.setHeight(size.height() + 2*minorMargin);
00301
00302 if (withText)
00303
00304 size.setWidth(size.width() + textSize.width() + majorMargin);
00305
00306
00307 if (isVertical())
00308 return QSize(size.height(), size.width());
00309 else
00310 return size;
00311 }
00312
00313 void KMultiTabBarTab::setState(bool newState)
00314 {
00315 setChecked(newState);
00316 updateGeometry();
00317 }
00318
00319 void KMultiTabBarTab::setIcon(const QString& icon)
00320 {
00321 QPixmap pic=SmallIcon(icon);
00322 setIcon(pic);
00323 }
00324
00325 void KMultiTabBarTab::setIcon(const QPixmap& icon)
00326 {
00327 QPushButton::setIcon(icon);
00328 }
00329
00330 bool KMultiTabBarTab::shouldDrawText() const
00331 {
00332 return (m_style==KMultiTabBar::KDEV3ICON) || isChecked();
00333 }
00334
00335 bool KMultiTabBarTab::isVertical() const
00336 {
00337 return m_position==KMultiTabBar::Right || m_position==KMultiTabBar::Left;
00338 }
00339
00340 void KMultiTabBarTab::paintEvent(QPaintEvent*) {
00341 QPainter painter(this);
00342
00343 QStyleOptionToolButton opt;
00344 initStyleOption(&opt);
00345
00346
00347 if (underMouse() || isChecked())
00348 style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &painter);
00349
00350 int hMargin, vMargin;
00351 computeMargins(&hMargin, &vMargin);
00352
00353
00354
00355
00356 QPixmap icon = iconPixmap();
00357 int textRoom = 0;
00358 int iconRoom = 0;
00359
00360 QString t;
00361 if (shouldDrawText()) {
00362 if (isVertical()) {
00363 iconRoom = icon.height() + 2*vMargin;
00364 textRoom = height() - iconRoom - vMargin;
00365 } else {
00366 iconRoom = icon.width() + 2*hMargin;
00367 textRoom = width() - iconRoom - hMargin;
00368 }
00369
00370 t = painter.fontMetrics().elidedText(text(), Qt::ElideRight, textRoom);
00371
00372
00373
00374 if (t == QLatin1String("...") || t == QChar(0x2026))
00375 t.clear();
00376 }
00377
00378 opt.text = t;
00379
00380
00381
00382
00383 if (!shouldDrawText()) {
00384 style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter | Qt::AlignVCenter, icon);
00385 return;
00386 }
00387
00388
00389 QRect iconArea;
00390 QRect labelArea;
00391
00392 bool bottomIcon = false;
00393 bool rtl = layoutDirection() == Qt::RightToLeft;
00394 if (isVertical()) {
00395 if (m_position == KMultiTabBar::Left && !rtl)
00396 bottomIcon = true;
00397 if (m_position == KMultiTabBar::Right && rtl)
00398 bottomIcon = true;
00399 }
00400
00401
00402 if (isVertical()) {
00403 if (bottomIcon) {
00404 labelArea = QRect(0, vMargin, width(), textRoom);
00405 iconArea = QRect(0, vMargin + textRoom, width(), iconRoom);
00406 } else {
00407 labelArea = QRect(0, iconRoom, width(), textRoom);
00408 iconArea = QRect(0, 0, width(), iconRoom);
00409 }
00410 } else {
00411
00412 if (rtl) {
00413 labelArea = QRect(hMargin, 0, textRoom, height());
00414 iconArea = QRect(hMargin + textRoom, 0, iconRoom, height());
00415 } else {
00416 labelArea = QRect(iconRoom, 0, textRoom, height());
00417 iconArea = QRect(0, 0, iconRoom, height());
00418 }
00419 }
00420
00421 style()->drawItemPixmap(&painter, iconArea, Qt::AlignCenter | Qt::AlignVCenter, icon);
00422
00423 if (t.isEmpty())
00424 return;
00425
00426 QRect labelPaintArea = labelArea;
00427
00428 if (isVertical()) {
00429
00430
00431 labelPaintArea = QRect(0, 0, labelArea.height(), labelArea.width());
00432
00433 QTransform tr;
00434
00435 if (bottomIcon) {
00436 tr.translate(labelArea.x(), labelPaintArea.width() + labelArea.y());
00437 tr.rotate(-90);
00438 } else {
00439 tr.translate(labelPaintArea.height() + labelArea.x(), labelArea.y());
00440 tr.rotate(90);
00441 }
00442 painter.setTransform(tr);
00443 }
00444
00445 style()->drawItemText(&painter, labelPaintArea, Qt::AlignLeading | Qt::AlignVCenter,
00446 palette(), true, t, QPalette::ButtonText);
00447 }
00448
00449
00451
00452 KMultiTabBar::KMultiTabBar(KMultiTabBarPosition pos, QWidget *parent)
00453 : QWidget(parent),
00454 d(new KMultiTabBarPrivate)
00455 {
00456 if (pos == Left || pos == Right)
00457 {
00458 d->m_l=new QVBoxLayout(this);
00459 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
00460 }
00461 else
00462 {
00463 d->m_l=new QHBoxLayout(this);
00464 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00465 }
00466 d->m_l->setMargin(0);
00467 d->m_l->setSpacing(0);
00468
00469 d->m_internal=new KMultiTabBarInternal(this, pos);
00470 setPosition(pos);
00471 setStyle(VSNET);
00472 d->m_l->insertWidget(0,d->m_internal);
00473 d->m_l->insertWidget(0,d->m_btnTabSep=new QFrame(this));
00474 d->m_btnTabSep->setFixedHeight(4);
00475 d->m_btnTabSep->setFrameStyle(QFrame::Panel | QFrame::Sunken);
00476 d->m_btnTabSep->setLineWidth(2);
00477 d->m_btnTabSep->hide();
00478
00479 updateGeometry();
00480 }
00481
00482 KMultiTabBar::~KMultiTabBar()
00483 {
00484 qDeleteAll( d->m_buttons );
00485 d->m_buttons.clear();
00486 delete d;
00487 }
00488
00489 int KMultiTabBar::appendButton(const QPixmap &pic, int id, QMenu *popup, const QString&)
00490 {
00491 KMultiTabBarButton *btn = new KMultiTabBarButton(pic, QString(), id, this);
00492 btn->setMenu(popup);
00493 d->m_buttons.append(btn);
00494 d->m_l->insertWidget(0,btn);
00495 btn->show();
00496 d->m_btnTabSep->show();
00497 return 0;
00498 }
00499
00500 void KMultiTabBar::updateSeparator() {
00501 bool hideSep=true;
00502 QListIterator<KMultiTabBarButton*> it(d->m_buttons);
00503 while (it.hasNext()){
00504 if (it.next()->isVisibleTo(this)) {
00505 hideSep=false;
00506 break;
00507 }
00508 }
00509 if (hideSep)
00510 d->m_btnTabSep->hide();
00511 else
00512 d->m_btnTabSep->show();
00513 }
00514
00515 int KMultiTabBar::appendTab(const QPixmap &pic, int id, const QString& text)
00516 {
00517 d->m_internal->appendTab(pic,id,text);
00518 return 0;
00519 }
00520
00521 KMultiTabBarButton* KMultiTabBar::button(int id) const
00522 {
00523 QListIterator<KMultiTabBarButton*> it(d->m_buttons);
00524 while ( it.hasNext() ) {
00525 KMultiTabBarButton *button = it.next();
00526 if ( button->id() == id )
00527 return button;
00528 }
00529
00530 return 0;
00531 }
00532
00533 KMultiTabBarTab* KMultiTabBar::tab(int id) const
00534 {
00535 return d->m_internal->tab(id);
00536 }
00537
00538 void KMultiTabBar::removeButton(int id)
00539 {
00540 for (int pos=0;pos<d->m_buttons.count();pos++)
00541 {
00542 if (d->m_buttons.at(pos)->id()==id)
00543 {
00544 d->m_buttons.takeAt(pos)->deleteLater();
00545 break;
00546 }
00547 }
00548
00549 if (d->m_buttons.count()==0)
00550 d->m_btnTabSep->hide();
00551 }
00552
00553 void KMultiTabBar::removeTab(int id)
00554 {
00555 d->m_internal->removeTab(id);
00556 }
00557
00558 void KMultiTabBar::setTab(int id,bool state)
00559 {
00560 KMultiTabBarTab *ttab=tab(id);
00561 if (ttab)
00562 ttab->setState(state);
00563 }
00564
00565 bool KMultiTabBar::isTabRaised(int id) const
00566 {
00567 KMultiTabBarTab *ttab=tab(id);
00568 if (ttab)
00569 return ttab->isChecked();
00570
00571 return false;
00572 }
00573
00574 void KMultiTabBar::setStyle(KMultiTabBarStyle style)
00575 {
00576 d->m_internal->setStyle(style);
00577 }
00578
00579 KMultiTabBar::KMultiTabBarStyle KMultiTabBar::tabStyle() const
00580 {
00581 return d->m_internal->m_style;
00582 }
00583
00584 void KMultiTabBar::setPosition(KMultiTabBarPosition pos)
00585 {
00586 d->m_position=pos;
00587 d->m_internal->setPosition(pos);
00588 }
00589
00590 KMultiTabBar::KMultiTabBarPosition KMultiTabBar::position() const
00591 {
00592 return d->m_position;
00593 }
00594
00595 void KMultiTabBar::fontChange(const QFont& )
00596 {
00597 updateGeometry();
00598 }
00599
00600
00601