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.

2463 lines
68KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 2005-2006 Inge Wallin <inge@lysator.liu.se>
  3. (C) 2004 Ariya Hidayat <ariya@kde.org>
  4. (C) 2002-2003 Norbert Andres <nandres@web.de>
  5. (C) 2000-2002 Laurent Montel <montel@kde.org>
  6. (C) 2002 John Dailey <dailey@vt.edu>
  7. (C) 2002 Phillip Mueller <philipp.mueller@gmx.de>
  8. (C) 2000 Werner Trobin <trobin@kde.org>
  9. (C) 1999-2000 Simon Hausmann <hausmann@kde.org>
  10. (C) 1999 David Faure <faure@kde.org>
  11. (C) 1998-2000 Torben Weis <weis@kde.org>
  12. This library is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU Library General Public
  14. License as published by the Free Software Foundation; either
  15. version 2 of the License, or (at your option) any later version.
  16. This library is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. Library General Public License for more details.
  20. You should have received a copy of the GNU Library General Public License
  21. along with this library; see the file COPYING.LIB. If not, write to
  22. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  23. * Boston, MA 02110-1301, USA.
  24. */
  25. #include <unistd.h>
  26. #include <assert.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <dirent.h>
  30. #include <pwd.h>
  31. #include <tqapplication.h>
  32. #include <tqfileinfo.h>
  33. #include <tqfont.h>
  34. #include <tqpair.h>
  35. #include <kstandarddirs.h>
  36. #include <kdebug.h>
  37. #include <tdeconfig.h>
  38. #include <tdemessagebox.h>
  39. #include <ksconfig.h>
  40. #include <tdetempfile.h>
  41. #include <KoApplication.h>
  42. #include <KoCommandHistory.h>
  43. #include <KoDocumentInfo.h>
  44. #include <KoDom.h>
  45. #include <KoMainWindow.h>
  46. #include <KoOasisSettings.h>
  47. #include <KoOasisStyles.h>
  48. #include <KoStoreDevice.h>
  49. #include <KoTemplateChooseDia.h>
  50. #include <KoVariable.h>
  51. #include <KoXmlNS.h>
  52. #include <KoXmlWriter.h>
  53. #include "kspread_canvas.h"
  54. #include "kspread_locale.h"
  55. #include "kspread_map.h"
  56. #include "kspread_sheet.h"
  57. #include "kspread_sheetprint.h"
  58. #include "kspread_style_manager.h"
  59. #include "kspread_undo.h"
  60. #include "kspread_util.h"
  61. #include "kspread_view.h"
  62. #include "commands.h"
  63. #include "damages.h"
  64. #include "formula.h"
  65. #include "functions.h"
  66. #include "ksploadinginfo.h"
  67. #include "selection.h"
  68. #include "valuecalc.h"
  69. #include "valueconverter.h"
  70. #include "valueformatter.h"
  71. #include "valueparser.h"
  72. #include "KSpreadDocIface.h"
  73. #include "kspread_doc.h"
  74. using namespace std;
  75. using namespace KSpread;
  76. static const int CURRENT_SYNTAX_VERSION = 1;
  77. // Make sure an appropriate DTD is available in www/koffice/DTD if changing this value
  78. static const char * CURRENT_DTD_VERSION = "1.2";
  79. class Doc::Private
  80. {
  81. public:
  82. Map *map;
  83. TDELocale *locale;
  84. StyleManager *styleManager;
  85. ValueParser *parser;
  86. ValueFormatter *formatter;
  87. ValueConverter *converter;
  88. ValueCalc *calc;
  89. Sheet *activeSheet;
  90. KSPLoadingInfo *m_loadingInfo;
  91. static TQValueList<Doc*> s_docs;
  92. static int s_docId;
  93. DCOPObject* dcop;
  94. // URL of the this part. This variable is only set if the load() function
  95. // had been called with an URL as argument.
  96. TQString fileURL;
  97. // for undo/redo
  98. int undoLocked;
  99. KoCommandHistory* commandHistory;
  100. // true if loading is in process, otherwise false.
  101. // This flag is used to avoid updates etc. during loading.
  102. bool isLoading;
  103. TQColor pageBorderColor;
  104. TQPtrList<Plugin> plugins;
  105. TQValueList<Reference> refs;
  106. TDECompletion listCompletion;
  107. int numOperations;
  108. TQValueList<Damage*> damages;
  109. // document properties
  110. int syntaxVersion;
  111. bool verticalScrollBar:1;
  112. bool horizontalScrollBar:1;
  113. bool columnHeader:1;
  114. bool rowHeader:1;
  115. TQColor gridColor;
  116. double indentValue;
  117. bool showStatusBar:1;
  118. bool showTabBar:1;
  119. bool showFormulaBar:1;
  120. bool showError:1;
  121. TDEGlobalSettings::Completion completionMode;
  122. KSpread::MoveTo moveTo;
  123. MethodOfCalc calcMethod;
  124. bool delayCalculation:1;
  125. KSpellConfig *spellConfig;
  126. bool dontCheckUpperWord:1;
  127. bool dontCheckTitleCase:1;
  128. bool configLoadFromFile:1;
  129. TQStringList spellListIgnoreAll;
  130. /// list of all objects
  131. TQPtrList<EmbeddedObject> m_embeddedObjects;
  132. KoPictureCollection m_pictureCollection;
  133. TQValueList<KoPictureKey> usedPictures;
  134. bool m_savingWholeDocument;
  135. };
  136. /*****************************************************************************
  137. *
  138. * Doc
  139. *
  140. *****************************************************************************/
  141. TQValueList<Doc*> Doc::Private::s_docs;
  142. int Doc::Private::s_docId = 0;
  143. Doc::Doc( TQWidget *parentWidget, const char *widgetName, TQObject* parent, const char* name, bool singleViewMode )
  144. : KoDocument( parentWidget, widgetName, parent, name, singleViewMode )
  145. {
  146. d = new Private;
  147. d->m_loadingInfo = 0L;
  148. d->map = new Map( this, "Map" );
  149. d->locale = new Locale;
  150. d->styleManager = new StyleManager();
  151. d->parser = new ValueParser( d->locale );
  152. d->converter = new ValueConverter ( d->parser );
  153. d->calc = new ValueCalc( d->converter );
  154. d->calc->setDoc (this);
  155. d->formatter = new ValueFormatter( d->converter );
  156. d->activeSheet = 0;
  157. d->pageBorderColor = TQt::red;
  158. d->configLoadFromFile = false;
  159. TQFont f( KoGlobal::defaultFont() );
  160. Format::setGlobalRowHeight( f.pointSizeFloat() + 3 );
  161. Format::setGlobalColWidth( ( f.pointSizeFloat() + 3 ) * 5 );
  162. d->plugins.setAutoDelete( false );
  163. d->delayCalculation = false;
  164. documents().append( this );
  165. setInstance( Factory::global(), false );
  166. setTemplateType( "kspread_template" );
  167. d->dcop = 0;
  168. d->isLoading = false;
  169. d->numOperations = 1; // don't start repainting before the GUI is done...
  170. d->undoLocked = 0;
  171. d->commandHistory = new KoCommandHistory( actionCollection() );
  172. connect( d->commandHistory, TQT_SIGNAL( commandExecuted() ), TQT_SLOT( commandExecuted() ) );
  173. connect( d->commandHistory, TQT_SIGNAL( documentRestored() ), TQT_SLOT( documentRestored() ) );
  174. // Make us scripsheet if the document has a name
  175. // Set a name if there is no name specified
  176. if ( !name )
  177. {
  178. TQString tmp( "Document%1" );
  179. tmp = tmp.arg( d->s_docId++ );
  180. setName( tmp.local8Bit());//tmp.latin1() );
  181. dcopObject();
  182. }
  183. else
  184. dcopObject();
  185. // default document properties
  186. d->syntaxVersion = CURRENT_SYNTAX_VERSION;
  187. d->verticalScrollBar = true;
  188. d->horizontalScrollBar = true;
  189. d->columnHeader = true;
  190. d->rowHeader = true;
  191. d->gridColor = TQt::lightGray;
  192. d->indentValue = 10.0;
  193. d->showStatusBar = true;
  194. d->showFormulaBar = true;
  195. d->showTabBar = true;
  196. d->showError = false;
  197. d->calcMethod = SumOfNumber;
  198. d->moveTo = KSpread::Bottom;
  199. d->completionMode = TDEGlobalSettings::CompletionAuto;
  200. d->spellConfig = 0;
  201. d->dontCheckUpperWord = false;
  202. d->dontCheckTitleCase = false;
  203. }
  204. Doc::~Doc()
  205. {
  206. //don't save config when kword is embedded into konqueror
  207. if(isReadWrite())
  208. saveConfig();
  209. delete d->dcop;
  210. d->s_docs.remove( this );
  211. kdDebug(36001) << "alive 1" << endl;
  212. delete d->commandHistory;
  213. delete d->spellConfig;
  214. delete d->locale;
  215. delete d->map;
  216. delete d->styleManager;
  217. delete d->parser;
  218. delete d->formatter;
  219. delete d->converter;
  220. delete d->calc;
  221. delete d;
  222. }
  223. TQValueList<Doc*> Doc::documents()
  224. {
  225. return Private::s_docs;
  226. }
  227. bool Doc::initDoc(InitDocFlags flags, TQWidget* parentWidget)
  228. {
  229. // ElapsedTime et( " initDoc " );
  230. TQString f;
  231. if (flags==KoDocument::InitDocEmpty)
  232. {
  233. TDEConfig *config = Factory::global()->config();
  234. int _page=1;
  235. if( config->hasGroup("Parameters" ))
  236. {
  237. config->setGroup( "Parameters" );
  238. _page=config->readNumEntry( "NbPage",1 ) ;
  239. }
  240. for( int i=0; i<_page; i++ )
  241. map()->addNewSheet();
  242. resetURL();
  243. setEmpty();
  244. initConfig();
  245. styleManager()->createBuiltinStyles();
  246. return true;
  247. }
  248. KoTemplateChooseDia::ReturnType ret;
  249. KoTemplateChooseDia::DialogType dlgtype;
  250. if (flags != KoDocument::InitDocFileNew )
  251. dlgtype = KoTemplateChooseDia::Everything;
  252. else
  253. dlgtype = KoTemplateChooseDia::OnlyTemplates;
  254. ret = KoTemplateChooseDia::choose( Factory::global(), f,
  255. dlgtype, "kspread_template", parentWidget );
  256. if ( ret == KoTemplateChooseDia::File )
  257. {
  258. KURL url( f );
  259. bool ok=openURL(url);
  260. while (KoDocument::isLoading())
  261. kapp->processEvents();
  262. return ok;
  263. }
  264. if ( ret == KoTemplateChooseDia::Empty )
  265. {
  266. TDEConfig *config = Factory::global()->config();
  267. int _page=1;
  268. if( config->hasGroup("Parameters" ))
  269. {
  270. config->setGroup( "Parameters" );
  271. _page=config->readNumEntry( "NbPage",1 ) ;
  272. }
  273. for( int i=0; i<_page; i++ )
  274. map()->addNewSheet ();
  275. resetURL();
  276. setEmpty();
  277. initConfig();
  278. styleManager()->createBuiltinStyles();
  279. return true;
  280. }
  281. if ( ret == KoTemplateChooseDia::Template )
  282. {
  283. resetURL();
  284. d->m_loadingInfo = new KSPLoadingInfo;
  285. d->m_loadingInfo->setLoadTemplate( true );
  286. bool ok = loadNativeFormat( f );
  287. if ( !ok )
  288. {
  289. showLoadingErrorDialog();
  290. deleteLoadingInfo();
  291. }
  292. setEmpty();
  293. initConfig();
  294. return ok;
  295. }
  296. return false;
  297. }
  298. void Doc::openTemplate (const TQString& file)
  299. {
  300. d->m_loadingInfo = new KSPLoadingInfo;
  301. d->m_loadingInfo->setLoadTemplate( true );
  302. KoDocument::openTemplate( file );
  303. deleteLoadingInfo();
  304. initConfig();
  305. }
  306. void Doc::initEmpty()
  307. {
  308. TDEConfig *config = Factory::global()->config();
  309. int _page=1;
  310. if( config->hasGroup("Parameters" ))
  311. {
  312. config->setGroup( "Parameters" );
  313. _page=config->readNumEntry( "NbPage",1 ) ;
  314. }
  315. for( int i=0; i<_page; i++ )
  316. map()->addNewSheet();
  317. resetURL();
  318. initConfig();
  319. styleManager()->createBuiltinStyles();
  320. KoDocument::initEmpty();
  321. }
  322. TDELocale *Doc::locale () const
  323. {
  324. return d->locale;
  325. }
  326. Map *Doc::map () const
  327. {
  328. return d->map;
  329. }
  330. StyleManager *Doc::styleManager () const
  331. {
  332. return d->styleManager;
  333. }
  334. ValueParser *Doc::parser () const
  335. {
  336. return d->parser;
  337. }
  338. ValueFormatter *Doc::formatter () const
  339. {
  340. return d->formatter;
  341. }
  342. ValueConverter *Doc::converter () const
  343. {
  344. return d->converter;
  345. }
  346. ValueCalc *Doc::calc () const
  347. {
  348. return d->calc;
  349. }
  350. void Doc::saveConfig()
  351. {
  352. if ( isEmbedded() ||!isReadWrite())
  353. return;
  354. TDEConfig *config = Factory::global()->config();
  355. config->setGroup( "Parameters" );
  356. config->writeEntry( "Zoom", m_zoom );
  357. }
  358. void Doc::initConfig()
  359. {
  360. TDEConfig *config = Factory::global()->config();
  361. if( config->hasGroup("KSpread Page Layout" ))
  362. {
  363. config->setGroup( "KSpread Page Layout" );
  364. setUnit( (KoUnit::Unit)config->readNumEntry( "Default unit page" ,0));
  365. }
  366. if( config->hasGroup("Parameters" ))
  367. {
  368. config->setGroup( "Parameters" );
  369. m_zoom = config->readNumEntry( "Zoom", 100 );
  370. }
  371. else
  372. m_zoom = 100;
  373. int undo=30;
  374. if(config->hasGroup("Misc" ) )
  375. {
  376. config->setGroup( "Misc" );
  377. undo=config->readNumEntry("UndoRedo",-1);
  378. }
  379. if(undo!=-1)
  380. setUndoRedoLimit(undo);
  381. setZoomAndResolution( m_zoom, KoGlobal::dpiX(), KoGlobal::dpiY() );
  382. }
  383. int Doc::syntaxVersion() const
  384. {
  385. return d->syntaxVersion;
  386. }
  387. bool Doc::isLoading() const
  388. {
  389. return d->isLoading || KoDocument::isLoading();
  390. }
  391. void Doc::doNotPaint(bool status)
  392. {
  393. d->isLoading = status;
  394. }
  395. TQColor Doc::pageBorderColor() const
  396. {
  397. return d->pageBorderColor;
  398. }
  399. void Doc::changePageBorderColor( const TQColor & _color)
  400. {
  401. d->pageBorderColor = _color;
  402. }
  403. const TQValueList<Reference> &Doc::listArea()
  404. {
  405. return d->refs;
  406. }
  407. TDECompletion& Doc::completion()
  408. {
  409. return d->listCompletion;
  410. }
  411. KoView* Doc::createViewInstance( TQWidget* parent, const char* name )
  412. {
  413. if ( name == 0 )
  414. name = "View";
  415. return new View( parent, name, this );
  416. }
  417. bool Doc::saveChildren( KoStore* _store )
  418. {
  419. return map()->saveChildren( _store );
  420. }
  421. int Doc::supportedSpecialFormats() const
  422. {
  423. return KoDocument::supportedSpecialFormats();
  424. }
  425. bool Doc::completeSaving( KoStore* _store )
  426. {
  427. d->m_pictureCollection.saveToStore( KoPictureCollection::CollectionPicture, _store, d->usedPictures );
  428. return true;
  429. }
  430. TQDomDocument Doc::saveXML()
  431. {
  432. //Terminate current cell edition, if any
  433. TQPtrListIterator<KoView> it( views() );
  434. /* don't pull focus away from the editor if this is just a background
  435. autosave */
  436. if (!isAutosaving())
  437. {
  438. for (; it.current(); ++it )
  439. static_cast<View *>( it.current() )->deleteEditor( true );
  440. }
  441. TQDomDocument doc = createDomDocument( "spreadsheet", CURRENT_DTD_VERSION );
  442. TQDomElement spread = doc.documentElement();
  443. spread.setAttribute( "editor", "KSpread" );
  444. spread.setAttribute( "mime", "application/x-kspread" );
  445. spread.setAttribute( "syntaxVersion", CURRENT_SYNTAX_VERSION );
  446. TQDomElement dlocale = ((Locale *)locale())->save( doc );
  447. spread.appendChild( dlocale );
  448. if (d->refs.count() != 0 )
  449. {
  450. TQDomElement areaname = saveAreaName( doc );
  451. spread.appendChild( areaname );
  452. }
  453. if( !d->spellListIgnoreAll.isEmpty() )
  454. {
  455. TQDomElement spellCheckIgnore = doc.createElement( "SPELLCHECKIGNORELIST" );
  456. spread.appendChild( spellCheckIgnore );
  457. for ( TQStringList::Iterator it = d->spellListIgnoreAll.begin(); it != d->spellListIgnoreAll.end(); ++it )
  458. {
  459. TQDomElement spellElem = doc.createElement( "SPELLCHECKIGNOREWORD" );
  460. spellCheckIgnore.appendChild( spellElem );
  461. spellElem.setAttribute( "word", *it );
  462. }
  463. }
  464. SavedDocParts::const_iterator iter = m_savedDocParts.begin();
  465. SavedDocParts::const_iterator end = m_savedDocParts.end();
  466. while ( iter != end )
  467. {
  468. // save data we loaded in the beginning and which has no owner back to file
  469. spread.appendChild( iter.data() );
  470. ++iter;
  471. }
  472. TQDomElement defaults = doc.createElement( "defaults" );
  473. defaults.setAttribute( "row-height", Format::globalRowHeight() );
  474. defaults.setAttribute( "col-width", Format::globalColWidth() );
  475. spread.appendChild( defaults );
  476. Plugin * plugin = d->plugins.first();
  477. for ( ; plugin != 0; plugin = d->plugins.next() )
  478. {
  479. TQDomElement data( plugin->saveXML( doc ) );
  480. if ( !data.isNull() )
  481. spread.appendChild( data );
  482. }
  483. TQDomElement s = styleManager()->save( doc );
  484. spread.appendChild( s );
  485. TQDomElement e = map()->save( doc );
  486. spread.appendChild( e );
  487. setModified( false );
  488. return doc;
  489. }
  490. bool Doc::loadChildren( KoStore* _store )
  491. {
  492. return map()->loadChildren( _store );
  493. }
  494. bool Doc::saveOasis( KoStore* store, KoXmlWriter* manifestWriter )
  495. {
  496. emitBeginOperation(true);
  497. bool result=saveOasisHelper( store, manifestWriter, SaveAll );
  498. emitEndOperation();
  499. return result;
  500. }
  501. bool Doc::saveOasisHelper( KoStore* store, KoXmlWriter* manifestWriter, SaveFlag saveFlag,
  502. TQString* /*plainText*/, KoPicture* /*picture*/ )
  503. {
  504. d->m_pictureCollection.assignUniqueIds();
  505. //Terminate current cell edition, if any
  506. TQPtrListIterator<KoView> it2( views() );
  507. d->m_savingWholeDocument = saveFlag == SaveAll ? true : false;
  508. /* don't pull focus away from the editor if this is just a background
  509. autosave */
  510. if (!isAutosaving())
  511. {
  512. for (; it2.current(); ++it2 )
  513. static_cast<View *>( it2.current() )->deleteEditor( true );
  514. }
  515. if ( !store->open( "content.xml" ) )
  516. return false;
  517. KoStoreDevice dev( store );
  518. KoXmlWriter* contentWriter = createOasisXmlWriter( &dev, "office:document-content" );
  519. KoGenStyles mainStyles;//for compile
  520. KTempFile contentTmpFile;
  521. //Check that temp file was successfully created
  522. if (contentTmpFile.status() != 0)
  523. {
  524. tqWarning("Creation of temporary file to store document content failed.");
  525. return false;
  526. }
  527. contentTmpFile.setAutoDelete( true );
  528. TQFile* tmpFile = contentTmpFile.file();
  529. KoXmlWriter contentTmpWriter( TQT_TQIODEVICE(tmpFile), 1 );
  530. //todo fixme just add a element for testing saving content.xml
  531. contentTmpWriter.startElement( "office:body" );
  532. contentTmpWriter.startElement( "office:spreadsheet" );
  533. int indexObj = 1;
  534. int partIndexObj = 0;
  535. // Saving the custom cell styles including the default cell style.
  536. styleManager()->saveOasis( mainStyles );
  537. // Saving the default column style
  538. KoGenStyle defaultColumnStyle( Doc::STYLE_COLUMN_USER, "table-column" );
  539. defaultColumnStyle.addPropertyPt( "style:column-width", Format::globalColWidth() );
  540. defaultColumnStyle.setDefaultStyle( true );
  541. mainStyles.lookup( defaultColumnStyle, "Default", KoGenStyles::DontForceNumbering );
  542. // Saving the default row style
  543. KoGenStyle defaultRowStyle( Doc::STYLE_ROW_USER, "table-row" );
  544. defaultRowStyle.addPropertyPt( "style:row-height", Format::globalRowHeight() );
  545. defaultRowStyle.setDefaultStyle( true );
  546. mainStyles.lookup( defaultRowStyle, "Default", KoGenStyles::DontForceNumbering );
  547. // Saving the map.
  548. map()->saveOasis( contentTmpWriter, mainStyles, store, manifestWriter, indexObj, partIndexObj );
  549. saveOasisAreaName( contentTmpWriter );
  550. contentTmpWriter.endElement(); ////office:spreadsheet
  551. contentTmpWriter.endElement(); ////office:body
  552. // Done with writing out the contents to the tempfile, we can now write out the automatic styles
  553. contentWriter->startElement( "office:automatic-styles" );
  554. TQValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_AUTO );
  555. TQValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
  556. for ( ; it != styles.end() ; ++it ) {
  557. (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" );
  558. }
  559. styles = mainStyles.styles( STYLE_PAGE );
  560. it = styles.begin();
  561. for ( ; it != styles.end() ; ++it ) {
  562. (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-properties" );
  563. }
  564. styles = mainStyles.styles( STYLE_COLUMN_AUTO );
  565. it = styles.begin();
  566. for ( ; it != styles.end() ; ++it ) {
  567. (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-column-properties" );
  568. }
  569. styles = mainStyles.styles( STYLE_ROW_AUTO );
  570. it = styles.begin();
  571. for ( ; it != styles.end() ; ++it ) {
  572. (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-row-properties" );
  573. }
  574. styles = mainStyles.styles( STYLE_CELL_AUTO );
  575. it = styles.begin();
  576. for ( ; it != styles.end() ; ++it ) {
  577. (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-cell-properties" );
  578. }
  579. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_NUMBER );
  580. it = styles.begin();
  581. for ( ; it != styles.end() ; ++it ) {
  582. (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ );
  583. }
  584. //TODO FIXME !!!!
  585. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_DATE );
  586. it = styles.begin();
  587. for ( ; it != styles.end() ; ++it ) {
  588. (*it).style->writeStyle( contentWriter, mainStyles, "number:date-style", (*it).name, 0 /*TODO ????*/ );
  589. }
  590. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_TIME );
  591. it = styles.begin();
  592. for ( ; it != styles.end() ; ++it ) {
  593. (*it).style->writeStyle( contentWriter, mainStyles, "number:time-style", (*it).name, 0 /*TODO ????*/ );
  594. }
  595. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_FRACTION );
  596. it = styles.begin();
  597. for ( ; it != styles.end() ; ++it ) {
  598. (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ );
  599. }
  600. //TODO FIME !!!!!
  601. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_PERCENTAGE );
  602. it = styles.begin();
  603. for ( ; it != styles.end() ; ++it ) {
  604. (*it).style->writeStyle( contentWriter, mainStyles, "number:percentage-style", (*it).name, 0 /*TODO ????*/ );
  605. }
  606. //TODO FIME !!!!!
  607. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_CURRENCY );
  608. it = styles.begin();
  609. for ( ; it != styles.end() ; ++it ) {
  610. (*it).style->writeStyle( contentWriter, mainStyles, "number:currency-style", (*it).name, 0 /*TODO ????*/ );
  611. }
  612. styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_SCIENTIFIC );
  613. it = styles.begin();
  614. for ( ; it != styles.end() ; ++it ) {
  615. (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ );
  616. }
  617. contentWriter->endElement(); // office:automatic-styles
  618. // And now we can copy over the contents from the tempfile to the real one
  619. tmpFile->close();
  620. contentWriter->addCompleteElement( TQT_TQIODEVICE(tmpFile) );
  621. contentTmpFile.close();
  622. contentWriter->endElement(); // root element
  623. contentWriter->endDocument();
  624. delete contentWriter;
  625. if ( !store->close() )
  626. return false;
  627. //add manifest line for content.xml
  628. manifestWriter->addManifestEntry( "content.xml", "text/xml" );
  629. //todo add manifest line for style.xml
  630. if ( !store->open( "styles.xml" ) )
  631. return false;
  632. manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
  633. saveOasisDocumentStyles( store, mainStyles );
  634. if ( !store->close() ) // done with styles.xml
  635. return false;
  636. makeUsedPixmapList();
  637. d->m_pictureCollection.saveOasisToStore( store, d->usedPictures, manifestWriter);
  638. if(!store->open("settings.xml"))
  639. return false;
  640. KoXmlWriter* settingsWriter = createOasisXmlWriter(&dev, "office:document-settings");
  641. settingsWriter->startElement("office:settings");
  642. settingsWriter->startElement("config:config-item-set");
  643. settingsWriter->addAttribute("config:name", "view-settings");
  644. KoUnit::saveOasis(settingsWriter, unit());
  645. saveOasisSettings( *settingsWriter );
  646. settingsWriter->endElement(); // config:config-item-set
  647. settingsWriter->startElement("config:config-item-set");
  648. settingsWriter->addAttribute("config:name", "configuration-settings");
  649. settingsWriter->addConfigItem("SpellCheckerIgnoreList", d->spellListIgnoreAll.join( "," ) );
  650. settingsWriter->endElement(); // config:config-item-set
  651. settingsWriter->endElement(); // office:settings
  652. settingsWriter->endElement(); // Root:element
  653. settingsWriter->endDocument();
  654. delete settingsWriter;
  655. if(!store->close())
  656. return false;
  657. manifestWriter->addManifestEntry("settings.xml", "text/xml");
  658. if ( saveFlag == SaveSelected )
  659. {
  660. TQPtrListIterator<EmbeddedObject> it(embeddedObjects() );
  661. for( ; it.current(); ++it )
  662. {
  663. if ( it.current()->getType() != OBJECT_CHART && it.current()->getType() != OBJECT_KOFFICE_PART )
  664. continue;
  665. KoDocumentChild *embedded = dynamic_cast<EmbeddedKOfficeObject *>(it.current() )->embeddedObject();
  666. //NOTE: If an application's .desktop file lies about opendocument support (ie. it indicates that it has
  667. //a native OASIS mime type, when it doesn't, this causes a crash when trying to reload and paint
  668. //the object, since it won't have an associated document.
  669. if ( !embedded->saveOasis( store, manifestWriter ) )
  670. continue;
  671. }
  672. }
  673. setModified( false );
  674. return true;
  675. }
  676. void Doc::loadOasisSettings( const TQDomDocument&settingsDoc )
  677. {
  678. KoOasisSettings settings( settingsDoc );
  679. KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
  680. if ( !viewSettings.isNull() )
  681. {
  682. setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit")));
  683. }
  684. map()->loadOasisSettings( settings );
  685. loadOasisIgnoreList( settings );
  686. }
  687. void Doc::saveOasisSettings( KoXmlWriter &settingsWriter )
  688. {
  689. settingsWriter.startElement("config:config-item-map-indexed");
  690. settingsWriter.addAttribute("config:name", "Views");
  691. settingsWriter.startElement( "config:config-item-map-entry" );
  692. map()->saveOasisSettings( settingsWriter );
  693. settingsWriter.endElement();
  694. settingsWriter.endElement();
  695. }
  696. void Doc::loadOasisIgnoreList( const KoOasisSettings& settings )
  697. {
  698. KoOasisSettings::Items configurationSettings = settings.itemSet( "configuration-settings" );
  699. if ( !configurationSettings.isNull() )
  700. {
  701. const TQString ignorelist = configurationSettings.parseConfigItemString( "SpellCheckerIgnoreList" );
  702. //kdDebug()<<" ignorelist :"<<ignorelist<<endl;
  703. d->spellListIgnoreAll = TQStringList::split( ',', ignorelist );
  704. }
  705. }
  706. void Doc::saveOasisDocumentStyles( KoStore* store, KoGenStyles& mainStyles ) const
  707. {
  708. KoStoreDevice stylesDev( store );
  709. KoXmlWriter* stylesWriter = createOasisXmlWriter( &stylesDev, "office:document-styles" );
  710. stylesWriter->startElement( "office:styles" );
  711. TQValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_USER );
  712. TQValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
  713. for ( ; it != styles.end() ; ++it ) {
  714. (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" );
  715. }
  716. // Writing out the common column styles.
  717. styles = mainStyles.styles( Doc::STYLE_COLUMN_USER );
  718. it = styles.begin();
  719. for ( ; it != styles.end() ; ++it ) {
  720. if ( (*it).style->isDefaultStyle() ) {
  721. (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-column-properties" );
  722. }
  723. else {
  724. (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-column-properties" );
  725. }
  726. }
  727. // Writing out the row column styles.
  728. styles = mainStyles.styles( Doc::STYLE_ROW_USER );
  729. it = styles.begin();
  730. for ( ; it != styles.end() ; ++it ) {
  731. if ( (*it).style->isDefaultStyle() ) {
  732. (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-row-properties" );
  733. }
  734. else {
  735. (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-row-properties" );
  736. }
  737. }
  738. // Writing out the common cell styles.
  739. styles = mainStyles.styles( Doc::STYLE_CELL_USER );
  740. it = styles.begin();
  741. for ( ; it != styles.end() ; ++it ) {
  742. if ( (*it).style->isDefaultStyle() ) {
  743. (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-cell-properties" );
  744. }
  745. else {
  746. (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-cell-properties" );
  747. }
  748. }
  749. styles = mainStyles.styles( KoGenStyle::STYLE_HATCH );
  750. it = styles.begin();
  751. for ( ; it != styles.end() ; ++it ) {
  752. (*it).style->writeStyle( stylesWriter, mainStyles, "draw:hatch", (*it).name, "style:graphic-properties" , true, true /*add draw:name*/);
  753. }
  754. styles = mainStyles.styles( KoGenStyle::STYLE_GRAPHICAUTO );
  755. it = styles.begin();
  756. for ( ; it != styles.end() ; ++it ) {
  757. (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties" );
  758. }
  759. stylesWriter->endElement(); // office:styles
  760. stylesWriter->startElement( "office:automatic-styles" );
  761. styles = mainStyles.styles( KoGenStyle::STYLE_PAGELAYOUT );
  762. it = styles.begin();
  763. for ( ; it != styles.end() ; ++it ) {
  764. (*it).style->writeStyle( stylesWriter, mainStyles, "style:page-layout", (*it).name, "style:page-layout-properties", false /*don't close*/ );
  765. stylesWriter->endElement();
  766. }
  767. stylesWriter->endElement(); // office:automatic-styles
  768. //code from kword
  769. stylesWriter->startElement( "office:master-styles" );
  770. styles = mainStyles.styles( Doc::STYLE_PAGEMASTER );
  771. it = styles.begin();
  772. for ( ; it != styles.end() ; ++it ) {
  773. (*it).style->writeStyle( stylesWriter, mainStyles, "style:master-page", (*it).name, "" );
  774. }
  775. stylesWriter->endElement(); // office:master-style
  776. stylesWriter->endElement(); // root element (office:document-styles)
  777. stylesWriter->endDocument();
  778. delete stylesWriter;;
  779. }
  780. bool Doc::loadOasis( const TQDomDocument& doc, KoOasisStyles& oasisStyles, const TQDomDocument& settings, KoStore* store)
  781. {
  782. if ( !d->m_loadingInfo )
  783. d->m_loadingInfo = new KSPLoadingInfo;
  784. TQTime dt;
  785. dt.start();
  786. emit sigProgress( 0 );
  787. d->isLoading = true;
  788. d->spellListIgnoreAll.clear();
  789. d->refs.clear();
  790. TQDomElement content = doc.documentElement();
  791. TQDomElement realBody ( KoDom::namedItemNS( content, KoXmlNS::office, "body" ) );
  792. if ( realBody.isNull() )
  793. {
  794. setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No office:body tag found." ));
  795. deleteLoadingInfo();
  796. return false;
  797. }
  798. TQDomElement body = KoDom::namedItemNS( realBody, KoXmlNS::office, "spreadsheet" );
  799. if ( body.isNull() )
  800. {
  801. kdError(32001) << "No office:spreadsheet found!" << endl;
  802. TQDomElement childElem;
  803. TQString localName;
  804. forEachElement( childElem, realBody ) {
  805. localName = childElem.localName();
  806. }
  807. if ( localName.isEmpty() )
  808. setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No tag found inside office:body." ) );
  809. else
  810. setErrorMessage( i18n( "This document is not a spreadsheet, but %1. Please try opening it with the appropriate application." ).arg( KoDocument::tagNameToDocumentType( localName ) ) );
  811. deleteLoadingInfo();
  812. return false;
  813. }
  814. KoOasisLoadingContext context( this, oasisStyles, store );
  815. //load in first
  816. styleManager()->loadOasisStyleTemplate( oasisStyles );
  817. // load default column style
  818. const TQDomElement* defaultColumnStyle = oasisStyles.defaultStyle( "table-column" );
  819. if ( defaultColumnStyle )
  820. {
  821. // kDebug() << "style:default-style style:family=\"table-column\"" << endl;
  822. KoStyleStack styleStack;
  823. styleStack.push( *defaultColumnStyle );
  824. styleStack.setTypeProperties( "table-column" );
  825. if ( styleStack.hasAttributeNS( KoXmlNS::style, "column-width" ) )
  826. {
  827. const double width = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "column-width" ), -1.0 );
  828. if ( width != -1.0 )
  829. {
  830. // kDebug() << "\tstyle:column-width: " << width << endl;
  831. Format::setGlobalColWidth( width );
  832. }
  833. }
  834. }
  835. // load default row style
  836. const TQDomElement* defaultRowStyle = oasisStyles.defaultStyle( "table-row" );
  837. if ( defaultRowStyle )
  838. {
  839. // kDebug() << "style:default-style style:family=\"table-row\"" << endl;
  840. KoStyleStack styleStack;
  841. styleStack.push( *defaultRowStyle );
  842. styleStack.setTypeProperties( "table-row" );
  843. if ( styleStack.hasAttributeNS( KoXmlNS::style, "row-height" ) )
  844. {
  845. const double height = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "row-height" ), -1.0 );
  846. if ( height != -1.0 )
  847. {
  848. // kDebug() << "\tstyle:row-height: " << height << endl;
  849. Format::setGlobalRowHeight( height );
  850. }
  851. }
  852. }
  853. // TODO check versions and mimetypes etc.
  854. loadOasisAreaName( body );
  855. loadOasisCellValidation( body );
  856. // all <sheet:sheet> goes to workbook
  857. if ( !map()->loadOasis( body, context ) )
  858. {
  859. d->isLoading = false;
  860. deleteLoadingInfo();
  861. return false;
  862. }
  863. if ( !settings.isNull() )
  864. {
  865. loadOasisSettings( settings );
  866. }
  867. emit sigProgress( 90 );
  868. initConfig();
  869. emit sigProgress(-1);
  870. //display loading time
  871. kdDebug(36001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl;
  872. return true;
  873. }
  874. bool Doc::loadXML( TQIODevice *, const TQDomDocument& doc )
  875. {
  876. TQTime dt;
  877. dt.start();
  878. emit sigProgress( 0 );
  879. d->isLoading = true;
  880. d->spellListIgnoreAll.clear();
  881. // <spreadsheet>
  882. TQDomElement spread = doc.documentElement();
  883. if ( spread.attribute( "mime" ) != "application/x-kspread" && spread.attribute( "mime" ) != "application/vnd.kde.kspread" )
  884. {
  885. d->isLoading = false;
  886. setErrorMessage( i18n( "Invalid document. Expected mimetype application/x-kspread or application/vnd.kde.kspread, got %1" ).arg( spread.attribute("mime") ) );
  887. return false;
  888. }
  889. d->syntaxVersion = Doc::getAttribute( spread, "syntaxVersion", 0 );
  890. if ( d->syntaxVersion > CURRENT_SYNTAX_VERSION )
  891. {
  892. int ret = KMessageBox::warningContinueCancel(
  893. 0, i18n("This document was created with a newer version of KSpread (syntax version: %1)\n"
  894. "When you open it with this version of KSpread, some information may be lost.").arg(d->syntaxVersion),
  895. i18n("File Format Mismatch"), KStdGuiItem::cont() );
  896. if ( ret == KMessageBox::Cancel )
  897. {
  898. setErrorMessage( "USER_CANCELED" );
  899. return false;
  900. }
  901. }
  902. // <locale>
  903. TQDomElement loc = spread.namedItem( "locale" ).toElement();
  904. if ( !loc.isNull() )
  905. ((Locale *) locale())->load( loc );
  906. emit sigProgress( 5 );
  907. TQDomElement defaults = spread.namedItem( "defaults" ).toElement();
  908. if ( !defaults.isNull() )
  909. {
  910. bool ok = false;
  911. double d = defaults.attribute( "row-height" ).toDouble( &ok );
  912. if ( !ok )
  913. return false;
  914. Format::setGlobalRowHeight( d );
  915. d = defaults.attribute( "col-width" ).toDouble( &ok );
  916. if ( !ok )
  917. return false;
  918. Format::setGlobalColWidth( d );
  919. }
  920. d->refs.clear();
  921. //<areaname >
  922. TQDomElement areaname = spread.namedItem( "areaname" ).toElement();
  923. if ( !areaname.isNull())
  924. loadAreaName(areaname);
  925. TQDomElement ignoreAll = spread.namedItem( "SPELLCHECKIGNORELIST").toElement();
  926. if ( !ignoreAll.isNull())
  927. {
  928. TQDomElement spellWord=spread.namedItem("SPELLCHECKIGNORELIST").toElement();
  929. spellWord=spellWord.firstChild().toElement();
  930. while ( !spellWord.isNull() )
  931. {
  932. if ( spellWord.tagName()=="SPELLCHECKIGNOREWORD" )
  933. {
  934. d->spellListIgnoreAll.append(spellWord.attribute("word"));
  935. }
  936. spellWord=spellWord.nextSibling().toElement();
  937. }
  938. }
  939. emit sigProgress( 40 );
  940. // In case of reload (e.g. from konqueror)
  941. map()->sheetList().clear(); // it's set to autoDelete
  942. TQDomElement styles = spread.namedItem( "styles" ).toElement();
  943. if ( !styles.isNull() )
  944. {
  945. if ( !styleManager()->loadXML( styles ) )
  946. {
  947. setErrorMessage( i18n( "Styles cannot be loaded." ) );
  948. d->isLoading = false;
  949. return false;
  950. }
  951. }
  952. // <map>
  953. TQDomElement mymap = spread.namedItem( "map" ).toElement();
  954. if ( mymap.isNull() )
  955. {
  956. setErrorMessage( i18n("Invalid document. No map tag.") );
  957. d->isLoading = false;
  958. return false;
  959. }
  960. if ( !map()->loadXML( mymap ) )
  961. {
  962. d->isLoading = false;
  963. return false;
  964. }
  965. //Backwards compatibility with older versions for paper layout
  966. if ( d->syntaxVersion < 1 )
  967. {
  968. TQDomElement paper = spread.namedItem( "paper" ).toElement();
  969. if ( !paper.isNull() )
  970. {
  971. loadPaper( paper );
  972. }
  973. }
  974. emit sigProgress( 85 );
  975. TQDomElement element( spread.firstChild().toElement() );
  976. while ( !element.isNull() )
  977. {
  978. TQString tagName( element.tagName() );
  979. if ( tagName != "locale" && tagName != "map" && tagName != "styles"
  980. && tagName != "SPELLCHECKIGNORELIST" && tagName != "areaname"
  981. && tagName != "paper" )
  982. {
  983. // belongs to a plugin, load it and save it for later use
  984. m_savedDocParts[ tagName ] = element;
  985. }
  986. element = element.nextSibling().toElement();
  987. }
  988. emit sigProgress( 90 );
  989. initConfig();
  990. emit sigProgress(-1);
  991. kdDebug(36001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl;
  992. emit sig_refreshView();
  993. return true;
  994. }
  995. void Doc::loadPaper( TQDomElement const & paper )
  996. {
  997. // <paper>
  998. TQString format = paper.attribute( "format" );
  999. TQString orientation = paper.attribute( "orientation" );
  1000. // <borders>
  1001. TQDomElement borders = paper.namedItem( "borders" ).toElement();
  1002. if ( !borders.isNull() )
  1003. {
  1004. float left = borders.attribute( "left" ).toFloat();
  1005. float right = borders.attribute( "right" ).toFloat();
  1006. float top = borders.attribute( "top" ).toFloat();
  1007. float bottom = borders.attribute( "bottom" ).toFloat();
  1008. //apply to all sheet
  1009. TQPtrListIterator<Sheet> it ( map()->sheetList() );
  1010. for( ; it.current(); ++it )
  1011. {
  1012. it.current()->print()->setPaperLayout( left, top, right, bottom,
  1013. format, orientation );
  1014. }
  1015. }
  1016. TQString hleft, hright, hcenter;
  1017. TQString fleft, fright, fcenter;
  1018. // <head>
  1019. TQDomElement head = paper.namedItem( "head" ).toElement();
  1020. if ( !head.isNull() )
  1021. {
  1022. TQDomElement left = head.namedItem( "left" ).toElement();
  1023. if ( !left.isNull() )
  1024. hleft = left.text();
  1025. TQDomElement center = head.namedItem( "center" ).toElement();
  1026. if ( !center.isNull() )
  1027. hcenter = center.text();
  1028. TQDomElement right = head.namedItem( "right" ).toElement();
  1029. if ( !right.isNull() )
  1030. hright = right.text();
  1031. }
  1032. // <foot>
  1033. TQDomElement foot = paper.namedItem( "foot" ).toElement();
  1034. if ( !foot.isNull() )
  1035. {
  1036. TQDomElement left = foot.namedItem( "left" ).toElement();
  1037. if ( !left.isNull() )
  1038. fleft = left.text();
  1039. TQDomElement center = foot.namedItem( "center" ).toElement();
  1040. if ( !center.isNull() )
  1041. fcenter = center.text();
  1042. TQDomElement right = foot.namedItem( "right" ).toElement();
  1043. if ( !right.isNull() )
  1044. fright = right.text();
  1045. }
  1046. //The macro "<sheet>" formerly was typed as "<table>"
  1047. hleft = hleft.replace( "<table>", "<sheet>" );
  1048. hcenter = hcenter.replace( "<table>", "<sheet>" );
  1049. hright = hright.replace( "<table>", "<sheet>" );
  1050. fleft = fleft.replace( "<table>", "<sheet>" );
  1051. fcenter = fcenter.replace( "<table>", "<sheet>" );
  1052. fright = fright.replace( "<table>", "<sheet>" );
  1053. TQPtrListIterator<Sheet> it ( map()->sheetList() );
  1054. for( ; it.current(); ++it )
  1055. {
  1056. it.current()->print()->setHeadFootLine( hleft, hcenter, hright,
  1057. fleft, fcenter, fright);
  1058. }
  1059. }
  1060. bool Doc::completeLoading( KoStore* /* _store */ )
  1061. {
  1062. kdDebug(36001) << "------------------------ COMPLETING --------------------" << endl;
  1063. d->isLoading = false;
  1064. // map()->update();
  1065. TQPtrListIterator<KoView> it( views() );
  1066. for (; it.current(); ++it )
  1067. ((View*)it.current())->initialPosition();
  1068. kdDebug(36001) << "------------------------ COMPLETION DONE --------------------" << endl;
  1069. setModified( false );
  1070. return true;
  1071. }
  1072. void Doc::registerPlugin( Plugin * plugin )
  1073. {
  1074. d->plugins.append( plugin );
  1075. }
  1076. void Doc::deregisterPlugin( Plugin * plugin )
  1077. {
  1078. d->plugins.remove( plugin );
  1079. }
  1080. bool Doc::docData( TQString const & xmlTag, TQDomElement & data )
  1081. {
  1082. SavedDocParts::iterator iter = m_savedDocParts.find( xmlTag );
  1083. if ( iter == m_savedDocParts.end() )
  1084. return false;
  1085. data = iter.data();
  1086. m_savedDocParts.erase( iter );
  1087. return true;
  1088. }
  1089. void Doc::setShowVerticalScrollBar(bool _show)
  1090. {
  1091. d->verticalScrollBar=_show;
  1092. }
  1093. bool Doc::showVerticalScrollBar()const
  1094. {
  1095. return d->verticalScrollBar;
  1096. }
  1097. void Doc::setShowHorizontalScrollBar(bool _show)
  1098. {
  1099. d->horizontalScrollBar=_show;
  1100. }
  1101. bool Doc::showHorizontalScrollBar()const
  1102. {
  1103. return d->horizontalScrollBar;
  1104. }
  1105. TDEGlobalSettings::Completion Doc::completionMode( ) const
  1106. {
  1107. return d->completionMode;
  1108. }
  1109. void Doc::setShowColumnHeader(bool _show)
  1110. {
  1111. d->columnHeader=_show;
  1112. }
  1113. bool Doc::showColumnHeader() const
  1114. {
  1115. return d->columnHeader;
  1116. }
  1117. void Doc::setShowRowHeader(bool _show)
  1118. {
  1119. d->rowHeader=_show;
  1120. }
  1121. bool Doc::showRowHeader() const
  1122. {
  1123. return d->rowHeader;
  1124. }
  1125. void Doc::setGridColor( const TQColor& color )
  1126. {
  1127. d->gridColor = color;
  1128. }
  1129. TQColor Doc::gridColor() const
  1130. {
  1131. return d->gridColor;
  1132. }
  1133. void Doc::setCompletionMode( TDEGlobalSettings::Completion complMode)
  1134. {
  1135. d->completionMode= complMode;
  1136. }
  1137. double Doc::indentValue() const
  1138. {
  1139. return d->indentValue;
  1140. }
  1141. void Doc::setIndentValue( double val )
  1142. {
  1143. d->indentValue = val;
  1144. }
  1145. void Doc::setShowStatusBar(bool _statusBar)
  1146. {
  1147. d->showStatusBar=_statusBar;
  1148. }
  1149. bool Doc::showStatusBar() const
  1150. {
  1151. return d->showStatusBar;
  1152. }
  1153. void Doc::setShowTabBar(bool _tabbar)
  1154. {
  1155. d->showTabBar=_tabbar;
  1156. }
  1157. bool Doc::showTabBar()const
  1158. {
  1159. return d->showTabBar;
  1160. }
  1161. void Doc::setShowFormulaBar(bool _formulaBar)
  1162. {
  1163. d->showFormulaBar=_formulaBar;
  1164. }
  1165. bool Doc::showFormulaBar() const
  1166. {
  1167. return d->showFormulaBar;
  1168. }
  1169. void Doc::setShowMessageError(bool _show)
  1170. {
  1171. d->showError=_show;
  1172. }
  1173. bool Doc::showMessageError() const
  1174. {
  1175. return d->showError;
  1176. }
  1177. KSpread::MoveTo Doc::getMoveToValue() const
  1178. {
  1179. return d->moveTo;
  1180. }
  1181. void Doc::setMoveToValue(KSpread::MoveTo _moveTo)
  1182. {
  1183. d->moveTo = _moveTo;
  1184. }
  1185. void Doc::setTypeOfCalc( MethodOfCalc _calc)
  1186. {
  1187. d->calcMethod=_calc;
  1188. }
  1189. MethodOfCalc Doc::getTypeOfCalc() const
  1190. {
  1191. return d->calcMethod;
  1192. }
  1193. void Doc::setKSpellConfig(KSpellConfig _tdespell)
  1194. {
  1195. if (d->spellConfig == 0 )
  1196. d->spellConfig = new KSpellConfig();
  1197. d->spellConfig->setNoRootAffix(_tdespell.noRootAffix ());
  1198. d->spellConfig->setRunTogether(_tdespell.runTogether ());
  1199. d->spellConfig->setDictionary(_tdespell.dictionary ());
  1200. d->spellConfig->setDictFromList(_tdespell.dictFromList());
  1201. d->spellConfig->setEncoding(_tdespell.encoding());
  1202. d->spellConfig->setClient(_tdespell.client());
  1203. }
  1204. KSpellConfig * Doc::getKSpellConfig()
  1205. {
  1206. if (!d->spellConfig)
  1207. {
  1208. KSpellConfig ksconfig;
  1209. TDEConfig *config = Factory::global()->config();
  1210. if( config->hasGroup("KSpell kspread" ) )
  1211. {
  1212. config->setGroup( "KSpell kspread" );
  1213. ksconfig.setNoRootAffix(config->readNumEntry ("KSpell_NoRootAffix", 0));
  1214. ksconfig.setRunTogether(config->readNumEntry ("KSpell_RunTogether", 0));
  1215. ksconfig.setDictionary(config->readEntry ("KSpell_Dictionary", ""));
  1216. ksconfig.setDictFromList(config->readNumEntry ("KSpell_DictFromList", false));
  1217. ksconfig.setEncoding(config->readNumEntry ("KSpell_Encoding", KS_E_ASCII));
  1218. ksconfig.setClient(config->readNumEntry ("KSpell_Client", KS_CLIENT_ISPELL));
  1219. setKSpellConfig(ksconfig);
  1220. setDontCheckUpperWord(config->readBoolEntry("KSpell_IgnoreUppercaseWords", false));
  1221. setDontCheckTitleCase(config->readBoolEntry("KSpell_IgnoreTitleCaseWords", false));
  1222. }
  1223. }
  1224. return d->spellConfig;
  1225. }
  1226. bool Doc::dontCheckUpperWord() const
  1227. {
  1228. return d->dontCheckUpperWord;
  1229. }
  1230. void Doc::setDontCheckUpperWord( bool b )
  1231. {
  1232. d->dontCheckUpperWord = b;
  1233. }
  1234. bool Doc::dontCheckTitleCase() const
  1235. {
  1236. return d->dontCheckTitleCase;
  1237. }
  1238. void Doc::setDontCheckTitleCase( bool b )
  1239. {
  1240. d->dontCheckTitleCase = b;
  1241. }
  1242. TQString Doc::unitName() const
  1243. {
  1244. return KoUnit::unitName( unit() );
  1245. }
  1246. void Doc::increaseNumOperation()
  1247. {
  1248. ++d->numOperations;
  1249. }
  1250. void Doc::decreaseNumOperation()
  1251. {
  1252. --d->numOperations;
  1253. }
  1254. void Doc::addIgnoreWordAllList( const TQStringList & _lst)
  1255. {
  1256. d->spellListIgnoreAll = _lst;
  1257. }
  1258. TQStringList Doc::spellListIgnoreAll() const
  1259. {
  1260. return d->spellListIgnoreAll;
  1261. }
  1262. void Doc::setZoomAndResolution( int zoom, int dpiX, int dpiY )
  1263. {
  1264. KoZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY );
  1265. }
  1266. void Doc::newZoomAndResolution( bool updateViews, bool /*forPrint*/ )
  1267. {
  1268. /* layout();
  1269. updateAllFrames();*/
  1270. if ( updateViews )
  1271. {
  1272. emit sig_refreshView();
  1273. }
  1274. }
  1275. void Doc::addCommand( KCommand* command )
  1276. {
  1277. if (undoLocked()) return;
  1278. d->commandHistory->addCommand( command, false );
  1279. setModified( true );
  1280. }
  1281. void Doc::addCommand( UndoAction* undo )
  1282. {
  1283. if (undoLocked()) return;
  1284. UndoWrapperCommand* command = new UndoWrapperCommand( undo );
  1285. addCommand( command );
  1286. setModified( true );
  1287. }
  1288. void Doc::undo()
  1289. {
  1290. undoLock ();
  1291. d->commandHistory->undo();
  1292. undoUnlock ();
  1293. }
  1294. void Doc::redo()
  1295. {
  1296. undoLock ();
  1297. d->commandHistory->redo();
  1298. undoUnlock ();
  1299. }
  1300. void Doc::commandExecuted()
  1301. {
  1302. setModified( true );
  1303. }
  1304. void Doc::documentRestored()
  1305. {
  1306. setModified( false );
  1307. }
  1308. void Doc::undoLock()
  1309. {
  1310. d->undoLocked++;
  1311. }
  1312. void Doc::undoUnlock()
  1313. {
  1314. d->undoLocked--;
  1315. }
  1316. bool Doc::undoLocked() const
  1317. {
  1318. return (d->undoLocked > 0);
  1319. }
  1320. KoCommandHistory* Doc::commandHistory()
  1321. {
  1322. return d->commandHistory;
  1323. }
  1324. void Doc::enableUndo( bool _b )
  1325. {
  1326. TQPtrListIterator<KoView> it( views() );
  1327. for (; it.current(); ++it )
  1328. static_cast<View *>( it.current() )->enableUndo( _b );
  1329. }
  1330. void Doc::enableRedo( bool _b )
  1331. {
  1332. TQPtrListIterator<KoView> it( views() );
  1333. for (; it.current(); ++it )
  1334. static_cast<View *>( it.current() )->enableRedo( _b );
  1335. }
  1336. void Doc::paintContent( TQPainter& painter, const TQRect& rect,
  1337. bool transparent, double zoomX, double /*zoomY*/ )
  1338. {
  1339. kdDebug(36001) << "paintContent() called on " << rect << endl;
  1340. // ElapsedTime et( "Doc::paintContent1" );
  1341. //kdDebug(36001) << "Doc::paintContent m_zoom=" << m_zoom << " zoomX=" << zoomX << " zoomY=" << zoomY << " transparent=" << transparent << endl;
  1342. // save current zoom
  1343. int oldZoom = m_zoom;
  1344. // choose sheet: the first or the active
  1345. Sheet* sheet = 0L;
  1346. if ( !d->activeSheet )
  1347. sheet = map()->firstSheet();
  1348. else
  1349. sheet = d->activeSheet;
  1350. if ( !sheet )
  1351. return;
  1352. // only one zoom is supported
  1353. double d_zoom = 1.0;
  1354. setZoomAndResolution( 100, KoGlobal::dpiX(), KoGlobal::dpiY() );
  1355. if ( m_zoomedResolutionX != zoomX )
  1356. d_zoom *= ( zoomX / m_zoomedResolutionX );
  1357. // KSpread support zoom, therefore no need to scale with worldMatrix
  1358. TQWMatrix matrix = painter.worldMatrix();
  1359. matrix.setMatrix( 1, 0, 0, 1, matrix.dx(), matrix.dy() );
  1360. TQRect prect = rect;
  1361. prect.setWidth( (int) (prect.width() * painter.worldMatrix().m11()) );
  1362. prect.setHeight( (int) (prect.height() * painter.worldMatrix().m22()) );
  1363. setZoomAndResolution( (int) ( d_zoom * 100 ), KoGlobal::dpiX(), KoGlobal::dpiY() );
  1364. // paint the content, now zoom is correctly set
  1365. kdDebug(36001)<<"paintContent-------------------------------------\n";
  1366. painter.save();
  1367. painter.setWorldMatrix( matrix );
  1368. paintContent( painter, prect, transparent, sheet, false );
  1369. painter.restore();
  1370. // restore zoom
  1371. m_zoom = oldZoom;
  1372. setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() );
  1373. }
  1374. void Doc::paintContent( TQPainter& painter, const TQRect& rect, bool /*transparent*/, Sheet* sheet, bool drawCursor )
  1375. {
  1376. if ( isLoading() )
  1377. return;
  1378. // ElapsedTime et( "Doc::paintContent2" );
  1379. // if ( !transparent )
  1380. // painter.eraseRect( rect );
  1381. double xpos;
  1382. double ypos;
  1383. int left_col = sheet->leftColumn( unzoomItX( rect.x() ), xpos );
  1384. int right_col = sheet->rightColumn( unzoomItX( rect.right() ) );
  1385. int top_row = sheet->topRow( unzoomItY( rect.y() ), ypos );
  1386. int bottom_row = sheet->bottomRow( unzoomItY( rect.bottom() ) );
  1387. TQPen pen;
  1388. pen.setWidth( 1 );
  1389. painter.setPen( pen );
  1390. /* Update the entire visible area. */
  1391. TQValueList<TQRect> cellAreaList;
  1392. cellAreaList.append( TQRect( left_col,
  1393. top_row,
  1394. right_col - left_col + 1,
  1395. bottom_row - top_row + 1) );
  1396. paintCellRegions(painter, rect, NULL, cellAreaList, sheet, drawCursor);
  1397. }
  1398. void Doc::paintUpdates()
  1399. {
  1400. // ElapsedTime et( "Doc::paintUpdates" );
  1401. TQPtrListIterator<KoView> it( views() );
  1402. View * view = NULL;
  1403. Sheet * sheet = NULL;
  1404. for (; it.current(); ++it )
  1405. {
  1406. view = static_cast<View *>( it.current() );
  1407. view->paintUpdates();
  1408. }
  1409. for (sheet = map()->firstSheet(); sheet != NULL;
  1410. sheet = map()->nextSheet())
  1411. {
  1412. sheet->clearPaintDirtyData();
  1413. }
  1414. }
  1415. void Doc::paintCellRegions(TQPainter& painter, const TQRect &viewRect,
  1416. View* view,
  1417. TQValueList<TQRect> cellRegions,
  1418. const Sheet* sheet, bool /*drawCursor*/)
  1419. {
  1420. //
  1421. // Clip away children
  1422. //
  1423. TQRegion rgn = painter.clipRegion();
  1424. if ( rgn.isEmpty() )
  1425. rgn = TQRegion( TQRect( 0, 0, viewRect.width(), viewRect.height() ) );
  1426. TQWMatrix matrix;
  1427. if ( view ) {
  1428. matrix.scale( zoomedResolutionX(),
  1429. zoomedResolutionY() );
  1430. matrix.translate( - view->canvasWidget()->xOffset(),
  1431. - view->canvasWidget()->yOffset() );
  1432. }
  1433. else {
  1434. matrix = painter.worldMatrix();
  1435. }
  1436. // TQPtrListIterator<KoDocumentChild> it( children() );
  1437. // for( ; it.current(); ++it ) {
  1438. // // if ( ((Child*)it.current())->sheet() == sheet &&
  1439. // // !m_pView->hasDocumentInWindow( it.current()->document() ) )
  1440. // if ( ((Child*)it.current())->sheet() == sheet)
  1441. // rgn -= it.current()->region( matrix );
  1442. // }
  1443. painter.setClipRegion( rgn );
  1444. TQPen pen;
  1445. pen.setWidth( 1 );
  1446. painter.setPen( pen );
  1447. TQRect cellRegion;
  1448. KoRect unzoomedViewRect = unzoomRect( viewRect );
  1449. for (unsigned int i=0; i < cellRegions.size(); i++) {
  1450. cellRegion = cellRegions[i];
  1451. PaintRegion(painter, unzoomedViewRect, view, cellRegion, sheet);
  1452. }
  1453. }
  1454. void Doc::PaintRegion(TQPainter &painter, const KoRect &viewRegion,
  1455. View* view, const TQRect &paintRegion,
  1456. const Sheet* sheet)
  1457. {
  1458. // Paint region has cell coordinates (col,row) while viewRegion has
  1459. // world coordinates. paintRegion is the cells to update and
  1460. // viewRegion is the area actually onscreen.
  1461. if ( paintRegion.left() <= 0 || paintRegion.top() <= 0 )
  1462. return;
  1463. // Get the world coordinates of the upper left corner of the
  1464. // paintRegion The view is NULL, when paintRegion is called from
  1465. // paintContent, which itself is only called, when we should paint
  1466. // the output for INACTIVE embedded view. If inactive embedded,
  1467. // then there is no view and we alwas start at top/left, so the
  1468. // offset is 0.
  1469. //
  1470. KoPoint dblCorner;
  1471. if ( view == 0L ) //Most propably we are embedded and inactive, so no offset
  1472. dblCorner = KoPoint( sheet->dblColumnPos( paintRegion.left() ),
  1473. sheet->dblRowPos( paintRegion.top() ) );
  1474. else
  1475. dblCorner = KoPoint( sheet->dblColumnPos( paintRegion.left() )
  1476. - view->canvasWidget()->xOffset(),
  1477. sheet->dblRowPos( paintRegion.top() )
  1478. - view->canvasWidget()->yOffset() );
  1479. KoPoint dblCurrentCellPos( dblCorner );
  1480. int regionBottom = paintRegion.bottom();
  1481. int regionRight = paintRegion.right();
  1482. int regionLeft = paintRegion.left();
  1483. int regionTop = paintRegion.top();
  1484. TQValueList<TQPoint> mergedCellsPainted;
  1485. for ( int y = regionTop;
  1486. y <= regionBottom && dblCurrentCellPos.y() <= viewRegion.bottom();
  1487. ++y )
  1488. {
  1489. const RowFormat * row_lay = sheet->rowFormat( y );
  1490. dblCurrentCellPos.setX( dblCorner.x() );
  1491. for ( int x = regionLeft;
  1492. x <= regionRight && dblCurrentCellPos.x() <= viewRegion.right();
  1493. ++x )
  1494. {
  1495. const ColumnFormat *col_lay = sheet->columnFormat( x );
  1496. Cell* cell = sheet->cellAt( x, y );
  1497. TQPoint cellRef( x, y );
  1498. #if 0
  1499. bool paintBordersBottom = false;
  1500. bool paintBordersRight = false;
  1501. bool paintBordersLeft = false;
  1502. bool paintBordersTop = false;
  1503. #endif
  1504. int paintBorder = Cell::Border_None;
  1505. TQPen rightPen( cell->effRightBorderPen( x, y ) );
  1506. TQPen leftPen( cell->effLeftBorderPen( x, y ) );
  1507. TQPen topPen( cell->effTopBorderPen( x, y ) );
  1508. TQPen bottomPen( cell->effBottomBorderPen( x, y ) );
  1509. // Paint border if outermost cell or if the pen is more "worth"
  1510. // than the border pen of the cell on the other side of the
  1511. // border or if the cell on the other side is not painted. In
  1512. // the latter case get the pen that is of more "worth"
  1513. // right border:
  1514. if ( x >= KS_colMax )
  1515. //paintBordersRight = true;
  1516. paintBorder |= Cell::Border_Right;
  1517. else if ( x == regionRight ) {
  1518. paintBorder |= Cell::Border_Right;
  1519. if ( cell->effRightBorderValue( x, y )
  1520. < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
  1521. rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
  1522. }
  1523. else {
  1524. paintBorder |= Cell::Border_Right;
  1525. if ( cell->effRightBorderValue( x, y )
  1526. < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
  1527. rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
  1528. }
  1529. // Similiar for other borders...
  1530. // bottom border:
  1531. if ( y >= KS_rowMax )
  1532. paintBorder |= Cell::Border_Bottom;
  1533. else if ( y == regionBottom ) {
  1534. paintBorder |= Cell::Border_Bottom;
  1535. if ( cell->effBottomBorderValue( x, y )
  1536. < sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
  1537. bottomPen = sheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
  1538. }
  1539. else {
  1540. paintBorder |= Cell::Border_Bottom;
  1541. if ( cell->effBottomBorderValue( x, y )
  1542. < sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
  1543. bottomPen = sheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
  1544. }
  1545. // left border:
  1546. if ( x == 1 )
  1547. paintBorder |= Cell::Border_Left;
  1548. else if ( x == regionLeft ) {
  1549. paintBorder |= Cell::Border_Left;
  1550. if ( cell->effLeftBorderValue( x, y )
  1551. < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
  1552. leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
  1553. }
  1554. else {
  1555. paintBorder |= Cell::Border_Left;
  1556. if ( cell->effLeftBorderValue( x, y )
  1557. < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
  1558. leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
  1559. }
  1560. // top border:
  1561. if ( y == 1 )
  1562. paintBorder |= Cell::Border_Top;
  1563. else if ( y == regionTop ) {
  1564. paintBorder |= Cell::Border_Top;
  1565. if ( cell->effTopBorderValue( x, y )
  1566. < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
  1567. topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
  1568. }
  1569. else {
  1570. paintBorder |= Cell::Border_Top;
  1571. if ( cell->effTopBorderValue( x, y )
  1572. < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
  1573. topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
  1574. }
  1575. #if 0
  1576. cell->paintCell( viewRegion, painter, view, dblCurrentCellPos, cellRef,
  1577. paintBordersRight, paintBordersBottom,
  1578. paintBordersLeft, paintBordersTop,
  1579. rightPen, bottomPen, leftPen, topPen,
  1580. mergedCellsPainted, false );
  1581. Cell::BorderSides highlightBorder=Cell::Border_None;
  1582. TQPen highlightPen;
  1583. #endif
  1584. cell->paintCell( viewRegion, painter, view, dblCurrentCellPos, cellRef,
  1585. paintBorder,
  1586. rightPen, bottomPen, leftPen, topPen,
  1587. mergedCellsPainted, false );
  1588. dblCurrentCellPos.setX( dblCurrentCellPos.x() + col_lay->dblWidth() );
  1589. }
  1590. dblCurrentCellPos.setY( dblCurrentCellPos.y() + row_lay->dblHeight() );
  1591. }
  1592. }
  1593. DCOPObject* Doc::dcopObject()
  1594. {
  1595. if ( !d->dcop )
  1596. d->dcop = new DocIface( this );
  1597. return d->dcop;
  1598. }
  1599. void Doc::addAreaName(const TQRect &_rect,const TQString & name,const TQString & sheetName)
  1600. {
  1601. setModified( true );
  1602. Reference tmp;
  1603. tmp.rect = _rect;
  1604. tmp.sheet_name = sheetName;
  1605. tmp.ref_name = name;
  1606. d->refs.append( tmp);
  1607. emit sig_addAreaName( name );
  1608. }
  1609. void Doc::removeArea( const TQString & name)
  1610. {
  1611. TQValueList<Reference>::Iterator it2;
  1612. for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 )
  1613. {
  1614. if((*it2).ref_name==name)
  1615. {
  1616. d->refs.remove(it2);
  1617. emit sig_removeAreaName( name );
  1618. return;
  1619. }
  1620. }
  1621. }
  1622. void Doc::changeAreaSheetName(const TQString & oldName,const TQString & sheetName)
  1623. {
  1624. TQValueList<Reference>::Iterator it2;
  1625. for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 )
  1626. {
  1627. if((*it2).sheet_name==oldName)
  1628. (*it2).sheet_name=sheetName;
  1629. }
  1630. }
  1631. TQRect Doc::getRectArea(const TQString &_sheetName)
  1632. {
  1633. TQValueList<Reference>::Iterator it2;
  1634. for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 )
  1635. {
  1636. if((*it2).ref_name==_sheetName)
  1637. {
  1638. return (*it2).rect;
  1639. }
  1640. }
  1641. return TQRect(-1,-1,-1,-1);
  1642. }
  1643. TQDomElement Doc::saveAreaName( TQDomDocument& doc )
  1644. {
  1645. TQDomElement element = doc.createElement( "areaname" );
  1646. TQValueList<Reference>::Iterator it2;
  1647. for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 )
  1648. {
  1649. TQDomElement e = doc.createElement("reference");
  1650. TQDomElement tabname = doc.createElement( "tabname" );
  1651. tabname.appendChild( doc.createTextNode( (*it2).sheet_name ) );
  1652. e.appendChild( tabname );
  1653. TQDomElement refname = doc.createElement( "refname" );
  1654. refname.appendChild( doc.createTextNode( (*it2).ref_name ) );
  1655. e.appendChild( refname );
  1656. TQDomElement rect = doc.createElement( "rect" );
  1657. rect.setAttribute( "left-rect", ((*it2).rect).left() );
  1658. rect.setAttribute( "right-rect",((*it2).rect).right() );
  1659. rect.setAttribute( "top-rect", ((*it2).rect).top() );
  1660. rect.setAttribute( "bottom-rect", ((*it2).rect).bottom() );
  1661. e.appendChild( rect );
  1662. element.appendChild(e);
  1663. }
  1664. return element;
  1665. }
  1666. void Doc::loadOasisCellValidation( const TQDomElement&body )
  1667. {
  1668. TQDomNode validation = KoDom::namedItemNS( body, KoXmlNS::table, "content-validations" );
  1669. kdDebug()<<"void Doc::loadOasisCellValidation( const TQDomElement&body ) \n";
  1670. kdDebug()<<"validation.isNull ? "<<validation.isNull()<<endl;
  1671. if ( !validation.isNull() )
  1672. {
  1673. TQDomNode n = validation.firstChild();
  1674. for( ; !n.isNull(); n = n.nextSibling() )
  1675. {
  1676. if ( n.isElement() )
  1677. {
  1678. TQDomElement element = n.toElement();
  1679. //kdDebug()<<" loadOasisCellValidation element.tagName() :"<<element.tagName()<<endl;
  1680. if ( element.tagName() == "content-validation" && element.namespaceURI() == KoXmlNS::table ) {
  1681. d->m_loadingInfo->appendValidation(element.attributeNS( KoXmlNS::table, "name", TQString() ), element );
  1682. kdDebug()<<" validation found :"<<element.attributeNS( KoXmlNS::table, "name", TQString() )<<endl;
  1683. }
  1684. else {
  1685. kdDebug()<<" Tag not recognize :"<<element.tagName()<<endl;
  1686. }
  1687. }
  1688. }
  1689. }
  1690. }
  1691. void Doc::saveOasisAreaName( KoXmlWriter & xmlWriter )
  1692. {
  1693. if ( listArea().count()>0 )
  1694. {
  1695. xmlWriter.startElement( "table:named-expressions" );
  1696. TQValueList<Reference>::Iterator it;
  1697. for ( it = d->refs.begin(); it != d->refs.end(); ++it )
  1698. {
  1699. xmlWriter.startElement( "table:named-range" );
  1700. xmlWriter.addAttribute( "table:name", ( *it ).ref_name );
  1701. xmlWriter.addAttribute( "table:base-cell-address", convertRefToBase( ( *it ).sheet_name, ( *it ).rect ) );
  1702. xmlWriter.addAttribute( "table:cell-range-address", convertRefToRange( ( *it ).sheet_name, ( *it ).rect ) );
  1703. xmlWriter.endElement();
  1704. }
  1705. xmlWriter.endElement();
  1706. }
  1707. }
  1708. void Doc::loadOasisAreaName( const TQDomElement& body )
  1709. {
  1710. kdDebug()<<"void Doc::loadOasisAreaName( const TQDomElement& body ) \n";
  1711. TQDomNode namedAreas = KoDom::namedItemNS( body, KoXmlNS::table, "named-expressions" );
  1712. if ( !namedAreas.isNull() )
  1713. {
  1714. kdDebug()<<" area name exist \n";
  1715. TQDomNode area = namedAreas.firstChild();
  1716. while ( !area.isNull() )
  1717. {
  1718. TQDomElement e = area.toElement();
  1719. if ( e.localName() == "named-range" )
  1720. {
  1721. if ( !e.hasAttributeNS( KoXmlNS::table, "name" ) || !e.hasAttributeNS( KoXmlNS::table, "cell-range-address" ) )
  1722. {
  1723. kdDebug() << "Reading in named area failed" << endl;
  1724. area = area.nextSibling();
  1725. continue;
  1726. }
  1727. // TODO: what is: sheet:base-cell-address
  1728. TQString name = e.attributeNS( KoXmlNS::table, "name", TQString() );
  1729. TQString range = e.attributeNS( KoXmlNS::table, "cell-range-address", TQString() );
  1730. kdDebug()<<"area name : "<<name<<" range :"<<range<<endl;
  1731. d->m_loadingInfo->addWordInAreaList( name );
  1732. kdDebug() << "Reading in named area, name: " << name << ", area: " << range << endl;
  1733. range = Oasis::decodeFormula( range );
  1734. if ( range.find( ':' ) == -1 )
  1735. {
  1736. Point p( range );
  1737. int n = range.find( '!' );
  1738. if ( n > 0 )
  1739. range = range + ":" + range.right( range.length() - n - 1);
  1740. kdDebug() << "=> Area: " << range << endl;
  1741. }
  1742. if ( range.contains( '!' ) && range[0] == '$' )
  1743. {
  1744. // cut absolute sheet indicator
  1745. range.remove( 0, 1 );
  1746. }
  1747. Range p( range );
  1748. addAreaName( p.range(), name, p.sheetName() );
  1749. kdDebug() << "Area range: " << p.toString() << endl;
  1750. }
  1751. else if ( e.localName() == "named-expression" )
  1752. {
  1753. kdDebug() << "Named expression found." << endl;
  1754. // TODO
  1755. }
  1756. area = area.nextSibling();
  1757. }
  1758. }
  1759. }
  1760. void Doc::loadAreaName( const TQDomElement& element )
  1761. {
  1762. TQDomElement tmp=element.firstChild().toElement();
  1763. for( ; !tmp.isNull(); tmp=tmp.nextSibling().toElement() )
  1764. {
  1765. if ( tmp.tagName() == "reference" )
  1766. {
  1767. TQString tabname;
  1768. TQString refname;
  1769. int left=0;
  1770. int right=0;
  1771. int top=0;
  1772. int bottom=0;
  1773. TQDomElement sheetName = tmp.namedItem( "tabname" ).toElement();
  1774. if ( !sheetName.isNull() )
  1775. {
  1776. tabname=sheetName.text();
  1777. }
  1778. TQDomElement referenceName = tmp.namedItem( "refname" ).toElement();
  1779. if ( !referenceName.isNull() )
  1780. {
  1781. refname=referenceName.text();
  1782. }
  1783. TQDomElement rect =tmp.namedItem( "rect" ).toElement();
  1784. if (!rect.isNull())
  1785. {
  1786. bool ok;
  1787. if ( rect.hasAttribute( "left-rect" ) )
  1788. left=rect.attribute("left-rect").toInt( &ok );
  1789. if ( rect.hasAttribute( "right-rect" ) )
  1790. right=rect.attribute("right-rect").toInt( &ok );
  1791. if ( rect.hasAttribute( "top-rect" ) )
  1792. top=rect.attribute("top-rect").toInt( &ok );
  1793. if ( rect.hasAttribute( "bottom-rect" ) )
  1794. bottom=rect.attribute("bottom-rect").toInt( &ok );
  1795. }
  1796. TQRect _rect;
  1797. _rect.setCoords(left,top,right,bottom);
  1798. addAreaName(_rect,refname,tabname);
  1799. }
  1800. }
  1801. }
  1802. void Doc::addStringCompletion(const TQString &stringCompletion)
  1803. {
  1804. if ( d->listCompletion.items().contains(stringCompletion) == 0 )
  1805. d->listCompletion.addItem( stringCompletion );
  1806. }
  1807. void Doc::refreshInterface()
  1808. {
  1809. emit sig_refreshView();
  1810. }
  1811. void Doc::refreshLocale()
  1812. {
  1813. emit sig_refreshLocale();
  1814. }
  1815. void Doc::emitBeginOperation(bool waitCursor)
  1816. {
  1817. //If an emitBeginOperation occurs with waitCursor enabled, then the waiting cursor is set
  1818. //until all operations have been completed.
  1819. //
  1820. //The reason being that any operations started before the first one with waitCursor set
  1821. //are expected to be completed in a short time anyway.
  1822. TQCursor* activeOverride = static_cast<TQCursor*>(TQApplication::overrideCursor());
  1823. if (waitCursor && ( (!activeOverride) || (activeOverride->shape() != TQt::waitCursor.shape()) ) )
  1824. {
  1825. TQApplication::setOverrideCursor(TQt::waitCursor);
  1826. }
  1827. // /* just duplicate the current cursor on the stack, then */
  1828. // else if (TQApplication::overrideCursor() != NULL)
  1829. // {
  1830. // TQApplication::setOverrideCursor(TQApplication::overrideCursor()->shape());
  1831. // }
  1832. KoDocument::emitBeginOperation();
  1833. d->delayCalculation = true;
  1834. d->numOperations++;
  1835. }
  1836. void Doc::emitBeginOperation(void)
  1837. {
  1838. emitBeginOperation(true);
  1839. }
  1840. void Doc::emitEndOperation()
  1841. {
  1842. d->numOperations--;
  1843. if (d->numOperations <= 0)
  1844. {
  1845. d->numOperations = 0;
  1846. d->delayCalculation = false;
  1847. }
  1848. KoDocument::emitEndOperation();
  1849. if (d->numOperations == 0)
  1850. {
  1851. TQApplication::restoreOverrideCursor();
  1852. /* do this after the parent class emitEndOperation because that allows updates
  1853. on the view again
  1854. */
  1855. paintUpdates();
  1856. }
  1857. }
  1858. void Doc::emitEndOperation( const Region& /*region*/ )
  1859. {
  1860. d->numOperations--;
  1861. if ( d->numOperations > 0 || !d->activeSheet )
  1862. {
  1863. KoDocument::emitEndOperation();
  1864. return;
  1865. }
  1866. d->numOperations = 0;
  1867. d->delayCalculation = false;
  1868. KoDocument::emitEndOperation();
  1869. TQApplication::restoreOverrideCursor();
  1870. /* do this after the parent class emitEndOperation because that allows updates
  1871. on the view again
  1872. */
  1873. paintUpdates();
  1874. }
  1875. bool Doc::delayCalculation() const
  1876. {
  1877. return d->delayCalculation;
  1878. }
  1879. void Doc::updateBorderButton()
  1880. {
  1881. TQPtrListIterator<KoView> it( views() );
  1882. for (; it.current(); ++it )
  1883. static_cast<View *>( it.current() )->updateBorderButton();
  1884. }
  1885. void Doc::insertSheet( Sheet * sheet )
  1886. {
  1887. TQPtrListIterator<KoView> it( views() );
  1888. for (; it.current(); ++it )
  1889. ((View*)it.current())->insertSheet( sheet );
  1890. }
  1891. void Doc::takeSheet( Sheet * sheet )
  1892. {
  1893. TQPtrListIterator<KoView> it( views() );
  1894. for (; it.current(); ++it )
  1895. ((View*)it.current())->removeSheet( sheet );
  1896. }
  1897. void Doc::addIgnoreWordAll( const TQString & word)
  1898. {
  1899. if( d->spellListIgnoreAll.findIndex( word )==-1)
  1900. d->spellListIgnoreAll.append( word );
  1901. }
  1902. void Doc::clearIgnoreWordAll( )
  1903. {
  1904. d->spellListIgnoreAll.clear();
  1905. }
  1906. void Doc::setDisplaySheet(Sheet *_sheet )
  1907. {
  1908. d->activeSheet = _sheet;
  1909. }
  1910. KSPLoadingInfo * Doc::loadingInfo() const
  1911. {
  1912. return d->m_loadingInfo;
  1913. }
  1914. void Doc::deleteLoadingInfo()
  1915. {
  1916. delete d->m_loadingInfo;
  1917. d->m_loadingInfo = 0;
  1918. }
  1919. Sheet * Doc::displaySheet() const
  1920. {
  1921. return d->activeSheet;
  1922. }
  1923. void Doc::addView( KoView *_view )
  1924. {
  1925. KoDocument::addView( _view );
  1926. TQPtrListIterator<KoView> it( views() );
  1927. for (; it.current(); ++it )
  1928. ((View*)it.current())->closeEditor();
  1929. }
  1930. void Doc::addDamage( Damage* damage )
  1931. {
  1932. d->damages.append( damage );
  1933. if( d->damages.count() == 1 )
  1934. TQTimer::singleShot( 0, this, TQT_SLOT( flushDamages() ) );
  1935. }
  1936. void Doc::flushDamages()
  1937. {
  1938. emit damagesFlushed( d->damages );
  1939. TQValueList<Damage*>::Iterator it;
  1940. for( it = d->damages.begin(); it != d->damages.end(); ++it )
  1941. delete *it;
  1942. d->damages.clear();
  1943. }
  1944. void Doc::loadConfigFromFile()
  1945. {
  1946. d->configLoadFromFile = true;
  1947. }
  1948. bool Doc::configLoadFromFile() const
  1949. {
  1950. return d->configLoadFromFile;
  1951. }
  1952. void Doc::insertObject( EmbeddedObject * obj )
  1953. {
  1954. switch ( obj->getType() )
  1955. {
  1956. case OBJECT_KOFFICE_PART: case OBJECT_CHART:
  1957. {
  1958. KoDocument::insertChild( dynamic_cast<EmbeddedKOfficeObject*>(obj)->embeddedObject() );
  1959. break;
  1960. }
  1961. default:
  1962. ;
  1963. }
  1964. d->m_embeddedObjects.append( obj );
  1965. }
  1966. TQPtrList<EmbeddedObject>& Doc::embeddedObjects()
  1967. {
  1968. return d->m_embeddedObjects;
  1969. }
  1970. KoPictureCollection *Doc::pictureCollection()
  1971. {
  1972. return &d->m_pictureCollection;
  1973. }
  1974. void Doc::repaint( const TQRect& rect )
  1975. {
  1976. TQRect r;
  1977. TQPtrListIterator<KoView> it( views() );
  1978. for( ; it.current(); ++it )
  1979. {
  1980. r = rect;
  1981. Canvas* canvas = ((View*)it.current())->canvasWidget();
  1982. r.moveTopLeft( TQPoint( r.x() - (int) canvas->xOffset(),
  1983. r.y() - (int) canvas->yOffset() ) );
  1984. canvas->update( r );
  1985. }
  1986. }
  1987. void Doc::repaint( EmbeddedObject *obj )
  1988. {
  1989. TQPtrListIterator<KoView> it( views() );
  1990. for( ; it.current(); ++it )
  1991. {
  1992. Canvas* canvas = ((View*)it.current())->canvasWidget();
  1993. if ( obj->sheet() == canvas->activeSheet() )
  1994. canvas->repaintObject( obj );
  1995. }
  1996. }
  1997. void Doc::repaint( const KoRect& rect )
  1998. {
  1999. TQRect r;
  2000. TQPtrListIterator<KoView> it( views() );
  2001. for( ; it.current(); ++it )
  2002. {
  2003. Canvas* canvas = ((View*)it.current())->canvasWidget();
  2004. r = zoomRect( rect );
  2005. r.moveBy( (int)( -canvas->xOffset()*zoomedResolutionX() ) ,
  2006. (int)( -canvas->yOffset() *zoomedResolutionY()) );
  2007. canvas->update( r );
  2008. }
  2009. }
  2010. void Doc::addShell( KoMainWindow *shell )
  2011. {
  2012. connect( shell, TQT_SIGNAL( documentSaved() ), d->commandHistory, TQT_SLOT( documentSaved() ) );
  2013. KoDocument::addShell( shell );
  2014. }
  2015. int Doc::undoRedoLimit() const
  2016. {
  2017. return d->commandHistory->undoLimit();
  2018. }
  2019. void Doc::setUndoRedoLimit(int val)
  2020. {
  2021. d->commandHistory->setUndoLimit(val);
  2022. d->commandHistory->setRedoLimit(val);
  2023. }
  2024. void Doc::insertPixmapKey( KoPictureKey key )
  2025. {
  2026. if ( !d->usedPictures.contains( key ) )
  2027. d->usedPictures.append( key );
  2028. }
  2029. void Doc::makeUsedPixmapList()
  2030. {
  2031. d->usedPictures.clear();
  2032. TQPtrListIterator<EmbeddedObject> it( d->m_embeddedObjects );
  2033. for ( ; it.current() ; ++it )
  2034. {
  2035. if( it.current()->getType() == OBJECT_PICTURE && ( d->m_savingWholeDocument || it.current()->isSelected() ) )
  2036. insertPixmapKey( static_cast<EmbeddedPictureObject*>( it.current() )->getKey() );
  2037. }
  2038. }
  2039. bool Doc::savingWholeDocument()
  2040. {
  2041. return d->m_savingWholeDocument;
  2042. }
  2043. #include "kspread_doc.moc"