00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kmdimainfrm.h"
00021
#include "kmdidockcontainer.h"
00022
#include "kmdidockcontainer.moc"
00023
00024
#include "kdockwidget_private.h"
00025
00026
#include <qwidgetstack.h>
00027
#include <qlayout.h>
00028
#include <qtimer.h>
00029
#include <qtooltip.h>
00030
#include <kmultitabbar.h>
00031
00032
#include <kdebug.h>
00033
#include <kiconloader.h>
00034
#include <kapplication.h>
00035
#include <kconfig.h>
00036
#include <klocale.h>
00037
00038
static const char*
const not_close_xpm[]={
00039
"5 5 2 1",
00040
"# c black",
00041
". c None",
00042
"#####",
00043
"#...#",
00044
"#...#",
00045
"#...#",
00046
"#####"};
00047
00048 KMdiDockContainer::KMdiDockContainer(
QWidget *parent,
QWidget *win,
int position,
int flags)
00049 :
QWidget(parent),KDockContainer()
00050 {
00051 m_block=
false;
00052 m_inserted=-1;
00053 m_mainWin = win;
00054 oldtab=-1;
00055 mTabCnt=0;
00056 m_position = position;
00057 m_previousTab=-1;
00058
00059 kdDebug(760)<<
"KMdiDockContainer created"<<endl;
00060
00061
QBoxLayout *l;
00062 m_vertical=!((position==KDockWidget::DockTop) || (position==KDockWidget::DockBottom));
00063
00064
if (!m_vertical)
00065 l=
new QVBoxLayout(
this);
00066
else
00067 l=
new QHBoxLayout(
this);
00068
00069 l->setAutoAdd(
false);
00070
00071 m_tb=
new KMultiTabBar(((position==KDockWidget::DockTop) || (position==KDockWidget::DockBottom))?
00072 KMultiTabBar::Horizontal:KMultiTabBar::Vertical,
this);
00073
00074 m_tb->setStyle(KMultiTabBar::KMultiTabBarStyle(flags));
00075 m_tb->showActiveTabTexts(
true);
00076
00077 m_tb->setPosition((position==KDockWidget::DockLeft)?KMultiTabBar::Left:
00078 (position==KDockWidget::DockBottom)?KMultiTabBar::Bottom:
00079 (position==KDockWidget::DockTop)?KMultiTabBar::Top:KMultiTabBar::Right);
00080
00081 m_ws=
new QWidgetStack(
this);
00082
00083 m_ws->setSizePolicy(
QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
00084
00085
if ( (position==KDockWidget::DockLeft) || (position==KDockWidget::DockTop))
00086 {
00087 l->add(m_tb);
00088 l->add(m_ws);
00089 }
00090
else
00091 {
00092 l->add(m_ws);
00093 l->add(m_tb);
00094 }
00095
00096 l->activate();
00097 m_ws->hide();
00098
00099 }
00100
00101 KMdiDockContainer::~KMdiDockContainer()
00102 {
00103
QMap<KDockWidget*,int>::iterator it;
00104
while (m_map.count()) {
00105 it = m_map.begin();
00106 KDockWidget *w=it.key();
00107
if (m_overlapButtons.contains(w)) {
00108 (static_cast<KDockWidgetHeader*>(w->getHeader()->qt_cast(
"KDockWidgetHeader")))->removeButton(m_overlapButtons[w]);
00109 m_overlapButtons.remove(w);
00110 }
00111 m_map.remove(w);
00112 w->undock();
00113 }
00114
deactivated(
this);
00115 }
00116
00117
00118
void KMdiDockContainer::init()
00119 {
00120
if (m_vertical)
00121 {
00122 parentDockWidget()->setForcedFixedWidth(m_tb->width());
00123 activateOverlapMode(m_tb->width());
00124 }
00125
else
00126 {
00127 parentDockWidget()->setForcedFixedHeight(m_tb->height());
00128 activateOverlapMode(m_tb->height());
00129 }
00130 }
00131
00132 KDockWidget *KMdiDockContainer::parentDockWidget()
00133 {
00134
return ((KDockWidget*)parent());
00135 }
00136
00137
void KMdiDockContainer::insertWidget (KDockWidget *dwdg,
QPixmap pixmap,
const QString &text,
int &)
00138 {
00139 KDockWidget* w = (KDockWidget*) dwdg;
00140
int tab;
00141
bool alreadyThere=m_map.contains(w);
00142
00143
if (alreadyThere)
00144 {
00145 tab=m_map[w];
00146
if (m_ws->addWidget(w,tab)!=tab) kdDebug(760)<<
"ERROR COULDN'T READD WIDGET************"<<endl;
00147 kdDebug(760)<<
"READDED WIDGET***********************************"<<endl;
00148
00149
00150 }
00151
else
00152 {
00153 tab=m_ws->addWidget(w);
00154 m_map.insert(w,tab);
00155 m_revMap.insert(tab,w);
00156
00157
if (((KDockWidget*)parentWidget())->mayBeShow())
00158 ((KDockWidget*)parentWidget())->dockBack();
00159
00160
if (w->getHeader()->qt_cast(
"KDockWidgetHeader"))
00161 {
00162 kdDebug(760)<<
"*** KDockWidgetHeader has been found"<<endl;
00163
00164 KDockWidgetHeader *hdr=static_cast<KDockWidgetHeader*>(w->getHeader()->
00165 qt_cast(
"KDockWidgetHeader"));
00166
00167 KDockButton_Private *btn =
new KDockButton_Private( hdr,
"OverlapButton" );
00168
00169 QToolTip::add( btn, i18n(
"Switch between overlap and side by side mode",
"Overlap") );
00170
00171 btn->setToggleButton(
true );
00172 btn->setPixmap( const_cast< const char** >(not_close_xpm) );
00173 hdr->addButton(btn);
00174 m_overlapButtons.insert(w,btn);
00175 btn->setOn(!isOverlapMode());
00176
00177 connect(btn,SIGNAL(clicked()),
this,SLOT(changeOverlapMode()));
00178 }
00179
00180 m_tb->appendTab(pixmap.isNull()?SmallIcon(
"misc"):pixmap,tab,w->tabPageLabel());
00181
00182 kdDebug(760)<<
"NAMENAMENAMENAME:===========================:"<<w->tabPageLabel()<<endl;
00183
00184
00185
00186 connect(m_tb->tab(tab),SIGNAL(clicked(
int)),
this,SLOT(tabClicked(
int)));
00187
00188 kdDebug(760)<<
"KMdiDockContainer::insertWidget()"<<endl;
00189
00190
00191
00192 mTabCnt++;
00193 m_inserted=tab;
00194
int dummy=0;
00195
00196 KDockContainer::insertWidget(w,pixmap,text,dummy);
00197 itemNames.append(w->name());
00198 tabCaptions.insert(w->name(),w->tabPageLabel());
00199 tabTooltips.insert(w->name(),w->toolTipString());
00200 }
00201
00202
00203 }
00204
00205
void KMdiDockContainer::showWidget(KDockWidget *w) {
00206
if (!m_map.contains(w))
return;
00207
int id=m_map[w];
00208 m_tb->setTab(
id,
true);
00209 tabClicked(
id);
00210 }
00211
00212
void KMdiDockContainer::changeOverlapMode()
00213 {
00214
const KDockButton_Private *btn=dynamic_cast<const KDockButton_Private*>(sender());
00215
00216 kdDebug(760)<<
"KMdiDockContainer::changeOverlapMode: button=="<<btn<<endl;
00217
00218
if (!btn)
return;
00219
00220
if (!btn->isOn()) {
00221 kdDebug(760)<<
"KMdiDockContainer::changeOverlapMode: activateOverlapMode"<<endl;
00222
if (m_vertical) {
00223 activateOverlapMode(m_tb->width());
00224 }
00225
else
00226 {
00227 activateOverlapMode(m_tb->height());
00228 }
00229 }
else {
00230 kdDebug(760)<<
"KMdiDockContainer::changeOverlapMode: deactivateOverlapMode"<<endl;
00231 deactivateOverlapMode();
00232 }
00233
00234
for (
QMap<KDockWidget*,KDockButton_Private*>::iterator it=m_overlapButtons.begin();
00235 it!=m_overlapButtons.end();++it)
00236 it.data()->setOn(!isOverlapMode());
00237 }
00238
00239
void KMdiDockContainer::hideIfNeeded() {
00240 kdDebug(760)<<
"************************* hideIfNeeded *************************"<<endl;
00241
if (!itemNames.count())
00242 ((KDockWidget*)parentWidget())->undock();
00243 }
00244
00245
void KMdiDockContainer::removeWidget(KDockWidget* dwdg)
00246 {
00247 KDockWidget* w = (KDockWidget*) dwdg;
00248
if (!m_map.contains(w))
return;
00249
int id=m_map[w];
00250 m_tb->setTab(
id,
false);
00251 tabClicked(
id);
00252 m_tb->removeTab(
id);
00253 m_ws->removeWidget(w);
00254 m_map.remove(w);
00255 m_revMap.remove(
id);
00256
if (m_overlapButtons.contains(w)) {
00257 (static_cast<KDockWidgetHeader*>(w->getHeader()->qt_cast(
"KDockWidgetHeader")))->removeButton(m_overlapButtons[w]);
00258 m_overlapButtons.remove(w);
00259 }
00260 KDockContainer::removeWidget(w);
00261 itemNames.remove(w->name());
00262 tabCaptions.remove(w->name());
00263 tabTooltips.remove(w->name());
00264
if (!itemNames.count())
00265 ((KDockWidget*)parentWidget())->undock();
00266 }
00267
00268
void KMdiDockContainer::undockWidget(KDockWidget *dwdg)
00269 {
00270 KDockWidget* w = (KDockWidget*) dwdg;
00271
00272
if (!m_map.contains(w))
00273
return;
00274
00275 kdDebug(760)<<
"Wiget has been undocked, setting tab down"<<endl;
00276
int id=m_map[w];
00277 m_tb->setTab(
id,
false);
00278 tabClicked(
id);
00279 }
00280
00281
void KMdiDockContainer::tabClicked(
int t)
00282 {
00283 kdDebug(760)<<
"KMdiDockContainer::tabClicked()"<<endl;
00284
bool call_makeVisible=!m_tabSwitching;
00285 m_tabSwitching=
true;
00286
if (m_tb->isTabRaised(t))
00287 {
00288
00289
if (m_ws->isHidden())
00290 {
00291 m_ws->show ();
00292 parentDockWidget()->restoreFromForcedFixedSize();
00293 }
00294
if (!m_ws->widget(t))
00295 {
00296 m_revMap[t]->manualDock(parentDockWidget(),KDockWidget::DockCenter,20);
00297
if (call_makeVisible) m_revMap[t]->makeDockVisible();
00298 m_tabSwitching=
false;
00299 emit
activated(
this);
00300
return;
00301 }
00302 m_ws->raiseWidget(t);
00303
if (m_ws->widget(t)) {
00304 KDockWidget *tmpDw=static_cast<KDockWidget*>(m_ws->widget(t)->qt_cast(
"KDockWidget"));
00305
if (tmpDw) {
00306
if (tmpDw->getWidget()) tmpDw->getWidget()->setFocus();
00307 }
else kdDebug(760)<<
"Something really weird is going on"<<endl;
00308 }
else
00309 kdDebug(760)<<
"KMdiDockContainer::tabClicked(int): m_ws->widget(t)==0 "<<endl;
00310
00311
if (oldtab!=t) m_tb->setTab(oldtab,
false);
00312 m_tabSwitching=
true;
00313 oldtab=t;
00314 emit
activated(
this);
00315 }
00316
else
00317 {
00318 m_previousTab=t;
00319
00320
if (m_block)
return;
00321 emit
deactivated(
this);
00322 m_block=
true;
00323
if (m_ws->widget(t))
00324 {
00325
00326 }
00327 m_block=
false;
00328 m_ws->hide ();
00329 kdDebug(760)<<
"Fixed Width:"<<m_tb->width()<<endl;
00330
if (m_vertical)
00331 parentDockWidget()->setForcedFixedWidth(m_tb->width()+2);
00332
else
00333 parentDockWidget()->setForcedFixedHeight(m_tb->height()+2);
00334 }
00335 m_tabSwitching=
false;
00336 }
00337
00338
void KMdiDockContainer::setToolTip (KDockWidget *,
QString &s)
00339 {
00340 kdDebug(760)<<
"***********************************Setting tooltip for a widget: "<<s<<endl;
00341 }
00342
00343
void KMdiDockContainer::setPixmap(KDockWidget* widget ,
const QPixmap& pixmap)
00344 {
00345
int id=m_ws->id(widget);
00346
if (
id==-1)
return;
00347 KMultiTabBarTab *tab=m_tb->tab(
id);
00348 tab->setIcon(pixmap.isNull()?SmallIcon(
"misc"):pixmap);
00349 }
00350
00351
void KMdiDockContainer::save(
QDomElement& dockEl)
00352 {
00353
QDomDocument doc=dockEl.ownerDocument();
00354
QDomElement el;
00355 el=doc.createElement(
"name");
00356 el.appendChild(doc.createTextNode(
QString(
"%1").arg(parent()->name())));
00357 dockEl.appendChild(el);
00358 el=doc.createElement(
"overlapMode");
00359 el.appendChild(doc.createTextNode(isOverlapMode() ?
"true":
"false"));
00360 dockEl.appendChild(el);
00361
QPtrList<KMultiTabBarTab>* tl=m_tb->tabs();
00362
QPtrListIterator<KMultiTabBarTab> it(*tl);
00363 QStringList::Iterator it2=itemNames.begin();
00364
int i=0;
00365
for (;it.current()!=0;++it,++it2)
00366 {
00367 el=doc.createElement(
"child");
00368 el.setAttribute(
"pos",
QString(
"%1").arg(i));
00369
QString s=tabCaptions[*it2];
00370
if (!s.isEmpty()) {
00371 el.setAttribute(
"tabCaption",s);
00372 }
00373 s=tabTooltips[*it2];
00374
if (!s.isEmpty()) {
00375 el.setAttribute(
"tabTooltip",s);
00376 }
00377 el.appendChild(doc.createTextNode(*it2));
00378 dockEl.appendChild(el);
00379
if (m_tb->isTabRaised(it.current()->id()))
00380 {
00381
QDomElement el2=doc.createElement(
"raised");
00382 el2.appendChild(doc.createTextNode(m_ws->widget(it.current()->id())->name()));
00383 el.appendChild(el2);
00384 }
00385 ++i;
00386 }
00387
00388
00389 }
00390
00391
void KMdiDockContainer::load(
QDomElement& dockEl)
00392 {
00393
QString raise;
00394
00395
for (
QDomNode n=dockEl.firstChild();!n.isNull();n=n.nextSibling()) {
00396
QDomElement el=n.toElement();
00397
if (el.isNull())
continue;
00398
if (el.tagName()==
"overlapMode") {
00399
if (el.attribute(
"overlapMode")!=
"false")
00400 activateOverlapMode(m_tb->width());
00401
else
00402 deactivateOverlapMode();
00403 }
else if (el.tagName()==
"child") {
00404 KDockWidget *dw=((KDockWidget*)parent())->dockManager()->getDockWidgetFromName(el.text());
00405
if (dw)
00406 {
00407
if (el.hasAttribute(
"tabCaption")) {
00408 dw->setTabPageLabel(el.attribute(
"tabCaption"));
00409 }
00410
if (el.hasAttribute(
"tabTooltip")) {
00411 dw->setToolTipString(el.attribute(
"tabTooltip"));
00412 }
00413 dw->manualDock((KDockWidget*)parent(),KDockWidget::DockCenter);
00414 }
00415 }
00416 }
00417
00418
00419
QPtrList<KMultiTabBarTab>* tl=m_tb->tabs();
00420
QPtrListIterator<KMultiTabBarTab> it1(*tl);
00421 m_ws->hide();
00422
if (m_vertical)
00423 parentDockWidget()->setForcedFixedWidth(m_tb->width());
00424
else
00425 parentDockWidget()->setForcedFixedHeight(m_tb->height());
00426
for (;it1.current()!=0;++it1)
00427 {
00428 m_tb->setTab(it1.current()->id(),
false);
00429 }
00430 kapp->syncX();
00431 m_delayedRaise=-1;
00432
00433
for (
QMap<KDockWidget*,KDockButton_Private*>::iterator it=m_overlapButtons.begin();
00434 it!=m_overlapButtons.end();++it)
00435 it.data()->setOn(!isOverlapMode());
00436
00437
if (!raise.isEmpty())
00438 {
00439
for (
QMap<KDockWidget*,int>::iterator it=m_map.begin();it!=m_map.end();++it)
00440 {
00441
if (it.key()->name()==raise)
00442 {
00443 m_delayedRaise=it.data();
00444 QTimer::singleShot(0,
this,SLOT(delayedRaise()));
00445 kdDebug(760)<<
"************** raising *******: "<<it.key()->name()<<endl;
00446
break;
00447 }
00448 }
00449
00450 }
00451
if (m_delayedRaise==-1) QTimer::singleShot(0,
this,SLOT(init()));
00452
00453
00454
00455
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
void KMdiDockContainer::save(KConfig* cfg,
const QString& group_or_prefix)
00473 {
00474
QString grp=cfg->group();
00475 cfg->deleteGroup(group_or_prefix+
QString(
"::%1").arg(parent()->name()));
00476 cfg->setGroup(group_or_prefix+
QString(
"::%1").arg(parent()->name()));
00477
00478
if (isOverlapMode()) cfg->writeEntry(
"overlapMode",
"true");
00479
else cfg->writeEntry(
"overlapMode",
"false");
00480
00481
QPtrList<KMultiTabBarTab>* tl=m_tb->tabs();
00482
QPtrListIterator<KMultiTabBarTab> it(*tl);
00483 QStringList::Iterator it2=itemNames.begin();
00484
int i=0;
00485
for (;it.current()!=0;++it,++it2)
00486 {
00487
00488 cfg->writeEntry(
QString(
"widget%1").arg(i),(*it2));
00489
QString s=tabCaptions[*it2];
00490
if (!s.isEmpty()) {
00491 cfg->writeEntry(
QString(
"widget%1-tabCaption").arg(i),s);
00492 }
00493 s=tabTooltips[*it2];
00494
if (!s.isEmpty()) {
00495 cfg->writeEntry(
QString(
"widget%1-tabTooltip").arg(i),s);
00496 }
00497
00498
if (m_tb->isTabRaised(it.current()->id()))
00499 cfg->writeEntry(m_ws->widget(it.current()->id())->name(),
true);
00500 ++i;
00501 }
00502 cfg->sync();
00503 cfg->setGroup(grp);
00504
00505 }
00506
00507
void KMdiDockContainer::load(KConfig* cfg,
const QString& group_or_prefix)
00508 {
00509
QString grp=cfg->group();
00510 cfg->setGroup(group_or_prefix+
QString(
"::%1").arg(parent()->name()));
00511
00512
if (cfg->readEntry(
"overlapMode")!=
"false")
00513 activateOverlapMode(m_tb->width());
00514
else
00515 deactivateOverlapMode();
00516
00517
00518
int i=0;
00519
QString raise;
00520
while (
true)
00521 {
00522
QString dwn=cfg->readEntry(
QString(
"widget%1").arg(i));
00523
if (dwn.isEmpty())
break;
00524 kdDebug(760)<<
"*************************************************************Configuring dockwidget :"<<dwn<<endl;
00525 KDockWidget *dw=((KDockWidget*)parent())->dockManager()->getDockWidgetFromName(dwn);
00526
if (dw)
00527 {
00528
QString s=cfg->readEntry(
QString(
"widget%1-tabCaption").arg(i));
00529
if (!s.isEmpty()) {
00530 dw->setTabPageLabel(s);
00531 }
00532 s=cfg->readEntry(
QString(
"widget%1-tabTooltip").arg(i));
00533
if (!s.isEmpty()) {
00534 dw->setToolTipString(s);
00535 }
00536 dw->manualDock((KDockWidget*)parent(),KDockWidget::DockCenter);
00537 }
00538
if (cfg->readBoolEntry(dwn,
false)) raise=dwn;
00539 i++;
00540
00541 }
00542
00543
QPtrList<KMultiTabBarTab>* tl=m_tb->tabs();
00544
QPtrListIterator<KMultiTabBarTab> it1(*tl);
00545 m_ws->hide();
00546
if (m_vertical)
00547 parentDockWidget()->setForcedFixedWidth(m_tb->width());
00548
else
00549 parentDockWidget()->setForcedFixedHeight(m_tb->height());
00550
for (;it1.current()!=0;++it1)
00551 {
00552 m_tb->setTab(it1.current()->id(),
false);
00553 }
00554 kapp->syncX();
00555 m_delayedRaise=-1;
00556
00557
for (
QMap<KDockWidget*,KDockButton_Private*>::iterator it=m_overlapButtons.begin();
00558 it!=m_overlapButtons.end();++it)
00559 it.data()->setOn(!isOverlapMode());
00560
00561
if (!raise.isEmpty())
00562 {
00563
for (
QMap<KDockWidget*,int>::iterator it=m_map.begin();it!=m_map.end();++it)
00564 {
00565
if (it.key()->name()==raise)
00566 {
00567
00568
00569
00570
00571
00572
00573
00574 m_delayedRaise=it.data();
00575 QTimer::singleShot(0,
this,SLOT(delayedRaise()));
00576 kdDebug(760)<<
"************** raising *******: "<<it.key()->name()<<endl;
00577
break;
00578 }
00579 }
00580
00581 }
00582
if (m_delayedRaise==-1) QTimer::singleShot(0,
this,SLOT(init()));
00583 cfg->setGroup(grp);
00584
00585 }
00586
00587
void KMdiDockContainer::delayedRaise()
00588 {
00589 m_tb->setTab(m_delayedRaise,
true);
00590 tabClicked(m_delayedRaise);
00591 }
00592
00593
void KMdiDockContainer::collapseOverlapped()
00594 {
00595
if (m_tabSwitching)
return;
00596
if (isOverlapMode()){
00597
QPtrList<KMultiTabBarTab>* tl=m_tb->tabs();
00598
QPtrListIterator<KMultiTabBarTab> it(*tl);
00599
for(;it.current();++it) {
00600
if (it.current()->isOn()) {
00601 kdDebug(760)<<
"Lowering TAB"<<endl;
00602 it.current()->setState(
false);
00603 tabClicked(it.current()->id());
00604 }
00605 }
00606 }
00607 }
00608
00609
void KMdiDockContainer::toggle() {
00610 kdDebug(760)<<
"DockContainer:activate"<<endl;
00611
if (m_tb->isTabRaised(oldtab)) {
00612 m_tb->setTab(oldtab,
false);
00613 tabClicked(oldtab);
00614
KMdiMainFrm *mainFrm = dynamic_cast<KMdiMainFrm*>(m_mainWin);
00615
if (mainFrm && mainFrm->
activeWindow() )
00616 mainFrm->
activeWindow()->setFocus();
00617
00618 }
else {
00619 kdDebug(760)<<
"KMdiDockContainer::toggle(): raising tab"<<endl;
00620
if (m_tb->tab(m_previousTab)==0) {
00621
if (m_tb->tabs()->count()==0)
return;
00622 m_previousTab=m_tb->tabs()->getFirst()->id();
00623 }
00624 m_tb->setTab(m_previousTab,
true);
00625 tabClicked(m_previousTab);
00626 }
00627 }
00628
00629
void KMdiDockContainer::prevToolView() {
00630
QPtrList<KMultiTabBarTab>* tabs=m_tb->tabs();
00631
int pos=tabs->findRef(m_tb->tab(oldtab));
00632
if (pos==-1)
return;
00633 pos--;
00634
if (pos<0) pos=tabs->count()-1;
00635 KMultiTabBarTab *tab=tabs->at(pos);
00636
if (!tab)
return;
00637 m_tb->setTab(tab->id(),
true);
00638 tabClicked(tab->id());
00639 }
00640
00641
void KMdiDockContainer::nextToolView() {
00642
QPtrList<KMultiTabBarTab>* tabs=m_tb->tabs();
00643
int pos=tabs->findRef(m_tb->tab(oldtab));
00644
if (pos==-1)
return;
00645 pos++;
00646
if (pos>=(
int)tabs->count()) pos=0;
00647 KMultiTabBarTab *tab=tabs->at(pos);
00648
if (!tab)
return;
00649 m_tb->setTab(tab->id(),
true);
00650 tabClicked(tab->id());
00651 }
00652
00653