00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00013
00014 #include <qptrlist.h>
00015 #include <qlayout.h>
00016 #include <qlabel.h>
00017 #include <qwidgetstack.h>
00018 #include <qguardedptr.h>
00019
00020 #include <kdebug.h>
00021 #include <kconfig.h>
00022
00023
00024 #include "ktabzoomframe.h"
00025
00026
00027 #include "ktabzoomwidget.h"
00028
00029
00030 class KTZWidgetInfo
00031 {
00032 public:
00033 KTZWidgetInfo( QWidget* w = 0 ): m_widget(w), m_index(0), m_barIndex(0) {}
00034
00035 QWidget *m_widget;
00036 int m_index, m_barIndex;
00037
00038 };
00039
00040
00041 class KTabZoomWidgetPrivate
00042 {
00043 public:
00044
00045 KTabZoomPosition::Position m_tabPosition;
00046 QWidget *m_content;
00047 KTabZoomBar *m_tabBar;
00048 QBoxLayout *m_layout;
00049 KTabZoomFrame *m_popup;
00050 QPtrList<KTZWidgetInfo> m_info;
00051 bool m_docked;
00052 QWidget *m_strut;
00053 QGuardedPtr<QWidget> m_lastActiveWidget;
00054 };
00055
00056
00057 KTabZoomWidget::KTabZoomWidget(QWidget *parent, KTabZoomPosition::Position pos, const char *name)
00058 : QWidget(parent, name)
00059 {
00060 d = new KTabZoomWidgetPrivate;
00061 d->m_info.setAutoDelete(true);
00062
00063 d->m_tabPosition = pos;
00064 d->m_content = 0;
00065 d->m_docked = false;
00066 d->m_strut = 0;
00067 d->m_lastActiveWidget = 0;
00068
00069 d->m_tabBar = new KTabZoomBar(this, pos);
00070 connect(d->m_tabBar, SIGNAL(selected(int)), this, SLOT(selected(int)));
00071 connect(d->m_tabBar, SIGNAL(unselected()), this, SLOT(unselected()));
00072
00073 if (pos == KTabZoomPosition::Left || pos == KTabZoomPosition::Right)
00074 d->m_layout = new QHBoxLayout(this);
00075 else
00076 d->m_layout = new QVBoxLayout(this);
00077
00078 d->m_popup = new KTabZoomFrame(parent, pos);
00079
00080 if(pos == KTabZoomPosition::Left || pos == KTabZoomPosition::Right)
00081 d->m_popup->setMinimumWidth(110);
00082 else
00083 d->m_popup->setMinimumHeight(125);
00084
00085 connect(d->m_popup, SIGNAL(closeClicked()), this, SLOT(unselected()));
00086 connect(d->m_popup, SIGNAL(dockToggled(bool)), this, SLOT(setDockMode(bool)));
00087 connect(d->m_popup, SIGNAL(sizeChanged()), this, SLOT(adjustStrut()));
00088
00089 d->m_popup->hide();
00090
00091 if (pos == KTabZoomPosition::Left || pos == KTabZoomPosition::Right)
00092 d->m_popup->resize(250, height());
00093 else
00094 d->m_popup->resize(width(), 125);
00095 }
00096
00097
00098 KTabZoomWidget::~KTabZoomWidget()
00099 {
00100 delete d;
00101 }
00102
00103
00104 void KTabZoomWidget::addTab(QWidget *widget, const QString &title, const QString& toolTip)
00105 {
00106 KTZWidgetInfo *info = new KTZWidgetInfo( widget );
00107
00108 info->m_barIndex = d->m_tabBar->addTab( QTab(title), toolTip );
00109 info->m_index = d->m_popup->addTab(widget, title);
00110
00111 connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDeleted()));
00112
00113 d->m_info.append(info);
00114
00115 switch (d->m_tabPosition)
00116 {
00117 case KTabZoomPosition::Bottom:
00118 case KTabZoomPosition::Top:
00119 if(widget->minimumSizeHint().height() + 12 > d->m_popup->minimumHeight())
00120 d->m_popup->setMinimumHeight(widget->minimumSizeHint().height() + 12);
00121 break;
00122 case KTabZoomPosition::Left:
00123 case KTabZoomPosition::Right:
00124 if(widget->minimumSizeHint().width() + 12 > d->m_popup->minimumWidth())
00125 d->m_popup->setMinimumWidth(widget->minimumSizeHint().width() + 12);
00126 break;
00127 }
00128
00129 emit tabsChanged();
00130 }
00131
00132
00133 void KTabZoomWidget::removeTab(QWidget *w) {
00134
00135 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00136 if (i->m_widget == w)
00137 {
00138 d->m_tabBar->removeTab(i->m_barIndex);
00139 d->m_popup->removeTab(i->m_index);
00140 d->m_info.remove(i);
00141 emit tabsChanged();
00142 return;
00143 }
00144
00145 }
00146
00147 void KTabZoomWidget::widgetDeleted()
00148 {
00149 const QWidget *w = static_cast<const QWidget*>(sender());
00150
00151 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00152 if (i->m_widget == w)
00153 {
00154 d->m_tabBar->removeTab(i->m_barIndex);
00155 d->m_popup->removeTab(i->m_index);
00156 d->m_info.remove(i);
00157 emit tabsChanged();
00158 return;
00159 }
00160 }
00161
00162
00163 void KTabZoomWidget::addContent(QWidget *content)
00164 {
00165
00166 if (d->m_content != 0)
00167 return;
00168
00169 d->m_content = content;
00170
00171 d->m_strut = new QWidget(this);
00172
00173 switch (d->m_tabPosition)
00174 {
00175 case KTabZoomPosition::Left:
00176 case KTabZoomPosition::Top:
00177 d->m_layout->addWidget(d->m_tabBar);
00178 d->m_layout->addWidget(d->m_strut);
00179 d->m_layout->addWidget(d->m_content,1);
00180 break;
00181
00182 case KTabZoomPosition::Right:
00183 case KTabZoomPosition::Bottom:
00184 d->m_layout->addWidget(d->m_content,1);
00185 d->m_layout->addWidget(d->m_strut);
00186 d->m_layout->addWidget(d->m_tabBar);
00187 break;
00188 }
00189
00190 d->m_strut->hide();
00191
00192 content->show();
00193 }
00194
00195
00196 void KTabZoomWidget::selected(int index)
00197 {
00198 calculateGeometry();
00199
00200 if (d->m_docked)
00201 {
00202 d->m_strut->show();
00203 adjustStrut();
00204 }
00205
00206 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00207 if (i->m_barIndex == index)
00208 {
00209 d->m_popup->selected(i->m_index);
00210 d->m_popup->show();
00211 d->m_lastActiveWidget = i->m_widget;
00212 return;
00213 }
00214 }
00215
00216 void KTabZoomWidget::setFocus()
00217 {
00218 if ( d->m_lastActiveWidget )
00219 d->m_lastActiveWidget->setFocus();
00220 }
00221
00222 bool KTabZoomWidget::hasFocus() const
00223 {
00224 return d->m_lastActiveWidget && d->m_lastActiveWidget->hasFocus();
00225 }
00226
00227 bool KTabZoomWidget::isDocked() const
00228 {
00229 return d->m_docked;
00230 }
00231
00232 bool KTabZoomWidget::isRaised() const
00233 {
00234 return d->m_popup->isVisible();
00235 }
00236
00237 bool KTabZoomWidget::isEmpty() const
00238 {
00239 return d->m_info.isEmpty();
00240 }
00241
00242 uint KTabZoomWidget::count() const
00243 {
00244 return d->m_info.count();
00245 }
00246
00247 int KTabZoomWidget::indexOf(QWidget *widget) const
00248 {
00249 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00250 if (i->m_widget == widget)
00251 return i->m_index;
00252
00253 return -1;
00254 }
00255
00256 QWidget *KTabZoomWidget::at(int index) const
00257 {
00258 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00259 if (i->m_index == index)
00260 return i->m_widget;
00261
00262 return 0;
00263 }
00264
00265 QWidget *KTabZoomWidget::current() const
00266 {
00267 return d->m_lastActiveWidget;
00268 }
00269
00270 void KTabZoomWidget::unselected()
00271 {
00272 d->m_popup->hide();
00273 d->m_tabBar->unsetButtons();
00274 d->m_strut->hide();
00275 }
00276
00277
00278 void KTabZoomWidget::raiseWidget(QWidget *widget)
00279 {
00280 if ( !widget )
00281 widget = d->m_lastActiveWidget;
00282 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00283 if (i->m_widget == widget || !widget)
00284 {
00285 d->m_tabBar->setActiveIndex(i->m_barIndex);
00286 d->m_lastActiveWidget = i->m_widget;
00287 return;
00288 }
00289 }
00290
00291
00292 void KTabZoomWidget::lowerAllWidgets()
00293 {
00294 d->m_tabBar->unsetButtons();
00295 }
00296
00297
00298 void KTabZoomWidget::lowerWidget(QWidget *w)
00299 {
00300 if (d->m_docked)
00301 return;
00302
00303 for (KTZWidgetInfo *i=d->m_info.first(); i != 0; i = d->m_info.next())
00304 if (i->m_widget == w)
00305 {
00306 d->m_popup->hide();
00307 d->m_tabBar->unsetButtons();
00308 return;
00309 }
00310 }
00311
00312
00313 void KTabZoomWidget::calculateGeometry()
00314 {
00315 switch (d->m_tabPosition)
00316 {
00317 case KTabZoomPosition::Left:
00318 d->m_popup->setGeometry(d->m_tabBar->width(), y(), d->m_popup->width(), height());
00319 break;
00320
00321 case KTabZoomPosition::Right:
00322 d->m_popup->setGeometry(d->m_tabBar->x() - d->m_popup->width(), y(), d->m_popup->width(), height());
00323 break;
00324
00325 case KTabZoomPosition::Top:
00326 d->m_popup->setGeometry(x(), d->m_tabBar->height(), width(), d->m_popup->height());
00327 break;
00328
00329 case KTabZoomPosition::Bottom:
00330 d->m_popup->setGeometry(x(), d->m_tabBar->y() - d->m_popup->height(), width(), d->m_popup->height());
00331 break;
00332 }
00333 }
00334
00335
00336 void KTabZoomWidget::resizeEvent(QResizeEvent *ev)
00337 {
00338 QWidget::resizeEvent(ev);
00339
00340 calculateGeometry();
00341 }
00342
00343
00344 void KTabZoomWidget::setDockMode(bool docked)
00345 {
00346 d->m_docked = docked;
00347
00348 d->m_tabBar->setDockMode(docked);
00349 d->m_popup->setDockMode(docked);
00350
00351 if (!docked)
00352 {
00353 d->m_strut->hide();
00354 return;
00355 }
00356
00357 if( !d->m_popup->isVisible() )
00358 d->m_popup->show();
00359 d->m_strut->show();
00360
00361 adjustStrut();
00362 }
00363
00364
00365 void KTabZoomWidget::saveSettings(KConfig *config)
00366 {
00367 config->writeEntry("Docked", d->m_docked);
00368 if (d->m_tabPosition == KTabZoomPosition::Left || d->m_tabPosition == KTabZoomPosition::Right)
00369 config->writeEntry("Strut", d->m_popup->width());
00370 else
00371 config->writeEntry("Strut", d->m_popup->height());
00372
00373 config->writeEntry("TabIndex", indexOf(current()));
00374 }
00375
00376
00377 void KTabZoomWidget::loadSettings(KConfig *config)
00378 {
00379 int s = config->readNumEntry("Strut", -1);
00380 if (s > 0)
00381 {
00382 if (d->m_tabPosition == KTabZoomPosition::Left || d->m_tabPosition == KTabZoomPosition::Right)
00383 d->m_popup->resize(s, d->m_popup->height());
00384 else
00385 d->m_popup->resize(d->m_popup->width(), s);
00386 }
00387
00388 setDockMode(config->readBoolEntry("Docked", false));
00389
00390 if (d->m_docked)
00391 {
00392 KTZWidgetInfo *i=d->m_info.first();
00393 if (i) {
00394 d->m_tabBar->setActiveIndex(config->readNumEntry("TabIndex", 0));
00395 } else {
00396
00397 setDockMode( false );
00398 }
00399 }
00400 }
00401
00402
00403 void KTabZoomWidget::adjustStrut()
00404 {
00405 if (!d->m_docked)
00406 return;
00407
00408 if (d->m_tabPosition == KTabZoomPosition::Left || d->m_tabPosition == KTabZoomPosition::Right)
00409 d->m_strut->setFixedWidth(d->m_popup->width());
00410 else
00411 d->m_strut->setFixedHeight(d->m_popup->height());
00412 }
00413
00414
00415 #include "ktabzoomwidget.moc"