00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 );
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
00143 m_initialActiveSheet = findSheet( activeSheet );
00144 }
00145
00146 }
00147
00148 void KSpreadMap::saveOasisSettings( KoXmlWriter &settingsWriter )
00149 {
00150 settingsWriter.addConfigItem( "ViewId", QString::fromLatin1( "View1" ) );
00151
00152
00153 KSpreadView * view = static_cast<KSpreadView*>( m_doc->views().getFirst());
00154 if ( view )
00155 {
00156
00157 view->saveCurrentSheetSelection();
00158 KSpreadCanvas * canvas = view->canvasWidget();
00159
00160 settingsWriter.addConfigItem( "ActiveTable", canvas->activeSheet()->sheetName() );
00161 }
00162
00163
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() ) );
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
00220
00221 KSpreadView * view = static_cast<KSpreadView*>(m_doc->views().getFirst());
00222 if ( view )
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
00266 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
00267 m_strPassword = passwd;
00268 }
00269 QDomNode sheetNode = KoDom::namedItemNS( body, KoXmlNS::table, "table" );
00270
00271
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
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
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
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
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
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
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