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