//============================================================================= // // File : kvi_mdimanager.cpp // Creation date : Wed Jun 21 2000 17:28:04 by Szymon Stefanek // // This file is part of the KVirc irc client distribution // Copyright (C) 2000-2003 Szymon Stefanek (pragma at kvirc dot net) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your opinion) any later version. // // This program is distributed in the HOPE that it will be USEFUL, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #define __KVIRC__ #include "kvi_debug.h" #include "kvi_settings.h" #include "kvi_mdimanager.h" #include "kvi_mdichild.h" #include "kvi_locale.h" #include "kvi_options.h" #include "kvi_iconmanager.h" #include "kvi_frame.h" #include "kvi_menubar.h" #include "kvi_mdicaption.h" #include "kvi_app.h" #include "kvi_tal_popupmenu.h" #include #include #include #include #include #include #include #ifdef COMPILE_USE_QT4 #include "kvi_tal_hbox.h" #endif #ifdef COMPILE_PSEUDO_TRANSPARENCY #include extern TQPixmap * g_pShadedParentGlobalDesktopBackground; #endif KviMdiManager::KviMdiManager(TQWidget * parent,KviFrame * pFrm,const char * name) : KviTalScrollView(parent) { setFrameShape(NoFrame); m_pZ = new KviPointerList; m_pZ->setAutoDelete(true); m_pFrm = pFrm; m_iSdiIconItemId = 0; m_iSdiCloseItemId = 0; m_iSdiRestoreItemId = 0; m_iSdiMinimizeItemId = 0; m_pSdiIconButton = 0; m_pSdiCloseButton = 0; m_pSdiRestoreButton = 0; m_pSdiMinimizeButton = 0; #ifdef COMPILE_USE_QT4 m_pSdiControls = 0; #endif m_pWindowPopup = new KviTalPopupMenu(this); connect(m_pWindowPopup,TQT_SIGNAL(activated(int)),this,TQT_SLOT(menuActivated(int))); connect(m_pWindowPopup,TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(fillWindowPopup())); m_pTileMethodPopup = new KviTalPopupMenu(this); connect(m_pTileMethodPopup,TQT_SIGNAL(activated(int)),this,TQT_SLOT(tileMethodMenuActivated(int))); #ifdef COMPILE_USE_QT4 viewport()->setAutoFillBackground(false); #else viewport()->setBackgroundMode(TQWidget::NoBackground); #endif setStaticBackground(true); resizeContents(width(),height()); #ifdef COMPILE_USE_QT4 setFocusPolicy(TQ_NoFocus); viewport()->setFocusPolicy(TQ_NoFocus); #else setFocusPolicy(TQ_NoFocus); viewport()->setFocusPolicy(TQ_NoFocus); #endif connect(g_pApp,TQT_SIGNAL(reloadImages()),this,TQT_SLOT(reloadImages())); } KviMdiManager::~KviMdiManager() { delete m_pZ; } void KviMdiManager::reloadImages() { for(KviMdiChild * c = m_pZ->first();c;c = m_pZ->next()) { c->reloadImages(); } } bool KviMdiManager::focusNextPrevChild(bool bNext) { //bug("FFFFFF"); // this is a TQScrollView bug... it doesn't pass this // event to the toplevel window return m_pFrm->focusNextPrevChild(bNext); } void KviMdiManager::drawContents(TQPainter *p,int x,int y,int w,int h) { //tqDebug("MY DRAW CONTENTS (%d,%d,%d,%d)",x,y,w,h); TQRect r(x,y,w,h); #ifdef COMPILE_PSEUDO_TRANSPARENCY if(g_pShadedParentGlobalDesktopBackground) { TQPoint pnt = viewport()->mapToGlobal(contentsToViewport(r.topLeft())); p->drawTiledPixmap(r,*(g_pShadedParentGlobalDesktopBackground),pnt); return; } #endif if(KVI_OPTION_PIXMAP(KviOption_pixmapMdiBackground).pixmap()) { p->drawTiledPixmap(r,*(KVI_OPTION_PIXMAP(KviOption_pixmapMdiBackground).pixmap())); } else { p->fillRect(r,KVI_OPTION_COLOR(KviOption_colorMdiBackground)); } } void KviMdiManager::manageChild(KviMdiChild * lpC,bool bCascade,TQRect *setGeom) { __range_valid(lpC); m_pZ->insert(0,lpC); //hidden -> last in the Z order if(bCascade) { TQPoint p = getCascadePoint(m_pZ->count()-1); addChild(lpC,p.x(),p.y()); } else { // FIXME: is this right ? TQPoint p = lpC->pos(); if(p.x() < 0)p.setX(0); if(p.y() < 0)p.setY(0); addChild(lpC,p.x(),p.y()); if(setGeom) { if(setGeom->left() < 0)setGeom->setLeft(0); if(setGeom->top() < 0)setGeom->setTop(0); moveChild(lpC,setGeom->x(),setGeom->y()); lpC->setGeometry(*setGeom); } } if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } void KviMdiManager::showAndActivate(KviMdiChild * lpC) { lpC->show(); setTopChild(lpC,true); if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } void KviMdiManager::setTopChild(KviMdiChild *lpC,bool bSetFocus) { __range_valid(lpC); // The following check fails safely at startup.... // __range_valid(lpC->isVisible() || lpC->testWState(WState_ForceHide)); KviMdiChild * pOldTop = m_pZ->last(); if(pOldTop != lpC) { m_pZ->setAutoDelete(false); if(!m_pZ->removeRef(lpC)) { m_pZ->setAutoDelete(true); return; // no such child ? } // disable the labels of all the other children //for(KviMdiChild *pC=m_pZ->first();pC;pC=m_pZ->next()) //{ // pC->captionLabel()->setActive(false); //} KviMdiChild * pMaximizedChild = pOldTop; if(pOldTop) { pOldTop->captionLabel()->setActive(false); if(pOldTop->m_state != KviMdiChild::Maximized)pMaximizedChild=0; } m_pZ->setAutoDelete(true); m_pZ->append(lpC); if(pMaximizedChild)lpC->maximize(); //do not animate the change lpC->raise(); if(pMaximizedChild)pMaximizedChild->restore(); } if(bSetFocus) { if(!lpC->hasFocus()) { lpC->setFocus(); /* if(topLevelWidget()->isActiveWindow()) { } */ } } } void KviMdiManager::focusInEvent(TQFocusEvent *) { focusTopChild(); } void KviMdiManager::destroyChild(KviMdiChild *lpC,bool bFocusTopChild) { bool bWasMaximized = lpC->state() == KviMdiChild::Maximized; disconnect(lpC); lpC->blockSignals(true); #ifdef _KVI_DEBUG_CHECK_RANGE_ //Report invalid results in a debug session __range_valid(m_pZ->removeRef(lpC)); #else m_pZ->removeRef(lpC); #endif if(bWasMaximized) { KviMdiChild * c=topChild(); if(c) { if(c->state() != KviMdiChild::Minimized)c->maximize(); else { // minimized top child...the last one leaveSDIMode(); } } else { // SDI state change leaveSDIMode(); } } if(bFocusTopChild)focusTopChild(); if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); updateContentsSize(); } KviMdiChild * KviMdiManager::highestChildExcluding(KviMdiChild * pChild) { KviMdiChild * c = m_pZ->last(); while(c && (c == pChild))c = m_pZ->prev(); return c; } TQPoint KviMdiManager::getCascadePoint(int indexOfWindow) { TQPoint pnt(0,0); if(indexOfWindow==0)return pnt; KviMdiChild *lpC=m_pZ->first(); int step=(lpC ? (lpC->captionLabel()->heightHint()+KVI_MDICHILD_BORDER) : 20); int availableHeight=viewport()->height()-(lpC ? lpC->minimumSize().height() : KVI_MDICHILD_MIN_HEIGHT); int availableWidth=viewport()->width()-(lpC ? lpC->minimumSize().width() : KVI_MDICHILD_MIN_WIDTH); int ax=0; int ay=0; for(int i=0;iavailableWidth)ax=0; if(ay>availableHeight)ay=0; } pnt.setX(ax); pnt.setY(ay); return pnt; } void KviMdiManager::mousePressEvent(TQMouseEvent *e) { //Popup the window menu if(e->button() & Qt::RightButton)m_pWindowPopup->popup(mapToGlobal(e->pos())); } void KviMdiManager::childMoved(KviMdiChild *) { updateContentsSize(); } void KviMdiManager::maximizeChild(KviMdiChild * lpC) { // the children must be moved once by the means of TQScrollView::moveChild() // so the TQScrollView internal structures get updated with the negative // position of the widget, otherwise, when restoring with moveChild() // it will refuse to move it back to the original position resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; moveChild(lpC,-KVI_MDICHILD_HIDDEN_EDGE, -(KVI_MDICHILD_HIDDEN_EDGE + KVI_MDICHILD_SPACING + lpC->m_pCaption->heightHint())); lpC->setGeometry( -KVI_MDICHILD_HIDDEN_EDGE, -(KVI_MDICHILD_HIDDEN_EDGE + KVI_MDICHILD_SPACING + lpC->m_pCaption->heightHint()), viewport()->width() + (KVI_MDICHILD_HIDDEN_EDGE * 2), //KVI_MDICHILD_DOUBLE_HIDDEN_EDGE, viewport()->height() + (KVI_MDICHILD_HIDDEN_EDGE * 2) + lpC->m_pCaption->heightHint() + KVI_MDICHILD_SPACING); if(isInSDIMode())updateSDIMode(); else { enterSDIMode(lpC); // make sure that the child is focused lpC->setFocus(); } // fixme: we could hide all the other children now! } void KviMdiManager::resizeEvent(TQResizeEvent *e) { //If we have a maximized children at the top , adjust its size KviTalScrollView::resizeEvent(e); KviMdiChild *lpC=m_pZ->last(); if(lpC) { if(lpC->state()==KviMdiChild::Maximized) { // SDI mode lpC->resize(viewport()->width() + (KVI_MDICHILD_HIDDEN_EDGE * 2), viewport()->height() + lpC->m_pCaption->heightHint() + (KVI_MDICHILD_HIDDEN_EDGE * 2) + KVI_MDICHILD_SPACING); return; } else { if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } } updateContentsSize(); } /* void KviMdiManager::childMaximized(KviMdiChild * lpC) { if(lpC == m_pZ->last()) { enterSDIMode(lpC); } updateContentsSize(); } */ void KviMdiManager::childMinimized(KviMdiChild * lpC,bool bWasMaximized) { __range_valid(lpC); if(m_pZ->findRef(lpC) == -1)return; if(m_pZ->count() > 1) { m_pZ->setAutoDelete(false); #ifdef _KVI_DEBUG_CHECK_RANGE_ //Report invalid results in a debug session __range_valid(m_pZ->removeRef(lpC)); #else m_pZ->removeRef(lpC); #endif m_pZ->setAutoDelete(true); m_pZ->insert(0,lpC); if(bWasMaximized) { // Need to maximize the top child lpC = m_pZ->last(); if(!lpC)return; //?? if(lpC->state()==KviMdiChild::Minimized) { if(bWasMaximized)leaveSDIMode(); return; } lpC->maximize(); //do nrot animate the change } else { if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } focusTopChild(); } else { // Unique window minimized...it won't loose the focus...!! setFocus(); //Remove focus from the child if(bWasMaximized)leaveSDIMode(); } updateContentsSize(); } void KviMdiManager::childRestored(KviMdiChild * lpC,bool bWasMaximized) { if(bWasMaximized) { if(lpC != m_pZ->last())return; // do nothing in this case leaveSDIMode(); updateContentsSize(); } if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } void KviMdiManager::focusTopChild() { KviMdiChild *lpC=m_pZ->last(); if(!lpC)return; if(!lpC->isVisible())return; // if(lpC->state()==KviMdiChild::Minimized)return; // tqDebug("Focusing top child %s",lpC->name()); //disable the labels of all the other children for(KviMdiChild *pC=m_pZ->first();pC;pC=m_pZ->next()) { if(pC != lpC) pC->captionLabel()->setActive(false); } lpC->raise(); if(!lpC->hasFocus())lpC->setFocus(); } void KviMdiManager::minimizeActiveChild() { KviMdiChild * lpC = m_pZ->last(); if(!lpC)return; if(lpC->state() != KviMdiChild::Minimized)lpC->minimize(); } void KviMdiManager::restoreActiveChild() { KviMdiChild * lpC = m_pZ->last(); if(!lpC)return; if(lpC->state() == KviMdiChild::Maximized)lpC->restore(); } void KviMdiManager::closeActiveChild() { KviMdiChild * lpC = m_pZ->last(); if(!lpC)return; lpC->closeRequest(); } void KviMdiManager::updateContentsSize() { KviMdiChild * c = m_pZ->last(); if(c) { if(c->state() == KviMdiChild::Maximized) { return; } } int fw = frameWidth() * 2; int mx = width() - fw; int my = height() - fw; for(c = m_pZ->first();c;c = m_pZ->next()) { if(c->isVisible()) { int x = childX(c) + c->width(); if(x > mx)mx = x; int y = childY(c) + c->height(); if(y > my)my = y; } } resizeContents(mx,my); } void KviMdiManager::updateSDIMode() { KviMdiChild * lpC = m_pZ->last(); if(m_pSdiCloseButton) m_pSdiCloseButton->setEnabled(lpC ? lpC->closeEnabled() : false); // This would result in an addictional main menu bar entry on MacOSX which would trigger a popup menu and not // a submenu. Due to the optical reasons it is removed here. // The same popup is triggered by right clicking on the window name in the channel window list. #ifndef Q_OS_MACX KviMenuBar * b = m_pFrm->mainMenuBar(); const TQPixmap * pix = lpC ? lpC->icon() : 0; if(!pix)pix = g_pIconManager->getSmallIcon(KVI_SMALLICON_NONE); else if(pix->isNull())pix = g_pIconManager->getSmallIcon(KVI_SMALLICON_NONE); if(!m_pSdiIconButton) { m_pSdiIconButton = new KviMenuBarToolButton(b,*pix,"nonne"); connect(m_pSdiIconButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(activeChildSystemPopup())); #ifdef COMPILE_USE_QT4 // This is an obscure, undocumented and internal function in QT4 TQMenuBar // I won't be surprised if this disappears.... b->setCornerWidget(m_pSdiIconButton,TQt::TopLeftCorner); m_pSdiIconButton->show(); #else m_iSdiIconItemId = b->insertItem(m_pSdiIconButton,-1,0); #endif connect(m_pSdiIconButton,TQT_SIGNAL(destroyed()),this,TQT_SLOT(sdiIconButtonDestroyed())); } else { m_pSdiIconButton->setPixmap(*pix); } #endif //Q_OS_MACX } void KviMdiManager::activeChildSystemPopup() { KviMdiChild * lpC = m_pZ->last(); if(!lpC)return; TQPoint pnt; if(m_pSdiIconButton) { pnt = m_pSdiIconButton->mapToGlobal(TQPoint(0,m_pSdiIconButton->height())); } else { pnt = TQCursor::pos(); } lpC->emitSystemPopupRequest(pnt); } bool KviMdiManager::isInSDIMode() { return (m_pSdiCloseButton != 0); } void KviMdiManager::enterSDIMode(KviMdiChild *lpC) { if(!m_pSdiCloseButton) { KviMenuBar * b = m_pFrm->mainMenuBar(); TQWidget * pButtonParent; #ifdef COMPILE_USE_QT4 m_pSdiControls = new KviTalHBox(b); m_pSdiControls->setMargin(0); m_pSdiControls->setSpacing(2); m_pSdiControls->setAutoFillBackground(false); pButtonParent = m_pSdiControls; #else pButtonParent = b; #endif m_pSdiMinimizeButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),"btnminimize"); connect(m_pSdiMinimizeButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(minimizeActiveChild())); #ifndef COMPILE_USE_QT4 m_iSdiMinimizeItemId = b->insertItem(m_pSdiMinimizeButton,-1,b->count()); #endif connect(m_pSdiMinimizeButton,TQT_SIGNAL(destroyed()),this,TQT_SLOT(sdiMinimizeButtonDestroyed())); m_pSdiRestoreButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),"btnrestore"); connect(m_pSdiRestoreButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(restoreActiveChild())); #ifndef COMPILE_USE_QT4 m_iSdiRestoreItemId = b->insertItem(m_pSdiRestoreButton,-1,b->count()); #endif connect(m_pSdiRestoreButton,TQT_SIGNAL(destroyed()),this,TQT_SLOT(sdiRestoreButtonDestroyed())); m_pSdiCloseButton = new KviMenuBarToolButton(pButtonParent,*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),"btnclose"); connect(m_pSdiCloseButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(closeActiveChild())); #ifndef COMPILE_USE_QT4 m_iSdiCloseItemId = b->insertItem(m_pSdiCloseButton,-1,b->count()); #endif connect(m_pSdiCloseButton,TQT_SIGNAL(destroyed()),this,TQT_SLOT(sdiCloseButtonDestroyed())); #ifdef COMPILE_USE_QT4 // This is an obscure, undocumented and internal function in QT4 TQMenuBar // I won't be surprised if this disappears.... b->setCornerWidget(m_pSdiControls,TQt::TopRightCorner); // The show below SHOULD force a re-layout of the menubar.. // but it doesn't work when the KviFrame is still hidden (at startup) // We handle this BUG in showEvent() m_pSdiControls->show(); #else m_pSdiRestoreButton->show(); m_pSdiMinimizeButton->show(); m_pSdiCloseButton->show(); #endif emit enteredSdiMode(); setVScrollBarMode(KviTalScrollView::AlwaysOff); setHScrollBarMode(KviTalScrollView::AlwaysOff); } updateSDIMode(); } void KviMdiManager::relayoutMenuButtons() { #ifdef COMPILE_USE_QT4 // force a re-layout of the menubar in TQt4 (see the note in enterSDIMode()) // by resetting the corner widget if(m_pSdiControls) { m_pFrm->mainMenuBar()->setCornerWidget(0,TQt::TopRightCorner); m_pFrm->mainMenuBar()->setCornerWidget(m_pSdiControls,TQt::TopRightCorner); } // also force an activation of the top MdiChild since it probably didn't get it yet KviMdiChild * c = topChild(); if(c) c->activate(false); #endif } void KviMdiManager::sdiIconButtonDestroyed() { m_iSdiIconItemId = 0; m_pSdiIconButton = 0; } void KviMdiManager::sdiMinimizeButtonDestroyed() { m_iSdiMinimizeItemId = 0; m_pSdiMinimizeButton = 0; } void KviMdiManager::sdiRestoreButtonDestroyed() { m_iSdiRestoreItemId = 0; m_pSdiRestoreButton = 0; } void KviMdiManager::sdiCloseButtonDestroyed() { m_iSdiCloseItemId = 0; m_pSdiCloseButton = 0; } void KviMdiManager::leaveSDIMode() { __range_valid(m_pSdiCloseButton); #ifdef COMPILE_USE_QT4 if(m_pSdiControls) { delete m_pSdiControls; m_pSdiControls = 0; } if(m_pSdiIconButton) { m_pSdiIconButton->hide(); // this will force a TQMenuBar relayout delete m_pSdiIconButton; m_pSdiIconButton = 0; } #else if(m_iSdiIconItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiIconItemId); if(m_iSdiCloseItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiCloseItemId); if(m_iSdiRestoreItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiRestoreItemId); if(m_iSdiMinimizeItemId != 0)m_pFrm->mainMenuBar()->removeItem(m_iSdiMinimizeItemId); #endif setVScrollBarMode(KviTalScrollView::Auto); setHScrollBarMode(KviTalScrollView::Auto); emit leftSdiMode(); } #define KVI_TILE_METHOD_ANODINE 0 #define KVI_TILE_METHOD_PRAGMA4HOR 1 #define KVI_TILE_METHOD_PRAGMA4VER 2 #define KVI_TILE_METHOD_PRAGMA6HOR 3 #define KVI_TILE_METHOD_PRAGMA6VER 4 #define KVI_TILE_METHOD_PRAGMA9HOR 5 #define KVI_TILE_METHOD_PRAGMA9VER 6 #define KVI_NUM_TILE_METHODS 7 void KviMdiManager::fillWindowPopup() { m_pWindowPopup->clear(); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CASCADEWINDOWS)),(__tr2qs("&Cascade Windows")),this,TQT_SLOT(cascadeWindows())); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CASCADEWINDOWS)),(__tr2qs("Cascade &Maximized")),this,TQT_SLOT(cascadeMaximized())); m_pWindowPopup->insertSeparator(); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("&Tile Windows")),this,TQT_SLOT(tile())); m_pTileMethodPopup->clear(); int id = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_AUTOTILEWINDOWS)),(__tr2qs("&Auto Tile")),this,TQT_SLOT(toggleAutoTile())); m_pTileMethodPopup->setItemChecked(id,KVI_OPTION_BOOL(KviOption_boolAutoTileWindows)); m_pTileMethodPopup->setItemParameter(id,-1); m_pTileMethodPopup->insertSeparator(); int ids[KVI_NUM_TILE_METHODS]; ids[KVI_TILE_METHOD_ANODINE] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Anodine's Full Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_ANODINE],KVI_TILE_METHOD_ANODINE); ids[KVI_TILE_METHOD_PRAGMA4HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 4-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA4HOR],KVI_TILE_METHOD_PRAGMA4HOR); ids[KVI_TILE_METHOD_PRAGMA4VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 4-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA4VER],KVI_TILE_METHOD_PRAGMA4VER); ids[KVI_TILE_METHOD_PRAGMA6HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 6-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA6HOR],KVI_TILE_METHOD_PRAGMA6HOR); ids[KVI_TILE_METHOD_PRAGMA6VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 6-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA6VER],KVI_TILE_METHOD_PRAGMA6VER); ids[KVI_TILE_METHOD_PRAGMA9HOR] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Horizontal 9-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA9HOR],KVI_TILE_METHOD_PRAGMA9HOR); ids[KVI_TILE_METHOD_PRAGMA9VER] = m_pTileMethodPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Pragma's Vertical 9-Grid"))); m_pTileMethodPopup->setItemParameter(ids[KVI_TILE_METHOD_PRAGMA9VER],KVI_TILE_METHOD_PRAGMA9VER); if(KVI_OPTION_UINT(KviOption_uintTileMethod) >= KVI_NUM_TILE_METHODS)KVI_OPTION_UINT(KviOption_uintTileMethod) = KVI_TILE_METHOD_PRAGMA9HOR; m_pTileMethodPopup->setItemChecked(ids[KVI_OPTION_UINT(KviOption_uintTileMethod)],true); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TILEWINDOWS)),(__tr2qs("Tile Met&hod")),m_pTileMethodPopup); m_pWindowPopup->insertSeparator(); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXVERTICAL)),(__tr2qs("Expand &Vertically")),this,TQT_SLOT(expandVertical())); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MAXHORIZONTAL)),(__tr2qs("Expand &Horizontally")),this,TQT_SLOT(expandHorizontal())); m_pWindowPopup->insertSeparator(); m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINIMIZE)),(__tr2qs("Mi&nimize All")),this,TQT_SLOT(minimizeAll())); // m_pWindowPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_RESTORE)),(__tr2qs("&Restore all")),this,TQT_SLOT(restoreAll())); // m_pWindowPopup->insertSeparator(); int i=100; TQString szItem; TQString szCaption; for(KviMdiChild *lpC=m_pZ->first();lpC;lpC=m_pZ->next()) { szItem.setNum(((uint)i)-99); szItem+=". "; szCaption = lpC->plainCaption(); if(szCaption.length() > 30) { TQString trail = szCaption.right(12); szCaption.truncate(12); szCaption+="..."; szCaption+=trail; } if(lpC->state()==KviMdiChild::Minimized) { szItem+="("; szItem+=szCaption; szItem+=")"; } else szItem+=szCaption; const TQPixmap * pix = lpC->icon(); if(pix && !(pix->isNull()))m_pWindowPopup->insertItem(*pix,szItem,i); else m_pWindowPopup->insertItem(szItem,i); m_pWindowPopup->setItemChecked(i,((uint)i)==(m_pZ->count()+99)); i++; } } void KviMdiManager::menuActivated(int id) { if(id<100)return; id-=100; __range_valid(((uint)id) < m_pZ->count()); KviMdiChild *lpC=m_pZ->at(id); if(!lpC)return; if(lpC->state()==KviMdiChild::Minimized)lpC->restore(); setTopChild(lpC,true); } void KviMdiManager::ensureNoMaximized() { KviMdiChild * lpC; for(lpC=m_pZ->first();lpC;lpC=m_pZ->next()) { if(lpC->state()==KviMdiChild::Maximized)lpC->restore(); } } void KviMdiManager::tileMethodMenuActivated(int id) { int idx = m_pTileMethodPopup->itemParameter(id); if(idx < 0)idx = 0; if(idx >= KVI_NUM_TILE_METHODS)idx = KVI_TILE_METHOD_PRAGMA9VER; KVI_OPTION_UINT(KviOption_uintTileMethod) = idx; if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows))tile(); } void KviMdiManager::cascadeWindows() { ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; int idx=0; KviPointerList list(*m_pZ); list.setAutoDelete(false); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Minimized) { TQPoint p = getCascadePoint(idx); moveChild(lpC,p.x(),p.y()); lpC->resize(lpC->sizeHint()); idx++; } list.removeFirst(); } focusTopChild(); updateContentsSize(); } void KviMdiManager::cascadeMaximized() { ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; int idx=0; KviPointerList list(*m_pZ); list.setAutoDelete(false); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Minimized) { TQPoint pnt(getCascadePoint(idx)); moveChild(lpC,pnt.x(),pnt.y()); TQSize curSize(viewport()->width() - pnt.x(),viewport()->height() - pnt.y()); if((lpC->minimumSize().width() > curSize.width()) || (lpC->minimumSize().height() > curSize.height()))lpC->resize(lpC->minimumSize()); else lpC->resize(curSize); idx++; } list.removeFirst(); } focusTopChild(); updateContentsSize(); } void KviMdiManager::expandVertical() { ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; KviPointerList list(*m_pZ); list.setAutoDelete(false); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Minimized) { moveChild(lpC,lpC->x(),0); lpC->resize(lpC->width(),viewport()->height()); } list.removeFirst(); } focusTopChild(); updateContentsSize(); } void KviMdiManager::expandHorizontal() { ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; KviPointerList list(*m_pZ); list.setAutoDelete(false); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Minimized) { moveChild(lpC,0,lpC->y()); lpC->resize(viewport()->width(),lpC->height()); } list.removeFirst(); } focusTopChild(); updateContentsSize(); } void KviMdiManager::minimizeAll() { KviPointerList list(*m_pZ); list.setAutoDelete(false); m_pFrm->setActiveWindow((KviWindow*)m_pFrm->firstConsole()); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Minimized)lpC->minimize(); list.removeFirst(); } focusTopChild(); updateContentsSize(); } /* void KviMdiManager::restoreAll() { int idx=0; KviPointerList list(*m_pZ); list.setAutoDelete(false); while(!list.isEmpty()) { KviMdiChild *lpC=list.first(); if(lpC->state() != KviMdiChild::Normal && (!(lpC->plainCaption()).contains("CONSOLE") )) lpC->restore(); list.removeFirst(); } focusTopChild(); updateContentsSize(); } */ int KviMdiManager::getVisibleChildCount() { int cnt=0; for(KviMdiChild *lpC=m_pZ->first();lpC;lpC=m_pZ->next()) { if(lpC->state() != KviMdiChild::Minimized)cnt++; } return cnt; } void KviMdiManager::tile() { switch(KVI_OPTION_UINT(KviOption_uintTileMethod)) { case KVI_TILE_METHOD_ANODINE: tileAnodine(); break; case KVI_TILE_METHOD_PRAGMA4HOR: tileAllInternal(4,true); break; case KVI_TILE_METHOD_PRAGMA4VER: tileAllInternal(4,false); break; case KVI_TILE_METHOD_PRAGMA6HOR: tileAllInternal(6,true); break; case KVI_TILE_METHOD_PRAGMA6VER: tileAllInternal(6,false); break; case KVI_TILE_METHOD_PRAGMA9HOR: tileAllInternal(9,true); break; case KVI_TILE_METHOD_PRAGMA9VER: tileAllInternal(9,false); break; default: KVI_OPTION_UINT(KviOption_uintTileMethod) = KVI_TILE_METHOD_PRAGMA9HOR; tileAllInternal(9,true); break; } } void KviMdiManager::toggleAutoTile() { if(KVI_OPTION_BOOL(KviOption_boolAutoTileWindows)) { KVI_OPTION_BOOL(KviOption_boolAutoTileWindows) = false; } else { KVI_OPTION_BOOL(KviOption_boolAutoTileWindows) = true; tile(); } } void KviMdiManager::tileAllInternal(int maxWnds,bool bHorizontal) { //NUM WINDOWS = 1,2,3,4,5,6,7,8,9 static int colstable[9]={ 1,1,1,2,2,2,3,3,3 }; //num columns static int rowstable[9]={ 1,2,3,2,3,3,3,3,3 }; //num rows static int lastwindw[9]={ 1,1,1,1,2,1,3,2,1 }; //last window multiplier static int colrecall[9]={ 0,0,0,3,3,3,6,6,6 }; //adjust self static int rowrecall[9]={ 0,0,0,0,4,4,4,4,4 }; //adjust self int * pColstable = bHorizontal ? colstable : rowstable; int * pRowstable = bHorizontal ? rowstable : colstable; int * pColrecall = bHorizontal ? colrecall : rowrecall; int * pRowrecall = bHorizontal ? rowrecall : colrecall; ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; KviMdiChild *lpTop=topChild(); int numVisible=getVisibleChildCount(); if(numVisible<1)return; int numToHandle=((numVisible > maxWnds) ? maxWnds : numVisible); int xQuantum=viewport()->width()/pColstable[numToHandle-1]; if(xQuantum < ((lpTop->minimumSize().width() > KVI_MDICHILD_MIN_WIDTH) ? lpTop->minimumSize().width() : KVI_MDICHILD_MIN_WIDTH)){ if(pColrecall[numToHandle-1]==0)tqDebug("Tile : Not enouh space"); else tileAllInternal(pColrecall[numToHandle-1],bHorizontal); return; } int yQuantum=viewport()->height()/pRowstable[numToHandle-1]; if(yQuantum < ((lpTop->minimumSize().height() > KVI_MDICHILD_MIN_HEIGHT) ? lpTop->minimumSize().height() : KVI_MDICHILD_MIN_HEIGHT)){ if(pRowrecall[numToHandle-1]==0)tqDebug("Tile : Not enough space"); else tileAllInternal(pRowrecall[numToHandle-1],bHorizontal); return; } int curX=0; int curY=0; int curRow=1; int curCol=1; int curWin=1; for(KviMdiChild * lpC=m_pZ->first();lpC;lpC=m_pZ->next()) { if(lpC->state()!=KviMdiChild::Minimized) { if((curWin%numToHandle)==0) { moveChild(lpC,curX,curY); lpC->resize(xQuantum * lastwindw[numToHandle-1],yQuantum); } else { moveChild(lpC,curX,curY); lpC->resize(xQuantum,yQuantum); } //example : 12 windows : 3 cols 3 rows if(curColsetFocus(); updateContentsSize(); } void KviMdiManager::tileAnodine() { ensureNoMaximized(); // this hack is needed to ensure that the scrollbars are hidden and the viewport()->width() and height() are correct resizeContents(visibleWidth(),visibleHeight()); updateScrollBars(); g_pApp->sendPostedEvents(); if(g_pApp->closingDown())return; KviMdiChild *lpTop=topChild(); int numVisible=getVisibleChildCount(); // count visible windows if(numVisible<1)return; int numCols=int(sqrt((double)numVisible)); // set columns to square root of visible count // create an array to form grid layout int *numRows=new int[numCols]; int numCurCol=0; while(numCurCol0) { numCurDiffCol--; numRows[numCurDiffCol]++; // add extra rows to column grid if(numCurDiffCol<1)numCurDiffCol=numCols; // rotate through the grid numDiff--; } numCurCol=0; int numCurRow=0; int curX=0; int curY=0; // the following code will size everything based on my grid above // there is no limit to the number of windows it will handle // it's great when a kick-ass theory works!!! // Pragma :) int xQuantum=viewport()->width()/numCols; int yQuantum=viewport()->height()/numRows[numCurCol]; for(KviMdiChild * lpC=m_pZ->first();lpC;lpC=m_pZ->next()) { if(lpC->state() != KviMdiChild::Minimized) { moveChild(lpC,curX,curY); lpC->resize(xQuantum,yQuantum); numCurRow++; curY+=yQuantum; if(numCurRow==numRows[numCurCol]) { numCurRow=0; numCurCol++; curY=0; curX+=xQuantum; if(numCurCol!=numCols)yQuantum=viewport()->height()/numRows[numCurCol]; } } } delete[] numRows; if(lpTop)lpTop->setFocus(); updateContentsSize(); }