00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdlib.h>
00021 #include <time.h>
00022
00023 #include <qfile.h>
00024
00025 #include <kmdcodec.h>
00026 #include <ktempfile.h>
00027
00028 #include <KoDom.h>
00029 #include <KoGenStyles.h>
00030 #include <KoOasisSettings.h>
00031 #include <KoXmlNS.h>
00032 #include <KoXmlWriter.h>
00033
00034 #include "kspread_canvas.h"
00035 #include "kspread_doc.h"
00036 #include "kspread_genvalidationstyle.h"
00037 #include "kspread_locale.h"
00038 #include "kspread_sheet.h"
00039 #include "kspread_view.h"
00040 #include "KSpreadMapIface.h"
00041
00042 #include "kspread_map.h"
00043
00044 using namespace KSpread;
00045
00046 bool Map::respectCase = true;
00047
00048 Map::Map ( Doc* doc, const char* name)
00049 : QObject( doc, name ),
00050 m_doc( doc ),
00051 m_initialActiveSheet( 0 ),
00052 m_initialMarkerColumn( 0 ),
00053 m_initialMarkerRow( 0 ),
00054 m_initialXOffset(0.0),
00055 m_initialYOffset(0.0),
00056 tableId (1),
00057 m_dcop( 0 )
00058 {
00059 m_lstSheets.setAutoDelete( true );
00060 }
00061
00062 Map::~Map()
00063 {
00064 delete m_dcop;
00065 }
00066
00067 Doc* Map::doc() const
00068 {
00069 return m_doc;
00070 }
00071
00072 void Map::setProtected( QCString const & passwd )
00073 {
00074 m_strPassword = passwd;
00075 }
00076
00077 Sheet* Map::createSheet()
00078 {
00079 QString s( i18n("Sheet%1") );
00080 s = s.arg( tableId++ );
00081 Sheet *t = new Sheet ( this, s , s.utf8());
00082 t->setSheetName( s, true );
00083 return t;
00084 }
00085
00086 void Map::addSheet( Sheet *_sheet )
00087 {
00088 m_lstSheets.append( _sheet );
00089
00090 m_doc->setModified( true );
00091
00092 emit sig_addSheet( _sheet );
00093 }
00094
00095 Sheet *Map::addNewSheet ()
00096 {
00097 Sheet *t = createSheet ();
00098 addSheet (t);
00099 return t;
00100 }
00101
00102 void Map::moveSheet( const QString & _from, const QString & _to, bool _before )
00103 {
00104 Sheet* sheetfrom = findSheet( _from );
00105 Sheet* sheetto = findSheet( _to );
00106
00107 int from = m_lstSheets.find( sheetfrom ) ;
00108 int to = m_lstSheets.find( sheetto ) ;
00109 if ( !_before )
00110 ++to;
00111
00112 if ( to > (int)m_lstSheets.count() )
00113 {
00114 m_lstSheets.append( sheetfrom );
00115 m_lstSheets.take( from );
00116 }
00117 else if ( from < to )
00118 {
00119 m_lstSheets.insert( to, sheetfrom );
00120 m_lstSheets.take( from );
00121 }
00122 else
00123 {
00124 m_lstSheets.take( from );
00125 m_lstSheets.insert( to, sheetfrom );
00126 }
00127 }
00128
00129 void Map::loadOasisSettings( KoOasisSettings &settings )
00130 {
00131 KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
00132 KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
00133 KoOasisSettings::Items firstView = viewMap.entry( 0 );
00134
00135 KoOasisSettings::NamedMap sheetsMap = firstView.namedMap( "Tables" );
00136 kdDebug()<<" loadOasisSettings( KoOasisSettings &settings ) exist : "<< !sheetsMap.isNull() <<endl;
00137 if ( !sheetsMap.isNull() )
00138 {
00139 QPtrListIterator<Sheet> it( m_lstSheets );
00140 for( ; it.current(); ++it )
00141 {
00142 it.current()->loadOasisSettings( sheetsMap );
00143 }
00144 }
00145
00146 QString activeSheet = firstView.parseConfigItemString( "ActiveTable" );
00147 kdDebug()<<" loadOasisSettings( KoOasisSettings &settings ) activeSheet :"<<activeSheet<<endl;
00148
00149 if (!activeSheet.isEmpty())
00150 {
00151
00152 m_initialActiveSheet = findSheet( activeSheet );
00153 }
00154
00155 }
00156
00157 void Map::saveOasisSettings( KoXmlWriter &settingsWriter )
00158 {
00159 settingsWriter.addConfigItem( "ViewId", QString::fromLatin1( "View1" ) );
00160
00161
00162 View * view = static_cast<View*>( m_doc->views().getFirst());
00163 if ( view )
00164 {
00165
00166 view->saveCurrentSheetSelection();
00167
00168 settingsWriter.addConfigItem( "ActiveTable", view->activeSheet()->sheetName() );
00169 }
00170
00171
00172 settingsWriter.startElement("config:config-item-map-named" );
00173 settingsWriter.addAttribute("config:name","Tables" );
00174 QPtrListIterator<Sheet> it( m_lstSheets );
00175 for( ; it.current(); ++it )
00176 {
00177 settingsWriter.startElement( "config:config-item-map-entry" );
00178 settingsWriter.addAttribute( "config:name", ( *it )->sheetName() );
00179 if ( view )
00180 {
00181 QPoint marker = view->markerFromSheet( *it );
00182 KoPoint offset = view->offsetFromSheet( *it );
00183 settingsWriter.addConfigItem( "CursorPositionX", marker.x() );
00184 settingsWriter.addConfigItem( "CursorPositionY", marker.y() );
00185 settingsWriter.addConfigItem( "xOffset", offset.x() );
00186 settingsWriter.addConfigItem( "yOffset", offset.y() );
00187 }
00188 it.current()->saveOasisSettings( settingsWriter );
00189 settingsWriter.endElement();
00190 }
00191 settingsWriter.endElement();
00192 }
00193
00194
00195 bool Map::saveOasis( KoXmlWriter & xmlWriter, KoGenStyles & mainStyles, KoStore *store, KoXmlWriter* manifestWriter, int &_indexObj, int &_partIndexObj )
00196 {
00197 if ( !m_strPassword.isEmpty() )
00198 {
00199 xmlWriter.addAttribute("table:structure-protected", "true" );
00200 QCString str = KCodecs::base64Encode( m_strPassword );
00201 xmlWriter.addAttribute("table:protection-key", QString( str.data() ) );
00202 }
00203
00204 GenValidationStyles valStyle;
00205
00206 KTempFile bodyTmpFile;
00207
00208 if (bodyTmpFile.status() != 0)
00209 {
00210 qWarning("Creation of temporary file to store document body failed.");
00211 return false;
00212 }
00213
00214 bodyTmpFile.setAutoDelete( true );
00215 QFile* tmpFile = bodyTmpFile.file();
00216 KoXmlWriter bodyTmpWriter( tmpFile );
00217
00218
00219 QPtrListIterator<Sheet> it( m_lstSheets );
00220 for( ; it.current(); ++it )
00221 {
00222 it.current()->saveOasis( bodyTmpWriter, mainStyles, valStyle, store, manifestWriter, _indexObj, _partIndexObj );
00223 }
00224
00225 valStyle.writeStyle( xmlWriter );
00226
00227
00228 tmpFile->close();
00229 xmlWriter.addCompleteElement( tmpFile );
00230 bodyTmpFile.close();
00231
00232 return true;
00233 }
00234
00235 QDomElement Map::save( QDomDocument& doc )
00236 {
00237 QDomElement mymap = doc.createElement( "map" );
00238
00239
00240 View * view = static_cast<View*>(m_doc->views().getFirst());
00241 if ( view )
00242 {
00243 Canvas * canvas = view->canvasWidget();
00244 mymap.setAttribute( "activeTable", canvas->activeSheet()->sheetName() );
00245 mymap.setAttribute( "markerColumn", canvas->markerColumn() );
00246 mymap.setAttribute( "markerRow", canvas->markerRow() );
00247 mymap.setAttribute( "xOffset", canvas->xOffset() );
00248 mymap.setAttribute( "yOffset", canvas->yOffset() );
00249 }
00250
00251 if ( !m_strPassword.isNull() )
00252 {
00253 if ( m_strPassword.size() > 0 )
00254 {
00255 QCString str = KCodecs::base64Encode( m_strPassword );
00256 mymap.setAttribute( "protected", QString( str.data() ) );
00257 }
00258 else
00259 mymap.setAttribute( "protected", "" );
00260 }
00261
00262 QPtrListIterator<Sheet> it( m_lstSheets );
00263 for( ; it.current(); ++it )
00264 {
00265 QDomElement e = it.current()->saveXML( doc );
00266 if ( e.isNull() )
00267 return e;
00268 mymap.appendChild( e );
00269 }
00270 return mymap;
00271 }
00272
00273 bool Map::loadOasis( const QDomElement& body, KoOasisLoadingContext& oasisContext, QDict<Style>& styleMap )
00274 {
00275 if ( body.hasAttributeNS( KoXmlNS::table, "structure-protected" ) )
00276 {
00277 QCString passwd( "" );
00278 if ( body.hasAttributeNS( KoXmlNS::table, "protection-key" ) )
00279 {
00280 QString p = body.attributeNS( KoXmlNS::table, "protection-key", QString::null );
00281 QCString str( p.latin1() );
00282 passwd = KCodecs::base64Decode( str );
00283 }
00284 m_strPassword = passwd;
00285 }
00286 QDomNode sheetNode = KoDom::namedItemNS( body, KoXmlNS::table, "table" );
00287
00288
00289 if ( sheetNode.isNull() ) return false;
00290
00291 while ( !sheetNode.isNull() )
00292 {
00293 QDomElement sheetElement = sheetNode.toElement();
00294 if( !sheetElement.isNull() )
00295 {
00296
00297
00298 if( sheetElement.nodeName() == "table:table" )
00299 {
00300 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00301 {
00302 Sheet* sheet = addNewSheet();
00303 sheet->setSheetName( sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ), true, false );
00304 }
00305 }
00306 }
00307 sheetNode = sheetNode.nextSibling();
00308 }
00309
00310
00311 sheetNode = body.firstChild();
00312 while ( !sheetNode.isNull() )
00313 {
00314 QDomElement sheetElement = sheetNode.toElement();
00315 if( !sheetElement.isNull() )
00316 {
00317 kdDebug()<<"tableElement.nodeName() bis :"<<sheetElement.nodeName()<<endl;
00318 if( sheetElement.nodeName() == "table:table" )
00319 {
00320 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00321 {
00322 QString name = sheetElement.attributeNS( KoXmlNS::table, "name", QString::null );
00323 Sheet* sheet = findSheet( name );
00324 if( sheet )
00325 sheet->loadOasis( sheetElement , oasisContext , styleMap);
00326 }
00327 }
00328 }
00329 sheetNode = sheetNode.nextSibling();
00330 }
00331
00332 return true;
00333 }
00334
00335
00336 bool Map::loadXML( const QDomElement& mymap )
00337 {
00338 QString activeSheet = mymap.attribute( "activeTable" );
00339 m_initialMarkerColumn = mymap.attribute( "markerColumn" ).toInt();
00340 m_initialMarkerRow = mymap.attribute( "markerRow" ).toInt();
00341 m_initialXOffset = mymap.attribute( "xOffset" ).toDouble();
00342 m_initialYOffset = mymap.attribute( "yOffset" ).toDouble();
00343
00344 QDomNode n = mymap.firstChild();
00345 if ( n.isNull() )
00346 {
00347
00348 doc()->setErrorMessage( i18n("This document has no sheets (tables).") );
00349 return false;
00350 }
00351 while( !n.isNull() )
00352 {
00353 QDomElement e = n.toElement();
00354 if ( !e.isNull() && e.tagName() == "table" )
00355 {
00356 Sheet *t = addNewSheet();
00357 if ( !t->loadXML( e ) )
00358 return false;
00359 }
00360 n = n.nextSibling();
00361 }
00362
00363 if ( mymap.hasAttribute( "protected" ) )
00364 {
00365 QString passwd = mymap.attribute( "protected" );
00366
00367 if ( passwd.length() > 0 )
00368 {
00369 QCString str( passwd.latin1() );
00370 m_strPassword = KCodecs::base64Decode( str );
00371 }
00372 else
00373 m_strPassword = QCString( "" );
00374 }
00375
00376 if (!activeSheet.isEmpty())
00377 {
00378
00379 m_initialActiveSheet = findSheet( activeSheet );
00380 }
00381
00382 return true;
00383 }
00384
00385 void Map::update()
00386 {
00387 QPtrListIterator<Sheet> it( m_lstSheets );
00388 for( ; it.current(); ++it )
00389 it.current()->recalc();
00390 }
00391
00392 Sheet* Map::findSheet( const QString & _name )
00393 {
00394 Sheet * t;
00395
00396 for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00397 {
00398 if ( _name.lower() == t->sheetName().lower() )
00399 return t;
00400 }
00401
00402 return 0L;
00403 }
00404
00405 Sheet * Map::nextSheet( Sheet * currentSheet )
00406 {
00407 Sheet * t;
00408
00409 if( currentSheet == m_lstSheets.last())
00410 return currentSheet;
00411
00412 for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00413 {
00414 if ( t == currentSheet )
00415 return m_lstSheets.next();
00416 }
00417
00418 return 0L;
00419 }
00420
00421 Sheet * Map::previousSheet( Sheet * currentSheet )
00422 {
00423 Sheet * t;
00424
00425 if( currentSheet == m_lstSheets.first())
00426 return currentSheet;
00427
00428 for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00429 {
00430 if ( t == currentSheet )
00431 return m_lstSheets.prev();
00432 }
00433
00434 return 0L;
00435 }
00436
00437 bool Map::saveChildren( KoStore * _store )
00438 {
00439 QPtrListIterator<Sheet> it( m_lstSheets );
00440 for( ; it.current(); ++it )
00441 {
00442
00443 if ( !it.current()->saveChildren( _store, it.current()->sheetName() ) )
00444 return false;
00445 }
00446 return true;
00447 }
00448
00449 bool Map::loadChildren( KoStore * _store )
00450 {
00451 QPtrListIterator<Sheet> it( m_lstSheets );
00452 for( ; it.current(); ++it )
00453 if ( !it.current()->loadChildren( _store ) )
00454 return false;
00455
00456 return true;
00457 }
00458
00459 DCOPObject * Map::dcopObject()
00460 {
00461 if ( !m_dcop )
00462 m_dcop = new MapIface( this );
00463
00464 return m_dcop;
00465 }
00466
00467 void Map::takeSheet( Sheet * sheet )
00468 {
00469 int pos = m_lstSheets.findRef( sheet );
00470 m_lstSheets.take( pos );
00471 m_lstDeletedSheets.append( sheet );
00472 }
00473
00474 void Map::insertSheet( Sheet * sheet )
00475 {
00476 int pos = m_lstDeletedSheets.findRef( sheet );
00477 if ( pos != -1 )
00478 m_lstDeletedSheets.take( pos );
00479 m_lstSheets.append(sheet);
00480 }
00481
00482
00483 QStringList Map::visibleSheets() const
00484 {
00485 QStringList result;
00486
00487 QPtrListIterator<Sheet> it( m_lstSheets );
00488 for( ; it; ++it )
00489 {
00490 Sheet* sheet = it.current();
00491 if( !sheet->isHidden() )
00492 result.append( sheet->sheetName() );
00493 }
00494
00495 return result;
00496 }
00497
00498
00499 QStringList Map::hiddenSheets() const
00500 {
00501 QStringList result;
00502
00503 QPtrListIterator<Sheet> it( m_lstSheets );
00504 for( ; it; ++it )
00505 {
00506 Sheet* sheet = it.current();
00507 if( sheet->isHidden() )
00508 result.append( sheet->sheetName() );
00509 }
00510
00511 return result;
00512 }
00513
00514 #include "kspread_map.moc"
00515