From 8362bf63dea22bbf6736609b0f49c152f975eb63 Mon Sep 17 00:00:00 2001 From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> Date: Wed, 20 Jan 2010 01:29:50 +0000 Subject: Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kspread/kspread_doc.cc | 2462 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2462 insertions(+) create mode 100644 kspread/kspread_doc.cc (limited to 'kspread/kspread_doc.cc') diff --git a/kspread/kspread_doc.cc b/kspread/kspread_doc.cc new file mode 100644 index 00000000..2164a28b --- /dev/null +++ b/kspread/kspread_doc.cc @@ -0,0 +1,2462 @@ +/* This file is part of the KDE project + Copyright (C) 2005-2006 Inge Wallin <inge@lysator.liu.se> + (C) 2004 Ariya Hidayat <ariya@kde.org> + (C) 2002-2003 Norbert Andres <nandres@web.de> + (C) 2000-2002 Laurent Montel <montel@kde.org> + (C) 2002 John Dailey <dailey@vt.edu> + (C) 2002 Phillip Mueller <philipp.mueller@gmx.de> + (C) 2000 Werner Trobin <trobin@kde.org> + (C) 1999-2000 Simon Hausmann <hausmann@kde.org> + (C) 1999 David Faure <faure@kde.org> + (C) 1998-2000 Torben Weis <weis@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <unistd.h> +#include <assert.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <pwd.h> + +#include <qapplication.h> +#include <qfileinfo.h> +#include <qfont.h> +#include <qpair.h> + +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kconfig.h> +#include <kmessagebox.h> +#include <ksconfig.h> +#include <ktempfile.h> + +#include <KoApplication.h> +#include <KoCommandHistory.h> +#include <KoDocumentInfo.h> +#include <KoDom.h> +#include <KoMainWindow.h> +#include <KoOasisSettings.h> +#include <KoOasisStyles.h> +#include <KoStoreDevice.h> +#include <KoTemplateChooseDia.h> +#include <KoVariable.h> +#include <KoXmlNS.h> +#include <KoXmlWriter.h> + +#include "kspread_canvas.h" +#include "kspread_locale.h" +#include "kspread_map.h" +#include "kspread_sheet.h" +#include "kspread_sheetprint.h" +#include "kspread_style_manager.h" +#include "kspread_undo.h" +#include "kspread_util.h" +#include "kspread_view.h" + +#include "commands.h" +#include "damages.h" +#include "formula.h" +#include "functions.h" +#include "ksploadinginfo.h" +#include "selection.h" +#include "valuecalc.h" +#include "valueconverter.h" +#include "valueformatter.h" +#include "valueparser.h" + +#include "KSpreadDocIface.h" + +#include "kspread_doc.h" + +using namespace std; +using namespace KSpread; + +static const int CURRENT_SYNTAX_VERSION = 1; +// Make sure an appropriate DTD is available in www/koffice/DTD if changing this value +static const char * CURRENT_DTD_VERSION = "1.2"; + +class Doc::Private +{ +public: + + Map *map; + KLocale *locale; + StyleManager *styleManager; + ValueParser *parser; + ValueFormatter *formatter; + ValueConverter *converter; + ValueCalc *calc; + + Sheet *activeSheet; + KSPLoadingInfo *m_loadingInfo; + static QValueList<Doc*> s_docs; + static int s_docId; + + DCOPObject* dcop; + + // URL of the this part. This variable is only set if the load() function + // had been called with an URL as argument. + QString fileURL; + + // for undo/redo + int undoLocked; + KoCommandHistory* commandHistory; + + // true if loading is in process, otherwise false. + // This flag is used to avoid updates etc. during loading. + bool isLoading; + + QColor pageBorderColor; + + QPtrList<Plugin> plugins; + + QValueList<Reference> refs; + KCompletion listCompletion; + + int numOperations; + + QValueList<Damage*> damages; + + // document properties + int syntaxVersion; + bool verticalScrollBar:1; + bool horizontalScrollBar:1; + bool columnHeader:1; + bool rowHeader:1; + QColor gridColor; + double indentValue; + bool showStatusBar:1; + bool showTabBar:1; + bool showFormulaBar:1; + bool showError:1; + KGlobalSettings::Completion completionMode; + KSpread::MoveTo moveTo; + MethodOfCalc calcMethod; + bool delayCalculation:1; + KSpellConfig *spellConfig; + bool dontCheckUpperWord:1; + bool dontCheckTitleCase:1; + bool configLoadFromFile:1; + QStringList spellListIgnoreAll; + /// list of all objects + QPtrList<EmbeddedObject> m_embeddedObjects; + KoPictureCollection m_pictureCollection; + QValueList<KoPictureKey> usedPictures; + bool m_savingWholeDocument; +}; + +/***************************************************************************** + * + * Doc + * + *****************************************************************************/ + +QValueList<Doc*> Doc::Private::s_docs; +int Doc::Private::s_docId = 0; + +Doc::Doc( QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name, bool singleViewMode ) + : KoDocument( parentWidget, widgetName, parent, name, singleViewMode ) +{ + d = new Private; + d->m_loadingInfo = 0L; + + d->map = new Map( this, "Map" ); + d->locale = new Locale; + d->styleManager = new StyleManager(); + + d->parser = new ValueParser( d->locale ); + d->converter = new ValueConverter ( d->parser ); + d->calc = new ValueCalc( d->converter ); + d->calc->setDoc (this); + d->formatter = new ValueFormatter( d->converter ); + + d->activeSheet = 0; + + d->pageBorderColor = Qt::red; + d->configLoadFromFile = false; + + QFont f( KoGlobal::defaultFont() ); + Format::setGlobalRowHeight( f.pointSizeFloat() + 3 ); + Format::setGlobalColWidth( ( f.pointSizeFloat() + 3 ) * 5 ); + + d->plugins.setAutoDelete( false ); + + d->delayCalculation = false; + + documents().append( this ); + + setInstance( Factory::global(), false ); + setTemplateType( "kspread_template" ); + + d->dcop = 0; + d->isLoading = false; + d->numOperations = 1; // don't start repainting before the GUI is done... + + d->undoLocked = 0; + d->commandHistory = new KoCommandHistory( actionCollection() ); + connect( d->commandHistory, SIGNAL( commandExecuted() ), SLOT( commandExecuted() ) ); + connect( d->commandHistory, SIGNAL( documentRestored() ), SLOT( documentRestored() ) ); + + + // Make us scripsheet if the document has a name + // Set a name if there is no name specified + if ( !name ) + { + QString tmp( "Document%1" ); + tmp = tmp.arg( d->s_docId++ ); + setName( tmp.local8Bit());//tmp.latin1() ); + dcopObject(); + } + else + dcopObject(); + + // default document properties + d->syntaxVersion = CURRENT_SYNTAX_VERSION; + d->verticalScrollBar = true; + d->horizontalScrollBar = true; + d->columnHeader = true; + d->rowHeader = true; + d->gridColor = Qt::lightGray; + d->indentValue = 10.0; + d->showStatusBar = true; + d->showFormulaBar = true; + d->showTabBar = true; + d->showError = false; + d->calcMethod = SumOfNumber; + d->moveTo = Bottom; + d->completionMode = KGlobalSettings::CompletionAuto; + d->spellConfig = 0; + d->dontCheckUpperWord = false; + d->dontCheckTitleCase = false; +} + +Doc::~Doc() +{ + //don't save config when kword is embedded into konqueror + if(isReadWrite()) + saveConfig(); + + delete d->dcop; + d->s_docs.remove( this ); + + kdDebug(36001) << "alive 1" << endl; + + delete d->commandHistory; + + delete d->spellConfig; + + delete d->locale; + delete d->map; + delete d->styleManager; + delete d->parser; + delete d->formatter; + delete d->converter; + delete d->calc; + + delete d; +} + +QValueList<Doc*> Doc::documents() +{ + return Private::s_docs; +} + +bool Doc::initDoc(InitDocFlags flags, QWidget* parentWidget) +{ + // ElapsedTime et( " initDoc " ); + + QString f; + + if (flags==KoDocument::InitDocEmpty) + { + KConfig *config = Factory::global()->config(); + int _page=1; + if( config->hasGroup("Parameters" )) + { + config->setGroup( "Parameters" ); + _page=config->readNumEntry( "NbPage",1 ) ; + } + + for( int i=0; i<_page; i++ ) + map()->addNewSheet(); + + resetURL(); + setEmpty(); + initConfig(); + styleManager()->createBuiltinStyles(); + + return true; + } + + KoTemplateChooseDia::ReturnType ret; + KoTemplateChooseDia::DialogType dlgtype; + if (flags != KoDocument::InitDocFileNew ) + dlgtype = KoTemplateChooseDia::Everything; + else + dlgtype = KoTemplateChooseDia::OnlyTemplates; + + ret = KoTemplateChooseDia::choose( Factory::global(), f, + dlgtype, "kspread_template", parentWidget ); + + if ( ret == KoTemplateChooseDia::File ) + { + KURL url( f ); + + bool ok=openURL(url); + + while (KoDocument::isLoading()) + kapp->processEvents(); + + return ok; + + + } + + if ( ret == KoTemplateChooseDia::Empty ) + { + KConfig *config = Factory::global()->config(); + int _page=1; + if( config->hasGroup("Parameters" )) + { + config->setGroup( "Parameters" ); + _page=config->readNumEntry( "NbPage",1 ) ; + } + + for( int i=0; i<_page; i++ ) + map()->addNewSheet (); + + resetURL(); + setEmpty(); + initConfig(); + styleManager()->createBuiltinStyles(); + return true; + } + + if ( ret == KoTemplateChooseDia::Template ) + { + resetURL(); + d->m_loadingInfo = new KSPLoadingInfo; + d->m_loadingInfo->setLoadTemplate( true ); + bool ok = loadNativeFormat( f ); + if ( !ok ) + { + showLoadingErrorDialog(); + deleteLoadingInfo(); + } + setEmpty(); + initConfig(); + return ok; + } + + return false; +} + +void Doc::openTemplate (const QString& file) +{ + d->m_loadingInfo = new KSPLoadingInfo; + d->m_loadingInfo->setLoadTemplate( true ); + KoDocument::openTemplate( file ); + deleteLoadingInfo(); + initConfig(); +} + +void Doc::initEmpty() +{ + KConfig *config = Factory::global()->config(); + int _page=1; + if( config->hasGroup("Parameters" )) + { + config->setGroup( "Parameters" ); + _page=config->readNumEntry( "NbPage",1 ) ; + } + + for( int i=0; i<_page; i++ ) + map()->addNewSheet(); + + resetURL(); + initConfig(); + styleManager()->createBuiltinStyles(); + + KoDocument::initEmpty(); +} + +KLocale *Doc::locale () const +{ + return d->locale; +} + +Map *Doc::map () const +{ + return d->map; +} + +StyleManager *Doc::styleManager () const +{ + return d->styleManager; +} + +ValueParser *Doc::parser () const +{ + return d->parser; +} + +ValueFormatter *Doc::formatter () const +{ + return d->formatter; +} + +ValueConverter *Doc::converter () const +{ + return d->converter; +} + +ValueCalc *Doc::calc () const +{ + return d->calc; +} + +void Doc::saveConfig() +{ + if ( isEmbedded() ||!isReadWrite()) + return; + KConfig *config = Factory::global()->config(); + config->setGroup( "Parameters" ); + config->writeEntry( "Zoom", m_zoom ); + +} + +void Doc::initConfig() +{ + KConfig *config = Factory::global()->config(); + + if( config->hasGroup("KSpread Page Layout" )) + { + config->setGroup( "KSpread Page Layout" ); + setUnit( (KoUnit::Unit)config->readNumEntry( "Default unit page" ,0)); + } + if( config->hasGroup("Parameters" )) + { + config->setGroup( "Parameters" ); + m_zoom = config->readNumEntry( "Zoom", 100 ); + } + else + m_zoom = 100; + + int undo=30; + if(config->hasGroup("Misc" ) ) + { + config->setGroup( "Misc" ); + undo=config->readNumEntry("UndoRedo",-1); + } + if(undo!=-1) + setUndoRedoLimit(undo); + + setZoomAndResolution( m_zoom, KoGlobal::dpiX(), KoGlobal::dpiY() ); +} + +int Doc::syntaxVersion() const +{ + return d->syntaxVersion; +} + +bool Doc::isLoading() const +{ + return d->isLoading || KoDocument::isLoading(); +} + +void Doc::doNotPaint(bool status) +{ + d->isLoading = status; +} + + +QColor Doc::pageBorderColor() const +{ + return d->pageBorderColor; +} + +void Doc::changePageBorderColor( const QColor & _color) +{ + d->pageBorderColor = _color; +} + +const QValueList<Reference> &Doc::listArea() +{ + return d->refs; +} + +KCompletion& Doc::completion() +{ + return d->listCompletion; +} + +KoView* Doc::createViewInstance( QWidget* parent, const char* name ) +{ + if ( name == 0 ) + name = "View"; + return new View( parent, name, this ); +} + +bool Doc::saveChildren( KoStore* _store ) +{ + return map()->saveChildren( _store ); +} + +int Doc::supportedSpecialFormats() const +{ + return KoDocument::supportedSpecialFormats(); +} + +bool Doc::completeSaving( KoStore* _store ) +{ + d->m_pictureCollection.saveToStore( KoPictureCollection::CollectionPicture, _store, d->usedPictures ); + + return true; +} + + +QDomDocument Doc::saveXML() +{ + //Terminate current cell edition, if any + QPtrListIterator<KoView> it( views() ); + + /* don't pull focus away from the editor if this is just a background + autosave */ + if (!isAutosaving()) + { + for (; it.current(); ++it ) + static_cast<View *>( it.current() )->deleteEditor( true ); + } + + QDomDocument doc = createDomDocument( "spreadsheet", CURRENT_DTD_VERSION ); + QDomElement spread = doc.documentElement(); + spread.setAttribute( "editor", "KSpread" ); + spread.setAttribute( "mime", "application/x-kspread" ); + spread.setAttribute( "syntaxVersion", CURRENT_SYNTAX_VERSION ); + + QDomElement dlocale = ((Locale *)locale())->save( doc ); + spread.appendChild( dlocale ); + + if (d->refs.count() != 0 ) + { + QDomElement areaname = saveAreaName( doc ); + spread.appendChild( areaname ); + } + + if( !d->spellListIgnoreAll.isEmpty() ) + { + QDomElement spellCheckIgnore = doc.createElement( "SPELLCHECKIGNORELIST" ); + spread.appendChild( spellCheckIgnore ); + for ( QStringList::Iterator it = d->spellListIgnoreAll.begin(); it != d->spellListIgnoreAll.end(); ++it ) + { + QDomElement spellElem = doc.createElement( "SPELLCHECKIGNOREWORD" ); + spellCheckIgnore.appendChild( spellElem ); + spellElem.setAttribute( "word", *it ); + } + } + + SavedDocParts::const_iterator iter = m_savedDocParts.begin(); + SavedDocParts::const_iterator end = m_savedDocParts.end(); + while ( iter != end ) + { + // save data we loaded in the beginning and which has no owner back to file + spread.appendChild( iter.data() ); + ++iter; + } + + QDomElement defaults = doc.createElement( "defaults" ); + defaults.setAttribute( "row-height", Format::globalRowHeight() ); + defaults.setAttribute( "col-width", Format::globalColWidth() ); + spread.appendChild( defaults ); + + Plugin * plugin = d->plugins.first(); + for ( ; plugin != 0; plugin = d->plugins.next() ) + { + QDomElement data( plugin->saveXML( doc ) ); + if ( !data.isNull() ) + spread.appendChild( data ); + } + + QDomElement s = styleManager()->save( doc ); + spread.appendChild( s ); + QDomElement e = map()->save( doc ); + spread.appendChild( e ); + + setModified( false ); + + return doc; +} + +bool Doc::loadChildren( KoStore* _store ) +{ + return map()->loadChildren( _store ); +} + +bool Doc::saveOasis( KoStore* store, KoXmlWriter* manifestWriter ) +{ + emitBeginOperation(true); + bool result=saveOasisHelper( store, manifestWriter, SaveAll ); + emitEndOperation(); + + return result; +} + +bool Doc::saveOasisHelper( KoStore* store, KoXmlWriter* manifestWriter, SaveFlag saveFlag, + QString* /*plainText*/, KoPicture* /*picture*/ ) +{ + d->m_pictureCollection.assignUniqueIds(); + //Terminate current cell edition, if any + QPtrListIterator<KoView> it2( views() ); + d->m_savingWholeDocument = saveFlag == SaveAll ? true : false; + + /* don't pull focus away from the editor if this is just a background + autosave */ + if (!isAutosaving()) + { + for (; it2.current(); ++it2 ) + static_cast<View *>( it2.current() )->deleteEditor( true ); + } + if ( !store->open( "content.xml" ) ) + return false; + + KoStoreDevice dev( store ); + KoXmlWriter* contentWriter = createOasisXmlWriter( &dev, "office:document-content" ); + KoGenStyles mainStyles;//for compile + + KTempFile contentTmpFile; + //Check that temp file was successfully created + if (contentTmpFile.status() != 0) + { + qWarning("Creation of temporary file to store document content failed."); + return false; + } + + contentTmpFile.setAutoDelete( true ); + QFile* tmpFile = contentTmpFile.file(); + KoXmlWriter contentTmpWriter( tmpFile, 1 ); + + + + //todo fixme just add a element for testing saving content.xml + contentTmpWriter.startElement( "office:body" ); + contentTmpWriter.startElement( "office:spreadsheet" ); + + int indexObj = 1; + int partIndexObj = 0; + + // Saving the custom cell styles including the default cell style. + styleManager()->saveOasis( mainStyles ); + + // Saving the default column style + KoGenStyle defaultColumnStyle( Doc::STYLE_COLUMN_USER, "table-column" ); + defaultColumnStyle.addPropertyPt( "style:column-width", Format::globalColWidth() ); + defaultColumnStyle.setDefaultStyle( true ); + mainStyles.lookup( defaultColumnStyle, "Default", KoGenStyles::DontForceNumbering ); + + // Saving the default row style + KoGenStyle defaultRowStyle( Doc::STYLE_ROW_USER, "table-row" ); + defaultRowStyle.addPropertyPt( "style:row-height", Format::globalRowHeight() ); + defaultRowStyle.setDefaultStyle( true ); + mainStyles.lookup( defaultRowStyle, "Default", KoGenStyles::DontForceNumbering ); + + // Saving the map. + map()->saveOasis( contentTmpWriter, mainStyles, store, manifestWriter, indexObj, partIndexObj ); + + saveOasisAreaName( contentTmpWriter ); + contentTmpWriter.endElement(); ////office:spreadsheet + contentTmpWriter.endElement(); ////office:body + + // Done with writing out the contents to the tempfile, we can now write out the automatic styles + contentWriter->startElement( "office:automatic-styles" ); + + QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_AUTO ); + QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" ); + } + + styles = mainStyles.styles( STYLE_PAGE ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-properties" ); + } + + styles = mainStyles.styles( STYLE_COLUMN_AUTO ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-column-properties" ); + } + + styles = mainStyles.styles( STYLE_ROW_AUTO ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-row-properties" ); + } + + styles = mainStyles.styles( STYLE_CELL_AUTO ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "style:style", (*it).name, "style:table-cell-properties" ); + } + + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_NUMBER ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ ); + } + + //TODO FIXME !!!! + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_DATE ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:date-style", (*it).name, 0 /*TODO ????*/ ); + } + + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_TIME ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:time-style", (*it).name, 0 /*TODO ????*/ ); + } + + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_FRACTION ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ ); + } + + //TODO FIME !!!!! + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_PERCENTAGE ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:percentage-style", (*it).name, 0 /*TODO ????*/ ); + } + + //TODO FIME !!!!! + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_CURRENCY ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:currency-style", (*it).name, 0 /*TODO ????*/ ); + } + + styles = mainStyles.styles( KoGenStyle::STYLE_NUMERIC_SCIENTIFIC ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( contentWriter, mainStyles, "number:number-style", (*it).name, 0 /*TODO ????*/ ); + } + + + contentWriter->endElement(); // office:automatic-styles + + + // And now we can copy over the contents from the tempfile to the real one + tmpFile->close(); + contentWriter->addCompleteElement( tmpFile ); + contentTmpFile.close(); + + + contentWriter->endElement(); // root element + contentWriter->endDocument(); + delete contentWriter; + if ( !store->close() ) + return false; + //add manifest line for content.xml + manifestWriter->addManifestEntry( "content.xml", "text/xml" ); + + //todo add manifest line for style.xml + if ( !store->open( "styles.xml" ) ) + return false; + + manifestWriter->addManifestEntry( "styles.xml", "text/xml" ); + saveOasisDocumentStyles( store, mainStyles ); + + if ( !store->close() ) // done with styles.xml + return false; + + makeUsedPixmapList(); + d->m_pictureCollection.saveOasisToStore( store, d->usedPictures, manifestWriter); + + if(!store->open("settings.xml")) + return false; + + KoXmlWriter* settingsWriter = createOasisXmlWriter(&dev, "office:document-settings"); + settingsWriter->startElement("office:settings"); + settingsWriter->startElement("config:config-item-set"); + settingsWriter->addAttribute("config:name", "view-settings"); + + KoUnit::saveOasis(settingsWriter, unit()); + + saveOasisSettings( *settingsWriter ); + + settingsWriter->endElement(); // config:config-item-set + + settingsWriter->startElement("config:config-item-set"); + settingsWriter->addAttribute("config:name", "configuration-settings"); + settingsWriter->addConfigItem("SpellCheckerIgnoreList", d->spellListIgnoreAll.join( "," ) ); + settingsWriter->endElement(); // config:config-item-set + settingsWriter->endElement(); // office:settings + settingsWriter->endElement(); // Root:element + settingsWriter->endDocument(); + delete settingsWriter; + + if(!store->close()) + return false; + + manifestWriter->addManifestEntry("settings.xml", "text/xml"); + + + if ( saveFlag == SaveSelected ) + { + QPtrListIterator<EmbeddedObject> it(embeddedObjects() ); + for( ; it.current(); ++it ) + { + if ( it.current()->getType() != OBJECT_CHART && it.current()->getType() != OBJECT_KOFFICE_PART ) + continue; + KoDocumentChild *embedded = dynamic_cast<EmbeddedKOfficeObject *>(it.current() )->embeddedObject(); + //NOTE: If an application's .desktop file lies about opendocument support (ie. it indicates that it has + //a native OASIS mime type, when it doesn't, this causes a crash when trying to reload and paint + //the object, since it won't have an associated document. + if ( !embedded->saveOasis( store, manifestWriter ) ) + continue; + } + } + + + setModified( false ); + + return true; +} + +void Doc::loadOasisSettings( const QDomDocument&settingsDoc ) +{ + KoOasisSettings settings( settingsDoc ); + KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" ); + if ( !viewSettings.isNull() ) + { + setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit"))); + } + map()->loadOasisSettings( settings ); + loadOasisIgnoreList( settings ); +} + +void Doc::saveOasisSettings( KoXmlWriter &settingsWriter ) +{ + settingsWriter.startElement("config:config-item-map-indexed"); + settingsWriter.addAttribute("config:name", "Views"); + settingsWriter.startElement( "config:config-item-map-entry" ); + map()->saveOasisSettings( settingsWriter ); + settingsWriter.endElement(); + settingsWriter.endElement(); +} + + +void Doc::loadOasisIgnoreList( const KoOasisSettings& settings ) +{ + KoOasisSettings::Items configurationSettings = settings.itemSet( "configuration-settings" ); + if ( !configurationSettings.isNull() ) + { + const QString ignorelist = configurationSettings.parseConfigItemString( "SpellCheckerIgnoreList" ); + //kdDebug()<<" ignorelist :"<<ignorelist<<endl; + d->spellListIgnoreAll = QStringList::split( ',', ignorelist ); + } +} + + +void Doc::saveOasisDocumentStyles( KoStore* store, KoGenStyles& mainStyles ) const +{ + KoStoreDevice stylesDev( store ); + KoXmlWriter* stylesWriter = createOasisXmlWriter( &stylesDev, "office:document-styles" ); + + stylesWriter->startElement( "office:styles" ); + QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_USER ); + QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:paragraph-properties" ); + } + + // Writing out the common column styles. + styles = mainStyles.styles( Doc::STYLE_COLUMN_USER ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + if ( (*it).style->isDefaultStyle() ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-column-properties" ); + } + else { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-column-properties" ); + } + } + + // Writing out the row column styles. + styles = mainStyles.styles( Doc::STYLE_ROW_USER ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + if ( (*it).style->isDefaultStyle() ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-row-properties" ); + } + else { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-row-properties" ); + } + } + + // Writing out the common cell styles. + styles = mainStyles.styles( Doc::STYLE_CELL_USER ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + if ( (*it).style->isDefaultStyle() ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:default-style", (*it).name, "style:table-cell-properties" ); + } + else { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name, "style:table-cell-properties" ); + } + } + + styles = mainStyles.styles( KoGenStyle::STYLE_HATCH ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "draw:hatch", (*it).name, "style:graphic-properties" , true, true /*add draw:name*/); + } + styles = mainStyles.styles( KoGenStyle::STYLE_GRAPHICAUTO ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties" ); + } + + stylesWriter->endElement(); // office:styles + + stylesWriter->startElement( "office:automatic-styles" ); + styles = mainStyles.styles( KoGenStyle::STYLE_PAGELAYOUT ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:page-layout", (*it).name, "style:page-layout-properties", false /*don't close*/ ); + stylesWriter->endElement(); + } + + stylesWriter->endElement(); // office:automatic-styles + //code from kword + stylesWriter->startElement( "office:master-styles" ); + + styles = mainStyles.styles( Doc::STYLE_PAGEMASTER ); + it = styles.begin(); + for ( ; it != styles.end() ; ++it ) { + (*it).style->writeStyle( stylesWriter, mainStyles, "style:master-page", (*it).name, "" ); + } + + stylesWriter->endElement(); // office:master-style + + + stylesWriter->endElement(); // root element (office:document-styles) + stylesWriter->endDocument(); + delete stylesWriter;; +} + +bool Doc::loadOasis( const QDomDocument& doc, KoOasisStyles& oasisStyles, const QDomDocument& settings, KoStore* store) +{ + if ( !d->m_loadingInfo ) + d->m_loadingInfo = new KSPLoadingInfo; + + QTime dt; + dt.start(); + + emit sigProgress( 0 ); + d->isLoading = true; + d->spellListIgnoreAll.clear(); + + d->refs.clear(); + + QDomElement content = doc.documentElement(); + QDomElement realBody ( KoDom::namedItemNS( content, KoXmlNS::office, "body" ) ); + if ( realBody.isNull() ) + { + setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No office:body tag found." )); + deleteLoadingInfo(); + return false; + } + QDomElement body = KoDom::namedItemNS( realBody, KoXmlNS::office, "spreadsheet" ); + + if ( body.isNull() ) + { + kdError(32001) << "No office:spreadsheet found!" << endl; + QDomElement childElem; + QString localName; + forEachElement( childElem, realBody ) { + localName = childElem.localName(); + } + if ( localName.isEmpty() ) + setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No tag found inside office:body." ) ); + else + setErrorMessage( i18n( "This document is not a spreadsheet, but %1. Please try opening it with the appropriate application." ).arg( KoDocument::tagNameToDocumentType( localName ) ) ); + deleteLoadingInfo(); + return false; + } + + KoOasisLoadingContext context( this, oasisStyles, store ); + + //load in first + styleManager()->loadOasisStyleTemplate( oasisStyles ); + + // load default column style + const QDomElement* defaultColumnStyle = oasisStyles.defaultStyle( "table-column" ); + if ( defaultColumnStyle ) + { +// kDebug() << "style:default-style style:family=\"table-column\"" << endl; + KoStyleStack styleStack; + styleStack.push( *defaultColumnStyle ); + styleStack.setTypeProperties( "table-column" ); + if ( styleStack.hasAttributeNS( KoXmlNS::style, "column-width" ) ) + { + const double width = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "column-width" ), -1.0 ); + if ( width != -1.0 ) + { +// kDebug() << "\tstyle:column-width: " << width << endl; + Format::setGlobalColWidth( width ); + } + } + } + + // load default row style + const QDomElement* defaultRowStyle = oasisStyles.defaultStyle( "table-row" ); + if ( defaultRowStyle ) + { +// kDebug() << "style:default-style style:family=\"table-row\"" << endl; + KoStyleStack styleStack; + styleStack.push( *defaultRowStyle ); + styleStack.setTypeProperties( "table-row" ); + if ( styleStack.hasAttributeNS( KoXmlNS::style, "row-height" ) ) + { + const double height = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "row-height" ), -1.0 ); + if ( height != -1.0 ) + { +// kDebug() << "\tstyle:row-height: " << height << endl; + Format::setGlobalRowHeight( height ); + } + } + } + + // TODO check versions and mimetypes etc. + loadOasisAreaName( body ); + loadOasisCellValidation( body ); + + // all <sheet:sheet> goes to workbook + if ( !map()->loadOasis( body, context ) ) + { + d->isLoading = false; + deleteLoadingInfo(); + return false; + } + + + if ( !settings.isNull() ) + { + loadOasisSettings( settings ); + } + emit sigProgress( 90 ); + initConfig(); + emit sigProgress(-1); + + //display loading time + kdDebug(36001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl; + return true; +} + +bool Doc::loadXML( QIODevice *, const QDomDocument& doc ) +{ + QTime dt; + dt.start(); + + emit sigProgress( 0 ); + d->isLoading = true; + d->spellListIgnoreAll.clear(); + // <spreadsheet> + QDomElement spread = doc.documentElement(); + + if ( spread.attribute( "mime" ) != "application/x-kspread" && spread.attribute( "mime" ) != "application/vnd.kde.kspread" ) + { + d->isLoading = false; + setErrorMessage( i18n( "Invalid document. Expected mimetype application/x-kspread or application/vnd.kde.kspread, got %1" ).arg( spread.attribute("mime") ) ); + return false; + } + + d->syntaxVersion = Doc::getAttribute( spread, "syntaxVersion", 0 ); + if ( d->syntaxVersion > CURRENT_SYNTAX_VERSION ) + { + int ret = KMessageBox::warningContinueCancel( + 0, i18n("This document was created with a newer version of KSpread (syntax version: %1)\n" + "When you open it with this version of KSpread, some information may be lost.").arg(d->syntaxVersion), + i18n("File Format Mismatch"), KStdGuiItem::cont() ); + if ( ret == KMessageBox::Cancel ) + { + setErrorMessage( "USER_CANCELED" ); + return false; + } + } + + // <locale> + QDomElement loc = spread.namedItem( "locale" ).toElement(); + if ( !loc.isNull() ) + ((Locale *) locale())->load( loc ); + + emit sigProgress( 5 ); + + QDomElement defaults = spread.namedItem( "defaults" ).toElement(); + if ( !defaults.isNull() ) + { + bool ok = false; + double d = defaults.attribute( "row-height" ).toDouble( &ok ); + if ( !ok ) + return false; + Format::setGlobalRowHeight( d ); + + d = defaults.attribute( "col-width" ).toDouble( &ok ); + + if ( !ok ) + return false; + + Format::setGlobalColWidth( d ); + } + + d->refs.clear(); + //<areaname > + QDomElement areaname = spread.namedItem( "areaname" ).toElement(); + if ( !areaname.isNull()) + loadAreaName(areaname); + + QDomElement ignoreAll = spread.namedItem( "SPELLCHECKIGNORELIST").toElement(); + if ( !ignoreAll.isNull()) + { + QDomElement spellWord=spread.namedItem("SPELLCHECKIGNORELIST").toElement(); + + spellWord=spellWord.firstChild().toElement(); + while ( !spellWord.isNull() ) + { + if ( spellWord.tagName()=="SPELLCHECKIGNOREWORD" ) + { + d->spellListIgnoreAll.append(spellWord.attribute("word")); + } + spellWord=spellWord.nextSibling().toElement(); + } + } + + emit sigProgress( 40 ); + // In case of reload (e.g. from konqueror) + map()->sheetList().clear(); // it's set to autoDelete + + QDomElement styles = spread.namedItem( "styles" ).toElement(); + if ( !styles.isNull() ) + { + if ( !styleManager()->loadXML( styles ) ) + { + setErrorMessage( i18n( "Styles cannot be loaded." ) ); + d->isLoading = false; + return false; + } + } + + // <map> + QDomElement mymap = spread.namedItem( "map" ).toElement(); + if ( mymap.isNull() ) + { + setErrorMessage( i18n("Invalid document. No map tag.") ); + d->isLoading = false; + return false; + } + if ( !map()->loadXML( mymap ) ) + { + d->isLoading = false; + return false; + } + + //Backwards compatibility with older versions for paper layout + if ( d->syntaxVersion < 1 ) + { + QDomElement paper = spread.namedItem( "paper" ).toElement(); + if ( !paper.isNull() ) + { + loadPaper( paper ); + } + } + + emit sigProgress( 85 ); + + QDomElement element( spread.firstChild().toElement() ); + while ( !element.isNull() ) + { + QString tagName( element.tagName() ); + + if ( tagName != "locale" && tagName != "map" && tagName != "styles" + && tagName != "SPELLCHECKIGNORELIST" && tagName != "areaname" + && tagName != "paper" ) + { + // belongs to a plugin, load it and save it for later use + m_savedDocParts[ tagName ] = element; + } + + element = element.nextSibling().toElement(); + } + + emit sigProgress( 90 ); + initConfig(); + emit sigProgress(-1); + + kdDebug(36001) << "Loading took " << (float)(dt.elapsed()) / 1000.0 << " seconds" << endl; + + emit sig_refreshView(); + + return true; +} + +void Doc::loadPaper( QDomElement const & paper ) +{ + // <paper> + QString format = paper.attribute( "format" ); + QString orientation = paper.attribute( "orientation" ); + + // <borders> + QDomElement borders = paper.namedItem( "borders" ).toElement(); + if ( !borders.isNull() ) + { + float left = borders.attribute( "left" ).toFloat(); + float right = borders.attribute( "right" ).toFloat(); + float top = borders.attribute( "top" ).toFloat(); + float bottom = borders.attribute( "bottom" ).toFloat(); + + //apply to all sheet + QPtrListIterator<Sheet> it ( map()->sheetList() ); + for( ; it.current(); ++it ) + { + it.current()->print()->setPaperLayout( left, top, right, bottom, + format, orientation ); + } + } + + QString hleft, hright, hcenter; + QString fleft, fright, fcenter; + // <head> + QDomElement head = paper.namedItem( "head" ).toElement(); + if ( !head.isNull() ) + { + QDomElement left = head.namedItem( "left" ).toElement(); + if ( !left.isNull() ) + hleft = left.text(); + QDomElement center = head.namedItem( "center" ).toElement(); + if ( !center.isNull() ) + hcenter = center.text(); + QDomElement right = head.namedItem( "right" ).toElement(); + if ( !right.isNull() ) + hright = right.text(); + } + // <foot> + QDomElement foot = paper.namedItem( "foot" ).toElement(); + if ( !foot.isNull() ) + { + QDomElement left = foot.namedItem( "left" ).toElement(); + if ( !left.isNull() ) + fleft = left.text(); + QDomElement center = foot.namedItem( "center" ).toElement(); + if ( !center.isNull() ) + fcenter = center.text(); + QDomElement right = foot.namedItem( "right" ).toElement(); + if ( !right.isNull() ) + fright = right.text(); + } + //The macro "<sheet>" formerly was typed as "<table>" + hleft = hleft.replace( "<table>", "<sheet>" ); + hcenter = hcenter.replace( "<table>", "<sheet>" ); + hright = hright.replace( "<table>", "<sheet>" ); + fleft = fleft.replace( "<table>", "<sheet>" ); + fcenter = fcenter.replace( "<table>", "<sheet>" ); + fright = fright.replace( "<table>", "<sheet>" ); + + QPtrListIterator<Sheet> it ( map()->sheetList() ); + for( ; it.current(); ++it ) + { + it.current()->print()->setHeadFootLine( hleft, hcenter, hright, + fleft, fcenter, fright); + } +} + +bool Doc::completeLoading( KoStore* /* _store */ ) +{ + kdDebug(36001) << "------------------------ COMPLETING --------------------" << endl; + + d->isLoading = false; + + // map()->update(); + + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + ((View*)it.current())->initialPosition(); + + kdDebug(36001) << "------------------------ COMPLETION DONE --------------------" << endl; + + setModified( false ); + return true; +} + + +void Doc::registerPlugin( Plugin * plugin ) +{ + d->plugins.append( plugin ); +} + +void Doc::deregisterPlugin( Plugin * plugin ) +{ + d->plugins.remove( plugin ); +} + +bool Doc::docData( QString const & xmlTag, QDomElement & data ) +{ + SavedDocParts::iterator iter = m_savedDocParts.find( xmlTag ); + if ( iter == m_savedDocParts.end() ) + return false; + + data = iter.data(); + m_savedDocParts.erase( iter ); + + return true; +} + +void Doc::setShowVerticalScrollBar(bool _show) +{ + d->verticalScrollBar=_show; +} + +bool Doc::showVerticalScrollBar()const +{ + return d->verticalScrollBar; +} + +void Doc::setShowHorizontalScrollBar(bool _show) +{ + d->horizontalScrollBar=_show; +} + +bool Doc::showHorizontalScrollBar()const +{ + return d->horizontalScrollBar; +} + +KGlobalSettings::Completion Doc::completionMode( ) const +{ + return d->completionMode; +} + +void Doc::setShowColumnHeader(bool _show) +{ + d->columnHeader=_show; +} + +bool Doc::showColumnHeader() const +{ + return d->columnHeader; +} + +void Doc::setShowRowHeader(bool _show) +{ + d->rowHeader=_show; +} + +bool Doc::showRowHeader() const +{ + return d->rowHeader; +} + +void Doc::setGridColor( const QColor& color ) +{ + d->gridColor = color; +} + +QColor Doc::gridColor() const +{ + return d->gridColor; +} + +void Doc::setCompletionMode( KGlobalSettings::Completion complMode) +{ + d->completionMode= complMode; +} + +double Doc::indentValue() const +{ + return d->indentValue; +} + +void Doc::setIndentValue( double val ) +{ + d->indentValue = val; +} + +void Doc::setShowStatusBar(bool _statusBar) +{ + d->showStatusBar=_statusBar; +} + +bool Doc::showStatusBar() const +{ + return d->showStatusBar; +} + +void Doc::setShowTabBar(bool _tabbar) +{ + d->showTabBar=_tabbar; +} + +bool Doc::showTabBar()const +{ + return d->showTabBar; +} + +void Doc::setShowFormulaBar(bool _formulaBar) +{ + d->showFormulaBar=_formulaBar; +} + +bool Doc::showFormulaBar() const +{ + return d->showFormulaBar; +} + +void Doc::setShowMessageError(bool _show) +{ + d->showError=_show; +} + +bool Doc::showMessageError() const +{ + return d->showError; +} + +KSpread::MoveTo Doc::getMoveToValue() const +{ + return d->moveTo; +} + +void Doc::setMoveToValue(KSpread::MoveTo _moveTo) +{ + d->moveTo = _moveTo; +} + +void Doc::setTypeOfCalc( MethodOfCalc _calc) +{ + d->calcMethod=_calc; +} + +MethodOfCalc Doc::getTypeOfCalc() const +{ + return d->calcMethod; +} + +void Doc::setKSpellConfig(KSpellConfig _kspell) +{ + if (d->spellConfig == 0 ) + d->spellConfig = new KSpellConfig(); + + d->spellConfig->setNoRootAffix(_kspell.noRootAffix ()); + d->spellConfig->setRunTogether(_kspell.runTogether ()); + d->spellConfig->setDictionary(_kspell.dictionary ()); + d->spellConfig->setDictFromList(_kspell.dictFromList()); + d->spellConfig->setEncoding(_kspell.encoding()); + d->spellConfig->setClient(_kspell.client()); +} + +KSpellConfig * Doc::getKSpellConfig() +{ + if (!d->spellConfig) + { + KSpellConfig ksconfig; + + KConfig *config = Factory::global()->config(); + if( config->hasGroup("KSpell kspread" ) ) + { + config->setGroup( "KSpell kspread" ); + ksconfig.setNoRootAffix(config->readNumEntry ("KSpell_NoRootAffix", 0)); + ksconfig.setRunTogether(config->readNumEntry ("KSpell_RunTogether", 0)); + ksconfig.setDictionary(config->readEntry ("KSpell_Dictionary", "")); + ksconfig.setDictFromList(config->readNumEntry ("KSpell_DictFromList", false)); + ksconfig.setEncoding(config->readNumEntry ("KSpell_Encoding", KS_E_ASCII)); + ksconfig.setClient(config->readNumEntry ("KSpell_Client", KS_CLIENT_ISPELL)); + setKSpellConfig(ksconfig); + + setDontCheckUpperWord(config->readBoolEntry("KSpell_IgnoreUppercaseWords", false)); + setDontCheckTitleCase(config->readBoolEntry("KSpell_IgnoreTitleCaseWords", false)); + } + } + return d->spellConfig; +} + +bool Doc::dontCheckUpperWord() const +{ + return d->dontCheckUpperWord; +} + +void Doc::setDontCheckUpperWord( bool b ) +{ + d->dontCheckUpperWord = b; +} + +bool Doc::dontCheckTitleCase() const +{ + return d->dontCheckTitleCase; +} + +void Doc::setDontCheckTitleCase( bool b ) +{ + d->dontCheckTitleCase = b; +} + +QString Doc::unitName() const +{ + return KoUnit::unitName( unit() ); +} + +void Doc::increaseNumOperation() +{ + ++d->numOperations; +} + +void Doc::decreaseNumOperation() +{ + --d->numOperations; +} + +void Doc::addIgnoreWordAllList( const QStringList & _lst) +{ + d->spellListIgnoreAll = _lst; +} + +QStringList Doc::spellListIgnoreAll() const +{ + return d->spellListIgnoreAll; +} + +void Doc::setZoomAndResolution( int zoom, int dpiX, int dpiY ) +{ + KoZoomHandler::setZoomAndResolution( zoom, dpiX, dpiY ); +} + +void Doc::newZoomAndResolution( bool updateViews, bool /*forPrint*/ ) +{ +/* layout(); + updateAllFrames();*/ + if ( updateViews ) + { + emit sig_refreshView(); + } +} + +void Doc::addCommand( KCommand* command ) +{ + if (undoLocked()) return; + d->commandHistory->addCommand( command, false ); + setModified( true ); +} + +void Doc::addCommand( UndoAction* undo ) +{ + if (undoLocked()) return; + UndoWrapperCommand* command = new UndoWrapperCommand( undo ); + addCommand( command ); + setModified( true ); +} + +void Doc::undo() +{ + undoLock (); + d->commandHistory->undo(); + undoUnlock (); +} + +void Doc::redo() +{ + undoLock (); + d->commandHistory->redo(); + undoUnlock (); +} + +void Doc::commandExecuted() +{ + setModified( true ); +} + +void Doc::documentRestored() +{ + setModified( false ); +} + +void Doc::undoLock() +{ + d->undoLocked++; +} + +void Doc::undoUnlock() +{ + d->undoLocked--; +} + +bool Doc::undoLocked() const +{ + return (d->undoLocked > 0); +} + +KoCommandHistory* Doc::commandHistory() +{ + return d->commandHistory; +} + +void Doc::enableUndo( bool _b ) +{ + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + static_cast<View *>( it.current() )->enableUndo( _b ); +} + +void Doc::enableRedo( bool _b ) +{ + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + static_cast<View *>( it.current() )->enableRedo( _b ); +} + +void Doc::paintContent( QPainter& painter, const QRect& rect, + bool transparent, double zoomX, double /*zoomY*/ ) +{ + kdDebug(36001) << "paintContent() called on " << rect << endl; + + // ElapsedTime et( "Doc::paintContent1" ); + //kdDebug(36001) << "Doc::paintContent m_zoom=" << m_zoom << " zoomX=" << zoomX << " zoomY=" << zoomY << " transparent=" << transparent << endl; + + // save current zoom + int oldZoom = m_zoom; + + // choose sheet: the first or the active + Sheet* sheet = 0L; + if ( !d->activeSheet ) + sheet = map()->firstSheet(); + else + sheet = d->activeSheet; + if ( !sheet ) + return; + + // only one zoom is supported + double d_zoom = 1.0; + setZoomAndResolution( 100, KoGlobal::dpiX(), KoGlobal::dpiY() ); + if ( m_zoomedResolutionX != zoomX ) + d_zoom *= ( zoomX / m_zoomedResolutionX ); + + // KSpread support zoom, therefore no need to scale with worldMatrix + QWMatrix matrix = painter.worldMatrix(); + matrix.setMatrix( 1, 0, 0, 1, matrix.dx(), matrix.dy() ); + QRect prect = rect; + prect.setWidth( (int) (prect.width() * painter.worldMatrix().m11()) ); + prect.setHeight( (int) (prect.height() * painter.worldMatrix().m22()) ); + setZoomAndResolution( (int) ( d_zoom * 100 ), KoGlobal::dpiX(), KoGlobal::dpiY() ); + // paint the content, now zoom is correctly set + kdDebug(36001)<<"paintContent-------------------------------------\n"; + painter.save(); + painter.setWorldMatrix( matrix ); + paintContent( painter, prect, transparent, sheet, false ); + painter.restore(); + + // restore zoom + m_zoom = oldZoom; + setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() ); +} + +void Doc::paintContent( QPainter& painter, const QRect& rect, bool /*transparent*/, Sheet* sheet, bool drawCursor ) +{ + if ( isLoading() ) + return; + // ElapsedTime et( "Doc::paintContent2" ); + + // if ( !transparent ) + // painter.eraseRect( rect ); + + double xpos; + double ypos; + int left_col = sheet->leftColumn( unzoomItX( rect.x() ), xpos ); + int right_col = sheet->rightColumn( unzoomItX( rect.right() ) ); + int top_row = sheet->topRow( unzoomItY( rect.y() ), ypos ); + int bottom_row = sheet->bottomRow( unzoomItY( rect.bottom() ) ); + QPen pen; + pen.setWidth( 1 ); + painter.setPen( pen ); + + /* Update the entire visible area. */ + QValueList<QRect> cellAreaList; + cellAreaList.append( QRect( left_col, + top_row, + right_col - left_col + 1, + bottom_row - top_row + 1) ); + + paintCellRegions(painter, rect, NULL, cellAreaList, sheet, drawCursor); +} + +void Doc::paintUpdates() +{ + // ElapsedTime et( "Doc::paintUpdates" ); + + QPtrListIterator<KoView> it( views() ); + View * view = NULL; + Sheet * sheet = NULL; + + for (; it.current(); ++it ) + { + view = static_cast<View *>( it.current() ); + view->paintUpdates(); + } + + for (sheet = map()->firstSheet(); sheet != NULL; + sheet = map()->nextSheet()) + { + sheet->clearPaintDirtyData(); + } +} + +void Doc::paintCellRegions(QPainter& painter, const QRect &viewRect, + View* view, + QValueList<QRect> cellRegions, + const Sheet* sheet, bool /*drawCursor*/) +{ + // + // Clip away children + // + + QRegion rgn = painter.clipRegion(); + if ( rgn.isEmpty() ) + rgn = QRegion( QRect( 0, 0, viewRect.width(), viewRect.height() ) ); + + QWMatrix matrix; + if ( view ) { + matrix.scale( zoomedResolutionX(), + zoomedResolutionY() ); + matrix.translate( - view->canvasWidget()->xOffset(), + - view->canvasWidget()->yOffset() ); + } + else { + matrix = painter.worldMatrix(); + } + +// QPtrListIterator<KoDocumentChild> it( children() ); +// for( ; it.current(); ++it ) { +// // if ( ((Child*)it.current())->sheet() == sheet && +// // !m_pView->hasDocumentInWindow( it.current()->document() ) ) +// if ( ((Child*)it.current())->sheet() == sheet) +// rgn -= it.current()->region( matrix ); +// } + painter.setClipRegion( rgn ); + + QPen pen; + pen.setWidth( 1 ); + painter.setPen( pen ); + + QRect cellRegion; + KoRect unzoomedViewRect = unzoomRect( viewRect ); + + for (unsigned int i=0; i < cellRegions.size(); i++) { + cellRegion = cellRegions[i]; + + PaintRegion(painter, unzoomedViewRect, view, cellRegion, sheet); + } +} + + +void Doc::PaintRegion(QPainter &painter, const KoRect &viewRegion, + View* view, const QRect &paintRegion, + const Sheet* sheet) +{ + // Paint region has cell coordinates (col,row) while viewRegion has + // world coordinates. paintRegion is the cells to update and + // viewRegion is the area actually onscreen. + + if ( paintRegion.left() <= 0 || paintRegion.top() <= 0 ) + return; + + // Get the world coordinates of the upper left corner of the + // paintRegion The view is NULL, when paintRegion is called from + // paintContent, which itself is only called, when we should paint + // the output for INACTIVE embedded view. If inactive embedded, + // then there is no view and we alwas start at top/left, so the + // offset is 0. + // + KoPoint dblCorner; + if ( view == 0L ) //Most propably we are embedded and inactive, so no offset + dblCorner = KoPoint( sheet->dblColumnPos( paintRegion.left() ), + sheet->dblRowPos( paintRegion.top() ) ); + else + dblCorner = KoPoint( sheet->dblColumnPos( paintRegion.left() ) + - view->canvasWidget()->xOffset(), + sheet->dblRowPos( paintRegion.top() ) + - view->canvasWidget()->yOffset() ); + KoPoint dblCurrentCellPos( dblCorner ); + + int regionBottom = paintRegion.bottom(); + int regionRight = paintRegion.right(); + int regionLeft = paintRegion.left(); + int regionTop = paintRegion.top(); + + QValueList<QPoint> mergedCellsPainted; + for ( int y = regionTop; + y <= regionBottom && dblCurrentCellPos.y() <= viewRegion.bottom(); + ++y ) + { + const RowFormat * row_lay = sheet->rowFormat( y ); + dblCurrentCellPos.setX( dblCorner.x() ); + + for ( int x = regionLeft; + x <= regionRight && dblCurrentCellPos.x() <= viewRegion.right(); + ++x ) + { + const ColumnFormat *col_lay = sheet->columnFormat( x ); + Cell* cell = sheet->cellAt( x, y ); + + QPoint cellRef( x, y ); + +#if 0 + bool paintBordersBottom = false; + bool paintBordersRight = false; + bool paintBordersLeft = false; + bool paintBordersTop = false; +#endif + int paintBorder = Cell::Border_None; + + QPen rightPen( cell->effRightBorderPen( x, y ) ); + QPen leftPen( cell->effLeftBorderPen( x, y ) ); + QPen topPen( cell->effTopBorderPen( x, y ) ); + QPen bottomPen( cell->effBottomBorderPen( x, y ) ); + + // Paint border if outermost cell or if the pen is more "worth" + // than the border pen of the cell on the other side of the + // border or if the cell on the other side is not painted. In + // the latter case get the pen that is of more "worth" + + // right border: + if ( x >= KS_colMax ) + //paintBordersRight = true; + paintBorder |= Cell::Border_Right; + else if ( x == regionRight ) { + paintBorder |= Cell::Border_Right; + if ( cell->effRightBorderValue( x, y ) + < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) ) + rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y ); + } + else { + paintBorder |= Cell::Border_Right; + if ( cell->effRightBorderValue( x, y ) + < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) ) + rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y ); + } + + // Similiar for other borders... + // bottom border: + if ( y >= KS_rowMax ) + paintBorder |= Cell::Border_Bottom; + else if ( y == regionBottom ) { + paintBorder |= Cell::Border_Bottom; + if ( cell->effBottomBorderValue( x, y ) + < sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) ) + bottomPen = sheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 ); + } + else { + paintBorder |= Cell::Border_Bottom; + if ( cell->effBottomBorderValue( x, y ) + < sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) ) + bottomPen = sheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 ); + } + + // left border: + if ( x == 1 ) + paintBorder |= Cell::Border_Left; + else if ( x == regionLeft ) { + paintBorder |= Cell::Border_Left; + if ( cell->effLeftBorderValue( x, y ) + < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) ) + leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y ); + } + else { + paintBorder |= Cell::Border_Left; + if ( cell->effLeftBorderValue( x, y ) + < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) ) + leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y ); + } + + // top border: + if ( y == 1 ) + paintBorder |= Cell::Border_Top; + else if ( y == regionTop ) { + paintBorder |= Cell::Border_Top; + if ( cell->effTopBorderValue( x, y ) + < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) ) + topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 ); + } + else { + paintBorder |= Cell::Border_Top; + if ( cell->effTopBorderValue( x, y ) + < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) ) + topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 ); + } + +#if 0 + cell->paintCell( viewRegion, painter, view, dblCurrentCellPos, cellRef, + paintBordersRight, paintBordersBottom, + paintBordersLeft, paintBordersTop, + rightPen, bottomPen, leftPen, topPen, + mergedCellsPainted, false ); + + Cell::BorderSides highlightBorder=Cell::Border_None; + QPen highlightPen; +#endif + + cell->paintCell( viewRegion, painter, view, dblCurrentCellPos, cellRef, + paintBorder, + rightPen, bottomPen, leftPen, topPen, + mergedCellsPainted, false ); + + + dblCurrentCellPos.setX( dblCurrentCellPos.x() + col_lay->dblWidth() ); + } + dblCurrentCellPos.setY( dblCurrentCellPos.y() + row_lay->dblHeight() ); + } +} + + +DCOPObject* Doc::dcopObject() +{ + if ( !d->dcop ) + d->dcop = new DocIface( this ); + + return d->dcop; +} + +void Doc::addAreaName(const QRect &_rect,const QString & name,const QString & sheetName) +{ + setModified( true ); + Reference tmp; + tmp.rect = _rect; + tmp.sheet_name = sheetName; + tmp.ref_name = name; + d->refs.append( tmp); + emit sig_addAreaName( name ); +} + +void Doc::removeArea( const QString & name) +{ + QValueList<Reference>::Iterator it2; + for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 ) + { + if((*it2).ref_name==name) + { + d->refs.remove(it2); + emit sig_removeAreaName( name ); + return; + } + } +} + +void Doc::changeAreaSheetName(const QString & oldName,const QString & sheetName) +{ + QValueList<Reference>::Iterator it2; + for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 ) + { + if((*it2).sheet_name==oldName) + (*it2).sheet_name=sheetName; + } +} + +QRect Doc::getRectArea(const QString &_sheetName) +{ + QValueList<Reference>::Iterator it2; + for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 ) + { + if((*it2).ref_name==_sheetName) + { + return (*it2).rect; + } + } + return QRect(-1,-1,-1,-1); +} + +QDomElement Doc::saveAreaName( QDomDocument& doc ) +{ + QDomElement element = doc.createElement( "areaname" ); + QValueList<Reference>::Iterator it2; + for ( it2 = d->refs.begin(); it2 != d->refs.end(); ++it2 ) + { + QDomElement e = doc.createElement("reference"); + QDomElement tabname = doc.createElement( "tabname" ); + tabname.appendChild( doc.createTextNode( (*it2).sheet_name ) ); + e.appendChild( tabname ); + + QDomElement refname = doc.createElement( "refname" ); + refname.appendChild( doc.createTextNode( (*it2).ref_name ) ); + e.appendChild( refname ); + + QDomElement rect = doc.createElement( "rect" ); + rect.setAttribute( "left-rect", ((*it2).rect).left() ); + rect.setAttribute( "right-rect",((*it2).rect).right() ); + rect.setAttribute( "top-rect", ((*it2).rect).top() ); + rect.setAttribute( "bottom-rect", ((*it2).rect).bottom() ); + e.appendChild( rect ); + element.appendChild(e); + } + return element; +} + +void Doc::loadOasisCellValidation( const QDomElement&body ) +{ + QDomNode validation = KoDom::namedItemNS( body, KoXmlNS::table, "content-validations" ); + kdDebug()<<"void Doc::loadOasisCellValidation( const QDomElement&body ) \n"; + kdDebug()<<"validation.isNull ? "<<validation.isNull()<<endl; + if ( !validation.isNull() ) + { + QDomNode n = validation.firstChild(); + for( ; !n.isNull(); n = n.nextSibling() ) + { + if ( n.isElement() ) + { + QDomElement element = n.toElement(); + //kdDebug()<<" loadOasisCellValidation element.tagName() :"<<element.tagName()<<endl; + if ( element.tagName() == "content-validation" && element.namespaceURI() == KoXmlNS::table ) { + d->m_loadingInfo->appendValidation(element.attributeNS( KoXmlNS::table, "name", QString::null ), element ); + kdDebug()<<" validation found :"<<element.attributeNS( KoXmlNS::table, "name", QString::null )<<endl; + } + else { + kdDebug()<<" Tag not recognize :"<<element.tagName()<<endl; + } + } + } + } +} + +void Doc::saveOasisAreaName( KoXmlWriter & xmlWriter ) +{ + if ( listArea().count()>0 ) + { + xmlWriter.startElement( "table:named-expressions" ); + QValueList<Reference>::Iterator it; + for ( it = d->refs.begin(); it != d->refs.end(); ++it ) + { + xmlWriter.startElement( "table:named-range" ); + + xmlWriter.addAttribute( "table:name", ( *it ).ref_name ); + xmlWriter.addAttribute( "table:base-cell-address", convertRefToBase( ( *it ).sheet_name, ( *it ).rect ) ); + xmlWriter.addAttribute( "table:cell-range-address", convertRefToRange( ( *it ).sheet_name, ( *it ).rect ) ); + + xmlWriter.endElement(); + } + xmlWriter.endElement(); + } +} + +void Doc::loadOasisAreaName( const QDomElement& body ) +{ + kdDebug()<<"void Doc::loadOasisAreaName( const QDomElement& body ) \n"; + QDomNode namedAreas = KoDom::namedItemNS( body, KoXmlNS::table, "named-expressions" ); + if ( !namedAreas.isNull() ) + { + kdDebug()<<" area name exist \n"; + QDomNode area = namedAreas.firstChild(); + while ( !area.isNull() ) + { + QDomElement e = area.toElement(); + + if ( e.localName() == "named-range" ) + { + if ( !e.hasAttributeNS( KoXmlNS::table, "name" ) || !e.hasAttributeNS( KoXmlNS::table, "cell-range-address" ) ) + { + kdDebug() << "Reading in named area failed" << endl; + area = area.nextSibling(); + continue; + } + + // TODO: what is: sheet:base-cell-address + QString name = e.attributeNS( KoXmlNS::table, "name", QString::null ); + QString range = e.attributeNS( KoXmlNS::table, "cell-range-address", QString::null ); + kdDebug()<<"area name : "<<name<<" range :"<<range<<endl; + d->m_loadingInfo->addWordInAreaList( name ); + kdDebug() << "Reading in named area, name: " << name << ", area: " << range << endl; + + range = Oasis::decodeFormula( range ); + + if ( range.find( ':' ) == -1 ) + { + Point p( range ); + + int n = range.find( '!' ); + if ( n > 0 ) + range = range + ":" + range.right( range.length() - n - 1); + + kdDebug() << "=> Area: " << range << endl; + } + + if ( range.contains( '!' ) && range[0] == '$' ) + { + // cut absolute sheet indicator + range.remove( 0, 1 ); + } + + Range p( range ); + + addAreaName( p.range(), name, p.sheetName() ); + kdDebug() << "Area range: " << p.toString() << endl; + } + else if ( e.localName() == "named-expression" ) + { + kdDebug() << "Named expression found." << endl; + // TODO + } + + area = area.nextSibling(); + } + } +} + +void Doc::loadAreaName( const QDomElement& element ) +{ + QDomElement tmp=element.firstChild().toElement(); + for( ; !tmp.isNull(); tmp=tmp.nextSibling().toElement() ) + { + if ( tmp.tagName() == "reference" ) + { + QString tabname; + QString refname; + int left=0; + int right=0; + int top=0; + int bottom=0; + QDomElement sheetName = tmp.namedItem( "tabname" ).toElement(); + if ( !sheetName.isNull() ) + { + tabname=sheetName.text(); + } + QDomElement referenceName = tmp.namedItem( "refname" ).toElement(); + if ( !referenceName.isNull() ) + { + refname=referenceName.text(); + } + QDomElement rect =tmp.namedItem( "rect" ).toElement(); + if (!rect.isNull()) + { + bool ok; + if ( rect.hasAttribute( "left-rect" ) ) + left=rect.attribute("left-rect").toInt( &ok ); + if ( rect.hasAttribute( "right-rect" ) ) + right=rect.attribute("right-rect").toInt( &ok ); + if ( rect.hasAttribute( "top-rect" ) ) + top=rect.attribute("top-rect").toInt( &ok ); + if ( rect.hasAttribute( "bottom-rect" ) ) + bottom=rect.attribute("bottom-rect").toInt( &ok ); + } + QRect _rect; + _rect.setCoords(left,top,right,bottom); + addAreaName(_rect,refname,tabname); + } + } +} + +void Doc::addStringCompletion(const QString &stringCompletion) +{ + if ( d->listCompletion.items().contains(stringCompletion) == 0 ) + d->listCompletion.addItem( stringCompletion ); +} + +void Doc::refreshInterface() +{ + emit sig_refreshView(); +} + +void Doc::refreshLocale() +{ + emit sig_refreshLocale(); +} + + +void Doc::emitBeginOperation(bool waitCursor) +{ + //If an emitBeginOperation occurs with waitCursor enabled, then the waiting cursor is set + //until all operations have been completed. + // + //The reason being that any operations started before the first one with waitCursor set + //are expected to be completed in a short time anyway. + QCursor* activeOverride = QApplication::overrideCursor(); + + if (waitCursor && ( (!activeOverride) || (activeOverride->shape() != Qt::waitCursor.shape()) ) ) + { + QApplication::setOverrideCursor(Qt::waitCursor); + } + +// /* just duplicate the current cursor on the stack, then */ +// else if (QApplication::overrideCursor() != NULL) +// { +// QApplication::setOverrideCursor(QApplication::overrideCursor()->shape()); +// } + + KoDocument::emitBeginOperation(); + d->delayCalculation = true; + d->numOperations++; +} + +void Doc::emitBeginOperation(void) +{ + emitBeginOperation(true); +} + + +void Doc::emitEndOperation() +{ + d->numOperations--; + + if (d->numOperations <= 0) + { + d->numOperations = 0; + d->delayCalculation = false; + } + + KoDocument::emitEndOperation(); + + if (d->numOperations == 0) + { + QApplication::restoreOverrideCursor(); + + /* do this after the parent class emitEndOperation because that allows updates + on the view again + */ + paintUpdates(); + } +} + +void Doc::emitEndOperation( const Region& /*region*/ ) +{ + d->numOperations--; + + if ( d->numOperations > 0 || !d->activeSheet ) + { + KoDocument::emitEndOperation(); + return; + } + + d->numOperations = 0; + d->delayCalculation = false; + + KoDocument::emitEndOperation(); + + QApplication::restoreOverrideCursor(); + + /* do this after the parent class emitEndOperation because that allows updates + on the view again + */ + paintUpdates(); +} + +bool Doc::delayCalculation() const +{ + return d->delayCalculation; +} + +void Doc::updateBorderButton() +{ + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + static_cast<View *>( it.current() )->updateBorderButton(); +} + +void Doc::insertSheet( Sheet * sheet ) +{ + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + ((View*)it.current())->insertSheet( sheet ); +} + +void Doc::takeSheet( Sheet * sheet ) +{ + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + ((View*)it.current())->removeSheet( sheet ); +} + +void Doc::addIgnoreWordAll( const QString & word) +{ + if( d->spellListIgnoreAll.findIndex( word )==-1) + d->spellListIgnoreAll.append( word ); +} + +void Doc::clearIgnoreWordAll( ) +{ + d->spellListIgnoreAll.clear(); +} + +void Doc::setDisplaySheet(Sheet *_sheet ) +{ + d->activeSheet = _sheet; +} + +KSPLoadingInfo * Doc::loadingInfo() const +{ + return d->m_loadingInfo; +} + +void Doc::deleteLoadingInfo() +{ + delete d->m_loadingInfo; + d->m_loadingInfo = 0; +} + +Sheet * Doc::displaySheet() const +{ + return d->activeSheet; +} + +void Doc::addView( KoView *_view ) +{ + KoDocument::addView( _view ); + QPtrListIterator<KoView> it( views() ); + for (; it.current(); ++it ) + ((View*)it.current())->closeEditor(); +} + +void Doc::addDamage( Damage* damage ) +{ + d->damages.append( damage ); + + if( d->damages.count() == 1 ) + QTimer::singleShot( 0, this, SLOT( flushDamages() ) ); +} + +void Doc::flushDamages() +{ + emit damagesFlushed( d->damages ); + QValueList<Damage*>::Iterator it; + for( it = d->damages.begin(); it != d->damages.end(); ++it ) + delete *it; + d->damages.clear(); +} + +void Doc::loadConfigFromFile() +{ + d->configLoadFromFile = true; +} + +bool Doc::configLoadFromFile() const +{ + return d->configLoadFromFile; +} + + +void Doc::insertObject( EmbeddedObject * obj ) +{ + switch ( obj->getType() ) + { + case OBJECT_KOFFICE_PART: case OBJECT_CHART: + { + KoDocument::insertChild( dynamic_cast<EmbeddedKOfficeObject*>(obj)->embeddedObject() ); + break; + } + default: + ; + } + d->m_embeddedObjects.append( obj ); +} + +QPtrList<EmbeddedObject>& Doc::embeddedObjects() +{ + return d->m_embeddedObjects; +} + +KoPictureCollection *Doc::pictureCollection() +{ + return &d->m_pictureCollection; +} + +void Doc::repaint( const QRect& rect ) +{ + QRect r; + QPtrListIterator<KoView> it( views() ); + for( ; it.current(); ++it ) + { + r = rect; + Canvas* canvas = ((View*)it.current())->canvasWidget(); + r.moveTopLeft( QPoint( r.x() - (int) canvas->xOffset(), + r.y() - (int) canvas->yOffset() ) ); + canvas->update( r ); + } +} + +void Doc::repaint( EmbeddedObject *obj ) +{ + QPtrListIterator<KoView> it( views() ); + for( ; it.current(); ++it ) + { + Canvas* canvas = ((View*)it.current())->canvasWidget(); + if ( obj->sheet() == canvas->activeSheet() ) + canvas->repaintObject( obj ); + } +} + +void Doc::repaint( const KoRect& rect ) +{ + QRect r; + QPtrListIterator<KoView> it( views() ); + for( ; it.current(); ++it ) + { + Canvas* canvas = ((View*)it.current())->canvasWidget(); + + r = zoomRect( rect ); + r.moveBy( (int)( -canvas->xOffset()*zoomedResolutionX() ) , + (int)( -canvas->yOffset() *zoomedResolutionY()) ); + canvas->update( r ); + } +} + +void Doc::addShell( KoMainWindow *shell ) +{ + connect( shell, SIGNAL( documentSaved() ), d->commandHistory, SLOT( documentSaved() ) ); + KoDocument::addShell( shell ); +} + +int Doc::undoRedoLimit() const +{ + return d->commandHistory->undoLimit(); +} + +void Doc::setUndoRedoLimit(int val) +{ + d->commandHistory->setUndoLimit(val); + d->commandHistory->setRedoLimit(val); +} + +void Doc::insertPixmapKey( KoPictureKey key ) +{ + if ( !d->usedPictures.contains( key ) ) + d->usedPictures.append( key ); +} + +void Doc::makeUsedPixmapList() +{ + d->usedPictures.clear(); + QPtrListIterator<EmbeddedObject> it( d->m_embeddedObjects ); + for ( ; it.current() ; ++it ) + { + if( it.current()->getType() == OBJECT_PICTURE && ( d->m_savingWholeDocument || it.current()->isSelected() ) ) + insertPixmapKey( static_cast<EmbeddedPictureObject*>( it.current() )->getKey() ); + } +} + +bool Doc::savingWholeDocument() +{ + return d->m_savingWholeDocument; +} + +#include "kspread_doc.moc" + -- cgit v1.2.1