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 "KWTableFrameSet.h"
00029 #include "KWDocument.h"
00030 #include "KWAnchor.h"
00031 #include "KWCanvas.h"
00032 #include "KWCommand.h"
00033 #include "KWViewMode.h"
00034 #include "KWView.h"
00035 #include "KWordFrameSetIface.h"
00036 #include "KWordTableFrameSetIface.h"
00037 #include "KWFrameList.h"
00038 #include "KWPageManager.h"
00039 #include "KWPage.h"
00040 #include "KWOasisSaver.h"
00041
00042 #include <KoOasisContext.h>
00043 #include <KoXmlWriter.h>
00044 #include <KoDom.h>
00045 #include <KoXmlNS.h>
00046 #include <KoTextObject.h>
00047 #include <KoTextParag.h>
00048
00049 #include <kmessagebox.h>
00050 #include <kdebug.h>
00051 #include <klocale.h>
00052 #include <dcopobject.h>
00053 #include <qapplication.h>
00054 #include <qpopupmenu.h>
00055 #include <qclipboard.h>
00056
00057
00058 KWTableFrameSet::KWTableFrameSet( KWDocument *doc, const QString & name ) :
00059 KWFrameSet( doc )
00060 {
00061 m_rows = m_cols = m_nr_cells = 0;
00062 m_name = QString::null;
00063 m_active = true;
00064 m_frames.setAutoDelete(false);
00065 if ( name.isEmpty() )
00066 m_name = doc->generateFramesetName( i18n( "Table %1" ) );
00067 else
00068 m_name = name;
00069 }
00070
00071 KWTableFrameSet::~KWTableFrameSet()
00072 {
00073 m_doc = 0L;
00074 }
00075
00076 KWordFrameSetIface* KWTableFrameSet::dcopObject()
00077 {
00078 if ( !m_dcop )
00079 m_dcop = new KWordTableFrameSetIface( this );
00080
00081 return m_dcop;
00082 }
00083
00084
00085 KWFrameSetEdit * KWTableFrameSet::createFrameSetEdit( KWCanvas * canvas )
00086 {
00087 return new KWTableFrameSetEdit( this, canvas );
00088 }
00089
00090 void KWTableFrameSet::updateFrames( int flags )
00091 {
00092 for(TableIter c(this); c; ++c)
00093 c.current()->updateFrames( flags );
00094 if ( isFloating() ) {
00095 KWAnchor * anchor = findAnchor( 0 );
00096 if ( anchor )
00097 anchor->resize();
00098 }
00099
00100 KWFrameSet::updateFrames( flags );
00101 }
00102
00103 void KWTableFrameSet::moveFloatingFrame( int , const KoPoint &position )
00104 {
00105
00106
00107 double dx = position.x() - m_colPositions[0];
00108 double dy = position.y() - m_rowPositions[0];
00109
00110 int oldPageNumber = cell(0,0)->frame(0)->pageNumber();
00111
00112
00113 moveBy( dx, dy );
00114
00115 if ( dx || dy ) {
00116 updateFrames();
00117 cell(0,0)->frame(0)->frameStack()->updateAfterMove( oldPageNumber );
00118 }
00119 }
00120
00121 KoSize KWTableFrameSet::floatingFrameSize( int )
00122 {
00123 return boundingRect().size();
00124 }
00125
00126 KCommand * KWTableFrameSet::anchoredObjectCreateCommand( int )
00127 {
00128 return new KWCreateTableCommand( i18n("Create Table"), this );
00129 }
00130
00131 KCommand * KWTableFrameSet::anchoredObjectDeleteCommand( int )
00132 {
00133 return new KWDeleteTableCommand( i18n("Delete Table"), this );
00134 }
00135
00136 KWAnchor * KWTableFrameSet::createAnchor( KoTextDocument *txt, int frameNum )
00137 {
00138
00139 return new KWAnchor( txt, this, frameNum );
00140 }
00141
00142 void KWTableFrameSet::createAnchors( KoTextParag * parag, int index, bool placeHolderExists ,
00143 bool repaint )
00144 {
00145
00146
00147
00148 KWAnchor * anchor = createAnchor( m_anchorTextFs->textDocument(), 0 );
00149 if ( !placeHolderExists )
00150 parag->insert( index, KoTextObject::customItemChar() );
00151 parag->setCustomItem( index, anchor, 0 );
00152 kdDebug(32004) << "KWTableFrameSet::createAnchors setting anchor" << endl;
00153 parag->setChanged( true );
00154 if ( repaint )
00155 emit repaintChanged( m_anchorTextFs );
00156 }
00157
00158 void KWTableFrameSet::deleteAnchors()
00159 {
00160 KWAnchor * anchor = findAnchor( 0 );
00161 kdDebug(32004) << "KWTableFrameSet::deleteAnchors anchor=" << anchor << endl;
00162 deleteAnchor( anchor );
00163 }
00164
00165
00166 void KWTableFrameSet::addCell( Cell* daCell )
00167 {
00168 m_rows = kMax( daCell->rowAfter(), m_rows );
00169 m_cols = kMax( daCell->columnAfter(), m_cols );
00170
00171 if ( m_rowArray.size() < daCell->rowAfter() )
00172 m_rowArray.resize( daCell->rowAfter() );
00173 for ( uint row = daCell->firstRow() ;row < daCell->rowAfter(); ++row )
00174 {
00175 if ( !m_rowArray[ row ] )
00176 m_rowArray.insert( row, new Row );
00177 m_rowArray[ row ]->addCell( daCell );
00178 }
00179 }
00180
00181 void KWTableFrameSet::removeCell( Cell* daCell )
00182 {
00183 for ( uint row = daCell->firstRow() ; row < daCell->rowAfter(); ++row )
00184 m_rowArray[ row ]->removeCell( daCell );
00185 }
00186
00187 void KWTableFrameSet::insertRowVector(uint index, Row *r)
00188 {
00189 if(m_rowArray.size() < m_rowArray.count() + 1)
00190 m_rowArray.resize(m_rowArray.count() + 1);
00191
00192 for(uint i = m_rowArray.count(); i > index; i--)
00193 m_rowArray.insert(i, m_rowArray[i-1]);
00194
00195 m_rowArray.insert(index, r);
00196 }
00197
00198
00199
00200
00201
00202 void KWTableFrameSet::insertEmptyColumn(uint index)
00203 {
00204 for(uint i = 0; i < m_rowArray.count(); ++i) {
00205 Row *r = m_rowArray[i];
00206 if(r->m_cellArray.size() < m_cols + 1)
00207 r->m_cellArray.resize(m_cols + 1);
00208 for(int j = m_cols - 1; j >= (int)index; --j)
00209 r->m_cellArray.insert(j + 1, r->m_cellArray[j]);
00210 r->m_cellArray.insert(index, 0);
00211 }
00212 }
00213
00214 KWTableFrameSet::Row*
00215 KWTableFrameSet::removeRowVector(uint index)
00216 {
00217 Q_ASSERT(index < m_rowArray.count() );
00218 Row *ret = m_rowArray.at(index);
00219 Row *r;
00220 for(uint i = index; i < m_rowArray.size() - 1; ++i){
00221 r = m_rowArray.at(i+1);
00222 m_rowArray.remove(i+1);
00223 m_rowArray.insert(i,r);
00224 }
00225 return ret;
00226 }
00227
00228
00229 KoRect KWTableFrameSet::boundingRect() {
00230 KoRect outerRect(m_colPositions[0],
00231 m_rowPositions[0],
00232 m_colPositions.last()-m_colPositions[0],
00233 m_rowPositions.last()-m_rowPositions[0]);
00234
00235
00236
00237
00238
00239
00240
00241 outerRect.rRight() += m_doc->zoomItX( 1 ) / m_doc->zoomedResolutionX();
00242 outerRect.rBottom() += m_doc->zoomItY( 1 ) / m_doc->zoomedResolutionY();
00243
00244 return outerRect;
00245
00246 }
00247
00248 double KWTableFrameSet::topWithoutBorder()
00249 {
00250 double top = 0.0;
00251 for (uint i = 0; i < getColumns(); i++)
00252 {
00253 KWTableFrameSet::Cell *daCell = cell( 0, i );
00254 top = kMax( top, m_rowPositions[0] + daCell->topBorder() );
00255 }
00256 return top;
00257 }
00258
00259
00260 double KWTableFrameSet::leftWithoutBorder()
00261 {
00262 double left = 0.0;
00263 for (uint i=0; i < getRows(); i++)
00264 {
00265 KWTableFrameSet::Cell *daCell = cell( i, 0 );
00266 left = kMax( left, m_colPositions[0] + daCell->leftBorder() );
00267 }
00268 return left;
00269 }
00270
00271
00272 KWTableFrameSet::Cell *KWTableFrameSet::cell( unsigned int row, unsigned int col ) const
00273 {
00274 if ( row < m_rowArray.size() && col < m_rowArray[row]->size() ) {
00275 Cell* cell = (*m_rowArray[row])[col];
00276 if ( cell )
00277 return cell;
00278 }
00279
00280
00281
00282
00283
00284 return 0L;
00285 }
00286
00287 KWTableFrameSet::Cell *KWTableFrameSet::cellByPos( double x, double y ) const
00288 {
00289 KWFrame *f = frameAtPos(x,y);
00290 if(f) return static_cast<KWTableFrameSet::Cell *> (f->frameSet());
00291 return 0L;
00292 }
00293
00294 void KWTableFrameSet::recalcCols(unsigned int col,unsigned int row) {
00295 if(col >= getColumns())
00296 col = getColumns()-1;
00297 if(row >= getRows())
00298 row = getRows()-1;
00299 Cell *activeCell = cell(row,col);
00300 Q_ASSERT( activeCell );
00301 if ( !activeCell )
00302 return;
00303 double difference = 0;
00304
00305 if(activeCell->frame(0)->left() - activeCell->leftBorder() != m_colPositions[activeCell->firstColumn()]) {
00306
00307 col = activeCell->firstRow();
00308 difference = 0-(activeCell->frame(0)->left() - activeCell->leftBorder() - m_colPositions[activeCell->firstColumn()]);
00309 }
00310
00311 if(activeCell->frame(0)->right() - activeCell->rightBorder() !=
00312 m_colPositions[activeCell->lastColumn()]) {
00313
00314 col = activeCell->columnAfter();
00315 double difference2 = activeCell->frame(0)->right() + activeCell->rightBorder() - m_colPositions[activeCell->columnAfter()];
00316
00317 double moved=difference2+difference;
00318 if(moved > -0.01 && moved < 0.01) {
00319 col=0;
00320 difference = difference2;
00321 } else if(difference2!=0)
00322 difference = difference2;
00323 }
00324
00325 m_redrawFromCol=getColumns();
00326 if(difference!=0) {
00327 double last=col==0?0:m_colPositions[col-1];
00328 for(unsigned int i=col; i < m_colPositions.count(); i++) {
00329 double &colPos = m_colPositions[i];
00330 colPos = colPos + difference;
00331 if(colPos-last < s_minFrameWidth) {
00332 difference += s_minFrameWidth - colPos;
00333 colPos = s_minFrameWidth + last;
00334 }
00335 last=colPos;
00336 }
00337 m_redrawFromCol=col;
00338 if(col>0) m_redrawFromCol--;
00339
00340 }
00341 updateFrames();
00342
00343 }
00344
00345
00346
00347
00348
00349 void KWTableFrameSet::recalcRows(unsigned int col, unsigned int row) {
00350 kdDebug(32004) << name() << " KWTableFrameSet::recalcRows ("<< col <<"," << row << ")" << endl;
00351
00352
00353 Cell *activeCell = cell(row,col);
00354 Q_ASSERT( activeCell );
00355 if ( !activeCell )
00356 return;
00357 double difference = 0;
00358
00359 if(activeCell->frame(0)->height() != activeCell->frame(0)->minimumFrameHeight() &&
00360 activeCell->type() == FT_TEXT) {
00361
00362
00363
00364
00365
00366 double minHeightOtherCols=0;
00367 double minHeightActiveRow=0;
00368 double minHeightMyCol=0;
00369 unsigned int rowSpan = activeCell->rowSpan();
00370 unsigned int startRow = activeCell->firstRow();
00371 for (uint colCount = 0; colCount < getColumns(); ++colCount )
00372 {
00373
00374 unsigned int rowCount=startRow;
00375 double thisColHeight=0;
00376 double thisColActiveRow=0;
00377
00378 do {
00379 Cell *thisCell=cell(rowCount,colCount);
00380 if ( !thisCell )
00381 break;
00382 if(thisCell->firstRow() < startRow) {
00383 rowSpan += startRow - thisCell->firstRow();
00384 startRow = thisCell->firstRow();
00385 break;
00386 }
00387 if(thisCell->rowAfter() > startRow + rowSpan) {
00388 rowSpan = thisCell->rowAfter() - startRow;
00389 break;
00390 }
00391
00392 thisColHeight+=thisCell->frame(0)->minimumFrameHeight();
00393 thisColHeight+=thisCell->topBorder();
00394 thisColHeight+=thisCell->bottomBorder();
00395
00396 if(thisCell->firstRow() >= activeCell->firstRow() && thisCell->rowAfter() <= activeCell->rowAfter())
00397 thisColActiveRow+=thisCell->frame(0)->minimumFrameHeight();
00398
00399 rowCount += thisCell->rowSpan();
00400 } while (rowCount < rowSpan+startRow);
00401
00402 if(colCount >= activeCell->firstColumn() &&
00403 colCount < activeCell->columnAfter() )
00404 minHeightMyCol = thisColHeight;
00405 else {
00406 minHeightOtherCols = kMax(minHeightOtherCols, thisColHeight);
00407 minHeightActiveRow = kMax(minHeightActiveRow, thisColActiveRow);
00408 }
00409 }
00410
00411 bool bottomRow = (startRow+rowSpan == activeCell->rowAfter());
00412 if(!bottomRow) {
00413 Cell *bottomCell=cell(startRow+rowSpan-1, activeCell->firstColumn());
00414 bottomCell->frame(0)->setHeight(bottomCell->frame(0)->minimumFrameHeight() +
00415 minHeightOtherCols - minHeightMyCol);
00416
00417 recalcRows(bottomCell->firstColumn(), bottomCell->firstRow());
00418 }
00419 if(activeCell->frame(0)->minimumFrameHeight() > activeCell->frame(0)->height()) {
00420 activeCell->frame(0)->setHeight(activeCell->frame(0)->minimumFrameHeight());
00421
00422 } else {
00423 double newHeight=kMax(activeCell->frame(0)->minimumFrameHeight(),minHeightActiveRow);
00424 if(bottomRow)
00425 newHeight=kMax(newHeight, minHeightOtherCols - (minHeightMyCol - activeCell->frame(0)->minimumFrameHeight()));
00426 activeCell->frame(0)->setHeight(newHeight);
00427
00428 }
00429 }
00430
00431 if(activeCell->frame(0)->top() - activeCell->topBorder() != getPositionOfRow(activeCell->firstRow())) {
00432
00433 row = activeCell->firstRow();
00434 difference = 0 - (activeCell->frame(0)->top() - activeCell->topBorder() - getPositionOfRow(row));
00435 }
00436
00437
00438 if(activeCell->frame(0)->bottom() + activeCell->bottomBorder() !=
00439 getPositionOfRow(activeCell->rowAfter())) {
00440
00441 row = activeCell->rowAfter();
00442 double difference2 = activeCell->frame(0)->bottom() + activeCell->bottomBorder() - getPositionOfRow(row);
00443 double moved=difference2+difference;
00444 if(moved > -0.01 && moved < 0.01) {
00445 row=0;
00446 difference = difference2;
00447 } else if( difference2!=0)
00448 difference = difference2;
00449 }
00450
00451 unsigned int fromRow = m_rows;
00452 unsigned int untilRow=0;
00453 if( QABS( difference ) > 1E-10 ) {
00454 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
00455 QValueList<double>::iterator j = m_rowPositions.begin();
00456 double last=0.0;
00457 int lineNumber=-1;
00458 while(j != m_rowPositions.end()) {
00459 lineNumber++;
00460 if(pageBound!=m_pageBoundaries.end()) {
00461 if((int)*pageBound == lineNumber) {
00462 if(lineNumber >= (int)row) {
00463 QValueList<double>::iterator nextJ = j;
00464 ++nextJ;
00465 difference -= *(nextJ)-*(j);
00466 kdDebug(32004) << "Deleting line with old pos: " << *j << endl;
00467 j=m_rowPositions.remove(j);
00468 j--;
00469 QValueList<unsigned int>::iterator tmp = pageBound;
00470 ++pageBound;
00471 m_pageBoundaries.remove(tmp);
00472 j++;
00473 continue;
00474 }
00475 ++pageBound;
00476 lineNumber--;
00477 }
00478 }
00479 if(lineNumber >= (int)row) {
00480 if(*(j)-last < s_minFrameHeight)
00481 difference += s_minFrameHeight - *(j) + last;
00482 last=*(j);
00483 kdDebug(32004) << "moving " << *(j) << " by " << difference << "; to " << (*j) + difference << endl;
00484 (*j) += difference;
00485 }
00486 j++;
00487 }
00488 fromRow=row;
00489 if(row>0) fromRow--;
00490 } else {
00491 row=0;
00492 }
00493 #if 0
00494 { QValueList<unsigned int>::iterator pb = m_pageBoundaries.begin();
00495 unsigned int i=0;
00496 double last=0;
00497 do {
00498 double cur=m_rowPositions[i];
00499 if(pb!=m_pageBoundaries.end() && *(pb)==i) {
00500 kdDebug(32004) << "line: " << i << ": " << cur << " *" << (last>cur?" (ALERT)":"") << endl;
00501 ++pb;
00502 } else
00503 kdDebug(32004) << "line: " << i << ": " << cur << (last>cur?" (ALERT)":"") << endl;
00504 last=cur;
00505 i++;
00506 } while( i<m_rowPositions.count());
00507 }
00508 #endif
00509 #if 0 // def SUPPORT_MULTI_PAGE_TABLES
00510
00511
00512 unsigned int pageNumber=cell(0,0)->frame(0)->pageNumber() +1;
00513 unsigned int lineNumber=1;
00514 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
00515 QValueList<double>::iterator j = m_rowPositions.begin();
00516
00517 double diff=0.0;
00518 double pageBottom = pageNumber * m_doc->ptPaperHeight() - m_doc->ptBottomBorder();
00519
00520 while(++j!=m_rowPositions.end()) {
00521 if(pageBound!=m_pageBoundaries.end() && *pageBound == lineNumber ) {
00522 if(*j > pageNumber * m_doc->ptPaperHeight() - m_doc->ptBottomBorder() ) {
00523 pageNumber++;
00524 pageBottom = pageNumber * m_doc->ptPaperHeight() - m_doc->ptBottomBorder();
00525
00526 untilRow=kMax(untilRow, *pageBound);
00527 pageBound++;
00528 }
00529 }
00530
00531
00532 if((*j) + diff > pageBottom) {
00533
00534 untilRow = m_rows;
00535 bool hugeRow = false;
00536 unsigned int breakRow = lineNumber-1;
00537
00538 #if 0
00539
00540 for(int i=0; i < getColumns() ; i++) {
00541 kdDebug() << "i: " << i<< endl;
00542 Cell *c= cell(breakRow, i);
00543 kdDebug() << "c: " << c->firstRow() << "," << c->m_col << " w: " << c->columnSpan() << ", h: " << c->rowSpan() << endl;
00544 if(c->firstRow() < breakRow) {
00545 breakRow = c->firstRow();
00546 i=-1;
00547 }
00548 }
00549 kdDebug() << "breakRow: " << breakRow<< endl;
00550 fromRow=kMin(fromRow, breakRow);
00551 if(breakRow < lineNumber+1) {
00552 for(unsigned int i=lineNumber+1; i > breakRow;i--)
00553 kdDebug() << "j--";
00554 for(unsigned int i=lineNumber+1; i > breakRow;i--)
00555 --j;
00556 lineNumber=breakRow+1;
00557 }
00558
00559
00560 for(unsigned int i=0; i < getColumns() ; i++) {
00561 if(cell(breakRow+1,i) && cell(breakRow+1,i)->frame(0)->height() > pageHeight)
00562 hugeRow=true;
00563 }
00564
00565
00566 #endif
00567
00568 double topOfPage = m_doc->ptPaperHeight() * pageNumber + m_doc->ptTopBorder();
00569
00570 QValueList<double>::iterator tmp = m_rowPositions.at(breakRow);
00571 diff += topOfPage - (*tmp);
00572
00573 lineNumber++;
00574 m_rowPositions.insert(j, topOfPage);
00575
00576
00577 pageBound = m_pageBoundaries.insert(pageBound, breakRow);
00578
00579 pageBound++;
00580 if(!hugeRow) {
00581
00582
00583
00584
00585 }
00586 pageNumber++;
00587 pageBottom = pageNumber * m_doc->ptPaperHeight() - m_doc->ptBottomBorder();
00588
00589 if((int)pageNumber > m_doc->numPages()) {
00590 int num = m_doc->appendPage();
00591 kdDebug(32004) << "Have appended page: " << num << " (one page mode!)" << endl;
00592 m_doc->afterInsertPage( num );
00593 }
00594 }
00595
00596 if(diff > 0)
00597 (*j) = (*j) + diff;
00598 lineNumber++;
00599
00600 #if 0 // def SUPPORT_MULTI_PAGE_TABLES
00601
00602 int i = 1;
00603 for ( QValueList<double>::iterator itDebug = m_rowPositions.begin(); itDebug != m_rowPositions.end(); ++itDebug, ++i )
00604 {
00605 kdDebug(32004) << "m_rowPosition[" << i << "]= " << (*itDebug) << endl;
00606 }
00607 #endif
00608
00609 }
00610 #endif
00611 #if 0
00612 { QValueList<unsigned int>::iterator pb = m_pageBoundaries.begin();
00613 unsigned int i=0;
00614 double last=0;
00615 do {
00616 double cur=m_rowPositions[i];
00617 if(pb!=m_pageBoundaries.end() && *(pb)==i) {
00618 kdDebug(32004) << "line: " << i << ": " << cur << " *" << (last>cur?" (ALERT)":"") << endl;
00619 ++pb;
00620 } else
00621 kdDebug(32004) << "line: " << i << ": " << cur << (last>cur?" (ALERT)":"") << endl;
00622 last=cur;
00623 i++;
00624 } while( i<m_rowPositions.count());
00625 }
00626 #endif
00627
00628
00629
00630
00631
00632
00633
00634 #if 0 // def SUPPORT_MULTI_PAGE_TABLES
00635 for(TableIter cell(this); cell; ++cell) {
00636 if((cell->rowAfter() > fromRow && cell->firstRow() < untilRow) || cell->columnAfter() > m_redrawFromCol)
00637 position(cell, (cell==activeCell && cell->frame(0)->isSelected()));
00638 }
00639 m_redrawFromCol = getColumns();
00640
00641
00642
00643
00644 QMap<unsigned int,int> rows;
00645 unsigned int top=m_rowPositions.count() - m_pageBoundaries.count()-1;
00646 for(unsigned int i=0; i < top; rows[i++]=0);
00647
00648
00649 for(TableIter i(this); i; ++i) {
00650 rows[i->firstRow()] += 1;
00651 }
00652
00653 unsigned int counter=top;
00654 int adjustment=m_pageBoundaries.count()-1;
00655
00656 do {
00657 counter--;
00658 if(adjustment >= 0 && counter == m_pageBoundaries[adjustment])
00659 adjustment--;
00660 if(rows[counter]==0) {
00661 kdDebug() << k_funcinfo << "no rows at counter=" << counter << " -> erasing" << endl;
00662 m_rows--;
00663 m_rowPositions.erase(m_rowPositions.at(counter+(adjustment>0?adjustment:0)));
00664 for (TableIter cell(this); cell; ++cell) {
00665 if(cell->firstRow() < counter && cell->rowAfter() > counter)
00666 cell->setRowSpan(cell->rowSpan()-1);
00667 if(cell->firstRow() > counter)
00668 cell->setFirstRow(cell->firstRow()-1);
00669 }
00670
00671 if(adjustment >= -1) {
00672 pageBound = m_pageBoundaries.at(adjustment+1);
00673 while(pageBound!=m_pageBoundaries.end()) {
00674 (*pageBound)= (*pageBound)-1;
00675 pageBound++;
00676 }
00677 }
00678 }
00679 } while(counter!=0);
00680 #endif
00681
00682
00683 m_redrawFromCol = 0;
00684 for (TableIter cell(this); cell; ++cell) {
00685 if((cell->rowAfter() > fromRow && cell->firstRow() < untilRow)
00686 || cell->columnAfter() > m_redrawFromCol)
00687 position(cell);
00688 }
00689 m_redrawFromCol = getColumns();
00690 kdDebug(32004) << name() << " KWTableFrameSet::recalcRows done" << endl;
00691 updateFrames();
00692 }
00693
00694 int KWTableFrameSet::columnEdgeAt( double x ) const
00695 {
00696
00697
00698
00699 double lastMiddlePos = 0;
00700 for ( uint i = 0; i < m_colPositions.count() - 1; i++ ) {
00701 double middlePos = ( m_colPositions[i] + m_colPositions[i+1] ) / 2;
00702 Q_ASSERT( lastMiddlePos < middlePos );
00703 if ( x > lastMiddlePos && x <= middlePos )
00704 return i;
00705 lastMiddlePos = middlePos;
00706 }
00707 return m_colPositions.count() - 1;
00708 }
00709
00710 int KWTableFrameSet::rowEdgeAt( double y ) const
00711 {
00712 double lastMiddlePos = 0;
00713 for ( uint i = 0; i < m_rowPositions.count() - 1; i++ ) {
00714 double middlePos = ( m_rowPositions[i] + m_rowPositions[i+1] ) / 2;
00715 Q_ASSERT( lastMiddlePos < middlePos );
00716 if ( y > lastMiddlePos && y <= middlePos )
00717 return i;
00718 lastMiddlePos = middlePos;
00719 }
00720 return m_rowPositions.count() - 1;
00721 }
00722
00723 double KWTableFrameSet::columnSize( unsigned int col )
00724 {
00725 return m_colPositions[ col ];
00726 }
00727
00728 double KWTableFrameSet::rowSize( unsigned int row )
00729 {
00730 return m_rowPositions[ row ];
00731 }
00732
00733 void KWTableFrameSet::resizeColumn( unsigned int col, double x )
00734 {
00735 kdDebug() << k_funcinfo << col << "," << x << endl;
00736 if ((col != 0) && (x - m_colPositions[ col-1 ] < s_minFrameWidth))
00737 m_colPositions[ col ] = m_colPositions[ col-1 ] + s_minFrameWidth;
00738 else
00739 if ((col != getColumns()) && (m_colPositions[ col + 1 ] - x < s_minFrameWidth))
00740 m_colPositions[col] = m_colPositions[ col + 1 ] - s_minFrameWidth;
00741 else
00742 m_colPositions[ col ] = x;
00743
00744
00745 for (TableIter cell(this); cell; ++cell) {
00746 if ( cell->columnAfter() >= col ) {
00747 position(cell);
00748 }
00749 }
00750 recalcCols( col-1, 0 );
00751 }
00752
00753 void KWTableFrameSet::resizeRow( unsigned int row, double y )
00754 {
00755 kdDebug() << k_funcinfo << row << "," << y << endl;
00756 double difference = m_rowPositions[row];
00757 if ((row != 0) && (y - m_rowPositions[ row-1 ] < s_minFrameHeight))
00758 m_rowPositions[ row ] = m_rowPositions[ row-1 ] + s_minFrameHeight;
00759 else
00760 if ((row != getRows()) && (m_rowPositions[ row + 1 ] - y < s_minFrameHeight))
00761 m_rowPositions[row] = m_rowPositions[ row + 1 ] - s_minFrameHeight;
00762 else
00763 m_rowPositions[ row ] = y;
00764 difference = m_rowPositions[row] - difference;
00765
00766
00767 if (row != 0)
00768 for (unsigned int i=row+1; i<= getRows(); i++)
00769 m_rowPositions[i] = m_rowPositions[i] + difference;
00770
00771
00772 for (TableIter cell(this); cell; ++cell) {
00773 if ( cell->rowAfter() >= row ) {
00774 position(cell);
00775 }
00776 }
00777 recalcRows( 0, row-1 );
00778 }
00779
00780 void KWTableFrameSet::resizeWidth( double width ) {
00781 Q_ASSERT(width != 0);
00782 Q_ASSERT(boundingRect().width() != 0);
00783 kdDebug() << "bounding width before resize " << boundingRect().width() << endl;
00784 double growth = width / boundingRect().width();
00785
00786
00787
00788
00789 double moveOffset = m_colPositions[0] * growth - m_colPositions[0];
00790
00791 for (uint i=0; i<m_colPositions.count(); i++) {
00792 m_colPositions[i] = m_colPositions[i] * growth - moveOffset;
00793 }
00794 finalize();
00795 kdDebug() << "bounding width after resize" << boundingRect().width() << endl;
00796 Q_ASSERT(boundingRect().width() - width < 0.01);
00797 }
00798
00799 void KWTableFrameSet::setBoundingRect( KoRect rect, CellSize widthMode, CellSize heightMode ) {
00800
00801 m_colPositions.clear();
00802 unsigned int cols=0;
00803 for (TableIter c(this); c; ++c)
00804 cols = kMax(cols, c.current()->columnAfter());
00805 double colWidth = rect.width() / cols;
00806 if ( widthMode == TblAuto ) {
00807 KWPage *page = pageManager()->page(rect);
00808 rect.setLeft( page->leftMargin() );
00809 colWidth = (page->width() - page->leftMargin() - page->rightMargin()) / cols;
00810 }
00811
00812 for(unsigned int i=0; i <= cols;i++) {
00813 m_colPositions.append(rect.x() + colWidth * i);
00814 }
00815
00816
00817 m_rowPositions.clear();
00818 m_pageBoundaries.clear();
00819 double rowHeight = 0;
00820 if( heightMode != TblAuto )
00821 rowHeight = rect.height() / m_rows;
00822 rowHeight=kMax(rowHeight, 22.0);
00823
00824 for(unsigned int i=0; i <= m_rows;i++) {
00825 m_rowPositions.append(rect.y() + rowHeight * i);
00826 }
00827
00828 double oneMm = MM_TO_POINT( 1.0 );
00829 for (TableIter cell(this); cell; ++cell) {
00830 KWFrame *frame = cell->frame(0);
00831 frame->setPaddingLeft( oneMm );
00832 frame->setPaddingRight( oneMm );
00833 frame->setPaddingTop( oneMm );
00834 frame->setPaddingBottom( oneMm );
00835 frame->setNewFrameBehavior( KWFrame::NoFollowup );
00836 position(cell, true);
00837 }
00838 }
00839
00840 void KWTableFrameSet::position( Cell *theCell, bool setMinFrameHeight ) {
00841 if(!theCell->frame(0)) {
00842 kdDebug(32004) << "errorous table cell!! row:" << theCell->firstRow()
00843 << ", col: " << theCell->firstColumn() << endl;
00844 return;
00845 }
00846 double x = *m_colPositions.at(theCell->firstColumn());
00847 double y = getPositionOfRow(theCell->firstRow());
00848 double width = (*m_colPositions.at(theCell->columnAfter())) - x;
00849 double height = getPositionOfRow(theCell->lastRow(), true) - y;
00850
00851 #if 0
00852 if(theCell->m_col==0) {
00853 kdDebug(32004) << "row " << theCell->firstRow() << " has top: "
00854 << y << ", and bottom: " << y + height << endl;
00855 }
00856 #endif
00857
00858
00859 KWFrame *theFrame = theCell->frame(0);
00860 x+=theCell->leftBorder();
00861 width-=theCell->leftBorder();
00862 width-=theCell->rightBorder();
00863 y+=theCell->topBorder();
00864 height-=theCell->topBorder();
00865 height-=theCell->bottomBorder();
00866
00867 theFrame->setRect( x,y,width,height);
00868 if( setMinFrameHeight )
00869 theFrame->setMinimumFrameHeight(height);
00870
00871 if(!theCell->isVisible())
00872 theCell->setVisible(true);
00873 }
00874
00875 double KWTableFrameSet::getPositionOfRow( unsigned int row, bool bottom ) {
00876 unsigned int adjustment=0;
00877 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
00878 while(pageBound != m_pageBoundaries.end() && (*pageBound) <= row + adjustment) {
00879 adjustment++;
00880 pageBound++;
00881 }
00882 if(m_rowPositions.count() < row+adjustment+(bottom?1:0))
00883 return 0;
00884 return m_rowPositions[row+adjustment+(bottom?1:0)];
00885 }
00886
00887 void KWTableFrameSet::moveBy( double dx, double dy ) {
00888 bool redraw=false;
00889 kdDebug(32004) << "KWTableFrameSet(" << name() << ")::moveBy(" << dx<<","<<dy<<")\n";
00890
00891 if(!(dy > -0.001 && dy < 0.001)) {
00892 redraw=true;
00893 QValueList<double>::iterator row = m_rowPositions.begin();
00894 while(row != m_rowPositions.end()) {
00895 (*row)= (*row)+dy;
00896 row++;
00897 }
00898 }
00899 if(!(dx > -0.001 && dx < 0.001)) {
00900 redraw=true;
00901 QValueList<double>::iterator col = m_colPositions.begin();
00902 while(col != m_colPositions.end()) {
00903 (*col)= (*col)+dx;
00904 col++;
00905 }
00906 }
00907
00908 if(redraw) {
00909 for(TableIter cell(this);cell;++cell)
00910 position(cell);
00911 }
00912 }
00913
00914
00915 void KWTableFrameSet::deleteRow( unsigned int row, RemovedRow &rr, bool _recalc)
00916 {
00917 Q_ASSERT(row < m_rowArray.size());
00918 const unsigned int rowspan=1;
00919
00920 double height= getPositionOfRow(row+rowspan-1,true) - getPositionOfRow(row);
00921 QValueList<double>::iterator tmp = m_rowPositions.at(row+rowspan);
00922 tmp=m_rowPositions.erase(tmp);
00923 while(tmp!=m_rowPositions.end()) {
00924 (*tmp)= (*tmp)-height;
00925 tmp++;
00926 }
00927
00928 rr.m_index = row;
00929 rr.m_rowHeight = height;
00930 rr.m_row = m_rowArray[row];
00931
00932
00933 for ( TableIter cell(this); cell; ++cell ) {
00934 if ( row >= cell->firstRow() && row < cell->rowAfter()) {
00935 if(cell->rowSpan() == 1) {
00936 m_frames.remove( cell->frame(0) );
00937 } else {
00938 cell->setRowSpan(cell->rowSpan()-rowspan);
00939 position(cell);
00940 }
00941
00942 } else if ( cell->firstRow() > row ) {
00943
00944 cell->setFirstRow( cell->firstRow() - rowspan );
00945 position(cell);
00946 }
00947 }
00948
00949 removeRowVector(row);
00950 m_rows -= rowspan;
00951 m_rowArray.resize( m_rows );
00952 validate();
00953
00954 if ( _recalc )
00955 recalcRows( 0, row-1 );
00956 }
00957
00958 void KWTableFrameSet::reInsertRow(RemovedRow &rr)
00959 {
00960 uint row = rr.index();
00961 Row *r = rr.row();
00962 uint rlen = r->count();
00963
00964
00965 for(MarkedIterator cell(this); cell; ++cell) {
00966
00967 if ( cell->firstRow() < row && cell->lastRow() >= row ){
00968 cell->setRowSpan(cell->rowSpan() + 1);
00969 }
00970 else if(r->m_cellArray[cell->firstColumn()] == cell.current()) {
00971 cell->setRowSpan(cell->rowSpan() + 1);
00972 }
00973 else if ( cell->firstRow() >= row ) {
00974
00975 cell->setFirstRow( cell->firstRow() + 1);
00976 }
00977 }
00978
00979
00980 for(uint i = 0; i < rlen; i++){
00981 if( m_frames.findRef((*r)[i]->frame(0)) == -1 )
00982 m_frames.append( (*r)[i]->frame(0) );
00983 }
00984
00985
00986 if(row == m_rows) {
00987 double d = m_rowPositions.last() + rr.height();
00988 m_rowPositions.append(d);
00989 }
00990 else {
00991 QValueList<double>::iterator top = m_rowPositions.at(row);
00992 QValueList<double>::iterator i = m_rowPositions.at(row+1);
00993 i = m_rowPositions.insert(i, *top + rr.height());
00994 i++;
00995 for(; i != m_rowPositions.end(); ++i) {
00996 *i = *i+ rr.height();
00997 }
00998 }
00999
01000
01001 m_rows++;
01002 insertRowVector(rr.index(), rr.takeRow());
01003
01004
01005 for(TableIter i(this); i ; ++i)
01006 position(i.current());
01007
01008 validate();
01009 }
01010
01011 void KWTableFrameSet::insertNewRow( uint idx, bool recalc, bool _removeable)
01012 {
01013
01014 (void) _removeable;
01015 unsigned int copyFromRow = idx==0?0:idx-1;
01016 if(idx==0)
01017 copyFromRow=1;
01018 Row *copyRow = m_rowArray[copyFromRow];
01019
01020 uint new_rows = m_rows + 1;
01021
01022 double height = getPositionOfRow(copyFromRow,true) - getPositionOfRow(copyFromRow);
01023
01024
01025 unsigned int adjustment=0;
01026 unsigned int untilRow=m_rows;
01027 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
01028 while(pageBound != m_pageBoundaries.end() && (*pageBound) <= idx) {
01029
01030 adjustment++;
01031 pageBound++;
01032 }
01033
01034
01035 QValueList<double>::iterator tmp = m_rowPositions.at(idx);
01036 double newPos = *tmp + height;
01037 tmp++;
01038 m_rowPositions.insert(tmp, newPos);
01039 for(unsigned int i=idx+adjustment+2; i < m_rowPositions.count(); i++) {
01040 double &rowPos = m_rowPositions[i];
01041 kdDebug(32004) << "adjusting " << rowPos << " -> " << rowPos + height << endl;
01042 rowPos = rowPos + height;
01043 if(*pageBound == i) {
01044 untilRow= *pageBound;
01045 break;
01046 }
01047 }
01048
01049 for ( MarkedIterator cells(this); cells; ++cells) {
01050 if ( cells->firstRow() >= idx ) {
01051 cells->setFirstRow(cells->firstRow()+1);
01052 }
01053 }
01054
01055 insertRowVector(idx, new Row);
01056
01057 unsigned int i = 0;
01058 while(i < getColumns()) {
01059
01060 if(idx != 0 && (idx != m_rows)) {
01061 Cell *c = cell(idx - 1, i);
01062 if( c == cell(idx + 1, i) ) {
01063 m_rowArray[idx]->addCell(c);
01064 c->setRowSpan(c->rowSpan() + 1);
01065 i += c->columnSpan();
01066 continue;
01067 }
01068 }
01069
01070 KWFrame *theFrame = new KWFrame(copyRow->m_cellArray[i]->frame(0));
01071 Cell *newCell=new Cell( this, idx, i, QString::null );
01072 newCell->setColumnSpan( cell(copyFromRow,i)->columnSpan() );
01073 addCell(newCell);
01074 newCell->addFrame( theFrame, false );
01075 position(newCell);
01076 i += newCell->columnSpan();
01077 }
01078
01079
01080
01081 m_rows = new_rows;
01082 validate();
01083 if ( recalc )
01084 finalize();
01085 }
01086
01087 void KWTableFrameSet::deleteColumn(uint col, RemovedColumn &rc)
01088 {
01089
01090 if(!rc.m_initialized) {
01091 rc.m_index = col;
01092 rc.m_width = m_colPositions[col+1] - m_colPositions[col];
01093 }
01094
01095
01096 QValueList<double>::iterator tmp = m_colPositions.at(col+1);
01097 tmp = m_colPositions.erase(tmp);
01098 while(tmp != m_colPositions.end()) {
01099 (*tmp) = (*tmp) - rc.m_width;
01100 tmp++;
01101 }
01102
01103
01104
01105
01106 CheckedIter iter(this);
01107 for(uint i = 0; i < m_rows; ++i) {
01108 Cell *daCell = cell(i, col);
01109
01110 if(!rc.m_initialized) {
01111 rc.m_column.append(daCell);
01112 rc.m_removed.append(daCell->columnSpan() == 1);
01113 }
01114
01115 if(daCell->columnSpan() == 1) {
01116 if(daCell->firstRow() == i) {
01117 m_frames.remove( daCell->frame(0) );
01118 m_nr_cells--;
01119 }
01120 m_rowArray[i]->m_cellArray.insert(col, 0);
01121 }
01122 else {
01123 if(daCell->firstRow() == i) {
01124 daCell->setColumnSpan( daCell->columnSpan() - 1 );
01125 position(daCell);
01126 }
01127 }
01128 }
01129
01130
01131 for(; iter; ++iter) {
01132 if (iter->firstColumn() > col ) {
01133 iter->setFirstColumn( iter->firstColumn() - 1);
01134 position(iter.current());
01135 }
01136 }
01137
01138
01139
01140 for(uint i = 0; i < m_rows; i++) {
01141 for(uint j = col + 1; j < m_cols; j++)
01142 m_rowArray[i]->m_cellArray.insert(j-1, m_rowArray[i]->m_cellArray[j]);
01143 }
01144 m_cols--;
01145 rc.m_initialized = true;
01146
01147 validate();
01148 recalcCols( col, 0 );
01149 recalcRows( col, 0 );
01150 }
01151
01152 void KWTableFrameSet::reInsertColumn(RemovedColumn &rc)
01153 {
01154 QValueList<double>::iterator tmp = m_colPositions.at(rc.m_index);
01155
01156 tmp = m_colPositions.insert(tmp, *tmp);
01157 tmp++;
01158 while(tmp != m_colPositions.end()) {
01159 (*tmp) = (*tmp) + rc.m_width;
01160 tmp++;
01161 }
01162
01163
01164
01165
01166 for ( MarkedIterator cells(this); cells ; ++cells ) {
01167 if ( cells->firstColumn() >= rc.m_index &&
01168 (rc.m_column.at(cells->firstRow()) != cells.current())) {
01169
01170 cells->setFirstColumn(cells->firstColumn() + 1);
01171 }
01172 }
01173 insertEmptyColumn(rc.m_index);
01174 m_cols++;
01175
01176 for(uint i = 0; i < m_rows; ++i) {
01177 bool removed = rc.m_removed[i];
01178 Cell *daCell = rc.m_column.at(i);
01179 if(i == daCell->firstRow()) {
01180 if(removed) {
01181 daCell->setColumnSpan(1);
01182 m_frames.append(daCell->frame(0));
01183 m_nr_cells++;
01184 }
01185 else {
01186 daCell->setColumnSpan(daCell->columnSpan() + 1);
01187 }
01188 addCell(daCell);
01189 }
01190 }
01191
01192 validate();
01193 finalize();
01194 }
01195
01196 void KWTableFrameSet::insertNewColumn( uint idx, double width)
01197 {
01198 QValueList<double>::iterator tmp = m_colPositions.at(idx);
01199
01200 tmp = m_colPositions.insert(tmp, *tmp);
01201 tmp++;
01202 while(tmp!=m_colPositions.end()) {
01203 (*tmp)= (*tmp)+width;
01204 tmp++;
01205 }
01206
01207 for ( MarkedIterator cells(this); cells ; ++cells ) {
01208 if ( cells->firstColumn() >= idx) {
01209 cells->setFirstColumn(cells->firstColumn() + 1);
01210 }
01211 }
01212 insertEmptyColumn(idx);
01213 m_cols++;
01214 uint copyCol = (idx == 0) ? 1 : idx - 1 ;
01215
01216
01217
01218 for( unsigned int i = 0; i < getRows(); i++ ) {
01219
01220
01221
01222
01223 if(idx != 0 && (idx != m_cols -1)) {
01224 Cell *c = cell(i, idx - 1);
01225 if( c == cell(i, idx + 1) ) {
01226
01227 c->setColumnSpan(c->columnSpan() + 1);
01228 addCell(c);
01229 i += c->rowSpan() - 1;
01230 continue;
01231 }
01232 }
01233
01234 Cell *newCell = new Cell( this, i, idx, QString::null );
01235 KWFrame *theFrame = new KWFrame(cell(i, copyCol)->frame(0));
01236 newCell->addFrame( theFrame, false );
01237 position(newCell);
01238 m_nr_cells++;
01239 }
01240 validate();
01241 finalize();
01242 }
01243
01244 void KWTableFrameSet::ungroup()
01245 {
01246
01247
01248 m_nr_cells = 0;
01249
01250 m_active = false;
01251 }
01252
01253 void KWTableFrameSet::group()
01254 {
01255
01256
01257
01258 m_nr_cells = 0;
01259 m_active = true;
01260 }
01261
01262 KCommand *KWTableFrameSet::joinCells(unsigned int colBegin,unsigned int rowBegin, unsigned int colEnd,unsigned int rowEnd) {
01263 Cell *firstCell = cell(rowBegin, colBegin);
01264
01265 if(rowBegin == rowEnd && colBegin == colEnd || cell(rowBegin,colBegin) == cell(rowEnd,colEnd))
01266 return 0L;
01267 QPtrList<KWFrameSet> listFrameSet;
01268 QPtrList<KWFrame> listCopyFrame;
01269
01270
01271 for(unsigned int i=colBegin; i<=colEnd;i++) {
01272 for(unsigned int j=rowBegin; j<=rowEnd;j++) {
01273 Cell *daCell = cell(j,i);
01274 if(daCell && daCell!=firstCell) {
01275 listFrameSet.append(daCell);
01276 listCopyFrame.append(daCell->frame(0)->getCopy());
01277 daCell->deleteFrame( daCell->frame(0));
01278 }
01279 }
01280 }
01281
01282 Q_ASSERT(firstCell);
01283
01284 firstCell->setColumnSpan(colEnd-colBegin+1);
01285 firstCell->setRowSpan(rowEnd-rowBegin+1);
01286 addCell(firstCell);
01287 position(firstCell);
01288 validate();
01289
01290 m_doc->updateAllFrames();
01291 m_doc->repaintAllViews();
01292 return new KWJoinCellCommand( i18n("Join Cells"), this,colBegin,rowBegin, colEnd,rowEnd,listFrameSet,listCopyFrame);
01293 }
01294
01295 KCommand *KWTableFrameSet::splitCell(unsigned int intoRows, unsigned int intoCols, unsigned int col, unsigned int row, QPtrList<KWFrameSet> listFrameSet, QPtrList<KWFrame>listFrame) {
01296 if(intoRows < 1 || intoCols < 1)
01297 return 0L;
01298
01299 kdDebug(32004) << "KWTableFrameSet::splitCell" << endl;
01300 Cell *daCell=cell(row,col);
01301 int rowsDiff = intoRows - daCell->rowSpan();
01302 int colsDiff = ((int) intoCols) - daCell->columnSpan();
01303
01304 if(rowsDiff >0) {
01305 unsigned int adjustment=0;
01306 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
01307 while(pageBound != m_pageBoundaries.end() && (*pageBound) <= row) {
01308 adjustment++;
01309 pageBound++;
01310 }
01311 double height = (m_rowPositions[row+adjustment+1] - m_rowPositions[row+adjustment])/intoRows;
01312
01313 QValueList<double>::iterator iRow = m_rowPositions.at(adjustment+row);
01314 for (int i=0; i < rowsDiff; i++) {
01315 double newPos = *iRow + height;
01316 iRow++;
01317 iRow=m_rowPositions.insert(iRow, newPos);
01318 }
01319
01320
01321 for(int i = 0; i < rowsDiff; ++i) {
01322 insertRowVector(row+i+1, new Row);
01323 m_rows++;
01324 }
01325
01326
01327
01328
01329 }
01330 if(colsDiff >0) {
01331 double width = (m_colPositions[col+1] - m_colPositions[col])/intoCols;
01332
01333 QValueList<double>::iterator iCol = m_colPositions.at(col);
01334 for (int i=0; i < colsDiff; i++) {
01335 double newPos = *iCol + width;
01336 iCol++;
01337 iCol=m_colPositions.insert(iCol, newPos);
01338 }
01339
01340 for(int i = 0; i < colsDiff; i++) {
01341 insertEmptyColumn(col+i+1);
01342 m_cols++;
01343 }
01344
01345
01346
01347 }
01348
01349
01350 for (CheckedIter i(this); i ; ++i) {
01351 if(daCell == i) continue;
01352
01353 if(rowsDiff>0) {
01354 if(row >= i->firstRow()&& row < i->firstRow()+ i->rowSpan())
01355 i->setRowSpan(i->rowSpan() + rowsDiff);
01356 if(i->firstRow() > row) {
01357 i->setFirstRow(i->firstRow() + rowsDiff);
01358
01359 }
01360 }
01361 if(colsDiff>0) {
01362 if(col >= i->firstColumn() && col < i->columnAfter())
01363 i->setColumnSpan(i->columnSpan() + colsDiff);
01364 if(i->firstColumn() > col)
01365 i->setFirstColumn(i->firstColumn() + colsDiff);
01366 }
01367
01368
01369
01370 if ( rowsDiff > 0 || colsDiff > 0 )
01371 addCell( i );
01372 }
01373
01374 int i=0;
01375 KWFrame *firstFrame = daCell->frame(0);
01376
01377 for (unsigned int y = 0; y < intoRows; y++) {
01378 for (unsigned int x = 0; x < intoCols; x++){
01379 if(x==0 && y==0)
01380 continue;
01381
01382 Cell *lastFrameSet=0L;
01383
01384 if(listFrameSet.isEmpty())
01385 lastFrameSet = new Cell( this, y + row, x + col );
01386 else
01387 lastFrameSet = static_cast<KWTableFrameSet::Cell*> (listFrameSet.at(i));
01388 lastFrameSet->setGroupManager(this);
01389
01390 KWFrame *theFrame=0L;
01391 if(listFrame.isEmpty())
01392 {
01393 theFrame=firstFrame->getCopy();
01394 theFrame->setRunAround( KWFrame::RA_NO );
01395 theFrame->setFrameBehavior(KWFrame::AutoExtendFrame);
01396 theFrame->setNewFrameBehavior(KWFrame::NoFollowup);
01397 lastFrameSet->addFrame( theFrame,false );
01398 }
01399 else
01400 lastFrameSet->addFrame( listFrame.at(i)->getCopy(),false );
01401 i++;
01402
01403
01404 if(rowsDiff <0 && y==0)
01405 lastFrameSet->setRowSpan(lastFrameSet->rowSpan() - rowsDiff);
01406 if(colsDiff <0 && x==0)
01407 lastFrameSet->setColumnSpan(lastFrameSet->columnSpan() - colsDiff);
01408
01409 addCell( lastFrameSet );
01410 position(lastFrameSet);
01411 }
01412 }
01413
01414
01415
01416 int r = (daCell->rowSpan() +1) - intoRows;
01417 if(r < 1) r=1;
01418 daCell->setRowSpan(r);
01419
01420 int c = (daCell->columnSpan() + 1) - intoCols;
01421 if(c < 1) c=1;
01422 daCell->setColumnSpan(c);
01423
01424 position(daCell);
01425 addCell(daCell);
01426 validate();
01427
01428 finalize();
01429
01430 return new KWSplitCellCommand(i18n("Split Cells"),this,col,row,intoCols, intoRows);
01431 }
01432
01433 void KWTableFrameSet::viewFormatting( QPainter &, int )
01434 {
01435 }
01436
01437 void KWTableFrameSet::validate()
01438 {
01439 for(CheckedIter cells(this); cells; ++cells) {
01440 if(cells->columnSpan() == 0 || cells->rowSpan() == 0) {
01441 kdDebug(32004) << " KWTableFrameSet::validate(): zero dimension" << endl;
01442 kdDebug(32004) << cells->firstRow() << " " << cells->firstColumn() << " " << cells->rowSpan()
01443 << " " << cells->columnSpan() << endl;
01444 }
01445
01446 for(uint i = cells->firstRow(); i < cells->rowAfter(); ++i) {
01447
01448 for(uint j = cells->firstColumn(); j < cells->columnAfter(); ++j) {
01449 if( cell(i,j) != cells.current() ) {
01450
01451 QString str = QString("| 0x%1 ").arg( (unsigned long)cells.current(), 0, 16 );
01452 kdDebug(32004) << " KWTableFrameSet::validate() failed " << endl;
01453 kdDebug(32004) << "at row: "<< i << " col: "<< j << " cell: "<< str << endl;
01454 kdDebug(32004) << cells->firstRow() << " " << cells->firstColumn() << " " << cells->rowSpan()
01455 << " " << cells->columnSpan() << endl;
01456
01457 }
01458 }
01459 }
01460 }
01461 }
01462
01463 void KWTableFrameSet::createEmptyRegion( const QRect & crect, QRegion & emptyRegion, KWViewMode *viewMode )
01464 {
01465
01466 if ( !viewMode->normalToView( m_doc->zoomRect( boundingRect() ) ).intersects( crect ) )
01467 return;
01468
01469 QRect outerRect( viewMode->normalToView( m_doc->zoomRect( boundingRect() )));
01470 outerRect &= crect;
01471 if ( !outerRect.isEmpty() )
01472 emptyRegion = emptyRegion.subtract( outerRect );
01473
01474 QPtrListIterator<KWFrame> frameIt = frameIterator();
01475 for ( ; frameIt.current(); ++frameIt )
01476 {
01477 QRect outerRect( viewMode->normalToView( frameIt.current()->outerRect(viewMode) ) );
01478
01479
01480 outerRect &= crect;
01481 if ( !outerRect.isEmpty() )
01482 emptyRegion = emptyRegion.subtract( outerRect );
01483 }
01484 }
01485
01486 void KWTableFrameSet::drawBorders( QPainter& painter, const QRect &crect, KWViewMode *viewMode ) {
01487
01488
01489
01490
01491
01492
01493 painter.save();
01494 QPen previewLinePen( QApplication::palette().color( QPalette::Active, QColorGroup::Mid ) );
01495 QColor defaultBorderColor = KoTextFormat::defaultTextColor( &painter );
01496 const int minborder = 1;
01497 bool drawPreviewLines = viewMode && viewMode->drawFrameBorders();
01498
01499
01500 unsigned int row=0;
01501 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
01502 for (unsigned int i=0 ; i < m_rowPositions.count() ; i++) {
01503
01504 bool bottom=false;
01505 if( (pageBound!=m_pageBoundaries.end() && (*pageBound) == row)
01506 || i == m_rowPositions.count()-1)
01507 bottom=true;
01508
01509 const KoBorder *border=0;
01510 double startPos =0;
01511 for(unsigned int col=0; col <= getColumns();) {
01512
01513 Cell *daCell = col < getColumns() ? cell(bottom?row-1:row, col) : 0;
01514
01515
01516
01517 if(daCell && daCell->firstRow() != (bottom?row-1:row))
01518 daCell=0;
01519
01520 if(startPos!=0 && (!daCell || col == getColumns() || (
01521 bottom && daCell->frame(0)->bottomBorder()!=*border ||
01522 !bottom && daCell->frame(0)->topBorder()!=*border
01523 ))) {
01524 if(border->width() > 0 || drawPreviewLines) {
01525 double y = m_rowPositions[i];
01526 if(row==0)
01527 y+=border->width() / 2;
01528 else if (row == getRows())
01529 y-=border->width() / 2;
01530 int ypix = m_doc->zoomItY(y);
01531 double offset=0.0;
01532 if(border->width() > 0 && col!=getColumns()) {
01533 if(daCell) offset=daCell->leftBorder();
01534 if ( row > 0 ) {
01535 Cell *c = cell(row-1, col);
01536 if(c) offset=kMax(offset, c->leftBorder());
01537 }
01538 }
01539 double x = m_colPositions[col] + offset;
01540 QPoint topLeft = viewMode->normalToView(QPoint(m_doc->zoomItX(startPos), ypix));
01541 QPoint bottomRight = viewMode->normalToView(QPoint(m_doc->zoomItX(x), ypix));
01542 QRect line = QRect(topLeft, bottomRight);
01543 if(crect.intersects( line )) {
01544
01545 if(border->width() <= 0)
01546 painter.setPen( previewLinePen );
01547 else {
01548 int borderWidth = KoBorder::zoomWidthY( border->width(), m_doc, minborder );
01549 painter.setPen( KoBorder::borderPen( *border, borderWidth, defaultBorderColor ) );
01550 }
01551
01552 painter.drawLine( line.left(), line.top(), line.right(), line.bottom());
01553 }
01554 }
01555
01556 startPos = 0;
01557 }
01558 if(daCell && startPos==0) {
01559 if(bottom)
01560 border=&(daCell->frame(0)->bottomBorder());
01561 else
01562 border=&(daCell->frame(0)->topBorder());
01563
01564 if(col==0)
01565 startPos = m_colPositions[col];
01566 else {
01567 double offset=0.0;
01568 if(border->width() > 0) {
01569 if(daCell) offset=daCell->leftBorder();
01570 if ( row > 0 ) {
01571 Cell *c = cell(row-1, col);
01572 if(c) offset=kMax(offset, c->leftBorder());
01573 }
01574 }
01575 startPos = m_colPositions[col] - offset;
01576 }
01577 }
01578 col += daCell ? daCell->columnSpan() : 1;
01579 }
01580 if(pageBound!=m_pageBoundaries.end() && (*pageBound) == row)
01581 pageBound++;
01582 else
01583 row++;
01584 }
01585
01586
01587 for (unsigned int col=0 ; col < m_colPositions.count(); col++) {
01588
01589 bool right = false;
01590 if(col == m_colPositions.count()-1)
01591 right = true;
01592 int cellColumn = right?col-1:col;
01593 Q_ASSERT( cellColumn >= 0 );
01594
01595 const KoBorder *border = 0;
01596 int startRow = -1;
01597 for(unsigned int row=0; row <= getRows();) {
01598
01599 Cell *daCell = row < getRows() ? cell(row, cellColumn) : 0;
01600
01601
01602 if(daCell && daCell->firstColumn() != (uint)cellColumn)
01603 daCell=0;
01604
01605 #if 0
01606 kdDebug() << "Condition: startRow:" << (startRow!=-1) << endl;
01607 if ( startRow != -1 ) {
01608 Q_ASSERT( border );
01609 kdDebug() << "Other conditions: cell:" << !daCell << endl;
01610 kdDebug() << " or last row:" << ( row == ( int )getRows() ) << endl;
01611 if ( daCell )
01612 kdDebug() << "Different border:" <<
01613 ( ( right && daCell->frame(0)->rightBorder() != *border) ||
01614 ( !right && daCell->frame(0)->leftBorder() != *border) )
01615 << endl;
01616 }
01617 #endif
01618
01619
01620 if ( !daCell && startRow == -1 && cellColumn == ((int)m_colPositions.count()-2 ) && right )
01621 {
01622
01623 int col = cellColumn;
01624 while ( !daCell && col>0 )
01625 {
01626 col--;
01627 daCell = cell(row, col);
01628 }
01629 if ( daCell && daCell->isJoinedCell() && ( (int)daCell->columnSpan() + col -1 ) == cellColumn )
01630 {
01631 border = &(daCell->frame(0)->rightBorder());
01632 startRow = row;
01633 }
01634 else
01635 daCell = 0;
01636 }
01637
01638
01639
01640
01641 if(startRow != -1 &&
01642 (!daCell || row == getRows() ||
01643 ( right && daCell->frame(0)->rightBorder() != *border) ||
01644 ( !right && daCell->frame(0)->leftBorder() != *border) )
01645 ) {
01646 if(border->width() > 0 || drawPreviewLines) {
01647 double x = m_colPositions[col];
01648 if(col==0) {
01649 x+=border->width() / 2;
01650 } else if(col==getColumns()) {
01651 x-=border->width() / 2;
01652 }
01653 int xpix = m_doc->zoomItX(x);
01654 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
01655 unsigned int topRow=startRow;
01656
01657 do {
01658 while( pageBound != m_pageBoundaries.end() && *(pageBound) < topRow )
01659 pageBound++;
01660
01661 unsigned int bottomRow;
01662 if(pageBound == m_pageBoundaries.end())
01663 bottomRow = m_rowPositions.count()-1;
01664 else
01665 bottomRow = *(pageBound++);
01666
01667
01668
01669 double offset=0.0;
01670 if(border->width() > 0) {
01671
01672 Cell *c=cell(topRow,col);
01673 if(c) offset=c->topBorder();
01674 if ( col > 0 ) {
01675 c=cell(topRow,col-1);
01676 if(c) offset=kMax(offset,c->topBorder());
01677 }
01678 if(topRow==0) offset=0.0;
01679 }
01680 double top=m_rowPositions[topRow]-offset;
01681
01682 unsigned int toRow=kMin((uint)row,bottomRow);
01683 offset=0.0;
01684 if(border->width() > 0 && toRow!=bottomRow) {
01685 if(daCell) offset=daCell->topBorder();
01686 Cell *c=cell(toRow,col-1);
01687 if(c) offset=kMax(offset,c->topBorder());
01688 }
01689 double bottom=m_rowPositions[toRow] + offset;
01690
01691 QPoint topLeft = viewMode->normalToView(QPoint(xpix, m_doc->zoomItY(top)));
01692 QPoint bottomRight = viewMode->normalToView(QPoint(xpix, m_doc->zoomItY(bottom)));
01693 QRect line = QRect(topLeft, bottomRight);
01694 if(crect.intersects( line )) {
01695 if(border->width() <= 0)
01696 painter.setPen( previewLinePen );
01697 else {
01698 int borderWidth = KoBorder::zoomWidthX( border->width(), m_doc, minborder );
01699 painter.setPen(KoBorder::borderPen( *border, borderWidth, defaultBorderColor ));
01700 }
01701
01702 painter.drawLine( line.left(), line.top(), line.right(), line.bottom());
01703 }
01704
01705 topRow=bottomRow+1;
01706 } while(topRow < (uint)row && topRow != m_rowPositions.count());
01707 }
01708
01709
01710 startRow = -1;
01711 }
01712
01713 if(daCell && startRow == -1) {
01714 startRow = row;
01715 if(right)
01716 border = &(daCell->frame(0)->rightBorder());
01717 else
01718 border = &(daCell->frame(0)->leftBorder());
01719
01720 }
01721 row += daCell ? daCell->rowSpan() : 1;
01722
01723 }
01724 }
01725
01726 #if 0
01727 if(drawPreviewLines) {
01728 QPen minsizeLinePen( red );
01729 painter.setPen( minsizeLinePen );
01730 for ( unsigned int i = 0; i < m_cells.count(); i++ ) {
01731 Cell *daCell = m_cells.at( i );
01732 double y = daCell->frame(0)->top() + daCell->frame(0)->minimumFrameHeight() + 1.5;
01733 if(y >= daCell->frame(0)->bottom()) continue;
01734 int ypix=m_doc->zoomItY(y);
01735 QPoint topLeft = viewMode->normalToView(QPoint(m_doc->zoomItX(daCell->frame(0)->left()), ypix));
01736 QPoint bottomRight = viewMode->normalToView(QPoint(m_doc->zoomItX(daCell->frame(0)->right()), ypix));
01737 QRect line = QRect(topLeft, bottomRight);
01738 if(crect.intersects( line )) {
01739 painter.drawLine( line.left(), line.top(), line.right(), line.bottom());
01740 }
01741 }
01742 }
01743 #endif
01744
01745 painter.restore();
01746 }
01747
01748 void KWTableFrameSet::drawContents( QPainter * painter, const QRect & crect,
01749 const QColorGroup & cg, bool onlyChanged, bool resetChanged,
01750 KWFrameSetEdit * edit, KWViewMode * viewMode,
01751 KWFrameViewManager *fvm )
01752 {
01753 for (TableIter cells(this) ; cells ; ++cells)
01754 {
01755 if (edit)
01756 {
01757 KWTableFrameSetEdit * tableEdit = static_cast<KWTableFrameSetEdit *>(edit);
01758 if ( tableEdit->currentCell() && ((Cell*) cells) == tableEdit->currentCell()->frameSet() )
01759 {
01760 cells->drawContents( painter, crect, cg, onlyChanged, resetChanged, tableEdit->currentCell(), viewMode, fvm );
01761 continue;
01762 }
01763 }
01764 cells->drawContents( painter, crect, cg, onlyChanged, resetChanged, 0L, viewMode, fvm );
01765 }
01766 drawBorders( *painter, crect, viewMode );
01767
01768 }
01769
01770
01771
01772
01773 void KWTableFrameSet::saveOasis( KoXmlWriter& writer, KoSavingContext& context, bool ) const
01774 {
01775 writer.startElement( "table:table" );
01776 writer.addAttribute( "table:name", name() );
01777 KoGenStyle tableStyle( KWDocument::STYLE_TABLE, "table" );
01778 tableStyle.addProperty( "table:align", "margins" );
01779 tableStyle.addPropertyPt( "style:width", m_colPositions.last()-m_colPositions[0] );
01780 const QString tableStyleName = context.mainStyles().lookup( tableStyle, "table" );
01781 writer.addAttribute( "table:style-name", tableStyleName );
01782
01783
01784
01785 for ( uint colNr = 0; colNr < getColumns(); ++colNr )
01786 {
01787 writer.startElement( "table:table-column" );
01788 KoGenStyle columnStyle( KWDocument::STYLE_TABLE_COLUMN, "table-column" );
01789 columnStyle.addPropertyPt( "style:column-width", m_colPositions[colNr+1] - m_colPositions[colNr] );
01790 const QString colStyleName = context.mainStyles().lookup( columnStyle, "col" );
01791 writer.addAttribute( "table:style-name", colStyleName );
01792 writer.endElement();
01793 }
01794
01795
01796
01797 for ( uint row = 0; row < getRows(); ++row )
01798 {
01799 writer.startElement( "table:table-row" );
01800
01801 KoGenStyle rowStyle( KWDocument::STYLE_TABLE_ROW, "table-row" );
01802 rowStyle.addPropertyPt( "table:row-height", m_rowPositions[row+1] - m_rowPositions[row] );
01803
01804 const QString rowStyleName = context.mainStyles().lookup( rowStyle, "row" );
01805 writer.addAttribute( "table:style-name", rowStyleName );
01806
01807 for ( uint col = 0; col < getColumns(); ++col )
01808 {
01809 Cell* daCell = cell(row, col);
01810 Q_ASSERT( daCell );
01811 if ( !daCell )
01812 continue;
01813
01814 if ( daCell->isFirstGridPosnFast( row, col ) )
01815 {
01816 writer.startElement( "table:table-cell" );
01817
01818
01819 KoGenStyle cellStyle( KWDocument::STYLE_TABLE_CELL_AUTO, "table-cell" );
01820 daCell->frame( 0 )->saveBorderProperties( cellStyle );
01821 const QString colStyleName = context.mainStyles().lookup( cellStyle, "cell" );
01822 writer.addAttribute( "table:style-name", colStyleName );
01823
01824
01825 if ( daCell->columnSpan() > 1 )
01826 writer.addAttribute( "table:number-columns-spanned", daCell->columnSpan() );
01827 if ( daCell->rowSpan() > 1 )
01828 writer.addAttribute( "table:number-row-spanned", daCell->rowSpan() );
01829
01830
01831 daCell->saveOasisContent( writer, context );
01832
01833 writer.endElement();
01834 }
01835 else
01836 {
01837
01838 writer.startElement( "table:covered-table-cell" );
01839 writer.endElement();
01840 }
01841 }
01842 writer.endElement();
01843 }
01844
01845 writer.endElement();
01846 }
01847
01848 void KWTableFrameSet::loadOasis( const QDomElement& tableTag, KoOasisContext& context )
01849 {
01850
01851 QMemArray<double> columnLefts(4);
01852 uint maxColumns = columnLefts.size() - 1;
01853
01854 uint col = 0;
01855 columnLefts[0] = 0.0;
01856 QDomElement elem;
01857 forEachElement( elem, tableTag )
01858 {
01859 if ( elem.localName() == "table-column" && elem.namespaceURI() == KoXmlNS::table )
01860 {
01861 uint repeat = elem.attributeNS( KoXmlNS::table, "number-columns-repeated", "1").toUInt();
01862 if (!repeat)
01863 repeat=1;
01864 KoStyleStack& styleStack = context.styleStack();
01865 styleStack.setTypeProperties( "table-column" );
01866 styleStack.save();
01867 context.fillStyleStack( elem, KoXmlNS::table, "style-name", "table-column" );
01868
01869 QString strWidth = styleStack.attributeNS( KoXmlNS::style, "column-width" );
01870 double width = KoUnit::parseValue( strWidth );
01871
01872 if ( width < 1.0 )
01873 {
01874 kdWarning(32004) << "Table column width ridiculous, assuming 1 inch!" << endl;
01875 width = 72.0;
01876 }
01877 else
01878 kdDebug(32004) << "- style width " << width << endl;
01879
01880 for ( uint j = 0; j < repeat; ++j )
01881 {
01882 ++col;
01883 if ( col >= maxColumns )
01884 {
01885
01886 maxColumns += 4;
01887 columnLefts.resize( maxColumns+1, QGArray::SpeedOptim );
01888 }
01889 columnLefts[col] = width + columnLefts[col-1];
01890 kdDebug(32004) << "Cell column " << col-1 << " left " << columnLefts[col-1] << " right " << columnLefts[col] << endl;
01891 }
01892 styleStack.restore();
01893 }
01894 }
01895
01896 uint row = 0;
01897 uint column = 0;
01898 parseInsideOfTable( tableTag, context, columnLefts, row, column, 0 );
01899 }
01900
01901 void KWTableFrameSet::parseInsideOfTable( const QDomElement& parent, KoOasisContext& context,
01902 const QMemArray<double> & columnLefts, uint& row, uint& column,
01903 double currentRowHeight )
01904 {
01905 kdDebug(32004) << "parseInsideOfTable" << endl;
01906 KoStyleStack& styleStack = context.styleStack();
01907
01908 QDomElement e;
01909 forEachElement( e, parent )
01910 {
01911 const QString localName = e.localName();
01912 const QString ns = e.namespaceURI();
01913 if ( ns != KoXmlNS::table ) {
01914 kdWarning(32004) << "Skipping element " << e.tagName() << " (in parseInsideOfTable)" << endl;
01915 continue;
01916 }
01917
01918 styleStack.save();
01919 if ( localName == "table-cell" )
01920 {
01921 loadOasisCell( e, context, columnLefts, row, column, currentRowHeight );
01922 ++column;
01923 }
01924 else if ( localName == "covered-table-cell" )
01925 {
01926 ++column;
01927 }
01928 else if ( localName == "table-row" )
01929 {
01930 context.fillStyleStack( e, KoXmlNS::table, "style-name", "table-row" );
01931 context.styleStack().setTypeProperties( "table-row" );
01932
01933
01934 double rowHeight = styleStack.attributeNS( KoXmlNS::table, "row-height" ).toDouble();
01935 column = 0;
01936 parseInsideOfTable( e, context, columnLefts, row, column, rowHeight );
01937 ++row;
01938 }
01939 else if ( localName == "table-header-rows" )
01940 {
01941
01942 parseInsideOfTable( e, context, columnLefts, row, column, currentRowHeight );
01943 }
01944 else if ( localName == "table-column" )
01945 {
01946
01947 }
01948
01949 else
01950 {
01951 kdWarning(32004) << "Skipping element " << localName << " (in parseInsideOfTable)" << endl;
01952 }
01953
01954 styleStack.restore();
01955 }
01956 }
01957
01958 void KWTableFrameSet::loadOasisCell( const QDomElement& element, KoOasisContext& context,
01959 const QMemArray<double> & columnLefts, uint row, uint column,
01960 double currentRowHeight )
01961 {
01962
01963
01964 KoStyleStack& styleStack = context.styleStack();
01965 uint rowSpan = element.attributeNS( KoXmlNS::table, "number-rows-spanned", QString::null ).toUInt();
01966 if ( rowSpan == 0 )
01967 rowSpan = 1;
01968 uint colSpan = element.attributeNS( KoXmlNS::table, "number-columns-spanned", QString::null ).toUInt();
01969 if ( colSpan == 0 )
01970 colSpan = 1;
01971
01972
01973 while(m_rowPositions.count() <= row + rowSpan + m_pageBoundaries.count()) {
01974 m_rowPositions.append(0);
01975 }
01976 while(m_colPositions.count() <= column + colSpan) {
01977 m_colPositions.append(0);
01978 }
01979
01980 Cell *daCell = new Cell( this, row, column, QString::null );
01981
01982 daCell->setRowSpan( rowSpan );
01983 daCell->setColumnSpan( colSpan );
01984 addCell( daCell );
01985
01986 double width = columnLefts[ QMIN( column+colSpan, columnLefts.size()-1 ) ] - columnLefts[column];
01987 double height = currentRowHeight > 0 ? currentRowHeight : 20;
01988 KWFrame* frame = new KWFrame( daCell, columnLefts[column], 0, width, height );
01989 if ( currentRowHeight > 0 )
01990 frame->setMinimumFrameHeight( height );
01991 frame->setRunAround( KWFrame::RA_NO );
01992 frame->setFrameBehavior( KWFrame::AutoExtendFrame );
01993 frame->setNewFrameBehavior( KWFrame::NoFollowup );
01994 daCell->addFrame( frame, false );
01995
01996 context.fillStyleStack( element, KoXmlNS::table, "style-name", "table-cell" );
01997 styleStack.setTypeProperties( "table-cell" );
01998
01999 daCell->frame( 0 )->loadBorderProperties( styleStack );
02000
02001 daCell->loadOasisContent( element, context );
02002 afterLoadingCell( daCell );
02003 }
02004
02005
02006 QDomElement KWTableFrameSet::save( QDomElement &parentElem, bool saveFrames ) {
02007
02008
02009 for (TableIter cells(this) ; cells ; ++cells)
02010 cells->save(parentElem, saveFrames);
02011 return QDomElement();
02012 }
02013
02014
02015 QDomElement KWTableFrameSet::toXML( QDomElement &parentElem, bool saveFrames )
02016 {
02017 QDomElement framesetElem = parentElem.ownerDocument().createElement( "FRAMESET" );
02018 parentElem.appendChild( framesetElem );
02019 KWFrameSet::saveCommon( framesetElem, false );
02020
02021 save( framesetElem, saveFrames );
02022 return framesetElem;
02023 }
02024
02025
02026 void KWTableFrameSet::fromXML( QDomElement &framesetElem, bool loadFrames, bool useNames )
02027 {
02028 KWFrameSet::load( framesetElem, false );
02029
02030 QDomElement cellElem = framesetElem.firstChild().toElement();
02031 for ( ; !cellElem.isNull() ; cellElem = cellElem.nextSibling().toElement() )
02032 {
02033 if ( cellElem.tagName() == "FRAMESET" )
02034 loadCell( cellElem, loadFrames, useNames );
02035 }
02036 }
02037
02038
02039 KWTableFrameSet::Cell* KWTableFrameSet::loadCell( QDomElement &framesetElem, bool loadFrames, bool useNames )
02040 {
02041 int _row = KWDocument::getAttribute( framesetElem, "row", 0 );
02042 if(_row <0) _row =0;
02043 unsigned int row=_row;
02044 int _col = KWDocument::getAttribute( framesetElem, "col", 0 );
02045 if(_col <0) _col =0;
02046 int _rows = KWDocument::getAttribute( framesetElem, "rows", 1 );
02047 if(_rows <0) _rows = 1;
02048 int _cols = KWDocument::getAttribute( framesetElem, "cols", 1 );
02049 if(_cols <0) _cols = 1;
02050
02051
02052 while(m_rowPositions.count() <= static_cast<unsigned int>(row + _rows + m_pageBoundaries.count())) {
02053 m_rowPositions.append(0);
02054 }
02055 while(m_colPositions.count() <= static_cast<unsigned int>(_col + _cols)) {
02056 m_colPositions.append(0);
02057 }
02058
02059 Cell *daCell = new Cell( this, row, _col, QString::null );
02060 QString autoName = daCell->name();
02061
02062 daCell->load( framesetElem, loadFrames );
02063 daCell->setRowSpan(_rows);
02064 daCell->setColumnSpan(_cols);
02065 addCell( daCell );
02066 afterLoadingCell( daCell );
02067 if ( !useNames )
02068 daCell->setName( autoName );
02069 return daCell;
02070 }
02071
02072
02073 void KWTableFrameSet::afterLoadingCell( Cell* daCell )
02074 {
02075 uint row = daCell->firstRow();
02076 uint col = daCell->firstColumn();
02077 uint rowSpan = daCell->rowSpan();
02078 uint colSpan = daCell->columnSpan();
02079 if(m_pageBoundaries.count() > 0) {
02080 unsigned int adjustment=0;
02081 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
02082 while(pageBound != m_pageBoundaries.end() && (*pageBound) <= row + adjustment) {
02083 adjustment++;
02084 pageBound++;
02085 }
02086 row+=adjustment;
02087 }
02088
02089 kdDebug(32004) << "loading cell (" << row << "," << col << ")\n";
02090 if(daCell->frame(0)) {
02091 daCell->frame(0)->setMinimumFrameHeight(daCell->frame(0)->height());
02092 QValueList<double>::iterator tmp = m_colPositions.at(col);
02093 if(*tmp == 0) (*tmp) = daCell->frame(0)->left();
02094 else (*tmp) = (daCell->frame(0)->left() + *tmp) / 2;
02095
02096 tmp = m_colPositions.at(col+colSpan);
02097 if(*tmp == 0) (*tmp) = daCell->frame(0)->right();
02098 else (*tmp) = (daCell->frame(0)->right() + *tmp) / 2;
02099
02100 tmp = m_rowPositions.at(row);
02101 if(*tmp == 0)
02102 (*tmp) = daCell->frame(0)->top();
02103 else {
02104 if (static_cast<int>(*tmp/m_doc->pageLayout().ptHeight) < static_cast<int>(daCell->frame(0)->top()/m_doc->pageLayout().ptHeight)) {
02105 kdDebug(32004) << "This cell is on a new page" << endl;
02106 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
02107 while(pageBound != m_pageBoundaries.end() && (*pageBound) < row) ++pageBound;
02108 if(*pageBound!=row) {
02109 m_pageBoundaries.insert(pageBound,row++);
02110 ++tmp;
02111 m_rowPositions.insert(tmp,daCell->frame(0)->top());
02112 }
02113 } else
02114 (*tmp) = (daCell->frame(0)->top() + *tmp) / 2;
02115 }
02116
02117 tmp = m_rowPositions.at( row + rowSpan );
02118 if(*tmp == 0)
02119 (*tmp) = daCell->frame(0)->bottom();
02120 else {
02121 if (static_cast<int>(*tmp/m_doc->pageLayout().ptHeight) > static_cast<int>(daCell->frame(0)->top()/m_doc->pageLayout().ptHeight)) {
02122 kdDebug(32004) << "next cell is on a new page" << endl;
02123 QValueList<unsigned int>::iterator pageBound = m_pageBoundaries.begin();
02124 while(pageBound != m_pageBoundaries.end() && (*pageBound) < row) ++pageBound;
02125 if(*pageBound!=row) {
02126 m_pageBoundaries.insert(pageBound,row++);
02127 m_rowPositions.insert(tmp,daCell->frame(0)->bottom());
02128 }
02129 } else
02130 (*tmp) = (daCell->frame(0)->bottom() + *tmp) / 2;
02131 }
02132 }
02133
02134 if ( m_rowPositions.count() != m_rows + 1 ) {
02135 kdDebug() << name() << " loadCell: m_rowPositions=" << m_rowPositions.count() << " m_rows= " << m_rows << endl;
02136 }
02137 }
02138
02139 int KWTableFrameSet::paragraphs()
02140 {
02141 int paragraphs = 0;
02142 for (TableIter cells(this) ; cells ; ++cells)
02143 paragraphs += cells->paragraphs();
02144 return paragraphs;
02145 }
02146
02147 int KWTableFrameSet::paragraphsSelected()
02148 {
02149 int paragraphs = 0;
02150 for (TableIter cells(this) ; cells ; ++cells)
02151 paragraphs += cells->paragraphsSelected();
02152 return paragraphs;
02153 }
02154
02155 bool KWTableFrameSet::statistics( QProgressDialog *progress, ulong & charsWithSpace, ulong & charsWithoutSpace, ulong & words,
02156 ulong & sentences, ulong & syllables, ulong & lines, bool selected )
02157 {
02158 for (TableIter cells(this) ; cells ; ++cells)
02159 if( ! cells->statistics( progress, charsWithSpace, charsWithoutSpace, words, sentences, syllables, lines, selected ) )
02160 {
02161 return false;
02162 }
02163 return true;
02164 }
02165
02166 void KWTableFrameSet::finalize( ) {
02167 kdDebug(32004) << "KWTableFrameSet::finalize" << endl;
02168
02169 for (TableIter cells(this) ; cells ; ++cells)
02170 {
02171 position( cells );
02172 cells->finalize();
02173 }
02174
02175 recalcCols(0, 0);
02176 recalcRows(0, 0);
02177 KWFrameSet::finalize();
02178 }
02179
02180 void KWTableFrameSet::layout()
02181 {
02182 for (TableIter cells(this) ; cells ; ++cells)
02183 cells->layout();
02184 }
02185
02186 void KWTableFrameSet::invalidate()
02187 {
02188 for (TableIter cells(this) ; cells ; ++cells)
02189 cells->invalidate();
02190 }
02191
02192 void KWTableFrameSet::setVisible( bool v )
02193 {
02194 for (TableIter cells(this) ; cells ; ++cells)
02195 cells->setVisible( v );
02196
02197 KWFrameSet::setVisible( v );
02198 }
02199
02200 bool KWTableFrameSet::canRemovePage( int num ) {
02201
02202
02203
02204
02205 QPtrListIterator<KWFrame> frameIt( frameIterator() );
02206 for ( ; frameIt.current(); ++frameIt ) {
02207 if ( frameIt.current()->pageNumber() == num ) {
02208 return false;
02209 }
02210 }
02211 return true;
02212 }
02213
02214 void KWTableFrameSet::addTextFrameSets( QPtrList<KWTextFrameSet> & lst, bool onlyReadWrite )
02215 {
02216 for (TableIter cells(this) ; cells ; ++cells)
02217 if (!cells->textObject()->protectContent() || onlyReadWrite )
02218 lst.append(cells);
02219 }
02220
02221 KWTextFrameSet* KWTableFrameSet::nextTextObject( KWFrameSet *obj )
02222 {
02223 bool found = false;
02224 KWTableFrameSet::Cell *tmp = dynamic_cast<KWTableFrameSet::Cell *>(obj);
02225
02226
02227 if ( tmp ) {
02228 for(TableIter i(this); i; ++i) {
02229 if(i.current() == tmp) {
02230 found = true;
02231 break;
02232 }
02233 }
02234 }
02235
02236 TableIter iter(this);
02237 if(found)
02238 iter.goToCell(tmp);
02239
02240 for(; iter; ++iter) {
02241 KWTextFrameSet *newFrm = iter->nextTextObject( obj );
02242 if(newFrm && newFrm->textObject()->needSpellCheck())
02243 return newFrm;
02244 }
02245
02246 return 0L;
02247 }
02248
02249 void KWTableFrameSet::setZOrder()
02250 {
02251 for( TableIter cells(this) ; cells ; ++cells ) {
02252 cells->setZOrder();
02253 }
02254
02255 }
02256
02257
02258
02259 QByteArray KWTableFrameSet::convertTableToText()
02260 {
02261 KWOasisSaver oasisSaver( m_doc );
02262 for (TableIter cells(this); cells; ++cells)
02263 {
02264 cells->textObject()->saveOasisContent( oasisSaver.bodyWriter(), oasisSaver.savingContext() );
02265 }
02266 if ( !oasisSaver.finish() )
02267 return QByteArray();
02268 return oasisSaver.data();
02269 }
02270
02271 #ifndef NDEBUG
02272 void KWTableFrameSet::printDebug( KWFrame * theFrame )
02273 {
02274 KWTableFrameSet::Cell *daCell = dynamic_cast<KWTableFrameSet::Cell *>( theFrame->frameSet() );
02275 Q_ASSERT( daCell );
02276 if ( daCell ) {
02277 kdDebug(32004) << " | |- row :" << daCell->firstRow() << endl;
02278 kdDebug(32004) << " | |- col :" << daCell->firstColumn() << endl;
02279 kdDebug(32004) << " | |- rows:" << daCell->rowSpan() << endl;
02280 kdDebug(32004) << " | +- cols:" << daCell->columnSpan() << endl;
02281 }
02282 }
02283
02284 void KWTableFrameSet::printArrayDebug() {
02285 kdDebug(32004) << " | Row/Cell arrays" << endl;
02286 Q_ASSERT( m_rows == m_rowArray.size() );
02287 for ( unsigned int row = 0; row < m_rows; ++row ) {
02288 QString str = QString( " | Row %1: " ).arg( row );
02289 for ( unsigned int col = 0; col < getColumns(); ++col )
02290 str += QString("| 0x%1 ").arg( (unsigned long)(*m_rowArray[row])[col], 0, 16 );
02291 kdDebug(32004) << str<< " |" << endl;
02292 }
02293 }
02294
02295 void KWTableFrameSet::printDebug() {
02296 kdDebug(32004) << " | Table size (" << m_rows << "x" << getColumns() << ")" << endl;
02297 kdDebug(32004) << " | col " << 0 << ": " << m_colPositions[0] << endl;
02298 for(unsigned int i=1;i<m_colPositions.count(); ++i)
02299 kdDebug(32004) << " | | " << i << ": " << m_colPositions[i] << endl;
02300 kdDebug(32004) << " | row " << 0 << ": " << m_rowPositions[0] << endl;
02301 for(unsigned int i=1;i<m_rowPositions.count(); ++i)
02302 kdDebug(32004) << " | | " << i << ": " << m_rowPositions[i] << endl;
02303
02304 printArrayDebug();
02305 KWFrameSet::printDebug();
02306 }
02307
02308 #endif
02309
02310
02311
02312 KWTableFrameSet::Cell::Cell( KWTableFrameSet *table, unsigned int row, unsigned int col, const QString & ) :
02313 KWTextFrameSet( table->m_doc,
02314
02315 i18n("Hello dear translator :), 1 is the table name, 2 and 3 are row and column", "%1 Cell %2,%3")
02316 .arg( table->name() ).arg(row).arg(col) )
02317 {
02318 m_row = row;
02319 m_col = col;
02320 m_rows = 1;
02321 m_cols = 1;
02322 m_isJoinedCell = false;
02323 setGroupManager( table );
02324 table->addCell( this );
02325 }
02326
02327 KWTableFrameSet::Cell::Cell( KWTableFrameSet *table, const Cell &original ) :
02328 KWTextFrameSet( table->m_doc, original.m_name+'_' )
02329 {
02330 m_row = original.m_row;
02331 m_col = original.m_col;
02332 m_rows = original.m_rows;
02333 m_cols = original.m_cols;
02334 m_isJoinedCell = original.m_isJoinedCell;
02335 setGroupManager( table );
02336 table->addCell( this );
02337 }
02338
02339 KWTableFrameSet::Cell::~Cell()
02340 {
02341 }
02342
02343 bool KWTableFrameSet::Cell::isAboveOrLeftOf( unsigned row, unsigned col ) const
02344 {
02345 return ( m_row < row ) || ( ( m_row == row ) && ( m_col < col ) );
02346 }
02347
02348 bool KWTableFrameSet::Cell::containsCell( unsigned row, unsigned col ) const
02349 {
02350 return ( m_row <= row &&
02351 m_col <= col &&
02352 rowAfter() > row &&
02353 columnAfter() > col );
02354 }
02355
02356 void KWTableFrameSet::Cell::addFrame(KWFrame *_frame, bool recalc) {
02357 if(groupmanager())
02358 groupmanager()->addFrame(_frame, recalc);
02359 KWTextFrameSet::addFrame(_frame, recalc);
02360 }
02361
02362 void KWTableFrameSet::Cell::frameDeleted( KWFrame* frm, bool recalc )
02363 {
02364 if(groupmanager())
02365 groupmanager()->deleteFrame( frm, false, recalc );
02366 }
02367
02368 double KWTableFrameSet::Cell::leftBorder() {
02369 double b = frame(0)->leftBorder().width();
02370 if(b==0.0)
02371 return 0.0;
02372 if(m_col==0)
02373 return b;
02374 return (b / 2);
02375 }
02376
02377 double KWTableFrameSet::Cell::rightBorder() {
02378 double b=frame(0)->rightBorder().width();
02379 if(b==0.0)
02380 return 0.0;
02381 if(m_col+m_cols==m_groupmanager->getColumns())
02382 return b;
02383 return (b / 2);
02384 }
02385
02386 double KWTableFrameSet::Cell::topBorder() {
02387 double b = frame(0)->topBorder().width();
02388 if(b==0.0)
02389 return 0.0;
02390 if(m_row==0)
02391 return b;
02392 return (b / 2);
02393 }
02394
02395 double KWTableFrameSet::Cell::bottomBorder() {
02396 double b = frame(0)->bottomBorder().width();
02397 if(b==0.0)
02398 return 0.0;
02399 if(rowAfter() == m_groupmanager->m_rows)
02400 return b;
02401 return (b / 2);
02402 }
02403
02404 void KWTableFrameSet::Cell::setLeftBorder(KoBorder newBorder) {
02405 KWFrame *f = frame(0);
02406 double diff = f->leftBorder().width() - newBorder.width();
02407 f->setLeftBorder(newBorder);
02408
02409 if((diff > 0.01 || diff < -0.01) && m_col!=0) {
02410 diff = diff / 2;
02411 m_groupmanager->cell(m_row, m_col-1)->setRightBorder(newBorder);
02412 }
02413 f->setLeft(f->left() - diff);
02414 }
02415
02416 void KWTableFrameSet::Cell::setRightBorder(KoBorder newBorder) {
02417 KWFrame *f = frame(0);
02418 double diff = f->rightBorder().width() - newBorder.width();
02419 f->setRightBorder(newBorder);
02420
02421 if((diff > 0.01 || diff < -0.01) && m_col+m_cols!=m_groupmanager->getColumns()) {
02422 diff = diff / 2;
02423 m_groupmanager->cell(m_row, m_col+1)->setLeftBorder(newBorder);
02424 }
02425 f->setRight(f->right() + diff);
02426 }
02427
02428 void KWTableFrameSet::Cell::setTopBorder(KoBorder newBorder) {
02429 KWFrame *f = frame(0);
02430 double diff = f->topBorder().width() - newBorder.width();
02431 f->setTopBorder(newBorder);
02432
02433 if((diff > 0.01 || diff < -0.01) && m_row!=0) {
02434 diff = diff / 2;
02435 m_groupmanager->cell(m_row-1, m_col)->setBottomBorder(newBorder);
02436 }
02437 f->setTop(f->top() - diff);
02438 }
02439
02440 void KWTableFrameSet::Cell::setBottomBorder(KoBorder newBorder) {
02441 KWFrame *f = frame(0);
02442 double diff = f->bottomBorder().width() - newBorder.width();
02443 f->setBottomBorder(newBorder);
02444
02445 if((diff > 0.01 || diff < -0.01) && rowAfter() != m_groupmanager->m_rows) {
02446 diff = diff / 2;
02447 m_groupmanager->cell(m_row+1, m_col)->setTopBorder(newBorder);
02448 }
02449 f->setBottom(f->bottom() + diff);
02450 }
02451
02452 void KWTableFrameSet::Cell::setZOrder()
02453 {
02454 QPtrListIterator<KWFrame> frameIt = frameIterator();
02455 for ( ; frameIt.current(); ++frameIt )
02456 {
02457 (*frameIt)->setZOrder( kWordDocument()->maxZOrder( (*frameIt)->pageNumber() ) + 1 );
02458 }
02459 }
02460
02461 void KWTableFrameSet::Cell::drawContents( QPainter * painter, const QRect & crect,
02462 const QColorGroup & cg, bool onlyChanged, bool resetChanged,
02463 KWFrameSetEdit * edit, KWViewMode * viewMode, KWFrameViewManager *fvm )
02464 {
02465 bool printing = painter->device()->devType() == QInternal::Printer;
02466 bool drawPreviewLines = viewMode && viewMode->drawFrameBorders();
02467 QRect cellRect = crect;
02468 if(!printing && drawPreviewLines) {
02469
02470 QRect zoomedRect( m_doc->zoomRect(*frame(0)) );
02471 QRect innerFrameRect( viewMode->normalToView( zoomedRect ) );
02472 innerFrameRect.addCoords(1, 1, -1, -1);
02473 cellRect = innerFrameRect.intersect(crect);
02474 }
02475 KWTextFrameSet::drawContents(painter, cellRect, cg, onlyChanged, resetChanged, edit, viewMode, fvm);
02476 }
02477
02478 KWTableFrameSetEdit::~KWTableFrameSetEdit()
02479 {
02480 if ( m_currentCell )
02481 m_currentCell->terminate();
02482 delete m_currentCell;
02483 }
02484
02485 void KWTableFrameSetEdit::mousePressEvent( QMouseEvent * e, const QPoint & nPoint, const KoPoint & dPoint )
02486 {
02487 setCurrentCell( dPoint );
02488 if ( m_currentCell )
02489 m_currentCell->mousePressEvent( e, nPoint, dPoint );
02490 }
02491
02492 void KWTableFrameSetEdit::setCurrentCell( const KoPoint & dPoint )
02493 {
02494 KWFrameSet *fs = tableFrameSet()->cellByPos( dPoint.x(), dPoint.y() );
02495 KWTextFrameSet *textframeSet = dynamic_cast<KWTextFrameSet *>(fs);
02496
02497 if ( textframeSet&& textframeSet->protectContent() && !tableFrameSet()->kWordDocument()->cursorInProtectedArea())
02498 return;
02499
02500 if ( fs && ( !m_currentCell || fs != m_currentCell->frameSet() ) )
02501 setCurrentCell( fs );
02502 }
02503
02504 void KWTableFrameSetEdit::setCurrentCell( KWFrameSet * fs, bool eraseSelection )
02505 {
02506 bool oldProtectContent = false;
02507 KWTextFrameSet *textframeSet=0L;
02508 if ( m_currentCell )
02509 textframeSet = dynamic_cast<KWTextFrameSet *>(m_currentCell->frameSet());
02510 if ( textframeSet )
02511 oldProtectContent = textframeSet->protectContent();
02512
02513 if ( m_currentCell )
02514 {
02515 m_currentCell->terminate(eraseSelection);
02516 delete m_currentCell;
02517 }
02518 m_currentCell = fs->createFrameSetEdit( m_canvas );
02519 textframeSet = dynamic_cast<KWTextFrameSet *>(m_currentCell->frameSet());
02520 if ( textframeSet )
02521 {
02522 if ( oldProtectContent != textframeSet->protectContent())
02523 {
02524 m_canvas->kWordDocument()->updateTextFrameSetEdit();
02525 }
02526 }
02527
02528
02529 m_currentFrame = fs->frame( 0 );
02530 KWTextFrameSetEdit *textframeSetEdit = dynamic_cast<KWTextFrameSetEdit *>(m_currentCell);
02531 if ( textframeSetEdit )
02532 {
02533 textframeSetEdit->ensureCursorVisible();
02534
02535 m_canvas->gui()->getView()->slotUpdateRuler();
02536 }
02537 }
02538
02539 KWFrameSetEdit* KWTableFrameSetEdit::currentTextEdit()
02540 {
02541 return m_currentCell;
02542 }
02543
02544
02545 void KWTableFrameSetEdit::keyPressEvent( QKeyEvent * e )
02546 {
02547
02548 if ( !m_currentCell )
02549 return;
02550 KWTableFrameSet::Cell *cell = static_cast<KWTableFrameSet::Cell *>(m_currentCell->frameSet());
02551 KWTextFrameSet *textframeSet = dynamic_cast<KWTextFrameSet *>(m_currentCell->frameSet());
02552 bool moveToOtherCell = true;
02553 if(textframeSet)
02554 {
02555
02556 KoTextDocument * textdoc = textframeSet->textDocument();
02557 if(textdoc->hasSelection( KoTextDocument::Standard ))
02558 moveToOtherCell=false;
02559 }
02560 KWTableFrameSet::Cell *fs = 0L;
02561
02562 bool tab=false;
02563 if(moveToOtherCell)
02564 {
02565 switch( e->key() ) {
02566 case QKeyEvent::Qt::Key_Up:
02567 {
02568 if(!(static_cast<KWTextFrameSetEdit *>(m_currentCell))->cursor()->parag()->prev())
02569 {
02570 KWTableFrameSet* tableFrame=tableFrameSet();
02571 int row = cell->firstRow() - 1;
02572 int col = cell->firstColumn();
02573 if (row < 0) {
02574 col--;
02575 row = tableFrame->getRows() - 1;
02576 }
02577 if (col < 0) {
02578
02579 col = tableFrame->getColumns() - 1;
02580 row = tableFrame->getRows() - 1;
02581 }
02582 fs=tableFrame->cell(row,col);
02583
02584
02585
02586
02587 }
02588 }
02589 break;
02590 case QKeyEvent::Qt::Key_Down:
02591 {
02592 if(!(static_cast<KWTextFrameSetEdit *>(m_currentCell))->cursor()->parag()->next())
02593 {
02594 KWTableFrameSet* tableFrame=tableFrameSet();
02595 unsigned int row = cell->rowAfter();
02596 unsigned int col = cell->firstColumn();
02597 if(row >= tableFrame->getRows()) {
02598 row=0;
02599 col++;
02600 }
02601 if(col >= tableFrame->getColumns()) {
02602
02603 col=0;
02604 row=0;
02605 }
02606 fs=tableFrame->cell(row,col);
02607 Q_ASSERT( fs );
02608 Q_ASSERT( fs->firstRow() == row );
02609 }
02610 }
02611 break;
02612 case QKeyEvent::Qt::Key_Backtab:
02613 tab=true;
02614 if (e->state() & QKeyEvent::ControlButton)
02615 break;
02616
02617 case QKeyEvent::Qt::Key_Left:
02618 {
02619 KoTextCursor *cur = (static_cast<KWTextFrameSetEdit *>(m_currentCell))->cursor();
02620 if ( tab || (!cur->parag()->prev()&&cur->index()==0) )
02621 {
02622 KWTableFrameSet* tableFrame=tableFrameSet();
02623 int row=cell->firstRow();
02624 int col=cell->firstColumn() - 1;
02625 if(col < 0) {
02626 col = (int)tableFrame->getColumns()-1;
02627 row--;
02628 }
02629 if(row < 0) {
02630
02631 col = (int)tableFrame->getColumns()-1;
02632 row = (int)tableFrame->getRows()-1;
02633 }
02634 fs=tableFrame->cell(row,col);
02635
02636
02637
02638
02639 }
02640 }
02641 break;
02642 case QKeyEvent::Qt::Key_Tab:
02643 tab=true;
02644 if (e->state() & QKeyEvent::ControlButton)
02645 break;
02646
02647 case QKeyEvent::Qt::Key_Right:
02648 {
02649 KoTextCursor *cur = (static_cast<KWTextFrameSetEdit *>(m_currentCell))->cursor();
02650 if( tab || (!cur->parag()->next()&&cur->index()==cur->parag()->string()->length()-1) )
02651 {
02652 KWTableFrameSet* tableFrame=tableFrameSet();
02653 unsigned int row = cell->firstRow();
02654 unsigned int col = cell->columnAfter();
02655 if(col >= tableFrame->getColumns()) {
02656 col = 0;
02657 row++;
02658 }
02659 if(row >= tableFrame->getRows()) {
02660
02661 col = 0;
02662 row = 0;
02663 }
02664 fs=tableFrame->cell(row,col);
02665 Q_ASSERT( fs );
02666 Q_ASSERT( fs->firstRow() == row );
02667 }
02668 }
02669 break;
02670 }
02671 }
02672 if ( fs )
02673 {
02674
02675 if ( fs->textObject()->protectContent() && !tableFrameSet()->kWordDocument()->cursorInProtectedArea())
02676 return;
02677 setCurrentCell( fs );
02678 }
02679 else if ( textframeSet )
02680 {
02681 if ( !textframeSet->textObject()->protectContent() )
02682 {
02683 if (tab && (e->state() & QKeyEvent::ControlButton) )
02684 {
02685 QKeyEvent event(QEvent::KeyPress, QKeyEvent::Qt::Key_Tab, 9, 0, QChar(9));
02686 m_currentCell->keyPressEvent( &event );
02687 }
02688 else
02689 m_currentCell->keyPressEvent( e );
02690 }
02691 else if(e->text().length() > 0)
02692 KMessageBox::information(0L, i18n("Read-only content cannot be changed. No modifications will be accepted."));
02693 }
02694 }
02695
02696 void KWTableFrameSetEdit::keyReleaseEvent( QKeyEvent * e )
02697 {
02698 if ( m_currentCell )
02699 m_currentCell->keyReleaseEvent( e );
02700 }
02701
02702 void KWTableFrameSetEdit::imStartEvent( QIMEvent* e )
02703 {
02704 if ( m_currentCell )
02705 m_currentCell->imStartEvent( e );
02706 }
02707
02708 void KWTableFrameSetEdit::imComposeEvent( QIMEvent* e )
02709 {
02710 if ( m_currentCell )
02711 m_currentCell->imComposeEvent( e );
02712 }
02713
02714 void KWTableFrameSetEdit::imEndEvent( QIMEvent* e )
02715 {
02716 if ( m_currentCell )
02717 m_currentCell->imEndEvent( e );
02718 }
02719
02720 void KWTableFrameSetEdit::dragMoveEvent( QDragMoveEvent * e, const QPoint &n, const KoPoint &d )
02721 {
02722 kdDebug(32004)<<"m_currentCell :"<<m_currentCell<<endl;
02723 if ( m_currentCell )
02724 {
02725 KWFrameSet *fs = tableFrameSet()->cellByPos( d.x(), d.y() );
02726 kdDebug(32004)<<"fs :"<<fs <<endl;
02727 if(fs && fs != m_currentCell->frameSet())
02728 setCurrentCell(fs, false);
02729 if(m_currentCell)
02730 m_currentCell->dragMoveEvent( e, n, d );
02731 }
02732 else
02733 {
02734 setCurrentCell( d );
02735 kdDebug(32004)<<"after m_currentCell :"<<m_currentCell<<endl;
02736 if(m_currentCell)
02737 m_currentCell->dragMoveEvent( e, n, d );
02738 }
02739 }
02740
02741 void KWTableFrameSet::Row::addCell( Cell *cell )
02742 {
02743 if ( m_cellArray.size() < cell->columnAfter())
02744 m_cellArray.resize( cell->columnAfter() );
02745 for ( uint col = cell->firstColumn() ; col < cell->columnAfter(); ++col )
02746 m_cellArray.insert( col, cell );
02747 }
02748
02749 void KWTableFrameSet::Row::removeCell( Cell* cell )
02750 {
02751 for ( uint col = cell->firstColumn() ; col < cell->columnAfter(); ++col )
02752 m_cellArray.remove( col );
02753 }
02754
02755 template<>
02756 KWTableFrameSet::Cell*
02757 KWTableFrameSet::TableIterator<KWTableFrameSet::VISIT_CELL>::operator++()
02758 {
02759 if(!m_cell) return 0;
02760
02761 Cell *ret = m_cell;
02762
02763 do{
02764
02765 if(m_table->cell(m_row,m_col)->lastColumn() >= m_limit[RIGHT] ) {
02766
02767 if (m_row >= m_limit[LOW]){
02768
02769 m_cell = 0;
02770 break;
02771 }
02772 else {
02773
02774 m_row += 1;
02775 m_col = m_limit[LEFT];
02776 }
02777 }
02778 else {
02779
02780 m_col = m_table->cell(m_row, m_col)->columnAfter();
02781 }
02782
02783 m_cell = m_table->cell(m_row,m_col);
02784 } while( m_cell && !m_cell->isFirstGridPosnFast(m_row,m_col) );
02785
02786 return ret;
02787 }
02788
02789 template<>
02790 KWTableFrameSet::Cell*
02791 KWTableFrameSet::TableIterator<KWTableFrameSet::VISIT_GRID>::operator++()
02792 {
02793 if(!m_cell) return 0;
02794
02795 Cell *ret = m_cell;
02796
02797 if(m_col == m_limit[RIGHT]) {
02798 if(m_row == m_limit[LOW]) {
02799 m_row = 0;
02800 m_col = 0;
02801 m_cell = 0;
02802 }
02803 else {
02804 m_row += 1;
02805 m_col = m_limit[LEFT];
02806 m_cell = m_table->cell(m_row, m_col);
02807 }
02808 }
02809 else {
02810 m_col += 1;
02811 m_cell = m_table->cell(m_row, m_col);
02812 }
02813
02814 return ret;
02815 }
02816
02817 KWTableFrameSet::MarkedIterator::MarkedIterator(KWTableFrameSet *table) :
02818 GridIter(table)
02819 {
02820
02821 for(GridIter cell(table); cell; ++cell)
02822 cell->clearMark();
02823
02824 if ( current() ) {
02825
02826
02827 current()->setMark();
02828 }
02829 }
02830
02831 KWTableFrameSet::Cell *
02832 KWTableFrameSet::MarkedIterator::operator++()
02833 {
02834 Cell *ret = GridIter::operator++();
02835
02836 while ( current() && current()->marked() ) {
02837 GridIter::operator++();
02838 }
02839 if ( current() ) {
02840
02841
02842 current()->setMark();
02843 }
02844 return ret;
02845 }
02846
02847 template<>
02848 KWTableFrameSet::TableIterator<KWTableFrameSet::CHECKED>::TableIterator(KWTableFrameSet *table):
02849 m_table(table)
02850 {
02851 Q_ASSERT(m_table);
02852 set_limits(0, (int)m_table->getColumns() - 1, 0, (int)m_table->getRows() - 1);
02853
02854 Cell *c = 0;
02855 for(uint i = m_limit[HIGH]; i <= m_limit[LOW]; ++i)
02856 for(uint j = m_limit[LEFT]; j <= m_limit[RIGHT]; ++j) {
02857
02858 c = m_table->cell(i,j);
02859 if(c) c->clearMark();
02860 }
02861 toFirstCell();
02862 }
02863
02864 template<>
02865 KWTableFrameSet::Cell*
02866 KWTableFrameSet::TableIterator<KWTableFrameSet::CHECKED>::operator++ ()
02867 {
02868
02869 Cell *ret = m_cell;
02870 if(!ret) return 0;
02871
02872 ret->setMark();
02873 m_cell = 0;
02874 uint i = m_row; uint j = m_col;
02875
02876 for(; i <= m_limit[LOW]; ++i) {
02877
02878 for(j = 0; j <= m_limit[RIGHT]; ++j) {
02879 m_cell = m_table->cell(i,j);
02880 if( m_cell && !m_cell->marked() ){
02881 m_row = i; m_col = j;
02882 goto out;
02883 }
02884 else if(i == m_limit[LOW] && j == m_limit[RIGHT]){
02885 m_cell = 0;
02886 goto out;
02887 }
02888 }
02889 }
02890
02891 out:
02892 return ret;
02893 }
02894
02895 template<>
02896 KWTableFrameSet::Cell*
02897 KWTableFrameSet::TableIterator<KWTableFrameSet::CHECKED>::toFirstCell ()
02898 {
02899 m_cell = 0;
02900 for(uint i = m_limit[HIGH]; i <= m_limit[LOW]; ++i)
02901 for(uint j = m_limit[LEFT]; j <= m_limit[RIGHT]; ++j) {
02902 m_cell = m_table->cell(i,j);
02903 if(m_cell) {
02904 m_row = i; m_col = j;
02905 goto out;
02906 }
02907 }
02908
02909 out:
02910 return m_cell;
02911 }
02912
02913 RemovedRow::RemovedRow() :
02914 m_row(0), m_index(0), m_rowHeight(0.0)
02915 {
02916
02917 }
02918
02919 RemovedRow::~RemovedRow()
02920 {
02921
02922 delete m_row;
02923 }
02924
02925 KWTableFrameSet::Row *RemovedRow::takeRow()
02926 {
02927 Q_ASSERT(m_row);
02928 KWTableFrameSet::Row *ret = m_row;
02929 m_row = 0;
02930 return ret;
02931 }
02932
02933 RemovedColumn::RemovedColumn()
02934 : m_column(), m_removed(), m_index(0), m_width(0), m_initialized(false){ }
02935
02936
02937 #include "KWTableFrameSet.moc"