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 Canvas * canvas = view->canvasWidget();
00168
00169 settingsWriter.addConfigItem( "ActiveTable", canvas->activeSheet()->sheetName() );
00170 }
00171
00172
00173 settingsWriter.startElement("config:config-item-map-named" );
00174 settingsWriter.addAttribute("config:name","Tables" );
00175 QPtrListIterator<Sheet> it( m_lstSheets );
00176 for( ; it.current(); ++it )
00177 {
00178 QPoint marker;
00179 if ( view )
00180 {
00181 marker = view->markerFromSheet( *it );
00182 }
00183 settingsWriter.startElement( "config:config-item-map-entry" );
00184 settingsWriter.addAttribute( "config:name", ( *it )->sheetName() );
00185 it.current()->saveOasisSettings( settingsWriter, marker);
00186 settingsWriter.endElement();
00187 }
00188 settingsWriter.endElement();
00189 }
00190
00191
00192 bool Map::saveOasis( KoXmlWriter & xmlWriter, KoGenStyles & mainStyles, KoStore *store, KoXmlWriter* manifestWriter, int &_indexObj, int &_partIndexObj )
00193 {
00194 if ( !m_strPassword.isEmpty() )
00195 {
00196 xmlWriter.addAttribute("table:structure-protected", "true" );
00197 QCString str = KCodecs::base64Encode( m_strPassword );
00198 xmlWriter.addAttribute("table:protection-key", QString( str.data() ) );
00199 }
00200
00201 GenValidationStyles valStyle;
00202
00203 KTempFile bodyTmpFile;
00204
00205 if (bodyTmpFile.status() != 0)
00206 {
00207 qWarning("Creation of temporary file to store document body failed.");
00208 return false;
00209 }
00210
00211 bodyTmpFile.setAutoDelete( true );
00212 QFile* tmpFile = bodyTmpFile.file();
00213 KoXmlWriter bodyTmpWriter( tmpFile );
00214
00215
00216 QPtrListIterator<Sheet> it( m_lstSheets );
00217 for( ; it.current(); ++it )
00218 {
00219 it.current()->saveOasis( bodyTmpWriter, mainStyles, valStyle, store, manifestWriter, _indexObj, _partIndexObj );
00220 }
00221
00222 valStyle.writeStyle( xmlWriter );
00223
00224
00225 tmpFile->close();
00226 xmlWriter.addCompleteElement( tmpFile );
00227 bodyTmpFile.close();
00228
00229 return true;
00230 }
00231
00232 QDomElement Map::save( QDomDocument& doc )
00233 {
00234 QDomElement mymap = doc.createElement( "map" );
00235
00236
00237 View * view = static_cast<View*>(m_doc->views().getFirst());
00238 if ( view )
00239 {
00240 Canvas * canvas = view->canvasWidget();
00241 mymap.setAttribute( "activeTable", canvas->activeSheet()->sheetName() );
00242 mymap.setAttribute( "markerColumn", canvas->markerColumn() );
00243 mymap.setAttribute( "markerRow", canvas->markerRow() );
00244 mymap.setAttribute( "xOffset", canvas->xOffset() );
00245 mymap.setAttribute( "yOffset", canvas->yOffset() );
00246 }
00247
00248 if ( !m_strPassword.isNull() )
00249 {
00250 if ( m_strPassword.size() > 0 )
00251 {
00252 QCString str = KCodecs::base64Encode( m_strPassword );
00253 mymap.setAttribute( "protected", QString( str.data() ) );
00254 }
00255 else
00256 mymap.setAttribute( "protected", "" );
00257 }
00258
00259 QPtrListIterator<Sheet> it( m_lstSheets );
00260 for( ; it.current(); ++it )
00261 {
00262 QDomElement e = it.current()->saveXML( doc );
00263 if ( e.isNull() )
00264 return e;
00265 mymap.appendChild( e );
00266 }
00267 return mymap;
00268 }
00269
00270 bool Map::loadOasis( const QDomElement& body, KoOasisLoadingContext& oasisContext, QDict<Style>& styleMap )
00271 {
00272 if ( body.hasAttributeNS( KoXmlNS::table, "structure-protected" ) )
00273 {
00274 QCString passwd( "" );
00275 if ( body.hasAttributeNS( KoXmlNS::table, "protection-key" ) )
00276 {
00277 QString p = body.attributeNS( KoXmlNS::table, "protection-key", QString::null );
00278 QCString str( p.latin1() );
00279 passwd = KCodecs::base64Decode( str );
00280 }
00281 m_strPassword = passwd;
00282 }
00283 QDomNode sheetNode = KoDom::namedItemNS( body, KoXmlNS::table, "table" );
00284
00285
00286 if ( sheetNode.isNull() ) return false;
00287
00288 while ( !sheetNode.isNull() )
00289 {
00290 QDomElement sheetElement = sheetNode.toElement();
00291 if( !sheetElement.isNull() )
00292 {
00293
00294
00295 if( sheetElement.nodeName() == "table:table" )
00296 {
00297 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00298 {
00299 Sheet* sheet = addNewSheet();
00300 sheet->setSheetName( sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ), true, false );
00301 }
00302 }
00303 }
00304 sheetNode = sheetNode.nextSibling();
00305 }
00306
00307
00308 sheetNode = body.firstChild();
00309 while ( !sheetNode.isNull() )
00310 {
00311 QDomElement sheetElement = sheetNode.toElement();
00312 if( !sheetElement.isNull() )
00313 {
00314 kdDebug()<<"tableElement.nodeName() bis :"<<sheetElement.nodeName()<<endl;
00315 if( sheetElement.nodeName() == "table:table" )
00316 {
00317 if( !sheetElement.attributeNS( KoXmlNS::table, "name", QString::null ).isEmpty() )
00318 {
00319 QString name = sheetElement.attributeNS( KoXmlNS::table, "name", QString::null );
00320 Sheet* sheet = findSheet( name );
00321 if( sheet )
00322 sheet->loadOasis( sheetElement , oasisContext , styleMap);
00323 }
00324 }
00325 }
00326 sheetNode = sheetNode.nextSibling();
00327 }
00328
00329 return true;
00330 }
00331
00332
00333 bool Map::loadXML( const QDomElement& mymap )
00334 {
00335 QString activeSheet = mymap.attribute( "activeTable" );
00336 m_initialMarkerColumn = mymap.attribute( "markerColumn" ).toInt();
00337 m_initialMarkerRow = mymap.attribute( "markerRow" ).toInt();
00338 m_initialXOffset = mymap.attribute( "xOffset" ).toDouble();
00339 m_initialYOffset = mymap.attribute( "yOffset" ).toDouble();
00340
00341 QDomNode n = mymap.firstChild();
00342 if ( n.isNull() )
00343 {
00344
00345 doc()->setErrorMessage( i18n("This document has no sheets (tables).") );
00346 return false;
00347 }
00348 while( !n.isNull() )
00349 {
00350 QDomElement e = n.toElement();
00351 if ( !e.isNull() && e.tagName() == "table" )
00352 {
00353 Sheet *t = addNewSheet();
00354 if ( !t->loadXML( e ) )
00355 return false;
00356 }
00357 n = n.nextSibling();
00358 }
00359
00360 if ( mymap.hasAttribute( "protected" ) )
00361 {
00362 QString passwd = mymap.attribute( "protected" );
00363
00364 if ( passwd.length() > 0 )
00365 {
00366 QCString str( passwd.latin1() );
00367 m_strPassword = KCodecs::base64Decode( str );
00368 }
00369 else
00370 m_strPassword = QCString( "" );
00371 }
00372
00373 if (!activeSheet.isEmpty())
00374 {
00375
00376 m_initialActiveSheet = findSheet( activeSheet );
00377 }
00378
00379 return true;
00380 }
00381
00382 void Map::update()
00383 {
00384 QPtrListIterator<Sheet> it( m_lstSheets );
00385 for( ; it.current(); ++it )
00386 it.current()->recalc();
00387 }
00388
00389 Sheet* Map::findSheet( const QString & _name )
00390 {
00391 Sheet * t;
00392
00393 for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00394 {
00395 if ( _name.lower() == t->sheetName().lower() )
00396 return t;
00397 }
00398
00399 return 0L;
00400 }
00401
00402 Sheet * Map::nextSheet( Sheet * currentSheet )
00403 {
00404 Sheet * t;
00405
00406 if( currentSheet == m_lstSheets.last())
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.next();
00413 }
00414
00415 return 0L;
00416 }
00417
00418 Sheet * Map::previousSheet( Sheet * currentSheet )
00419 {
00420 Sheet * t;
00421
00422 if( currentSheet == m_lstSheets.first())
00423 return currentSheet;
00424
00425 for ( t = m_lstSheets.first(); t != 0L; t = m_lstSheets.next() )
00426 {
00427 if ( t == currentSheet )
00428 return m_lstSheets.prev();
00429 }
00430
00431 return 0L;
00432 }
00433
00434 bool Map::saveChildren( KoStore * _store )
00435 {
00436 QPtrListIterator<Sheet> it( m_lstSheets );
00437 for( ; it.current(); ++it )
00438 {
00439
00440 if ( !it.current()->saveChildren( _store, it.current()->sheetName() ) )
00441 return false;
00442 }
00443 return true;
00444 }
00445
00446 bool Map::loadChildren( KoStore * _store )
00447 {
00448 QPtrListIterator<Sheet> it( m_lstSheets );
00449 for( ; it.current(); ++it )
00450 if ( !it.current()->loadChildren( _store ) )
00451 return false;
00452
00453 return true;
00454 }
00455
00456 DCOPObject * Map::dcopObject()
00457 {
00458 if ( !m_dcop )
00459 m_dcop = new MapIface( this );
00460
00461 return m_dcop;
00462 }
00463
00464 void Map::takeSheet( Sheet * sheet )
00465 {
00466 int pos = m_lstSheets.findRef( sheet );
00467 m_lstSheets.take( pos );
00468 m_lstDeletedSheets.append( sheet );
00469 }
00470
00471 void Map::insertSheet( Sheet * sheet )
00472 {
00473 int pos = m_lstDeletedSheets.findRef( sheet );
00474 if ( pos != -1 )
00475 m_lstDeletedSheets.take( pos );
00476 m_lstSheets.append(sheet);
00477 }
00478
00479
00480 QStringList Map::visibleSheets() const
00481 {
00482 QStringList result;
00483
00484 QPtrListIterator<Sheet> it( m_lstSheets );
00485 for( ; it; ++it )
00486 {
00487 Sheet* sheet = it.current();
00488 if( !sheet->isHidden() )
00489 result.append( sheet->sheetName() );
00490 }
00491
00492 return result;
00493 }
00494
00495
00496 QStringList Map::hiddenSheets() const
00497 {
00498 QStringList result;
00499
00500 QPtrListIterator<Sheet> it( m_lstSheets );
00501 for( ; it; ++it )
00502 {
00503 Sheet* sheet = it.current();
00504 if( sheet->isHidden() )
00505 result.append( sheet->sheetName() );
00506 }
00507
00508 return result;
00509 }
00510
00511 #include "kspread_map.moc"
00512