kspread Library API Documentation

kspread_map.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 
00021 #include "kspread_map.h"
00022 #include "kspread_doc.h"
00023 #include "kspread_canvas.h"
00024 #include "kspread_view.h"
00025 #include "kspread_locale.h"
00026 #include "kspread_genvalidationstyle.h"
00027 #include "KSpreadMapIface.h"
00028 
00029 #include <koOasisSettings.h>
00030 #include <kmdcodec.h>
00031 #include <koGenStyles.h>
00032 #include <koxmlns.h>
00033 #include <kodom.h>
00034 #include <time.h>
00035 #include <stdlib.h>
00036 #include <ktempfile.h>
00037 #include <qfile.h>
00038 
00039 bool KSpreadMap::respectCase = true;
00040 
00041 KSpreadMap::KSpreadMap ( KSpreadDoc* doc, const char* name)
00042   : QObject( doc, name ),
00043     m_initialActiveSheet( 0 ),
00044     m_initialMarkerColumn( 0 ),
00045     m_initialMarkerRow( 0 ),
00046     tableId (1),
00047     m_doc( doc ),
00048     m_dcop( 0 )
00049 {
00050   m_lstSheets.setAutoDelete( true );
00051 }
00052 
00053 KSpreadMap::~KSpreadMap()
00054 {
00055     delete m_dcop;
00056 }
00057 
00058 KSpreadDoc* KSpreadMap::doc()
00059 {
00060   return m_doc;
00061 }
00062 
00063 void KSpreadMap::setProtected( QCString const & passwd )
00064 {
00065   m_strPassword = passwd;
00066 }
00067 
00068 KSpreadSheet* KSpreadMap::createSheet()
00069 {
00070   QString s( i18n("Sheet%1") );
00071   s = s.arg( tableId++ );
00072   KSpreadSheet *t = new KSpreadSheet ( this, s , s.utf8());
00073   t->setSheetName( s, TRUE ); // huh? (Werner)
00074   return t;
00075 }
00076 
00077 void KSpreadMap::addSheet( KSpreadSheet *_sheet )
00078 {
00079   m_lstSheets.append( _sheet );
00080 
00081   m_doc->setModified( TRUE );
00082 
00083   emit sig_addSheet( _sheet );
00084 }
00085 
00086 KSpreadSheet *KSpreadMap::addNewSheet ()
00087 {
00088   KSpreadSheet *t = createSheet ();
00089   addSheet (t);
00090   return t;
00091 }
00092 
00093 void KSpreadMap::moveSheet( const QString & _from, const QString & _to, bool _before )
00094 {
00095   KSpreadSheet* sheetfrom = findSheet( _from );
00096   KSpreadSheet* sheetto = findSheet( _to );
00097 
00098   int from = m_lstSheets.find( sheetfrom ) ;
00099   int to = m_lstSheets.find( sheetto ) ;
00100   if ( !_before )
00101   ++to;
00102 
00103   if ( to > (int)m_lstSheets.count() )
00104   {
00105     m_lstSheets.append( sheetfrom );
00106     m_lstSheets.take( from );
00107   }
00108   else if ( from < to )
00109   {
00110     m_lstSheets.insert( to, sheetfrom );
00111     m_lstSheets.take( from );
00112   }
00113   else
00114   {
00115     m_lstSheets.take( from );
00116     m_lstSheets.insert( to, sheetfrom );
00117   }
00118 }
00119 
00120 void KSpreadMap::loadOasisSettings( KoOasisSettings &settings )
00121 {
00122     KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
00123     KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
00124     KoOasisSettings::Items firstView = viewMap.entry( 0 );
00125 
00126     KoOasisSettings::NamedMap sheetsMap = firstView.namedMap( "Tables" );
00127     kdDebug()<<" loadOasisSettings( KoOasisSettings &settings ) exist : "<< !sheetsMap.isNull() <<endl;
00128     if ( !sheetsMap.isNull() )
00129     {
00130         QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00131         for( ; it.current(); ++it )
00132         {
00133             it.current()->loadOasisSettings( sheetsMap );
00134         }
00135     }
00136 
00137     QString activeSheet = firstView.parseConfigItemString( "ActiveTable" );
00138     kdDebug()<<" loadOasisSettings( KoOasisSettings &settings ) activeSheet :"<<activeSheet<<endl;
00139 
00140     if (!activeSheet.isEmpty())
00141     {
00142         // Used by KSpreadView's constructor
00143         m_initialActiveSheet = findSheet( activeSheet );
00144     }
00145 
00146 }
00147 
00148 void KSpreadMap::saveOasisSettings( KoXmlWriter &settingsWriter )
00149 {
00150     settingsWriter.addConfigItem( "ViewId", QString::fromLatin1( "View1" ) );
00151     // Save visual info for the first view, such as active sheet and active cell
00152     // It looks like a hack, but reopening a document creates only one view anyway (David)
00153     KSpreadView * view = static_cast<KSpreadView*>( m_doc->views().getFirst());
00154     if ( view ) // no view if embedded document
00155     {
00156         // save current sheet selection before to save marker, otherwise current pos is not saved
00157         view->saveCurrentSheetSelection();
00158         KSpreadCanvas * canvas = view->canvasWidget();
00159         //<config:config-item config:name="ActiveTable" config:type="string">Feuille1</config:config-item>
00160         settingsWriter.addConfigItem( "ActiveTable",  canvas->activeSheet()->sheetName() );
00161     }
00162 
00163     //<config:config-item-map-named config:name="Tables">
00164     settingsWriter.startElement("config:config-item-map-named" );
00165     settingsWriter.addAttribute("config:name","Tables" );
00166     QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00167     for( ; it.current(); ++it )
00168     {
00169         QPoint marker;
00170         if ( view )
00171         {
00172             marker = view->markerFromSheet( *it );
00173         }
00174         settingsWriter.startElement( "config:config-item-map-entry" );
00175         settingsWriter.addAttribute( "config:name", ( *it )->sheetName() );
00176         it.current()->saveOasisSettings( settingsWriter, marker);
00177         settingsWriter.endElement();
00178     }
00179     settingsWriter.endElement();
00180 }
00181 
00182 
00183 bool KSpreadMap::saveOasis( KoXmlWriter & xmlWriter, KoGenStyles & mainStyles )
00184 {
00185     if ( !m_strPassword.isEmpty() )
00186     {
00187         xmlWriter.addAttribute("table:structure-protected", "true" );
00188         QCString str = KCodecs::base64Encode( m_strPassword );
00189         xmlWriter.addAttribute("table:protection-key", QString( str.data() ) );/* FIXME !!!!*/
00190     }
00191 
00192     KSpreadGenValidationStyles valStyle;
00193 
00194     KTempFile bodyTmpFile;
00195     bodyTmpFile.setAutoDelete( true );
00196     QFile* tmpFile = bodyTmpFile.file();
00197     KoXmlWriter bodyTmpWriter( tmpFile );
00198 
00199 
00200     QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00201     for( ; it.current(); ++it )
00202     {
00203         it.current()->saveOasis( bodyTmpWriter, mainStyles, valStyle );
00204     }
00205 
00206     valStyle.writeStyle( xmlWriter );
00207 
00208 
00209     tmpFile->close();
00210     xmlWriter.addCompleteElement( tmpFile );
00211     bodyTmpFile.close();
00212 
00213     return true;
00214 }
00215 
00216 QDomElement KSpreadMap::save( QDomDocument& doc )
00217 {
00218   QDomElement mymap = doc.createElement( "map" );
00219   // Save visual info for the first view, such as active sheet and active cell
00220   // It looks like a hack, but reopening a document creates only one view anyway (David)
00221   KSpreadView * view = static_cast<KSpreadView*>(m_doc->views().getFirst());
00222   if ( view ) // no view if embedded document
00223   {
00224     KSpreadCanvas * canvas = view->canvasWidget();
00225     mymap.setAttribute( "activeTable", canvas->activeSheet()->sheetName() );
00226     mymap.setAttribute( "markerColumn", canvas->markerColumn() );
00227     mymap.setAttribute( "markerRow", canvas->markerRow() );
00228   }
00229 
00230   if ( !m_strPassword.isNull() )
00231   {
00232     if ( m_strPassword.size() > 0 )
00233     {
00234       QCString str = KCodecs::base64Encode( m_strPassword );
00235       mymap.setAttribute( "protected", QString( str.data() ) );
00236     }
00237     else
00238       mymap.setAttribute( "protected", "" );
00239   }
00240 
00241   QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00242   for( ; it.current(); ++it )
00243   {
00244     QDomElement e = it.current()->saveXML( doc );
00245     if ( e.isNull() )
00246       return e;
00247     mymap.appendChild( e );
00248   }
00249 
00250   return mymap;
00251 }
00252 
00253 bool KSpreadMap::loadOasis( const QDomElement& body, KoOasisStyles& oasisStyles )
00254 {
00255     if ( body.hasAttributeNS( KoXmlNS::table, "structure-protected" ) )
00256     {
00257         QCString passwd( "" );
00258         if ( body.hasAttributeNS( KoXmlNS::table, "protection-key" ) )
00259         {
00260             QString p = body.attributeNS( KoXmlNS::table, "protection-key", QString::null );
00261             QCString str( p.latin1() );
00262             kdDebug(30518) << "Decoding password: " << str << endl;
00263             passwd = KCodecs::base64Decode( str );
00264         }
00265         //todo remove me !!!!!!!! FIXME
00266         kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
00267         m_strPassword = passwd;
00268     }
00269     QDomNode sheetNode = KoDom::namedItemNS( body, KoXmlNS::table, "table" );
00270 
00271     // sanity check
00272     if ( sheetNode.isNull() ) return false;
00273 
00274     while ( !sheetNode.isNull() )
00275     {
00276         QDomElement sheetElement = sheetNode.toElement();
00277         if( !sheetElement.isNull() )
00278         {
00279             kdDebug()<<"  KSpreadMap::loadOasis tableElement is not null \n";
00280             kdDebug()<<"tableElement.nodeName() :"<<sheetElement.nodeName()<<endl;
00281             if( sheetElement.nodeName() == "table:table" )
00282             {
00283                 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00284                 {
00285                     KSpreadSheet* sheet = addNewSheet();
00286                     sheet->setSheetName( sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ), true, false );
00287                 }
00288             }
00289         }
00290         sheetNode = sheetNode.nextSibling();
00291     }
00292 
00293     // load the sheet
00294     sheetNode = body.firstChild();
00295     while ( !sheetNode.isNull() )
00296     {
00297         QDomElement sheetElement = sheetNode.toElement();
00298         if( !sheetElement.isNull() )
00299         {
00300             kdDebug()<<"tableElement.nodeName() bis :"<<sheetElement.nodeName()<<endl;
00301             if( sheetElement.nodeName() == "table:table" )
00302             {
00303                 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00304                 {
00305                     QString name = sheetElement.attributeNS( KoXmlNS::table, "name", QString::null );
00306                     KSpreadSheet* sheet = findSheet( name );
00307                     if( sheet )
00308                         sheet->loadOasis( sheetElement , oasisStyles );
00309                 }
00310             }
00311         }
00312         sheetNode = sheetNode.nextSibling();
00313     }
00314 
00315     return true;
00316 }
00317 
00318 
00319 bool KSpreadMap::loadXML( const QDomElement& mymap )
00320 {
00321   QString activeSheet = mymap.attribute( "activeTable" );
00322   m_initialMarkerColumn = mymap.attribute( "markerColumn" ).toInt();
00323   m_initialMarkerRow = mymap.attribute( "markerRow" ).toInt();
00324 
00325   QDomNode n = mymap.firstChild();
00326   if ( n.isNull() )
00327   {
00328       // We need at least one sheet !
00329       doc()->setErrorMessage( i18n("This document has no sheets (tables).") );
00330       return false;
00331   }
00332   while( !n.isNull() )
00333   {
00334     QDomElement e = n.toElement();
00335     if ( !e.isNull() && e.tagName() == "table" )
00336     {
00337       KSpreadSheet *t = addNewSheet();
00338       if ( !t->loadXML( e ) )
00339         return false;
00340     }
00341     n = n.nextSibling();
00342   }
00343 
00344   if ( mymap.hasAttribute( "protected" ) )
00345   {
00346     QString passwd = mymap.attribute( "protected" );
00347 
00348     if ( passwd.length() > 0 )
00349     {
00350       QCString str( passwd.latin1() );
00351       m_strPassword = KCodecs::base64Decode( str );
00352     }
00353     else
00354       m_strPassword = QCString( "" );
00355   }
00356 
00357   if (!activeSheet.isEmpty())
00358   {
00359     // Used by KSpreadView's constructor
00360     m_initialActiveSheet = findSheet( activeSheet );
00361   }
00362 
00363   return true;
00364 }
00365 
00366 void KSpreadMap::update()
00367 {
00368   QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00369   for( ; it.current(); ++it )
00370     it.current()->recalc();
00371 }
00372 
00373 KSpreadSheet* KSpreadMap::findSheet( const QString & _name )
00374 {
00375     KSpreadSheet * t;
00376 
00377     for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00378     {
00379         if ( _name == t->sheetName() )
00380             return t;
00381     }
00382 
00383     return 0L;
00384 }
00385 
00386 KSpreadSheet * KSpreadMap::nextSheet( KSpreadSheet * currentSheet )
00387 {
00388     KSpreadSheet * t;
00389 
00390     if( currentSheet == m_lstSheets.last())
00391       return currentSheet;
00392 
00393     for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00394     {
00395         if ( t  == currentSheet )
00396             return m_lstSheets.next();
00397     }
00398 
00399     return 0L;
00400 }
00401 
00402 KSpreadSheet * KSpreadMap::previousSheet( KSpreadSheet * currentSheet )
00403 {
00404     KSpreadSheet * t;
00405 
00406     if( currentSheet == m_lstSheets.first())
00407       return currentSheet;
00408 
00409     for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00410     {
00411         if ( t  == currentSheet )
00412             return m_lstSheets.prev();
00413     }
00414 
00415     return 0L;
00416 }
00417 
00418 bool KSpreadMap::saveChildren( KoStore * _store )
00419 {
00420   QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00421   for( ; it.current(); ++it )
00422   {
00423     // set the child document's url to an internal url (ex: "tar:/0/1")
00424     if ( !it.current()->saveChildren( _store, it.current()->sheetName() ) )
00425       return false;
00426   }
00427   return true;
00428 }
00429 
00430 bool KSpreadMap::loadChildren( KoStore * _store )
00431 {
00432   QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00433   for( ; it.current(); ++it )
00434     if ( !it.current()->loadChildren( _store ) )
00435       return false;
00436 
00437   return true;
00438 }
00439 
00440 DCOPObject * KSpreadMap::dcopObject()
00441 {
00442     if ( !m_dcop )
00443         m_dcop = new KSpreadMapIface( this );
00444 
00445     return m_dcop;
00446 }
00447 
00448 void KSpreadMap::takeSheet( KSpreadSheet * sheet )
00449 {
00450     int pos = m_lstSheets.findRef( sheet );
00451     m_lstSheets.take( pos );
00452     m_lstDeletedSheets.append( sheet );
00453 }
00454 
00455 void KSpreadMap::insertSheet( KSpreadSheet * sheet )
00456 {
00457     int pos = m_lstDeletedSheets.findRef( sheet );
00458     if ( pos != -1 )
00459         m_lstDeletedSheets.take( pos );
00460     m_lstSheets.append(sheet);
00461 }
00462 
00463 // FIXME cache this for faster operation
00464 QStringList KSpreadMap::visibleSheets() const
00465 {
00466     QStringList result;
00467 
00468     QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00469     for( ; it; ++it )
00470     {
00471         KSpreadSheet* sheet = it.current();
00472         if( !sheet->isHidden() )
00473             result.append( sheet->sheetName() );
00474     }
00475 
00476     return result;
00477 }
00478 
00479 // FIXME cache this for faster operation
00480 QStringList KSpreadMap::hiddenSheets() const
00481 {
00482     QStringList result;
00483 
00484     QPtrListIterator<KSpreadSheet> it( m_lstSheets );
00485     for( ; it; ++it )
00486     {
00487         KSpreadSheet* sheet = it.current();
00488         if( sheet->isHidden() )
00489             result.append( sheet->sheetName() );
00490     }
00491 
00492     return result;
00493 }
00494 
00495 #include "kspread_map.moc"
00496 
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:13 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003