KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1218 lines
33KB

  1. /* This file is part of the KDE project
  2. Copyright 2005 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
  3. Copyright 2002-2004 Ariya Hidayat <ariya@kde.org>
  4. Copyright 2002-2003 Norbert Andres <nandres@web.de>
  5. Copyright 2002 John Dailey <dailey@vt.edu>
  6. Copyright 2001-2002 Philipp Mueller <philipp.mueller@gmx.de>
  7. Copyright 2000-2002 Laurent Montel <montel@kde.org>
  8. Copyright 2000-2001 Werner Trobin <trobin@kde.org>
  9. Copyright 1999-2001 David Faure <faure@kde.org>
  10. Copyright 1998-2000 Torben Weis <weis@kde.org>
  11. Copyright 1998-1999 Stephan Kulow <coolo@kde.org>
  12. Copyright 1998 Reginald Stadlbauer <reggie@kde.org>
  13. This library is free software; you can redistribute it and/or
  14. modify it under the terms of the GNU Library General Public
  15. License as published by the Free Software Foundation; either
  16. version 2 of the License, or (at your option) any later version.
  17. This library is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. Library General Public License for more details.
  21. You should have received a copy of the GNU Library General Public License
  22. along with this library; see the file COPYING.LIB. If not, write to
  23. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  24. * Boston, MA 02110-1301, USA.
  25. */
  26. #include <math.h>
  27. #include <tqregexp.h>
  28. #include <tdeconfig.h>
  29. #include <kdebug.h>
  30. #include "kspread_doc.h"
  31. #include "kspread_locale.h"
  32. #include "kspread_sheet.h"
  33. #include "kspread_undo.h"
  34. #include "kspread_value.h"
  35. #include "valueconverter.h"
  36. #include "kspread_autofill.h"
  37. using namespace KSpread;
  38. TQStringList *AutoFillSequenceItem::month = 0L;
  39. TQStringList *AutoFillSequenceItem::shortMonth = 0L;
  40. TQStringList *AutoFillSequenceItem::day = 0L;
  41. TQStringList *AutoFillSequenceItem::shortDay = 0L;
  42. TQStringList *AutoFillSequenceItem::other = 0L;
  43. /**********************************************************************************
  44. *
  45. * AutoFillDeltaSequence
  46. *
  47. **********************************************************************************/
  48. AutoFillDeltaSequence::AutoFillDeltaSequence( AutoFillSequence *_first, AutoFillSequence *_next )
  49. : m_ok(true),
  50. m_sequence(0L)
  51. {
  52. if ( _first->count() != _next->count() )
  53. {
  54. m_ok = false;
  55. return;
  56. }
  57. m_sequence = new TQMemArray<double> ( _first->count() );
  58. AutoFillSequenceItem *item = _first->getFirst();
  59. AutoFillSequenceItem *item2 = _next->getFirst();
  60. int i = 0;
  61. // for( item = _first->getFirst(); item != 0L && item2 != 0L; item = _first->getNext() );
  62. for ( i = 0; i < _first->count(); i++ )
  63. {
  64. double d;
  65. if ( !item->getDelta( item2, d ) )
  66. {
  67. m_ok = false;
  68. return;
  69. }
  70. m_sequence->at( i++ ) = d;
  71. item2 = _next->getNext();
  72. item = _first->getNext();
  73. }
  74. }
  75. AutoFillDeltaSequence::~AutoFillDeltaSequence()
  76. {
  77. delete m_sequence;
  78. }
  79. bool AutoFillDeltaSequence::equals( AutoFillDeltaSequence *_delta )
  80. {
  81. if ( m_sequence == 0L )
  82. return false;
  83. if ( _delta->getSequence() == 0L )
  84. return false;
  85. if ( m_sequence->size() != _delta->getSequence()->size() )
  86. return false;
  87. for ( unsigned int i = 0; i < m_sequence->size(); i++ )
  88. {
  89. if ( m_sequence->at( i ) != _delta->getSequence()->at( i ) )
  90. return false;
  91. }
  92. return true;
  93. }
  94. double AutoFillDeltaSequence::getItemDelta( int _pos )
  95. {
  96. if ( m_sequence == 0L )
  97. return 0.0;
  98. return m_sequence->at( _pos );
  99. }
  100. /**********************************************************************************
  101. *
  102. * AutoFillSequenceItem
  103. *
  104. **********************************************************************************/
  105. AutoFillSequenceItem::AutoFillSequenceItem( int _i )
  106. {
  107. m_IValue = _i;
  108. m_Type = INTEGER;
  109. }
  110. AutoFillSequenceItem::AutoFillSequenceItem( double _d )
  111. {
  112. m_DValue = _d;
  113. m_Type = FLOAT;
  114. }
  115. AutoFillSequenceItem::AutoFillSequenceItem( const TQString &_str )
  116. {
  117. m_String = _str;
  118. m_Type = STRING;
  119. if ( month == 0L )
  120. {
  121. month = new TQStringList();
  122. month->append( i18n("January") );
  123. month->append( i18n("February") );
  124. month->append( i18n("March") );
  125. month->append( i18n("April") );
  126. month->append( i18n("May") );
  127. month->append( i18n("June") );
  128. month->append( i18n("July") );
  129. month->append( i18n("August") );
  130. month->append( i18n("September") );
  131. month->append( i18n("October") );
  132. month->append( i18n("November") );
  133. month->append( i18n("December") );
  134. }
  135. if ( shortMonth == 0L )
  136. {
  137. shortMonth = new TQStringList();
  138. shortMonth->append( i18n("Jan") );
  139. shortMonth->append( i18n("Feb") );
  140. shortMonth->append( i18n("Mar") );
  141. shortMonth->append( i18n("Apr") );
  142. shortMonth->append( i18n("May short", "May") );
  143. shortMonth->append( i18n("Jun") );
  144. shortMonth->append( i18n("Jul") );
  145. shortMonth->append( i18n("Aug") );
  146. shortMonth->append( i18n("Sep") );
  147. shortMonth->append( i18n("Oct") );
  148. shortMonth->append( i18n("Nov") );
  149. shortMonth->append( i18n("Dec") );
  150. }
  151. if ( day == 0L )
  152. {
  153. day = new TQStringList();
  154. day->append( i18n("Monday") );
  155. day->append( i18n("Tuesday") );
  156. day->append( i18n("Wednesday") );
  157. day->append( i18n("Thursday") );
  158. day->append( i18n("Friday") );
  159. day->append( i18n("Saturday") );
  160. day->append( i18n("Sunday") );
  161. }
  162. if ( shortDay == 0L )
  163. {
  164. shortDay = new TQStringList();
  165. shortDay->append( i18n("Mon") );
  166. shortDay->append( i18n("Tue") );
  167. shortDay->append( i18n("Wed") );
  168. shortDay->append( i18n("Thu") );
  169. shortDay->append( i18n("Fri") );
  170. shortDay->append( i18n("Sat") );
  171. shortDay->append( i18n("Sun") );
  172. }
  173. if( other==0L)
  174. {
  175. // other=new TQStringList();
  176. TDEConfig *config = Factory::global()->config();
  177. config->setGroup( "Parameters" );
  178. other=new TQStringList(config->readListEntry("Other list"));
  179. }
  180. if ( month->find( _str ) != month->end() )
  181. {
  182. m_Type = MONTH;
  183. return;
  184. }
  185. if ( shortMonth->find( _str ) != shortMonth->end() )
  186. {
  187. m_Type = SHORTMONTH;
  188. return;
  189. }
  190. if ( day->find( _str ) != day->end() )
  191. {
  192. m_Type = DAY;
  193. return;
  194. }
  195. if ( shortDay->find( _str ) != shortDay->end() )
  196. {
  197. m_Type = SHORTDAY;
  198. return;
  199. }
  200. if( other->find(_str)!=other->end())
  201. {
  202. m_Type = OTHER;
  203. m_OtherBegin=0;
  204. m_OtherEnd=other->count();
  205. int index= other->findIndex(_str);
  206. //find end and begin of qstringlist of other.
  207. for ( TQStringList::Iterator it = other->find(_str); it != other->end();++it )
  208. {
  209. if((*it)=="\\")
  210. {
  211. m_OtherEnd=index;
  212. break;
  213. }
  214. index++;
  215. }
  216. index= other->findIndex(_str);
  217. for ( TQStringList::Iterator it = other->find(_str); it != other->begin();--it )
  218. {
  219. if((*it)=="\\")
  220. {
  221. m_OtherBegin=index;
  222. break;
  223. }
  224. index--;
  225. }
  226. return;
  227. }
  228. if ( m_String[0] == '=' )
  229. m_Type = FORMULA;
  230. }
  231. bool AutoFillSequenceItem::getDelta( AutoFillSequenceItem *seq, double &_delta )
  232. {
  233. if ( seq->getType() != m_Type )
  234. return false;
  235. switch( m_Type )
  236. {
  237. case INTEGER:
  238. _delta = (double)( seq->getIValue() - m_IValue );
  239. return true;
  240. case FLOAT:
  241. _delta = seq->getDValue() - m_DValue;
  242. return true;
  243. case FORMULA:
  244. case STRING:
  245. if ( m_String == seq->getString() )
  246. {
  247. _delta = 0.0;
  248. return true;
  249. }
  250. return false;
  251. case MONTH:
  252. {
  253. int i = month->findIndex( m_String );
  254. int j = month->findIndex( seq->getString() );
  255. int k = j;
  256. if ( j + 1 == i )
  257. _delta = -1.0;
  258. else
  259. _delta = ( double )( k - i );
  260. return true;
  261. }
  262. case SHORTMONTH:
  263. {
  264. int i = shortMonth->findIndex( m_String );
  265. int j = shortMonth->findIndex( seq->getString() );
  266. int k = j;
  267. if ( j + 1 == i )
  268. _delta = -1.0;
  269. else
  270. _delta = ( double )( k - i );
  271. return true;
  272. }
  273. case DAY:
  274. {
  275. int i = day->findIndex( m_String );
  276. int j = day->findIndex( seq->getString() );
  277. int k = j;
  278. if ( j + 1 == i )
  279. _delta = -1.0;
  280. else
  281. _delta = ( double )( k - i );
  282. kdDebug() << m_String << " i: " << i << " j: " << j << " k: " << k << " delta: " << _delta << endl;
  283. return true;
  284. }
  285. case SHORTDAY:
  286. {
  287. int i = shortDay->findIndex( m_String );
  288. int j = shortDay->findIndex( seq->getString() );
  289. int k = j;
  290. if ( j + 1 == i )
  291. _delta = -1.0;
  292. else
  293. _delta = ( double )( k - i );
  294. return true;
  295. }
  296. case OTHER:
  297. {
  298. if( m_OtherEnd!= seq->getIOtherEnd() || m_OtherBegin!= seq->getIOtherBegin())
  299. return false;
  300. int i = other->findIndex( m_String );
  301. int j = other->findIndex( seq->getString() );
  302. int k = j;
  303. if ( j < i )
  304. k += (m_OtherEnd - m_OtherBegin - 1);
  305. /*if ( j + 1 == i )
  306. _delta = -1.0;
  307. else*/
  308. _delta = ( double )( k - i );
  309. return true;
  310. }
  311. default:
  312. return false;
  313. }
  314. }
  315. TQString AutoFillSequenceItem::getSuccessor( int _no, double _delta )
  316. {
  317. TQString erg;
  318. switch( m_Type )
  319. {
  320. case INTEGER:
  321. erg.sprintf("%i", m_IValue + _no * (int)_delta );
  322. break;
  323. case FLOAT:
  324. erg.sprintf("%f", m_DValue + (double)_no * _delta );
  325. break;
  326. case FORMULA:
  327. case STRING:
  328. erg = m_String;
  329. break;
  330. case MONTH:
  331. {
  332. int i = month->findIndex( m_String );
  333. int j = i + _no * (int) _delta;
  334. while (j < 0)
  335. j += month->count();
  336. int k = j % month->count();
  337. erg = (*month->at( k ));
  338. }
  339. break;
  340. case SHORTMONTH:
  341. {
  342. int i = shortMonth->findIndex( m_String );
  343. int j = i + _no * (int) _delta;
  344. while (j < 0)
  345. j += shortMonth->count();
  346. int k = j % shortMonth->count();
  347. erg = (*shortMonth->at( k ));
  348. }
  349. break;
  350. case DAY:
  351. {
  352. int i = day->findIndex( m_String );
  353. int j = i + _no * (int) _delta;
  354. while (j < 0)
  355. j += day->count();
  356. int k = j % day->count();
  357. erg = (*day->at( k ));
  358. }
  359. break;
  360. case SHORTDAY:
  361. {
  362. int i = shortDay->findIndex( m_String );
  363. int j = i + _no * (int) _delta;
  364. while (j < 0)
  365. j += shortDay->count();
  366. int k = j % shortDay->count();
  367. erg = (*shortDay->at( k ));
  368. }
  369. break;
  370. case OTHER:
  371. {
  372. int i = other->findIndex( m_String )-(m_OtherBegin+1);
  373. int j = i + _no * (int) _delta;
  374. int k = j % (m_OtherEnd - m_OtherBegin-1);
  375. erg = (*other->at( (k+m_OtherBegin+1) ));
  376. }
  377. case TIME:
  378. case DATE:
  379. // gets never called but fixes a warning while compiling
  380. break;
  381. }
  382. return TQString( erg );
  383. }
  384. TQString AutoFillSequenceItem::getPredecessor( int _no, double _delta )
  385. {
  386. TQString erg;
  387. switch( m_Type )
  388. {
  389. case INTEGER:
  390. erg.sprintf("%i", m_IValue - _no * (int)_delta );
  391. break;
  392. case FLOAT:
  393. erg.sprintf("%f", m_DValue - (double)_no * _delta );
  394. break;
  395. case FORMULA:
  396. case STRING:
  397. erg = m_String;
  398. break;
  399. case MONTH:
  400. {
  401. int i = month->findIndex( m_String );
  402. int j = i - _no * (int) _delta;
  403. while ( j < 0 )
  404. j += month->count();
  405. int k = j % month->count();
  406. erg = (*month->at( k ));
  407. }
  408. break;
  409. case SHORTMONTH:
  410. {
  411. int i = shortMonth->findIndex( m_String );
  412. int j = i - _no * (int) _delta;
  413. while ( j < 0 )
  414. j += shortMonth->count();
  415. int k = j % shortMonth->count();
  416. erg = (*shortMonth->at( k ));
  417. }
  418. break;
  419. case DAY:
  420. {
  421. int i = day->findIndex( m_String );
  422. int j = i - _no * (int) _delta;
  423. while ( j < 0 )
  424. j += day->count();
  425. int k = j % day->count();
  426. erg = (*day->at( k ));
  427. }
  428. break;
  429. case SHORTDAY:
  430. {
  431. int i = shortDay->findIndex( m_String );
  432. int j = i - _no * (int) _delta;
  433. while ( j < 0 )
  434. j += shortDay->count();
  435. int k = j % shortDay->count();
  436. erg = (*shortDay->at( k ));
  437. }
  438. break;
  439. case OTHER:
  440. {
  441. int i = other->findIndex( m_String ) - (m_OtherBegin + 1);
  442. int j = i - _no * (int) _delta;
  443. while ( j < 0 )
  444. j += (m_OtherEnd - m_OtherBegin - 1);
  445. int k = j % (m_OtherEnd - m_OtherBegin - 1);
  446. erg = (*other->at( (k + m_OtherBegin + 1) ));
  447. }
  448. case TIME:
  449. case DATE:
  450. // gets never called but fixes a warning while compiling
  451. break;
  452. }
  453. return TQString( erg );
  454. }
  455. /**********************************************************************************
  456. *
  457. * AutoFillSequence
  458. *
  459. **********************************************************************************/
  460. AutoFillSequence::AutoFillSequence( Cell *_cell )
  461. {
  462. sequence.setAutoDelete( true );
  463. if ( _cell->isFormula() )
  464. {
  465. TQString d = _cell->encodeFormula();
  466. sequence.append( new AutoFillSequenceItem( d ) );
  467. }
  468. else if ( _cell->value().isNumber() )
  469. {
  470. if ( floor( _cell->value().asFloat() ) == _cell->value().asFloat() )
  471. {
  472. sequence.append( new AutoFillSequenceItem( (int)_cell->value().asFloat()) );
  473. }
  474. else
  475. sequence.append( new AutoFillSequenceItem(_cell->value().asFloat() ) );
  476. }
  477. else if ( !_cell->text().isEmpty() )
  478. sequence.append( new AutoFillSequenceItem( _cell->text() ) );
  479. }
  480. bool AutoFillSequence::matches( AutoFillSequence* _seq, AutoFillDeltaSequence *_delta )
  481. {
  482. AutoFillDeltaSequence delta( this, _seq );
  483. if ( !delta.isOk() )
  484. return false;
  485. if ( delta.equals( _delta ) )
  486. return true;
  487. return false;
  488. }
  489. void AutoFillSequence::fillCell( Cell *src, Cell *dest, AutoFillDeltaSequence *delta, int _block, bool down )
  490. {
  491. TQString erg = "";
  492. // Special handling for formulas
  493. if ( sequence.first() != 0L && sequence.first()->getType() == AutoFillSequenceItem::FORMULA )
  494. {
  495. TQString f = dest->decodeFormula( sequence.first()->getString() );
  496. dest->setCellText( f );
  497. dest->copyFormat( src );
  498. return;
  499. }
  500. AutoFillSequenceItem *item;
  501. int i = 0;
  502. if (down)
  503. {
  504. for ( item = sequence.first(); item != 0L; item = sequence.next() )
  505. erg += item->getSuccessor( _block, delta->getItemDelta( i++ ) );
  506. }
  507. else
  508. {
  509. for ( item = sequence.first(); item != 0L; item = sequence.next() )
  510. erg += item->getPredecessor( _block, delta->getItemDelta( i++ ) );
  511. }
  512. dest->setCellText( erg );
  513. dest->copyFormat( src );
  514. }
  515. /**********************************************************************************
  516. *
  517. * Sheet
  518. *
  519. **********************************************************************************/
  520. void Sheet::autofill( TQRect &src, TQRect &dest )
  521. {
  522. if (src == dest)
  523. {
  524. return;
  525. }
  526. setRegionPaintDirty( dest );
  527. doc()->emitBeginOperation();
  528. if ( !doc()->undoLocked() )
  529. {
  530. UndoAutofill *undo = new UndoAutofill( doc(), this, dest );
  531. doc()->addCommand( undo );
  532. }
  533. // disable the update of the max sroll range on each cell insertion
  534. // Bug 124806: creating series takes extremely long time
  535. enableScrollBarUpdates(false);
  536. // Fill from left to right
  537. if ( src.left() == dest.left() && src.right() < dest.right() )
  538. {
  539. for ( int y = src.top(); y <= src.bottom(); y++ )
  540. {
  541. int x;
  542. TQPtrList<Cell> destList;
  543. for ( x = src.right() + 1; x <= dest.right(); x++ )
  544. destList.append( nonDefaultCell( x, y ) );
  545. TQPtrList<Cell> srcList;
  546. for ( x = src.left(); x <= src.right(); x++ )
  547. srcList.append( cellAt( x, y ) );
  548. TQPtrList<AutoFillSequence> seqList;
  549. seqList.setAutoDelete( true );
  550. for ( x = src.left(); x <= src.right(); x++ )
  551. seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
  552. fillSequence( srcList, destList, seqList );
  553. }
  554. }
  555. // Fill from top to bottom
  556. if ( src.top() == dest.top() && src.bottom() < dest.bottom() )
  557. {
  558. for ( int x = src.left(); x <= dest.right(); x++ )
  559. {
  560. int y;
  561. TQPtrList<Cell> destList;
  562. for ( y = src.bottom() + 1; y <= dest.bottom(); y++ )
  563. destList.append( nonDefaultCell( x, y ) );
  564. TQPtrList<Cell> srcList;
  565. for ( y = src.top(); y <= src.bottom(); y++ )
  566. {
  567. srcList.append( cellAt( x, y ) );
  568. }
  569. TQPtrList<AutoFillSequence> seqList;
  570. seqList.setAutoDelete( true );
  571. for ( y = src.top(); y <= src.bottom(); y++ )
  572. seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
  573. fillSequence( srcList, destList, seqList );
  574. }
  575. }
  576. // Fill from right to left
  577. if ( ( src.left() == dest.right() || src.left() == dest.right() - 1) && src.right() >= dest.right() )
  578. {
  579. if ( src.left() != dest.right() )
  580. dest.setRight( dest.right() - 1 );
  581. for ( int y = dest.top(); y <= dest.bottom(); y++ )
  582. {
  583. int x;
  584. TQPtrList<Cell> destList;
  585. for ( x = dest.left(); x < src.left(); x++ )
  586. {
  587. destList.append( nonDefaultCell( x, y ) );
  588. }
  589. TQPtrList<Cell> srcList;
  590. for ( x = src.left(); x <= src.right(); x++ )
  591. {
  592. srcList.append( cellAt( x, y ) );
  593. }
  594. TQPtrList<AutoFillSequence> seqList;
  595. seqList.setAutoDelete( true );
  596. for ( x = src.left(); x <= src.right(); x++ )
  597. seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
  598. fillSequence( srcList, destList, seqList, false );
  599. }
  600. }
  601. // Fill from bottom to top
  602. if ( (src.top() == dest.bottom() || src.top() == (dest.bottom() - 1) ) && src.bottom() >= dest.bottom() )
  603. {
  604. if (src.top() != dest.bottom() )
  605. dest.setBottom(dest.bottom() - 1);
  606. int startVal = TQMIN( dest.left(), src.left());
  607. int endVal = TQMAX(src.right(), dest.right());
  608. for ( int x = startVal; x <= endVal; x++ )
  609. {
  610. int y;
  611. TQPtrList<Cell> destList;
  612. for ( y = dest.top(); y < src.top(); y++ )
  613. destList.append( nonDefaultCell( x, y ) );
  614. TQPtrList<Cell> srcList;
  615. for ( y = src.top(); y <= src.bottom(); ++y )
  616. {
  617. srcList.append( cellAt( x, y ) );
  618. }
  619. TQPtrList<AutoFillSequence> seqList;
  620. seqList.setAutoDelete( true );
  621. for ( y = src.top(); y <= src.bottom(); y++ )
  622. seqList.append( new AutoFillSequence( cellAt( x, y ) ) );
  623. fillSequence( srcList, destList, seqList, false );
  624. }
  625. }
  626. // update the max sroll range ONCE here
  627. enableScrollBarUpdates(true);
  628. checkRangeHBorder(dest.right());
  629. checkRangeVBorder(dest.bottom());
  630. emit sig_updateView( this );
  631. // doc()->emitEndOperation();
  632. }
  633. void Sheet::fillSequence( TQPtrList<Cell>& _srcList,
  634. TQPtrList<Cell>& _destList,
  635. TQPtrList<AutoFillSequence>& _seqList,
  636. bool down)
  637. {
  638. doc()->emitBeginOperation(true);
  639. /* try finding an interval to use to fill the sequence */
  640. if (!FillSequenceWithInterval(_srcList, _destList, _seqList, down))
  641. {
  642. /* if no interval was found, just copy down through */
  643. FillSequenceWithCopy(_srcList, _destList, down);
  644. }
  645. doc()->emitEndOperation();
  646. }
  647. TQVariant getDiff( const Value& value1, const Value& value2 , AutoFillSequenceItem::Type type )
  648. {
  649. if ( type == AutoFillSequenceItem::FLOAT )
  650. return TQVariant( value2.asFloat() - value1.asFloat() );
  651. if ( type == AutoFillSequenceItem::TIME || type == AutoFillSequenceItem::DATE )
  652. return TQVariant( (int)( value2.asInteger() - value1.asInteger() ) );
  653. return TQVariant( (int)0 );
  654. // note: date and time difference can be calculated as
  655. // the difference of the serial number
  656. /* if( (type == AutoFillSequenceItem::FLOAT) ||
  657. (type == AutoFillSequenceItem::DATE) ||
  658. (type == AutoFillSequenceItem::TIME) )
  659. return ( value2.asFloat() - value1.asFloat() );
  660. else
  661. return 0.0;*/
  662. }
  663. bool Sheet::FillSequenceWithInterval(TQPtrList<Cell>& _srcList,
  664. TQPtrList<Cell>& _destList,
  665. TQPtrList<AutoFillSequence>& _seqList,
  666. bool down)
  667. {
  668. if (_srcList.first()->isFormula())
  669. return false;
  670. TQPtrList<AutoFillDeltaSequence> deltaList;
  671. deltaList.setAutoDelete( true );
  672. bool ok = false;
  673. if ( _srcList.first()->value().isNumber() || _srcList.first()->isDate() || _srcList.first()->isTime() )
  674. {
  675. AutoFillSequenceItem::Type type;
  676. TQValueVector< TQVariant > tmp( _seqList.count() ); /*= new TQValueList< TQVariant > ( _seqList.count() )*/;
  677. TQValueVector< TQVariant > diff( _seqList.count() ); /*= new TQValueList< TQVariant > ( _seqList.count() )*/;
  678. int p = -1;
  679. int count = 0;
  680. int tmpcount = 0;
  681. Cell * cell = _srcList.first();
  682. Cell * cell2 = _srcList.next();
  683. bool singleCellOnly = (cell2 == 0);
  684. if ( cell->isDate() )
  685. type = AutoFillSequenceItem::DATE;
  686. else if ( cell->isTime() )
  687. type = AutoFillSequenceItem::TIME;
  688. else if ( cell->value().isNumber() )
  689. type = AutoFillSequenceItem::FLOAT;
  690. else
  691. return false; // Cannot happen due to if condition
  692. while ( cell && (cell2 || singleCellOnly) )
  693. {
  694. Value cellValue = cell->value();
  695. Value cell2Value;
  696. //If we only have a single cell, the interval will depend upon the data type.
  697. //- For numeric values, set the interval to 0 as we don't know what might be useful as a sequence
  698. //- For time values, set the interval to one hour, as this will probably be the most useful setting
  699. //- For date values, set the interval to one day, as this will probably be the most useful setting
  700. //
  701. //Note that the above options were chosen for consistency with Excel. Gnumeric (1.59) sets
  702. //the interval to 0 for all types, OpenOffice.org (2.00) uses increments of 1.00, 1 hour and 1 day
  703. //respectively
  704. if (singleCellOnly)
  705. {
  706. if (type == AutoFillSequenceItem::FLOAT)
  707. cell2Value = cellValue;
  708. else if ( type == AutoFillSequenceItem::TIME)
  709. cell2Value = Value( cellValue.asTime().addSecs( 60*60 ) );
  710. else if ( type == AutoFillSequenceItem::DATE)
  711. cell2Value = Value ( cellValue.asDate().addDays( 1 ) );
  712. }
  713. else
  714. {
  715. cell2Value = cell2->value();
  716. // check if both cells contain the same type
  717. if ( ( !cellValue.isNumber() )
  718. || ( cell2->isDate() && type != AutoFillSequenceItem::DATE )
  719. || ( cell2->isTime() && type != AutoFillSequenceItem::TIME ) )
  720. {
  721. count = 0;
  722. ok = false;
  723. break;
  724. }
  725. }
  726. TQVariant delta = getDiff(cellValue , cell2Value , type );
  727. if (count < 1)
  728. {
  729. p = count;
  730. diff[ count++ ] = delta;
  731. }
  732. else
  733. {
  734. // same value again?
  735. if (diff[ p ] == delta)
  736. {
  737. // store it somewhere else for the case we need it later
  738. ++p;
  739. tmp[ tmpcount++ ] = delta;
  740. }
  741. else
  742. {
  743. // if we have saved values in another buffer we have to insert them first
  744. if ( tmpcount > 0 )
  745. {
  746. for ( int i = 0; i < tmpcount; ++i )
  747. {
  748. diff[ count++ ] = tmp.at( i );
  749. }
  750. tmpcount = 0;
  751. }
  752. // insert the value
  753. p = 0;
  754. diff[ count++ ] = delta;
  755. }
  756. }
  757. // check next cell pair
  758. cell = cell2;
  759. cell2 = _srcList.next();
  760. }
  761. // we have found something:
  762. if (count > 0 && (tmpcount > 0 || count == 1))
  763. {
  764. TQVariant cellValue( (int) 0 );
  765. Cell * dest;
  766. Cell * src;
  767. int i = tmpcount;
  768. if (down)
  769. {
  770. dest = _destList.first();
  771. src = _srcList.last();
  772. }
  773. else
  774. {
  775. dest = _destList.last();
  776. src = _srcList.first();
  777. i *= -1;
  778. }
  779. if ( type == AutoFillSequenceItem::FLOAT )
  780. cellValue = src->value().asFloat();
  781. else
  782. cellValue = (int)src->value().asInteger();
  783. TQString res;
  784. // copy all the data
  785. while (dest)
  786. {
  787. if (down)
  788. {
  789. while ( i >= count )
  790. i -= count;
  791. }
  792. else
  793. {
  794. while ( i < 0)
  795. i += count;
  796. }
  797. TQVariant currentDiff = diff.at( i );
  798. if (cellValue.type() == TQVariant::Double)
  799. if (down)
  800. cellValue = cellValue.asDouble() + currentDiff.asDouble();
  801. else
  802. cellValue = cellValue.asDouble() - currentDiff.asDouble();
  803. else
  804. if (down)
  805. cellValue = cellValue.asInt() + currentDiff.asInt();
  806. else
  807. cellValue = cellValue.asInt() - currentDiff.asInt();
  808. if ( type == AutoFillSequenceItem::TIME)
  809. {
  810. Value timeValue = doc()->converter()->asTime( Value(cellValue.asInt()) );
  811. Value stringValue = doc()->converter()->asString( timeValue );
  812. dest->setCellText( stringValue.asString() );
  813. }
  814. else if ( type == AutoFillSequenceItem::DATE)
  815. {
  816. Value dateValue = doc()->converter()->asDate( Value(cellValue.asInt()) );
  817. Value stringValue = doc()->converter()->asString( dateValue );
  818. dest->setCellText( stringValue.asString() );
  819. }
  820. else
  821. dest->setCellText( cellValue.asString() );
  822. dest->copyFormat( src );
  823. if (down)
  824. {
  825. ++i;
  826. dest = _destList.next();
  827. src = _srcList.next();
  828. }
  829. else
  830. {
  831. --i;
  832. dest = _destList.prev();
  833. src = _srcList.prev();
  834. }
  835. if (!src)
  836. src = _srcList.last();
  837. }
  838. ok = true;
  839. }
  840. else
  841. {
  842. ok = false;
  843. }
  844. // delete tmp;
  845. // delete diff;
  846. return ok;
  847. }
  848. // What is the interval (block)? If your sheet looks like this:
  849. // 1 3 5 7 9
  850. // then the interval has the length 1 and the delta list is [2].
  851. // 2 200 3 300 4 400
  852. // Here the interval has length 2 and the delta list is [1,100]
  853. // How big is the interval. It is in the range from [2...n/2].
  854. // The case of an interval of length n is handled below.
  855. //
  856. // We try to find the shortest interval.
  857. for ( unsigned int step = 1; step <= _seqList.count() / 2; step++ )
  858. {
  859. kdDebug() << "Looking for interval: " << step << " seqList count: " << _seqList.count() << endl;
  860. // If the interval is of length 'step' then the _seqList size must
  861. // be a multiple of 'step'
  862. if ( _seqList.count() % step == 0 )
  863. {
  864. // Be optimistic
  865. ok = true;
  866. deltaList.clear();
  867. // Guess the delta by looking at cells 0...2*step-1
  868. //
  869. // Since the interval may be of length 'step' we calculate the delta
  870. // between cells 0 and step, 1 and step+1, ...., step-1 and 2*step-1
  871. for ( unsigned int t = 0; t < step; t++ )
  872. {
  873. deltaList.append( new AutoFillDeltaSequence( _seqList.at(t),
  874. _seqList.at(t+step) ) );
  875. ok = deltaList.getLast()->isOk();
  876. }
  877. /* Verify the delta by looking at cells step..._seqList.count()
  878. We only looked at the cells 0 ... '2*step-1'.
  879. Now test wether the cells from "(tst-1) * step + s" share the same delta
  880. with the cell "tst * step + s" for all test=1..._seqList.count()/step
  881. and for all s=0...step-1.
  882. */
  883. for ( unsigned int tst = 1; ok && ( tst * step < _seqList.count() );
  884. tst++ )
  885. {
  886. for ( unsigned int s = 0; ok && ( s < step ); s++ )
  887. {
  888. if ( !_seqList.at( (tst-1) * step + s )->
  889. matches( _seqList.at( tst * step + s ), deltaList.at( s ) ) )
  890. ok = false;
  891. }
  892. }
  893. // Did we find a valid interval ?
  894. if ( ok )
  895. {
  896. unsigned int s = 0;
  897. // Amount of intervals (blocks)
  898. int block = _seqList.count() / step;
  899. // Start iterating with the first cell
  900. Cell * cell;
  901. if (down)
  902. cell = _destList.first();
  903. else
  904. {
  905. cell = _destList.last();
  906. block -= (_seqList.count() - 1);
  907. }
  908. // Loop over all destination cells
  909. while ( cell )
  910. {
  911. kdDebug() << "Valid interval, cell: " << cell->row() << " block: " << block << endl;
  912. // End of block? -> start again from beginning
  913. if (down)
  914. {
  915. if ( s == step )
  916. {
  917. ++block;
  918. s = 0;
  919. }
  920. }
  921. else
  922. {
  923. if ( s >= step )
  924. {
  925. s = step - 1;
  926. ++block;
  927. }
  928. }
  929. kdDebug() << "Step: " << step << " S: " << s << " Block " << block
  930. << " SeqList: " << _seqList.count()
  931. << " SrcList: " << _srcList.count() << " DeltaList: " << deltaList.count()
  932. << endl;
  933. // Set the value of 'cell' by adding 'block' times the delta tp the
  934. // value of cell 's'.
  935. _seqList.at( s )->fillCell( _srcList.at( s ), cell,
  936. deltaList.at( s ), block, down );
  937. if (down)
  938. {
  939. // Next cell
  940. cell = _destList.next();
  941. ++s;
  942. }
  943. else
  944. {
  945. // Previous cell
  946. cell = _destList.prev();
  947. --s;
  948. }
  949. }
  950. }
  951. }
  952. }
  953. return ok;
  954. }
  955. void Sheet::FillSequenceWithCopy(TQPtrList<Cell>& _srcList,
  956. TQPtrList<Cell>& _destList,
  957. bool down)
  958. {
  959. // We did not find any valid interval. So just copy over the marked
  960. // area.
  961. Cell * cell;
  962. if (down)
  963. cell = _destList.first();
  964. else
  965. cell = _destList.last();
  966. int incr = 1;
  967. unsigned int s = 0;
  968. double factor = 1;
  969. if (!down)
  970. s = _srcList.count() - 1;
  971. if ( _srcList.at( s )->value().isNumber() &&
  972. !(_srcList.at( s )->isDate() || _srcList.at( s )->isTime() ) )
  973. factor = _srcList.at( s )->value().asFloat();
  974. while ( cell )
  975. {
  976. if (down)
  977. {
  978. if ( s == _srcList.count() )
  979. s = 0;
  980. }
  981. else
  982. {
  983. if ( s >= _srcList.count() )
  984. s = _srcList.count() - 1;
  985. }
  986. if ( !_srcList.at( s )->text().isEmpty() )
  987. {
  988. if ( _srcList.at( s )->isFormula() )
  989. {
  990. TQString d = _srcList.at( s )->encodeFormula();
  991. cell->setCellText( cell->decodeFormula( d ) );
  992. }
  993. else if(_srcList.at( s )->value().isNumber() && _srcList.count()==1)
  994. {
  995. double val;
  996. int format_type = _srcList.at( s )->formatType();
  997. if ( format_type == Percentage_format )
  998. {
  999. factor = 0.01; // one percent
  1000. }
  1001. else if ( _srcList.at( s )->isTime() )
  1002. {
  1003. // FIXME this is a workaround to avoid those nasty one minute off
  1004. // "dragging down" time is inaccurate overa large lists!
  1005. // This is the best approximation I could find (raphael)
  1006. if (down)
  1007. {
  1008. // factor = 1.000002/24. + 0.000000001;
  1009. factor = 0.041666751;
  1010. }
  1011. else
  1012. { //when dragging "up" the error must of course be the other way round
  1013. factor = 0.0416665;
  1014. }
  1015. }
  1016. if (!down)
  1017. val = (_srcList.at( s )->value().asFloat() - (incr * factor));
  1018. else
  1019. val = (_srcList.at( s )->value().asFloat() + (incr * factor));
  1020. TQString tmp;
  1021. tmp = tmp.setNum(val);
  1022. cell->setCellText( tmp );
  1023. ++incr;
  1024. }
  1025. else if((AutoFillSequenceItem::month != 0L)
  1026. && AutoFillSequenceItem::month->find( _srcList.at( s )->text()) != 0L
  1027. && AutoFillSequenceItem::month->find( _srcList.at( s )->text()) != AutoFillSequenceItem::month->end()
  1028. && _srcList.count() == 1)
  1029. {
  1030. TQString strMonth=_srcList.at( s )->text();
  1031. int i = AutoFillSequenceItem::month->findIndex( strMonth )+incr;
  1032. int k = (i) % AutoFillSequenceItem::month->count();
  1033. cell->setCellText((*AutoFillSequenceItem::month->at( k )));
  1034. incr++;
  1035. }
  1036. else if(AutoFillSequenceItem::day != 0L
  1037. && AutoFillSequenceItem::day->find( _srcList.at( s )->text()) != 0L
  1038. && AutoFillSequenceItem::day->find( _srcList.at( s )->text())
  1039. != AutoFillSequenceItem::day->end()
  1040. && _srcList.count()==1)
  1041. {
  1042. TQString strDay=_srcList.at( s )->text();
  1043. int i = AutoFillSequenceItem::day->findIndex( strDay )+incr;
  1044. int k = (i) % AutoFillSequenceItem::day->count();
  1045. cell->setCellText((*AutoFillSequenceItem::day->at( k )));
  1046. incr++;
  1047. }
  1048. else
  1049. {
  1050. TQRegExp number("(\\d+)");
  1051. int pos =number.search(_srcList.at( s )->text());
  1052. if( pos!=-1 )
  1053. {
  1054. TQString tmp=number.cap(1);
  1055. int num=tmp.toInt()+incr;
  1056. cell->setCellText(_srcList.at( s )->text().replace(number,TQString::number(num)));
  1057. ++incr;
  1058. }
  1059. else if ( !_srcList.at( s )->link().isEmpty() )
  1060. {
  1061. cell->setCellText( _srcList.at( s )->text() );
  1062. cell->setLink( _srcList.at( s )->link() );
  1063. }
  1064. else
  1065. {
  1066. cell->setCellText( _srcList.at( s )->text() );
  1067. }
  1068. }
  1069. }
  1070. else
  1071. cell->setCellText( "" );
  1072. cell->copyFormat( _srcList.at( s ) );
  1073. if (down)
  1074. {
  1075. cell = _destList.next();
  1076. ++s;
  1077. }
  1078. else
  1079. {
  1080. cell = _destList.prev();
  1081. --s;
  1082. }
  1083. }
  1084. return;
  1085. }