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
00029
00030
00031 #include <math.h>
00032
00033 #include <qregexp.h>
00034
00035 #include <kconfig.h>
00036 #include <kdebug.h>
00037
00038 #include "kspread_doc.h"
00039 #include "kspread_locale.h"
00040 #include "kspread_sheet.h"
00041 #include "kspread_undo.h"
00042 #include "kspread_value.h"
00043 #include "valueconverter.h"
00044 #include "kspread_autofill.h"
00045
00046 using namespace KSpread;
00047
00048 QStringList *AutoFillSequenceItem::month = 0L;
00049 QStringList *AutoFillSequenceItem::shortMonth = 0L;
00050 QStringList *AutoFillSequenceItem::day = 0L;
00051 QStringList *AutoFillSequenceItem::shortDay = 0L;
00052 QStringList *AutoFillSequenceItem::other = 0L;
00053
00054
00055
00056
00057
00058
00059 AutoFillDeltaSequence::AutoFillDeltaSequence( AutoFillSequence *_first, AutoFillSequence *_next )
00060 : m_ok(true),
00061 m_sequence(0L)
00062 {
00063 if ( _first->count() != _next->count() )
00064 {
00065 m_ok = false;
00066 return;
00067 }
00068
00069 m_sequence = new QMemArray<double> ( _first->count() );
00070
00071 AutoFillSequenceItem *item = _first->getFirst();
00072 AutoFillSequenceItem *item2 = _next->getFirst();
00073 int i = 0;
00074
00075 for ( i = 0; i < _first->count(); i++ )
00076 {
00077 double d;
00078 if ( !item->getDelta( item2, d ) )
00079 {
00080 m_ok = false;
00081 return;
00082 }
00083 m_sequence->at( i++ ) = d;
00084 item2 = _next->getNext();
00085 item = _first->getNext();
00086 }
00087 }
00088
00089 AutoFillDeltaSequence::~AutoFillDeltaSequence()
00090 {
00091 delete m_sequence;
00092 }
00093
00094 bool AutoFillDeltaSequence::equals( AutoFillDeltaSequence *_delta )
00095 {
00096 if ( m_sequence == 0L )
00097 return false;
00098 if ( _delta->getSequence() == 0L )
00099 return false;
00100 if ( m_sequence->size() != _delta->getSequence()->size() )
00101 return false;
00102
00103 for ( unsigned int i = 0; i < m_sequence->size(); i++ )
00104 {
00105 if ( m_sequence->at( i ) != _delta->getSequence()->at( i ) )
00106 return false;
00107 }
00108
00109 return true;
00110 }
00111
00112 double AutoFillDeltaSequence::getItemDelta( int _pos )
00113 {
00114 if ( m_sequence == 0L )
00115 return 0.0;
00116
00117 return m_sequence->at( _pos );
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 AutoFillSequenceItem::AutoFillSequenceItem( int _i )
00127 {
00128 m_IValue = _i;
00129 m_Type = INTEGER;
00130 }
00131
00132 AutoFillSequenceItem::AutoFillSequenceItem( double _d )
00133 {
00134 m_DValue = _d;
00135 m_Type = FLOAT;
00136 }
00137
00138 AutoFillSequenceItem::AutoFillSequenceItem( const QString &_str )
00139 {
00140 m_String = _str;
00141 m_Type = STRING;
00142
00143 if ( month == 0L )
00144 {
00145 month = new QStringList();
00146 month->append( i18n("January") );
00147 month->append( i18n("February") );
00148 month->append( i18n("March") );
00149 month->append( i18n("April") );
00150 month->append( i18n("May") );
00151 month->append( i18n("June") );
00152 month->append( i18n("July") );
00153 month->append( i18n("August") );
00154 month->append( i18n("September") );
00155 month->append( i18n("October") );
00156 month->append( i18n("November") );
00157 month->append( i18n("December") );
00158 }
00159
00160 if ( shortMonth == 0L )
00161 {
00162 shortMonth = new QStringList();
00163 shortMonth->append( i18n("Jan") );
00164 shortMonth->append( i18n("Feb") );
00165 shortMonth->append( i18n("Mar") );
00166 shortMonth->append( i18n("Apr") );
00167 shortMonth->append( i18n("May short", "May") );
00168 shortMonth->append( i18n("Jun") );
00169 shortMonth->append( i18n("Jul") );
00170 shortMonth->append( i18n("Aug") );
00171 shortMonth->append( i18n("Sep") );
00172 shortMonth->append( i18n("Oct") );
00173 shortMonth->append( i18n("Nov") );
00174 shortMonth->append( i18n("Dec") );
00175 }
00176
00177 if ( day == 0L )
00178 {
00179 day = new QStringList();
00180 day->append( i18n("Monday") );
00181 day->append( i18n("Tuesday") );
00182 day->append( i18n("Wednesday") );
00183 day->append( i18n("Thursday") );
00184 day->append( i18n("Friday") );
00185 day->append( i18n("Saturday") );
00186 day->append( i18n("Sunday") );
00187 }
00188
00189 if ( shortDay == 0L )
00190 {
00191 shortDay = new QStringList();
00192 shortDay->append( i18n("Mon") );
00193 shortDay->append( i18n("Tue") );
00194 shortDay->append( i18n("Wed") );
00195 shortDay->append( i18n("Thu") );
00196 shortDay->append( i18n("Fri") );
00197 shortDay->append( i18n("Sat") );
00198 shortDay->append( i18n("Sun") );
00199 }
00200
00201 if( other==0L)
00202 {
00203
00204 KConfig *config = Factory::global()->config();
00205 config->setGroup( "Parameters" );
00206 other=new QStringList(config->readListEntry("Other list"));
00207 }
00208
00209 if ( month->find( _str ) != month->end() )
00210 {
00211 m_Type = MONTH;
00212 return;
00213 }
00214
00215 if ( shortMonth->find( _str ) != shortMonth->end() )
00216 {
00217 m_Type = SHORTMONTH;
00218 return;
00219 }
00220
00221 if ( day->find( _str ) != day->end() )
00222 {
00223 m_Type = DAY;
00224 return;
00225 }
00226
00227 if ( shortDay->find( _str ) != shortDay->end() )
00228 {
00229 m_Type = SHORTDAY;
00230 return;
00231 }
00232
00233 if( other->find(_str)!=other->end())
00234 {
00235 m_Type = OTHER;
00236 m_OtherBegin=0;
00237 m_OtherEnd=other->count();
00238 int index= other->findIndex(_str);
00239
00240 for ( QStringList::Iterator it = other->find(_str); it != other->end();++it )
00241 {
00242 if((*it)=="\\")
00243 {
00244 m_OtherEnd=index;
00245 break;
00246 }
00247 index++;
00248 }
00249 index= other->findIndex(_str);
00250 for ( QStringList::Iterator it = other->find(_str); it != other->begin();--it )
00251 {
00252 if((*it)=="\\")
00253 {
00254 m_OtherBegin=index;
00255 break;
00256 }
00257 index--;
00258 }
00259 return;
00260 }
00261
00262 if ( m_String[0] == '=' )
00263 m_Type = FORMULA;
00264 }
00265
00266 bool AutoFillSequenceItem::getDelta( AutoFillSequenceItem *seq, double &_delta )
00267 {
00268 if ( seq->getType() != m_Type )
00269 return false;
00270
00271 switch( m_Type )
00272 {
00273 case INTEGER:
00274 _delta = (double)( seq->getIValue() - m_IValue );
00275 return true;
00276 case FLOAT:
00277 _delta = seq->getDValue() - m_DValue;
00278 return true;
00279 case FORMULA:
00280 case STRING:
00281 if ( m_String == seq->getString() )
00282 {
00283 _delta = 0.0;
00284 return true;
00285 }
00286 return false;
00287 case MONTH:
00288 {
00289 int i = month->findIndex( m_String );
00290 int j = month->findIndex( seq->getString() );
00291 int k = j;
00292
00293 if ( j + 1 == i )
00294 _delta = -1.0;
00295 else
00296 _delta = ( double )( k - i );
00297 return true;
00298 }
00299
00300 case SHORTMONTH:
00301 {
00302 int i = shortMonth->findIndex( m_String );
00303 int j = shortMonth->findIndex( seq->getString() );
00304 int k = j;
00305
00306 if ( j + 1 == i )
00307 _delta = -1.0;
00308 else
00309 _delta = ( double )( k - i );
00310 return true;
00311 }
00312
00313 case DAY:
00314 {
00315 int i = day->findIndex( m_String );
00316 int j = day->findIndex( seq->getString() );
00317 int k = j;
00318
00319 if ( j + 1 == i )
00320 _delta = -1.0;
00321 else
00322 _delta = ( double )( k - i );
00323 kdDebug() << m_String << " i: " << i << " j: " << j << " k: " << k << " delta: " << _delta << endl;
00324 return true;
00325 }
00326
00327 case SHORTDAY:
00328 {
00329 int i = shortDay->findIndex( m_String );
00330 int j = shortDay->findIndex( seq->getString() );
00331 int k = j;
00332
00333 if ( j + 1 == i )
00334 _delta = -1.0;
00335 else
00336 _delta = ( double )( k - i );
00337 return true;
00338 }
00339 case OTHER:
00340 {
00341 if( m_OtherEnd!= seq->getIOtherEnd() || m_OtherBegin!= seq->getIOtherBegin())
00342 return false;
00343 int i = other->findIndex( m_String );
00344 int j = other->findIndex( seq->getString() );
00345 int k = j;
00346 if ( j < i )
00347 k += (m_OtherEnd - m_OtherBegin - 1);
00348
00349
00350
00351 _delta = ( double )( k - i );
00352 return true;
00353 }
00354 default:
00355 return false;
00356 }
00357 }
00358
00359 QString AutoFillSequenceItem::getSuccessor( int _no, double _delta )
00360 {
00361 QString erg;
00362 switch( m_Type )
00363 {
00364 case INTEGER:
00365 erg.sprintf("%i", m_IValue + _no * (int)_delta );
00366 break;
00367 case FLOAT:
00368 erg.sprintf("%f", m_DValue + (double)_no * _delta );
00369 break;
00370 case FORMULA:
00371 case STRING:
00372 erg = m_String;
00373 break;
00374 case MONTH:
00375 {
00376 int i = month->findIndex( m_String );
00377 int j = i + _no * (int) _delta;
00378 while (j < 0)
00379 j += month->count();
00380 int k = j % month->count();
00381 erg = (*month->at( k ));
00382 }
00383 break;
00384 case SHORTMONTH:
00385 {
00386 int i = shortMonth->findIndex( m_String );
00387 int j = i + _no * (int) _delta;
00388 while (j < 0)
00389 j += shortMonth->count();
00390 int k = j % shortMonth->count();
00391 erg = (*shortMonth->at( k ));
00392 }
00393 break;
00394 case DAY:
00395 {
00396 int i = day->findIndex( m_String );
00397 int j = i + _no * (int) _delta;
00398 while (j < 0)
00399 j += day->count();
00400 int k = j % day->count();
00401 erg = (*day->at( k ));
00402 }
00403 break;
00404 case SHORTDAY:
00405 {
00406 int i = shortDay->findIndex( m_String );
00407 int j = i + _no * (int) _delta;
00408 while (j < 0)
00409 j += shortDay->count();
00410 int k = j % shortDay->count();
00411 erg = (*shortDay->at( k ));
00412 }
00413 break;
00414 case OTHER:
00415 {
00416 int i = other->findIndex( m_String )-(m_OtherBegin+1);
00417 int j = i + _no * (int) _delta;
00418 int k = j % (m_OtherEnd - m_OtherBegin-1);
00419 erg = (*other->at( (k+m_OtherBegin+1) ));
00420 }
00421 case TIME:
00422 case DATE:
00423
00424 break;
00425 }
00426
00427 return QString( erg );
00428 }
00429
00430 QString AutoFillSequenceItem::getPredecessor( int _no, double _delta )
00431 {
00432 QString erg;
00433 switch( m_Type )
00434 {
00435 case INTEGER:
00436 erg.sprintf("%i", m_IValue - _no * (int)_delta );
00437 break;
00438 case FLOAT:
00439 erg.sprintf("%f", m_DValue - (double)_no * _delta );
00440 break;
00441 case FORMULA:
00442 case STRING:
00443 erg = m_String;
00444 break;
00445 case MONTH:
00446 {
00447 int i = month->findIndex( m_String );
00448 int j = i - _no * (int) _delta;
00449 while ( j < 0 )
00450 j += month->count();
00451 int k = j % month->count();
00452 erg = (*month->at( k ));
00453 }
00454 break;
00455 case SHORTMONTH:
00456 {
00457 int i = shortMonth->findIndex( m_String );
00458 int j = i - _no * (int) _delta;
00459 while ( j < 0 )
00460 j += shortMonth->count();
00461 int k = j % shortMonth->count();
00462 erg = (*shortMonth->at( k ));
00463 }
00464 break;
00465 case DAY:
00466 {
00467 int i = day->findIndex( m_String );
00468 int j = i - _no * (int) _delta;
00469 while ( j < 0 )
00470 j += day->count();
00471 int k = j % day->count();
00472 erg = (*day->at( k ));
00473 }
00474 case SHORTDAY:
00475 {
00476 int i = shortDay->findIndex( m_String );
00477 int j = i - _no * (int) _delta;
00478 while ( j < 0 )
00479 j += shortDay->count();
00480 int k = j % shortDay->count();
00481 erg = (*shortDay->at( k ));
00482 }
00483 break;
00484 case OTHER:
00485 {
00486 int i = other->findIndex( m_String ) - (m_OtherBegin + 1);
00487 int j = i - _no * (int) _delta;
00488 while ( j < 0 )
00489 j += (m_OtherEnd - m_OtherBegin - 1);
00490 int k = j % (m_OtherEnd - m_OtherBegin - 1);
00491 erg = (*other->at( (k + m_OtherBegin + 1) ));
00492 }
00493 case TIME:
00494 case DATE:
00495
00496 break;
00497 }
00498
00499 return QString( erg );
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 AutoFillSequence::AutoFillSequence( Cell *_cell )
00509 {
00510 sequence.setAutoDelete( true );
00511
00512 if ( _cell->isFormula() )
00513 {
00514 QString d = _cell->encodeFormula();
00515 sequence.append( new AutoFillSequenceItem( d ) );
00516 }
00517 else if ( _cell->value().isNumber() )
00518 {
00519 if ( floor( _cell->value().asFloat() ) == _cell->value().asFloat() )
00520 {
00521 sequence.append( new AutoFillSequenceItem( (int)_cell->value().asFloat()) );
00522 }
00523 else
00524 sequence.append( new AutoFillSequenceItem(_cell->value().asFloat() ) );
00525 }
00526 else if ( !_cell->text().isEmpty() )
00527 sequence.append( new AutoFillSequenceItem( _cell->text() ) );
00528 }
00529
00530 bool AutoFillSequence::matches( AutoFillSequence* _seq, AutoFillDeltaSequence *_delta )
00531 {
00532 AutoFillDeltaSequence delta( this, _seq );
00533 if ( !delta.isOk() )
00534 return false;
00535
00536 if ( delta.equals( _delta ) )
00537 return true;
00538
00539 return false;
00540 }
00541
00542 void AutoFillSequence::fillCell( Cell *src, Cell *dest, AutoFillDeltaSequence *delta, int _block, bool down )
00543 {
00544 QString erg = "";
00545
00546
00547 if ( sequence.first() != 0L && sequence.first()->getType() == AutoFillSequenceItem::FORMULA )
00548 {
00549 QString f = dest->decodeFormula( sequence.first()->getString() );
00550 dest->setCellText( f );
00551 dest->copyFormat( src );
00552 return;
00553 }
00554
00555 AutoFillSequenceItem *item;
00556 int i = 0;
00557 if (down)
00558 {
00559 for ( item = sequence.first(); item != 0L; item = sequence.next() )
00560 erg += item->getSuccessor( _block, delta->getItemDelta( i++ ) );
00561 }
00562 else
00563 {
00564 for ( item = sequence.first(); item != 0L; item = sequence.next() )
00565 erg += item->getPredecessor( _block, delta->getItemDelta( i++ ) );
00566 }
00567
00568 dest->setCellText( erg );
00569 dest->copyFormat( src );
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 void Sheet::autofill( QRect &src, QRect &dest )
00579 {
00580 if (src == dest)
00581 {
00582 return;
00583 }
00584
00585 setRegionPaintDirty( dest );
00586
00587 doc()->emitBeginOperation();
00588
00589 if ( !doc()->undoLocked() )
00590 {
00591 UndoAutofill *undo = new UndoAutofill( doc(), this, dest );
00592 doc()->addCommand( undo );
00593 }
00594
00595
00596 if ( src.left() == dest.left() && src.right() < dest.right() )
00597 {
00598 for ( int y = src.top(); y <= src.bottom(); y++ )
00599 {
00600 int x;
00601 QPtrList<Cell> destList;
00602 for ( x = src.right() + 1; x <= dest.right(); x++ )
00603 destList.append( nonDefaultCell( x, y ) );
00604 QPtrList<Cell> srcList;
00605 for ( x = src.left(); x <= src.right(); x++ )
00606 srcList.append( cellAt( x, y ) );
00607 QPtrList<AutoFillSequence> seqList;
00608 seqList.setAutoDelete( true );
00609 for ( x = src.left(); x <= src.right(); x++ )
00610 seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
00611 fillSequence( srcList, destList, seqList );
00612 }
00613 }
00614
00615
00616 if ( src.top() == dest.top() && src.bottom() < dest.bottom() )
00617 {
00618 for ( int x = src.left(); x <= dest.right(); x++ )
00619 {
00620 int y;
00621 QPtrList<Cell> destList;
00622 for ( y = src.bottom() + 1; y <= dest.bottom(); y++ )
00623 destList.append( nonDefaultCell( x, y ) );
00624 QPtrList<Cell> srcList;
00625 for ( y = src.top(); y <= src.bottom(); y++ )
00626 {
00627 srcList.append( cellAt( x, y ) );
00628 }
00629 QPtrList<AutoFillSequence> seqList;
00630 seqList.setAutoDelete( true );
00631 for ( y = src.top(); y <= src.bottom(); y++ )
00632 seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
00633 fillSequence( srcList, destList, seqList );
00634 }
00635 }
00636
00637
00638 if ( ( src.left() == dest.right() || src.left() == dest.right() - 1) && src.right() >= dest.right() )
00639 {
00640 if ( src.left() != dest.right() )
00641 dest.setRight( dest.right() - 1 );
00642
00643 for ( int y = dest.top(); y <= dest.bottom(); y++ )
00644 {
00645 int x;
00646 QPtrList<Cell> destList;
00647
00648 for ( x = dest.left(); x < src.left(); x++ )
00649 {
00650 destList.append( nonDefaultCell( x, y ) );
00651 }
00652 QPtrList<Cell> srcList;
00653 for ( x = src.left(); x <= src.right(); x++ )
00654 {
00655 srcList.append( cellAt( x, y ) );
00656 }
00657 QPtrList<AutoFillSequence> seqList;
00658 seqList.setAutoDelete( true );
00659 for ( x = src.left(); x <= src.right(); x++ )
00660 seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
00661 fillSequence( srcList, destList, seqList, false );
00662 }
00663 }
00664
00665
00666 if ( (src.top() == dest.bottom() || src.top() == (dest.bottom() - 1) ) && src.bottom() >= dest.bottom() )
00667 {
00668 if (src.top() != dest.bottom() )
00669 dest.setBottom(dest.bottom() - 1);
00670 int startVal = QMIN( dest.left(), src.left());
00671 int endVal = QMAX(src.right(), dest.right());
00672 for ( int x = startVal; x <= endVal; x++ )
00673 {
00674 int y;
00675 QPtrList<Cell> destList;
00676 for ( y = dest.top(); y < src.top(); y++ )
00677 destList.append( nonDefaultCell( x, y ) );
00678 QPtrList<Cell> srcList;
00679 for ( y = src.top(); y <= src.bottom(); ++y )
00680 {
00681 srcList.append( cellAt( x, y ) );
00682 }
00683 QPtrList<AutoFillSequence> seqList;
00684 seqList.setAutoDelete( true );
00685 for ( y = src.top(); y <= src.bottom(); y++ )
00686 seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
00687 fillSequence( srcList, destList, seqList, false );
00688 }
00689 }
00690
00691 emit sig_updateView( this );
00692
00693 }
00694
00695
00696 void Sheet::fillSequence( QPtrList<Cell>& _srcList,
00697 QPtrList<Cell>& _destList,
00698 QPtrList<AutoFillSequence>& _seqList,
00699 bool down)
00700 {
00701 doc()->emitBeginOperation(true);
00702
00703
00704 if (!FillSequenceWithInterval(_srcList, _destList, _seqList, down))
00705 {
00706
00707 FillSequenceWithCopy(_srcList, _destList, down);
00708 }
00709
00710 doc()->emitEndOperation();
00711
00712 }
00713
00714 QVariant getDiff( const Value& value1, const Value& value2 , AutoFillSequenceItem::Type type )
00715 {
00716 if ( type == AutoFillSequenceItem::FLOAT )
00717 return QVariant( value2.asFloat() - value1.asFloat() );
00718 if ( type == AutoFillSequenceItem::TIME || type == AutoFillSequenceItem::DATE )
00719 return QVariant( (int)( value2.asInteger() - value1.asInteger() ) );
00720
00721 return QVariant( (int)0 );
00722
00723
00724
00725
00726
00727
00728
00729
00730 }
00731
00732 bool Sheet::FillSequenceWithInterval(QPtrList<Cell>& _srcList,
00733 QPtrList<Cell>& _destList,
00734 QPtrList<AutoFillSequence>& _seqList,
00735 bool down)
00736 {
00737 if (_srcList.first()->isFormula())
00738 return false;
00739
00740 QPtrList<AutoFillDeltaSequence> deltaList;
00741 deltaList.setAutoDelete( true );
00742 bool ok = false;
00743
00744 if ( _srcList.first()->value().isNumber() || _srcList.first()->isDate() || _srcList.first()->isTime() )
00745 {
00746 AutoFillSequenceItem::Type type;
00747
00748 QValueVector< QVariant > tmp( _seqList.count() ); ;
00749 QValueVector< QVariant > diff( _seqList.count() ); ;
00750 int p = -1;
00751 int count = 0;
00752 int tmpcount = 0;
00753
00754 Cell * cell = _srcList.first();
00755 Cell * cell2 = _srcList.next();
00756
00757 bool singleCellOnly = (cell2 == 0);
00758
00759 if ( cell->isDate() )
00760 type = AutoFillSequenceItem::DATE;
00761 else if ( cell->isTime() )
00762 type = AutoFillSequenceItem::TIME;
00763 else if ( cell->value().isNumber() )
00764 type = AutoFillSequenceItem::FLOAT;
00765 else
00766 return false;
00767
00768 while ( cell && (cell2 || singleCellOnly) )
00769 {
00770
00771 Value cellValue = cell->value();
00772 Value cell2Value;
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 if (singleCellOnly)
00783 {
00784 if (type == AutoFillSequenceItem::FLOAT)
00785 cell2Value = cellValue;
00786 else if ( type == AutoFillSequenceItem::TIME)
00787 cell2Value = Value( cellValue.asTime().addSecs( 60*60 ) );
00788 else if ( type == AutoFillSequenceItem::DATE)
00789 cell2Value = Value ( cellValue.asDate().addDays( 1 ) );
00790 }
00791 else
00792 {
00793 cell2Value = cell2->value();
00794
00795
00796 if ( ( !cellValue.isNumber() )
00797 || ( cell2->isDate() && type != AutoFillSequenceItem::DATE )
00798 || ( cell2->isTime() && type != AutoFillSequenceItem::TIME ) )
00799 {
00800 count = 0;
00801 ok = false;
00802 break;
00803 }
00804 }
00805
00806 QVariant delta = getDiff(cellValue , cell2Value , type );
00807
00808 if (count < 1)
00809 {
00810 p = count;
00811 diff[ count++ ] = delta;
00812 }
00813 else
00814 {
00815
00816 if (diff[ p ] == delta)
00817 {
00818
00819 ++p;
00820 tmp[ tmpcount++ ] = delta;
00821 }
00822 else
00823 {
00824
00825 if ( tmpcount > 0 )
00826 {
00827 for ( int i = 0; i < tmpcount; ++i )
00828 {
00829 diff[ count++ ] = tmp.at( i );
00830 }
00831
00832 tmpcount = 0;
00833 }
00834
00835
00836 p = 0;
00837 diff[ count++ ] = delta;
00838 }
00839 }
00840
00841
00842 cell = cell2;
00843 cell2 = _srcList.next();
00844 }
00845
00846
00847 if (count > 0 && (tmpcount > 0 || count == 1))
00848 {
00849 QVariant cellValue( (int) 0 );
00850
00851 Cell * dest;
00852 Cell * src;
00853
00854 int i = tmpcount;
00855 if (down)
00856 {
00857 dest = _destList.first();
00858 src = _srcList.last();
00859 }
00860 else
00861 {
00862 dest = _destList.last();
00863 src = _srcList.first();
00864
00865 i *= -1;
00866 }
00867
00868 if ( type == AutoFillSequenceItem::FLOAT )
00869 cellValue = src->value().asFloat();
00870 else
00871 cellValue = (int)src->value().asInteger();
00872
00873 QString res;
00874
00875 while (dest)
00876 {
00877 if (down)
00878 {
00879 while ( i >= count )
00880 i -= count;
00881 }
00882 else
00883 {
00884 while ( i < 0)
00885 i += count;
00886 }
00887
00888 QVariant currentDiff = diff.at( i );
00889
00890 if (cellValue.type() == QVariant::Double)
00891 if (down)
00892 cellValue = cellValue.asDouble() + currentDiff.asDouble();
00893 else
00894 cellValue = cellValue.asDouble() - currentDiff.asDouble();
00895 else
00896 if (down)
00897 cellValue = cellValue.asInt() + currentDiff.asInt();
00898 else
00899 cellValue = cellValue.asInt() - currentDiff.asInt();
00900
00901 if ( type == AutoFillSequenceItem::TIME)
00902 {
00903 Value timeValue = doc()->converter()->asTime( Value(cellValue.asInt()) );
00904 Value stringValue = doc()->converter()->asString( timeValue );
00905 dest->setCellText( stringValue.asString() );
00906 }
00907 else if ( type == AutoFillSequenceItem::DATE)
00908 {
00909 Value dateValue = doc()->converter()->asDate( Value(cellValue.asInt()) );
00910 Value stringValue = doc()->converter()->asString( dateValue );
00911 dest->setCellText( stringValue.asString() );
00912 }
00913 else
00914 dest->setCellText( cellValue.asString() );
00915
00916 dest->copyFormat( src );
00917
00918 if (down)
00919 {
00920 ++i;
00921 dest = _destList.next();
00922 src = _srcList.next();
00923 }
00924 else
00925 {
00926 --i;
00927 dest = _destList.prev();
00928 src = _srcList.prev();
00929 }
00930
00931 if (!src)
00932 src = _srcList.last();
00933 }
00934
00935 ok = true;
00936 }
00937 else
00938 {
00939 ok = false;
00940 }
00941
00942
00943
00944
00945 return ok;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 for ( unsigned int step = 1; step <= _seqList.count() / 2; step++ )
00960 {
00961 kdDebug() << "Looking for interval: " << step << " seqList count: " << _seqList.count() << endl;
00962
00963
00964 if ( _seqList.count() % step == 0 )
00965 {
00966
00967 ok = true;
00968
00969 deltaList.clear();
00970
00971
00972
00973
00974
00975 for ( unsigned int t = 0; t < step; t++ )
00976 {
00977 deltaList.append( new AutoFillDeltaSequence( _seqList.at(t),
00978 _seqList.at(t+step) ) );
00979 ok = deltaList.getLast()->isOk();
00980 }
00981
00982
00983
00984
00985
00986
00987
00988 for ( unsigned int tst = 1; ok && ( tst * step < _seqList.count() );
00989 tst++ )
00990 {
00991 for ( unsigned int s = 0; ok && ( s < step ); s++ )
00992 {
00993 if ( !_seqList.at( (tst-1) * step + s )->
00994 matches( _seqList.at( tst * step + s ), deltaList.at( s ) ) )
00995 ok = false;
00996 }
00997 }
00998
00999 if ( ok )
01000 {
01001 unsigned int s = 0;
01002
01003 int block = _seqList.count() / step;
01004
01005
01006 Cell * cell;
01007 if (down)
01008 cell = _destList.first();
01009 else
01010 {
01011 cell = _destList.last();
01012 block -= (_seqList.count() - 1);
01013 }
01014
01015
01016
01017 while ( cell )
01018 {
01019 kdDebug() << "Valid interval, cell: " << cell->row() << " block: " << block << endl;
01020
01021
01022 if (down)
01023 {
01024 if ( s == step )
01025 {
01026 ++block;
01027 s = 0;
01028 }
01029 }
01030 else
01031 {
01032 if ( s >= step )
01033 {
01034 s = step - 1;
01035 ++block;
01036 }
01037 }
01038
01039 kdDebug() << "Step: " << step << " S: " << s << " Block " << block
01040 << " SeqList: " << _seqList.count()
01041 << " SrcList: " << _srcList.count() << " DeltaList: " << deltaList.count()
01042 << endl;
01043
01044
01045
01046 _seqList.at( s )->fillCell( _srcList.at( s ), cell,
01047 deltaList.at( s ), block, down );
01048
01049 if (down)
01050 {
01051
01052 cell = _destList.next();
01053 ++s;
01054 }
01055 else
01056 {
01057
01058 cell = _destList.prev();
01059 --s;
01060 }
01061 }
01062 }
01063 }
01064 }
01065 return ok;
01066 }
01067
01068 void Sheet::FillSequenceWithCopy(QPtrList<Cell>& _srcList,
01069 QPtrList<Cell>& _destList,
01070 bool down)
01071 {
01072
01073
01074 Cell * cell;
01075
01076 if (down)
01077 cell = _destList.first();
01078 else
01079 cell = _destList.last();
01080 int incr = 1;
01081 unsigned int s = 0;
01082 double factor = 1;
01083
01084 if (!down)
01085 s = _srcList.count() - 1;
01086
01087 if ( _srcList.at( s )->value().isNumber() &&
01088 !(_srcList.at( s )->isDate() || _srcList.at( s )->isTime() ) )
01089 factor = _srcList.at( s )->value().asFloat();
01090
01091 while ( cell )
01092 {
01093 if (down)
01094 {
01095 if ( s == _srcList.count() )
01096 s = 0;
01097 }
01098 else
01099 {
01100 if ( s >= _srcList.count() )
01101 s = _srcList.count() - 1;
01102 }
01103
01104 if ( !_srcList.at( s )->text().isEmpty() )
01105 {
01106 if ( _srcList.at( s )->isFormula() )
01107 {
01108 QString d = _srcList.at( s )->encodeFormula();
01109 cell->setCellText( cell->decodeFormula( d ) );
01110 }
01111 else if(_srcList.at( s )->value().isNumber() && _srcList.count()==1)
01112 {
01113 double val;
01114 int format_type = _srcList.at( s )->formatType();
01115 if ( format_type == Percentage_format )
01116 {
01117 factor = 0.01;
01118 }
01119 else if ( _srcList.at( s )->isTime() )
01120 {
01121
01122
01123
01124 if (down)
01125 {
01126
01127 factor = 0.041666751;
01128 }
01129 else
01130 {
01131 factor = 0.0416665;
01132 }
01133 }
01134
01135 if (!down)
01136 val = (_srcList.at( s )->value().asFloat() - (incr * factor));
01137 else
01138 val = (_srcList.at( s )->value().asFloat() + (incr * factor));
01139
01140 QString tmp;
01141 tmp = tmp.setNum(val);
01142 cell->setCellText( tmp );
01143 ++incr;
01144 }
01145 else if((AutoFillSequenceItem::month != 0L)
01146 && AutoFillSequenceItem::month->find( _srcList.at( s )->text()) != 0L
01147 && AutoFillSequenceItem::month->find( _srcList.at( s )->text()) != AutoFillSequenceItem::month->end()
01148 && _srcList.count() == 1)
01149 {
01150 QString strMonth=_srcList.at( s )->text();
01151 int i = AutoFillSequenceItem::month->findIndex( strMonth )+incr;
01152 int k = (i) % AutoFillSequenceItem::month->count();
01153 cell->setCellText((*AutoFillSequenceItem::month->at( k )));
01154 incr++;
01155 }
01156 else if(AutoFillSequenceItem::day != 0L
01157 && AutoFillSequenceItem::day->find( _srcList.at( s )->text()) != 0L
01158 && AutoFillSequenceItem::day->find( _srcList.at( s )->text())
01159 != AutoFillSequenceItem::day->end()
01160 && _srcList.count()==1)
01161 {
01162 QString strDay=_srcList.at( s )->text();
01163 int i = AutoFillSequenceItem::day->findIndex( strDay )+incr;
01164 int k = (i) % AutoFillSequenceItem::day->count();
01165 cell->setCellText((*AutoFillSequenceItem::day->at( k )));
01166 incr++;
01167 }
01168 else
01169 {
01170 QRegExp number("(\\d+)");
01171 int pos =number.search(_srcList.at( s )->text());
01172 if( pos!=-1 )
01173 {
01174 QString tmp=number.cap(1);
01175 int num=tmp.toInt()+incr;
01176 cell->setCellText(_srcList.at( s )->text().replace(number,QString::number(num)));
01177 ++incr;
01178 }
01179 else if ( !_srcList.at( s )->link().isEmpty() )
01180 {
01181 cell->setCellText( _srcList.at( s )->text() );
01182 cell->setLink( _srcList.at( s )->link() );
01183 }
01184 else
01185 {
01186 cell->setCellText( _srcList.at( s )->text() );
01187 }
01188 }
01189 }
01190 else
01191 cell->setCellText( "" );
01192
01193 cell->copyFormat( _srcList.at( s ) );
01194
01195 if (down)
01196 {
01197 cell = _destList.next();
01198 ++s;
01199 }
01200 else
01201 {
01202 cell = _destList.prev();
01203 --s;
01204 }
01205 }
01206 return;
01207 }