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