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
00026
00027
00028
#include "kmdichildarea.h"
00029
#include "kmdichildarea.moc"
00030
00031
#include "kmdidefines.h"
00032
00033
#include <kconfig.h>
00034
#include <kglobal.h>
00035
00036
#include <math.h>
00037
#include <qpopupmenu.h>
00038
00039
00041
00043
00044
00045
00046 KMdiChildArea::KMdiChildArea(
QWidget *parent)
00047 :
QFrame(parent, "kmdi_childarea")
00048 {
00049 setFrameStyle(QFrame::Panel|QFrame::Sunken);
00050
m_captionFont =
QFont();
00051
QFontMetrics fm(
m_captionFont);
00052 m_captionFontLineSpacing = fm.lineSpacing();
00053
KMdiChildArea::getCaptionColors( palette(),
m_captionActiveBackColor,
m_captionActiveForeColor,
00054
m_captionInactiveBackColor,
m_captionInactiveForeColor );
00055
00056
00057
00058
00059
m_pZ =
new QPtrList<KMdiChildFrm>;
00060
m_pZ->setAutoDelete(
true);
00061 setFocusPolicy(ClickFocus);
00062
m_defaultChildFrmSize =
QSize(400,300);
00063 }
00064
00065
00066
00067 KMdiChildArea::~KMdiChildArea()
00068 {
00069
delete m_pZ;
00070 }
00071
00072
00073
00074 void KMdiChildArea::manageChild(
KMdiChildFrm *lpC,
bool bShow,
bool bCascade)
00075 {
00076
KMdiChildFrm * top=
topChild();
00077
if (
m_pZ->findRef(lpC)!=-1) {
00078
m_pZ->take();
00079
while (
m_pZ->findNext(lpC)!=-1)
00080
m_pZ->take();
00081 }
00082
00083
if (bShow)
00084
m_pZ->append(lpC);
00085
else
00086
m_pZ->insert(0,lpC);
00087
00088
if(bCascade)lpC->move(
getCascadePoint(
m_pZ->count()-1));
00089
if(bShow){
00090
if(top){
00091
if(top->
state() == KMdiChildFrm::Maximized){
00092 emit
sysButtonConnectionsMustChange( top,lpC);
00093 top->
setState(KMdiChildFrm::Normal,
false);
00094 lpC->
setState(KMdiChildFrm::Maximized,
false);
00095 }
00096 }
00097 lpC->show();
00098
focusTopChild();
00099 }
00100 }
00101
00102
00103
00104 void KMdiChildArea::destroyChild(
KMdiChildFrm *lpC,
bool bFocusTopChild)
00105 {
00106
bool bWasMaximized = lpC->
state() == KMdiChildFrm::Maximized;
00107
00108
00109 QObject::disconnect(lpC);
00110 lpC->blockSignals(
true);
00111
m_pZ->setAutoDelete(
false);
00112
m_pZ->removeRef(lpC);
00113
00114
00115
KMdiChildFrm* newTopChild =
topChild();
00116
if (bWasMaximized){
00117
if (newTopChild) {
00118 newTopChild->
setState(KMdiChildFrm::Maximized,
false);
00119 emit
sysButtonConnectionsMustChange(lpC, newTopChild);
00120 }
00121
else {
00122 emit
noMaximizedChildFrmLeft(lpC);
00123 }
00124 }
00125
delete lpC;
00126
m_pZ->setAutoDelete(
true);
00127
00128
if (bFocusTopChild)
00129
focusTopChild();
00130 }
00131
00132
00133
00134 void KMdiChildArea::destroyChildButNotItsView(
KMdiChildFrm *lpC,
bool bFocusTopChild)
00135 {
00136
bool bWasMaximized = lpC->
state() == KMdiChildFrm::Maximized;
00137
00138
00139 QObject::disconnect(lpC);
00140 lpC->
unsetClient();
00141
m_pZ->setAutoDelete(
false);
00142
m_pZ->removeRef(lpC);
00143
00144
00145
KMdiChildFrm* newTopChild =
topChild();
00146
if (bWasMaximized){
00147
if (newTopChild) {
00148 newTopChild->
setState(KMdiChildFrm::Maximized,
false);
00149 emit
sysButtonConnectionsMustChange(lpC, newTopChild);
00150 }
00151
else {
00152 emit
noMaximizedChildFrmLeft(lpC);
00153 }
00154 }
00155
delete lpC;
00156
m_pZ->setAutoDelete(
true);
00157
00158
if (bFocusTopChild)
00159
focusTopChild();
00160 }
00161
00162
00163
00164 void KMdiChildArea::setTopChild(
KMdiChildFrm *lpC,
bool )
00165 {
00166
if(
m_pZ->last() != lpC){
00167
m_pZ->setAutoDelete(
false);
00168
if (lpC) {
00169
m_pZ->removeRef(lpC);
00170 }
00171
00172
for(
KMdiChildFrm *pC=
m_pZ->first();pC;pC=
m_pZ->next()){
00173 pC->
m_pCaption->
setActive(
false);
00174 }
00175
if (!lpC) {
00176
return;
00177 }
00178
00179
KMdiChildFrm *pMaximizedChild =
m_pZ->last();
00180
if (pMaximizedChild && pMaximizedChild->
m_state != KMdiChildFrm::Maximized) {
00181 pMaximizedChild = 0L;
00182 }
00183
m_pZ->setAutoDelete(
true);
00184
m_pZ->append(lpC);
00185
int nChildAreaMinW = 0, nChildAreaMinH = 0;
00186
int nChildAreaMaxW = QWIDGETSIZE_MAX, nChildAreaMaxH = QWIDGETSIZE_MAX;
00187
if ( (pMaximizedChild != 0L) && (lpC->
m_pClient != 0L) ) {
00188 nChildAreaMinW = lpC->
m_pClient->minimumWidth();
00189 nChildAreaMinH = lpC->
m_pClient->minimumHeight();
00191
00192
00193 }
00194 setMinimumSize(nChildAreaMinW, nChildAreaMinH);
00195 setMaximumSize(nChildAreaMaxW, nChildAreaMaxH);
00196
if (pMaximizedChild) {
00197
const bool bDontAnimate =
false;
00198
00199 lpC->
setState(KMdiChildFrm::Maximized, bDontAnimate);
00200 qApp->sendPostedEvents();
00201
00202 pMaximizedChild->
setState(KMdiChildFrm::Normal, bDontAnimate);
00203 qApp->processOneEvent();
00204 emit
sysButtonConnectionsMustChange( pMaximizedChild, lpC);
00205 }
00206
else {
00207 lpC->raise();
00208 }
00209 QFocusEvent::setReason(QFocusEvent::Other);
00210 lpC->
m_pClient->setFocus();
00211 }
00212 }
00213
00214
00215
00216 void KMdiChildArea::resizeEvent(
QResizeEvent* e)
00217 {
00218
00219
KMdiChildFrm *lpC=
m_pZ->last();
00220
if(lpC){
00221
if(lpC->
m_state == KMdiChildFrm::Maximized) {
00222
int clientw = 0, clienth = 0;
00223
if (lpC->
m_pClient != 0L) {
00224 clientw = lpC->
m_pClient->width();
00225 clienth = lpC->
m_pClient->height();
00226 }
00227 lpC->resize( width() + KMDI_CHILDFRM_DOUBLE_BORDER,
00228 height() + lpC->
m_pCaption->
heightHint() + KMDI_CHILDFRM_SEPARATOR + KMDI_CHILDFRM_DOUBLE_BORDER);
00229 }
00230 }
00231
layoutMinimizedChildren();
00232 QWidget::resizeEvent(e);
00233 }
00234
00235
00236
00237 void KMdiChildArea::mousePressEvent(
QMouseEvent *e)
00238 {
00239
00240
if(e->button() & RightButton)
00241 emit
popupWindowMenu( mapToGlobal( e->pos()));
00242 }
00243
00244
00245
00246 QPoint KMdiChildArea::getCascadePoint(
int indexOfWindow)
00247 {
00248
if (indexOfWindow < 0) {
00249 indexOfWindow =
m_pZ->count();
00250 }
00251
QPoint pnt(0,0);
00252
if(indexOfWindow==0)
return pnt;
00253
00254
bool bTopLevelMode =
false;
00255
if( height() == 1)
00256 bTopLevelMode =
true;
00257
00258
KMdiChildFrm *lpC=
m_pZ->first();
00259
int step=(lpC ? lpC->
m_pCaption->
heightHint()+KMDI_CHILDFRM_BORDER : 20);
00260
int h=(bTopLevelMode ? QApplication::desktop()->height() : height());
00261
int w=(bTopLevelMode ? QApplication::desktop()->width() : width());
00262
00263
int availableHeight=h-(lpC ? lpC->minimumSize().height() :
m_defaultChildFrmSize.height());
00264
int availableWidth=w-(lpC ? lpC->minimumSize().width() :
m_defaultChildFrmSize.width());
00265
int ax=0;
00266
int ay=0;
00267
for(
int i=0;i<indexOfWindow;i++){
00268 ax+=step;
00269 ay+=step;
00270
if(ax>availableWidth)ax=0;
00271
if(ay>availableHeight)ay=0;
00272 }
00273 pnt.setX(ax);
00274 pnt.setY(ay);
00275
return pnt;
00276 }
00277
00278
00279
00280 void KMdiChildArea::childMinimized(
KMdiChildFrm *lpC,
bool bWasMaximized)
00281 {
00282
if(
m_pZ->findRef(lpC) == -1)
return;
00283
if(
m_pZ->count() > 1){
00284
m_pZ->setAutoDelete(
false);
00285
m_pZ->removeRef(lpC);
00286
m_pZ->setAutoDelete(
true);
00287
m_pZ->insert(0,lpC);
00288
if(bWasMaximized){
00289
00290 lpC =
m_pZ->last();
00291
if(!lpC)
return;
00292
if(lpC->
m_state==KMdiChildFrm::Minimized)
return;
00293 lpC->
setState(KMdiChildFrm::Maximized,
false);
00294 }
00295
focusTopChild();
00296 }
else {
00297 setFocus();
00298 }
00299 }
00300
00301
00302
00303 void KMdiChildArea::focusTopChild()
00304 {
00305
KMdiChildFrm *lpC=
m_pZ->last();
00306
if(!lpC) {
00307 emit
lastChildFrmClosed();
00308
return;
00309 }
00310
00311
for(
KMdiChildFrm *pC=
m_pZ->first();pC;pC=
m_pZ->next()){
00312
if(pC != lpC)pC->
m_pCaption->
setActive(
false);
00313 }
00314 lpC->raise();
00315
if (!lpC->
m_pClient->hasFocus()) {
00316 lpC->
m_pClient->
activate();
00317 }
00318 }
00319
00320
00321
00322 void KMdiChildArea::cascadeWindows()
00323 {
00324
int idx=0;
00325
QPtrList<KMdiChildFrm> list(*
m_pZ);
00326 list.setAutoDelete(
false);
00327
while(!list.isEmpty()){
00328
KMdiChildFrm *lpC=list.first();
00329
if(lpC->
m_state != KMdiChildFrm::Minimized){
00330
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00331 lpC->move(
getCascadePoint(idx));
00332 idx++;
00333 }
00334 list.removeFirst();
00335 }
00336
focusTopChild();
00337 }
00338
00339
00340
00341 void KMdiChildArea::cascadeMaximized()
00342 {
00343
int idx=0;
00344
QPtrList<KMdiChildFrm> list(*
m_pZ);
00345
00346 list.setAutoDelete(
false);
00347
while(!list.isEmpty()){
00348
KMdiChildFrm *lpC=list.first();
00349
if(lpC->
m_state != KMdiChildFrm::Minimized){
00350
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00351
QPoint pnt(
getCascadePoint(idx));
00352 lpC->move(pnt);
00353
QSize curSize(width()-pnt.x(),height()-pnt.y());
00354
if((lpC->minimumSize().width() > curSize.width()) ||
00355 (lpC->minimumSize().height() > curSize.height()))lpC->resize(lpC->minimumSize());
00356
else lpC->resize(curSize);
00357 idx++;
00358 }
00359 list.removeFirst();
00360 }
00361
focusTopChild();
00362 }
00363
00364 void KMdiChildArea::expandVertical()
00365 {
00366
int idx=0;
00367
QPtrList<KMdiChildFrm> list(*
m_pZ);
00368 list.setAutoDelete(
false);
00369
while(!list.isEmpty()){
00370
KMdiChildFrm *lpC=list.first();
00371
if(lpC->
m_state != KMdiChildFrm::Minimized){
00372
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00373 lpC->setGeometry(lpC->x(),0,lpC->width(),height());
00374 idx++;
00375 }
00376 list.removeFirst();
00377 }
00378
focusTopChild();
00379 }
00380
00381 void KMdiChildArea::expandHorizontal()
00382 {
00383
int idx=0;
00384
QPtrList<KMdiChildFrm> list(*
m_pZ);
00385 list.setAutoDelete(
false);
00386
while(!list.isEmpty()){
00387
KMdiChildFrm *lpC=list.first();
00388
if(lpC->
m_state != KMdiChildFrm::Minimized){
00389
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00390 lpC->setGeometry(0,lpC->y(),width(),lpC->height());
00391 idx++;
00392 }
00393 list.removeFirst();
00394 }
00395
focusTopChild();
00396 }
00397
00398
00399
00400 int KMdiChildArea::getVisibleChildCount()
const
00401
{
00402
int cnt=0;
00403
for(
KMdiChildFrm *lpC=
m_pZ->first();lpC;lpC=
m_pZ->next()){
00404
if ((lpC->
m_state != KMdiChildFrm::Minimized) &&
00405 (lpC->isVisible())) cnt++;
00406 }
00407
return cnt;
00408 }
00409
00410
00411
00412 void KMdiChildArea::tilePragma()
00413 {
00414
tileAllInternal(9);
00415 }
00416
00417
00418
00419 void KMdiChildArea::tileAllInternal(
int maxWnds)
00420 {
00421
00422
static int colstable[9]={ 1,1,1,2,2,2,3,3,3 };
00423
static int rowstable[9]={ 1,2,3,2,3,3,3,3,3 };
00424
static int lastwindw[9]={ 1,1,1,1,2,1,3,2,1 };
00425
static int colrecall[9]={ 0,0,0,3,3,3,6,6,6 };
00426
static int rowrecall[9]={ 0,0,0,0,4,4,4,4,4 };
00427
00428
KMdiChildFrm *lpTop =
topChild();
00429
int numVisible =
getVisibleChildCount();
00430
if (numVisible<1)
return;
00431
int numToHandle = ((numVisible > maxWnds) ? maxWnds : numVisible);
00432
int xQuantum = width()/colstable[numToHandle-1];
00433
if (xQuantum < ((lpTop->minimumSize().width() >
m_defaultChildFrmSize.width()) ? lpTop->minimumSize().width() :
m_defaultChildFrmSize.width())) {
00434
if (colrecall[numToHandle-1] != 0) {
00435
tileAllInternal(colrecall[numToHandle-1]);
00436
return;
00437 }
00438 }
00439
int yQuantum=height()/rowstable[numToHandle-1];
00440
if (yQuantum < ((lpTop->minimumSize().height() >
m_defaultChildFrmSize.height()) ? lpTop->minimumSize().height() :
m_defaultChildFrmSize.height())) {
00441
if (rowrecall[numToHandle-1] != 0) {
00442
tileAllInternal(rowrecall[numToHandle-1]);
00443
return;
00444 }
00445 }
00446
int curX=0;
00447
int curY=0;
00448
int curRow=1;
00449
int curCol=1;
00450
int curWin=1;
00451
for (
KMdiChildFrm *lpC=
m_pZ->first();lpC;lpC=
m_pZ->next()) {
00452
if (lpC->
m_state!=KMdiChildFrm::Minimized) {
00453
00454
if (lpC->
m_state==KMdiChildFrm::Maximized)
00455 lpC->
restorePressed();
00456
if ((curWin%numToHandle)==0)
00457 lpC->setGeometry(curX,curY,xQuantum * lastwindw[numToHandle-1],yQuantum);
00458
else
00459 lpC->setGeometry(curX,curY,xQuantum,yQuantum);
00460
00461
if (curCol<colstable[numToHandle-1]) {
00462 curX+=xQuantum;
00463 curCol++;
00464 }
00465
else {
00466 curX = 0;
00467 curCol = 1;
00468
if (curRow < rowstable[numToHandle-1]) {
00469 curY += yQuantum;
00470 curRow++;
00471 }
00472
else {
00473 curY = 0;
00474 curRow = 1;
00475 }
00476 }
00477 curWin++;
00478 }
00479 }
00480
if (lpTop)
00481 lpTop->
m_pClient->
activate();
00482 }
00483
00484 void KMdiChildArea::tileAnodine()
00485 {
00486
KMdiChildFrm *lpTop=
topChild();
00487
int numVisible=
getVisibleChildCount();
00488
if(numVisible<1)
return;
00489
int numCols=int(sqrt((
double)numVisible));
00490
00491
int *numRows=
new int[numCols];
00492
int numCurCol=0;
00493
while(numCurCol<numCols){
00494 numRows[numCurCol]=numCols;
00495 numCurCol++;
00496 }
00497
int numDiff=numVisible-(numCols*numCols);
00498
int numCurDiffCol=numCols;
00499
while(numDiff>0){
00500 numCurDiffCol--;
00501 numRows[numCurDiffCol]++;
00502
if(numCurDiffCol<1)numCurDiffCol=numCols;
00503 numDiff--;
00504 }
00505 numCurCol=0;
00506
int numCurRow=0;
00507
int curX=0;
00508
int curY=0;
00509
00510
00511
00512
int xQuantum=width()/numCols;
00513
int yQuantum=height()/numRows[numCurCol];
00514
for(
KMdiChildFrm *lpC=
m_pZ->first();lpC;lpC=
m_pZ->next()){
00515
if(lpC->
m_state != KMdiChildFrm::Minimized){
00516
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00517 lpC->setGeometry(curX,curY,xQuantum,yQuantum);
00518 numCurRow++;
00519 curY+=yQuantum;
00520
if(numCurRow==numRows[numCurCol]){
00521 numCurRow=0;
00522 numCurCol++;
00523 curY=0;
00524 curX+=xQuantum;
00525
if(numCurCol!=numCols)yQuantum=height()/numRows[numCurCol];
00526 }
00527 }
00528 }
00529
delete[] numRows;
00530
if (lpTop) {
00531 lpTop->
m_pClient->
activate();
00532 }
00533 }
00534
00535
00536 void KMdiChildArea::tileVertically()
00537 {
00538
KMdiChildFrm *lpTop=
topChild();
00539
int numVisible=
getVisibleChildCount();
00540
if(numVisible<1)
return;
00541
00542
int w = width() / numVisible;
00543
int lastWidth = 0;
00544
if( numVisible > 1)
00545 lastWidth = width() - (w * (numVisible - 1));
00546
else
00547 lastWidth = w;
00548
int h = height();
00549
int posX = 0;
00550
int countVisible = 0;
00551
00552
for(
KMdiChildFrm *lpC=
m_pZ->first();lpC;lpC=
m_pZ->next()){
00553
if(lpC->
m_state != KMdiChildFrm::Minimized){
00554
if(lpC->
m_state==KMdiChildFrm::Maximized)lpC->
restorePressed();
00555 countVisible++;
00556
if( countVisible < numVisible) {
00557 lpC->setGeometry( posX, 0, w, h);
00558 posX += w;
00559 }
00560
else {
00561 lpC->setGeometry( posX, 0, lastWidth, h);
00562 }
00563 }
00564 }
00565
if (lpTop) {
00566 lpTop->
m_pClient->
activate();
00567 }
00568 }
00569
00570
00571 void KMdiChildArea::layoutMinimizedChildren()
00572 {
00573
int posX = 0;
00574
int posY = height();
00575
for(
KMdiChildFrm* child =
m_pZ->first(); child ; child =
m_pZ->next())
00576 {
00577
if( child->
state() == KMdiChildFrm::Minimized) {
00578
if( ( posX > 0) && ( posX + child->width() > width()) )
00579 {
00580 posX = 0;
00581 posY -= child->height();
00582 }
00583 child->move( posX, posY - child->height());
00584 posX = child->geometry().right();
00585 }
00586 }
00587 }
00588
00589
00590 void KMdiChildArea::setMdiCaptionFont(
const QFont &fnt)
00591 {
00592
m_captionFont = fnt;
00593
QFontMetrics fm(
m_captionFont);
00594 m_captionFontLineSpacing = fm.lineSpacing();
00595
00596
for (
KMdiChildFrm *pC =
m_pZ->first(); pC; pC =
m_pZ->next()) {
00597 pC->
doResize();
00598 }
00599 }
00600
00601 void KMdiChildArea::setMdiCaptionActiveForeColor(
const QColor &clr)
00602 {
00603
m_captionActiveForeColor = clr;
00604 }
00605
00606 void KMdiChildArea::setMdiCaptionActiveBackColor(
const QColor &clr)
00607 {
00608
m_captionActiveBackColor = clr;
00609 }
00610
00611 void KMdiChildArea::setMdiCaptionInactiveForeColor(
const QColor &clr)
00612 {
00613
m_captionInactiveForeColor = clr;
00614 }
00615
00616 void KMdiChildArea::setMdiCaptionInactiveBackColor(
const QColor &clr)
00617 {
00618
m_captionInactiveBackColor = clr;
00619 }
00620
00621
00622
00623
00624
00625
00626
#if defined(Q_WS_WIN)
00627
#include "qt_windows.h"
00628 QRgb qt_colorref2qrgb(COLORREF col)
00629 {
00630
return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
00631 }
00632
00633
00634
#ifndef SPI_GETGRADIENTCAPTIONS
00635
# define SPI_GETGRADIENTCAPTIONS 0x1008
00636
#endif
00637
#ifndef COLOR_GRADIENTACTIVECAPTION
00638
# define COLOR_GRADIENTACTIVECAPTION 27
00639
#endif
00640
#ifndef COLOR_GRADIENTINACTIVECAPTION
00641
# define COLOR_GRADIENTINACTIVECAPTION 28
00642
#endif
00643
#endif
00644
00645 void KMdiChildArea::getCaptionColors(
const QPalette &pal,
00646
QColor &activeBG,
QColor &activeFG,
QColor &inactiveBG,
QColor &inactiveFG )
00647 {
00648
QColor def_activeBG = pal.
active().highlight();
00649
QColor def_activeFG = pal.
active().highlightedText();
00650
QColor def_inactiveBG = pal.
inactive().dark();
00651
QColor def_inactiveFG = pal.
inactive().brightText();
00652
00653
if ( QApplication::desktopSettingsAware() ) {
00654
#if defined(Q_WS_WIN)
00655
00656 activeBG = qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION));
00657 activeFG = qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT));
00658 inactiveBG = qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION));
00659 inactiveFG = qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
00660
#else
00661
00662 KConfig *cfg = KGlobal::config();
00663 cfg->setGroup(
"WM" );
00664 activeBG = cfg->readColorEntry(
"activeBackground", &def_activeBG);
00665 activeFG = cfg->readColorEntry(
"activeForeground", &def_activeFG);
00666 inactiveBG = cfg->readColorEntry(
"inactiveBackground", &def_inactiveBG);
00667 inactiveFG = cfg->readColorEntry(
"inactiveForeground", &def_inactiveFG);
00668
#endif
00669
}
00670
else {
00671 activeBG = def_activeBG;
00672 activeFG = def_activeFG;
00673 inactiveBG = def_inactiveBG;
00674 inactiveFG = def_inactiveFG;
00675 }
00676 }
00677
00678
00679