exports.cpp
author insilmaril
Thu, 25 Feb 2010 11:03:52 +0000
changeset 824 36eb4b8f409e
parent 823 0bba81dde1bc
child 825 1ad892c1a709
permissions -rw-r--r--
Added dialog for HTML export. Grouping in Switchboard shortcuts
     1 #include "exports.h"
     2 
     3 #include "branchitem.h"
     4 #include "file.h"
     5 #include "linkablemapobj.h"
     6 #include "misc.h"
     7 #include "mainwindow.h"
     8 #include "warningdialog.h"
     9 #include "xsltproc.h"
    10 
    11 
    12 extern Main *mainWindow;
    13 extern QDir vymBaseDir;
    14 extern QString vymName;
    15 
    16 ExportBase::ExportBase()
    17 {
    18 	init();
    19 }
    20 
    21 ExportBase::ExportBase(VymModel *m)
    22 {
    23 	init();
    24 	model=m;
    25 }
    26 
    27 ExportBase::~ExportBase()
    28 {
    29 	// Cleanup tmpdir
    30 	removeDir (tmpDir);
    31 }
    32 
    33 void ExportBase::init()
    34 {
    35 	indentPerDepth="  ";
    36 	bool ok;
    37     tmpDir.setPath (makeTmpDir(ok,"vym-export"));
    38 	if (!tmpDir.exists() || !ok)
    39 		QMessageBox::critical( 0, QObject::tr( "Error" ),
    40 					   QObject::tr("Couldn't access temporary directory\n"));
    41 	cancelFlag=false;				   
    42 }
    43 
    44 void ExportBase::setDir(const QDir &d)
    45 {
    46 	outDir=d;
    47 }
    48 
    49 void ExportBase::setFile (const QString &p)
    50 {
    51 	outputFile=p;
    52 }
    53 
    54 QString ExportBase::getFile ()
    55 {
    56 	return outputFile;
    57 }
    58 
    59 void ExportBase::setModel(VymModel *m)
    60 {
    61 	model=m;
    62 }
    63 
    64 void ExportBase::setCaption (const QString &s)
    65 {
    66 	caption=s;
    67 }
    68 
    69 void ExportBase::addFilter(const QString &s)
    70 {
    71 	filter=s;
    72 }
    73 
    74 bool ExportBase::execDialog()
    75 {
    76 	{
    77 		QFileDialog *fd=new QFileDialog( 0, caption);
    78 		fd->setFilter (filter);
    79 		fd->setCaption(caption);
    80 		fd->setMode( QFileDialog::AnyFile );
    81 		fd->setDir (outDir);
    82 		fd->show();
    83 
    84 		if ( fd->exec() == QDialog::Accepted )
    85 		{
    86 			if (QFile (fd->selectedFile()).exists() )
    87 			{
    88 				QMessageBox mb( vymName,
    89 					QObject::tr("The file %1 exists already.\nDo you want to overwrite it?").arg(fd->selectedFile()), 
    90 				QMessageBox::Warning,
    91 				QMessageBox::Yes | QMessageBox::Default,
    92 				QMessageBox::Cancel | QMessageBox::Escape,
    93 				Qt::NoButton );
    94 				mb.setButtonText( QMessageBox::Yes, QObject::tr("Overwrite") );
    95 				mb.setButtonText( QMessageBox::No, QObject::tr("Cancel"));
    96 				ExportBase ex;
    97 				switch( mb.exec() ) 
    98 				{
    99 					case QMessageBox::Yes:
   100 						// save 
   101 						break;;
   102 					case QMessageBox::Cancel:
   103 						cancelFlag=true;
   104 						return false;
   105 						break;
   106 				}
   107 			}
   108 			outputFile=fd->selectedFile();
   109 			cancelFlag=false;
   110 			return true;
   111 		}
   112 	}
   113 	return false;
   114 }
   115 
   116 bool ExportBase::canceled()
   117 {
   118 	return cancelFlag;
   119 }
   120 
   121 QString ExportBase::getSectionString(TreeItem *start)
   122 {
   123 	// Make prefix like "2.5.3" for "bo:2,bo:5,bo:3"
   124 	QString r;
   125 	TreeItem *ti=start;
   126 	int depth=ti->depth();
   127 	while (depth>0)
   128 	{
   129 		r=QString("%1").arg(1+ti->num(),0,10)+"." + r;
   130 		ti=ti->parent(); 
   131 		depth=ti->depth();
   132 	}	
   133 	if (r.isEmpty())
   134 		return r;
   135 	else	
   136 		return r + " ";
   137 }
   138 
   139 ////////////////////////////////////////////////////////////////////////
   140 ExportAO::ExportAO()
   141 {
   142 	filter="TXT (*.txt)";
   143 	caption=vymName+ " -" +QObject::tr("Export as ASCII")+" "+QObject::tr("(still experimental)");
   144 }
   145 
   146 void ExportAO::doExport()	
   147 {
   148 	QFile file (outputFile);
   149 	if ( !file.open( QIODevice::WriteOnly ) )
   150 	{
   151 		qWarning ("ExportAO::doExport couldn't open "+outputFile);
   152 		return;
   153 	}
   154 	QTextStream ts( &file );	// use LANG decoding here...
   155 
   156 	// Main loop over all branches
   157 	QString s;
   158 	QString curIndent;
   159 	int i;
   160 	BranchItem *cur=NULL;
   161 	BranchItem *prev=NULL;
   162 
   163 	QString colString;
   164 	QColor col;
   165 
   166 	cur=model->nextBranch (cur,prev);
   167 	while (cur) 
   168 	{
   169 		if (cur->getType()==TreeItem::Branch || cur->getType()==TreeItem::MapCenter)
   170 		{
   171 			// Make indentstring
   172 			curIndent="";
   173 			for (i=0;i<cur->depth()-1;i++) curIndent+= indentPerDepth;
   174 
   175 			if (!cur->hasHiddenExportParent() )
   176 			{
   177 				col=cur->getHeadingColor();
   178 				if (col==QColor (255,0,0))
   179 					colString="[R]";
   180 				else if (col==QColor (217,81,0))
   181 					colString="[O]";
   182 				else if (col==QColor (0,85,0))
   183 					colString="[G]";
   184 				else  	
   185 					colString="[?]";
   186 				switch (cur->depth())
   187 				{
   188 					case 0:
   189 						//ts << underline (cur->getHeading(),QString("="));
   190 						//ts << "\n";
   191 						break;
   192 					case 1:
   193 						//ts << "\n";
   194 						//ts << (underline ( cur->getHeading(), QString("-") ) );
   195 						//ts << "\n";
   196 						break;
   197 					case 2: // Main heading
   198 						ts << "\n";
   199 						ts << underline ( cur->getHeading(), QString("=") );
   200 						ts << "\n";
   201 						break;
   202 					case 3: // Achievement, Bonus, Objective ...
   203 						ts << "\n\n";
   204 						ts << underline ( cur->getHeading(), "-");
   205 						ts << "\n\n";
   206 						break;
   207 					case 4:	// That's the item we need to know
   208 						//ts << (curIndent + "* " + colString+" "+ cur->getHeading());
   209 						ts << colString+" "+ cur->getHeading();
   210 						if (cur->isActiveStandardFlag ("hook-green"))
   211 							ts << " [DONE] ";
   212 						else	if (cur->isActiveStandardFlag ("wip"))
   213 							ts << " [WIP] ";
   214 						else	if (cur->isActiveStandardFlag ("cross-red"))
   215 							ts << " [NOT STARTED] ";
   216 						ts << "\n";
   217 						break;
   218 					default:
   219 						ts << (curIndent + "- " + cur->getHeading());
   220 						ts << "\n";
   221 						break;
   222 				}
   223 
   224 				// If necessary, write note
   225 				if (!cur->getNoteObj().isEmpty())
   226 				{
   227 					curIndent +="  | ";
   228 					s=cur->getNoteASCII( curIndent, 80);
   229 					ts << s;
   230 				}
   231 			}
   232 		}
   233 		cur=model->nextBranch(cur,prev);
   234 	}
   235 	file.close();
   236 }
   237 
   238 QString ExportAO::underline (const QString &text, const QString &line)
   239 {
   240 	QString r=text + "\n";
   241 	for (int j=0;j<text.length();j++) r+=line;
   242 	return r;
   243 }
   244 
   245 
   246 ////////////////////////////////////////////////////////////////////////
   247 ExportASCII::ExportASCII()
   248 {
   249 	filter="TXT (*.txt)";
   250 	caption=vymName+ " -" +QObject::tr("Export as ASCII")+" "+QObject::tr("(still experimental)");
   251 }
   252 
   253 void ExportASCII::doExport()	
   254 {
   255 	QFile file (outputFile);
   256 	if ( !file.open( QIODevice::WriteOnly ) )
   257 	{
   258 		qWarning ("ExportASCII::doExport couldn't open "+outputFile);
   259 		return;
   260 	}
   261 	QTextStream ts( &file );	// use LANG decoding here...
   262 
   263 	// Main loop over all branches
   264 	QString s;
   265 	QString curIndent;
   266 	int i;
   267 	BranchItem *cur=NULL;
   268 	BranchItem *prev=NULL;
   269 
   270 	cur=model->nextBranch (cur,prev);
   271 	while (cur) 
   272 	{
   273 		if (cur->getType()==TreeItem::Branch || cur->getType()==TreeItem::MapCenter)
   274 		{
   275 			// Make indentstring
   276 			curIndent="";
   277 			for (i=1;i<cur->depth()-1;i++) curIndent+= indentPerDepth;
   278 
   279 			if (!cur->hasHiddenExportParent() )
   280 			{
   281 				//std::cout << "ExportASCII::  "<<curIndent.toStdString()<<cur->getHeading().toStdString()<<std::endl;
   282 				switch (cur->depth())
   283 				{
   284 					case 0:
   285 						ts << underline (cur->getHeading(),QString("="));
   286 						ts << "\n";
   287 						break;
   288 					case 1:
   289 						ts << "\n";
   290 						ts << (underline (getSectionString(cur) + cur->getHeading(), QString("-") ) );
   291 						ts << "\n";
   292 						break;
   293 					case 2:
   294 						ts << "\n";
   295 						ts << (curIndent + "* " + cur->getHeading());
   296 						ts << "\n";
   297 						break;
   298 					case 3:
   299 						ts << (curIndent + "- " + cur->getHeading());
   300 						ts << "\n";
   301 						break;
   302 					default:
   303 						ts << (curIndent + "- " + cur->getHeading());
   304 						ts << "\n";
   305 						break;
   306 				}
   307 
   308 				// If necessary, write note
   309 				if (!cur->getNoteObj().isEmpty())
   310 				{
   311 					curIndent +="  | ";
   312 					s=cur->getNoteASCII( curIndent, 80);
   313 					ts << s;
   314 				}
   315 			}
   316 		}
   317 		cur=model->nextBranch(cur,prev);
   318 	}
   319 	file.close();
   320 }
   321 
   322 QString ExportASCII::underline (const QString &text, const QString &line)
   323 {
   324 	QString r=text + "\n";
   325 	for (int j=0;j<text.length();j++) r+=line;
   326 	return r;
   327 }
   328 
   329 
   330 ////////////////////////////////////////////////////////////////////////
   331 void ExportCSV::doExport()
   332 {
   333 	QFile file (outputFile);
   334 	if ( !file.open( QIODevice::WriteOnly ) )
   335 	{
   336 		qWarning ("ExportBase::exportXML  couldn't open "+outputFile);
   337 		return;
   338 	}
   339 	QTextStream ts( &file );	// use LANG decoding here...
   340 
   341 	// Write header
   342 	ts << "\"Note\""  <<endl;
   343 
   344 	// Main loop over all branches
   345 	QString s;
   346 	QString curIndent("");
   347 	int i;
   348 	BranchItem *cur=NULL;
   349 	BranchItem *prev=NULL;
   350 	cur=model->nextBranch (cur,prev);
   351 	while (cur) 
   352 	{
   353 		if (!cur->hasHiddenExportParent() )
   354 		{
   355 			// If necessary, write note
   356 			if (!cur->getNoteObj().isEmpty())
   357 			{
   358 				s =cur->getNoteASCII();
   359 				s=s.replace ("\n","\n"+curIndent);
   360 				ts << ("\""+s+"\",");
   361 			} else
   362 				ts <<"\"\",";
   363 
   364 			// Make indentstring
   365 			for (i=0;i<cur->depth();i++) curIndent+= "\"\",";
   366 
   367 			// Write heading
   368 			ts << curIndent << "\"" << cur->getHeading()<<"\""<<endl;
   369 		}
   370 		
   371 		cur=model->nextBranch(cur,prev);
   372 		curIndent="";
   373 	}
   374 	file.close();
   375 }
   376 
   377 ////////////////////////////////////////////////////////////////////////
   378 void ExportKDE3Bookmarks::doExport() 
   379 {
   380 	WarningDialog dia;
   381 	dia.showCancelButton (true);
   382 	dia.setText(QObject::tr("Exporting the %1 bookmarks will overwrite\nyour existing bookmarks file.").arg("KDE"));
   383 	dia.setCaption(QObject::tr("Warning: Overwriting %1 bookmarks").arg("KDE 3"));
   384 	dia.setShowAgainName("/exports/KDE/overwriteKDEBookmarks");
   385 	if (dia.exec()==QDialog::Accepted)
   386 	{
   387 		model->exportXML(tmpDir.path(),false);
   388 
   389 		XSLTProc p;
   390 		p.setInputFile (tmpDir.path()+"/"+model->getMapName()+".xml");
   391 		p.setOutputFile (tmpDir.home().path()+"/.kde/share/apps/konqueror/bookmarks.xml");
   392 		p.setXSLFile (vymBaseDir.path()+"/styles/vym2kdebookmarks.xsl");
   393 		p.process();
   394 
   395 		QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
   396 		QProcess *proc= new QProcess ;
   397 		proc->start( ub);
   398 		if (!proc->waitForStarted())
   399 		{
   400 			QMessageBox::warning(0, 
   401 				QObject::tr("Warning"),
   402 				QObject::tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
   403 		}	
   404 	}
   405 }
   406 
   407 ////////////////////////////////////////////////////////////////////////
   408 void ExportKDE4Bookmarks::doExport() 
   409 {
   410 	WarningDialog dia;
   411 	dia.showCancelButton (true);
   412 	dia.setText(QObject::tr("Exporting the %1 bookmarks will overwrite\nyour existing bookmarks file.").arg("KDE 4"));
   413 	dia.setCaption(QObject::tr("Warning: Overwriting %1 bookmarks").arg("KDE"));
   414 	dia.setShowAgainName("/exports/KDE/overwriteKDEBookmarks");
   415 	if (dia.exec()==QDialog::Accepted)
   416 	{
   417 		model->exportXML(tmpDir.path(),false);
   418 
   419 		XSLTProc p;
   420 		p.setInputFile (tmpDir.path()+"/"+model->getMapName()+".xml");
   421 		p.setOutputFile (tmpDir.home().path()+"/.kde4/share/apps/konqueror/bookmarks.xml");
   422 		p.setXSLFile (vymBaseDir.path()+"/styles/vym2kdebookmarks.xsl");
   423 		p.process();
   424 
   425 		QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
   426 		QProcess *proc= new QProcess ;
   427 		proc->start( ub);
   428 		if (!proc->waitForStarted())
   429 		{
   430 			QMessageBox::warning(0, 
   431 				QObject::tr("Warning"),
   432 				QObject::tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
   433 		}	
   434 	}
   435 }
   436 
   437 ////////////////////////////////////////////////////////////////////////
   438 void ExportFirefoxBookmarks::doExport() 
   439 {
   440 	WarningDialog dia;
   441 	dia.showCancelButton (true);
   442 	dia.setText(QObject::tr("Exporting the %1 bookmarks will overwrite\nyour existing bookmarks file.").arg("Firefox"));
   443 	dia.setCaption(QObject::tr("Warning: Overwriting %1 bookmarks").arg("Firefox"));
   444 	dia.setShowAgainName("/vym/warnings/overwriteImportBookmarks");
   445 	if (dia.exec()==QDialog::Accepted)
   446 	{
   447 		model->exportXML(tmpDir.path(),false);
   448 
   449 /*
   450 		XSLTProc p;
   451 		p.setInputFile (tmpDir.path()+"/"+me->getMapName()+".xml");
   452 		p.setOutputFile (tmpDir.home().path()+"/.kde/share/apps/konqueror/bookmarks.xml");
   453 		p.setXSLFile (vymBaseDir.path()+"/styles/vym2kdebookmarks.xsl");
   454 		p.process();
   455 
   456 		QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
   457 		QProcess *proc = new QProcess( );
   458 		proc->addArgument(ub);
   459 
   460 		if ( !proc->start() ) 
   461 		{
   462 			QMessageBox::warning(0, 
   463 				QObject::tr("Warning"),
   464 				QObject::tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
   465 		}	
   466 
   467 */
   468 	}
   469 }
   470 
   471 ////////////////////////////////////////////////////////////////////////
   472 ExportHTML::ExportHTML():ExportBase()
   473 {
   474 	init();
   475 }
   476 
   477 ExportHTML::ExportHTML(VymModel *m):ExportBase(m)
   478 {
   479 	init();
   480 }
   481 
   482 void ExportHTML::init()
   483 {
   484 	singularDelimiter=": ";
   485 	noSingulars=true;	
   486 	frameURLs=true;
   487 	useMapColors=true;
   488 	cssFileName="vym.css";
   489 	cssOriginalPath="";	// Is set in VymModel, based on default setting in ExportHTMLDialog
   490 
   491 	if (model &&model->getMapEditor()) 
   492 		offset=model->getMapEditor()->getTotalBBox().topLeft();
   493 }
   494 
   495 QString ExportHTML::getBranchText(BranchItem *current)
   496 {
   497 	if (current)
   498 	{
   499 		bool vis=false;
   500 		QRectF hr;
   501 		LinkableMapObj *lmo=current->getLMO();
   502 		if (lmo)
   503 		{
   504 			hr=((BranchObj*)lmo)->getBBoxHeading();
   505 			if (lmo->isVisibleObj()) vis=true;
   506 		}
   507 		QString col;
   508 		QString id=model->getSelectString(current);
   509 		if (useMapColors)
   510 			col=QString("style='color:%1'").arg(current->getHeadingColor().name());
   511 		QString s=QString("<span class='vym-branch%1' %2 id='%3'>")
   512 			.arg(current->depth())
   513 			.arg(col)
   514 			.arg(id);
   515 		QString url=current->getURL();	
   516 		if (!url.isEmpty())
   517 		{
   518 			s+=QString ("<a href=\"%1\">").arg(url);
   519 			s+=QString ("<img src=\"flags/flag-url-16x16.png\">%1</a>").arg(quotemeta(current->getHeading()));
   520 			s+="</a>";
   521 			
   522 			QRectF fbox=current->getBBoxURLFlag ();
   523 			if (vis)
   524 				imageMap+=QString("  <area shape='rect' coords='%1,%2,%3,%4' href='%5'>\n")
   525 					.arg(fbox.left()-offset.x())
   526 					.arg(fbox.top()-offset.y())
   527 					.arg(fbox.right()-offset.x())
   528 					.arg(fbox.bottom()-offset.y())
   529 					.arg(url);
   530 		} else	
   531 			s+=quotemeta(current->getHeading());
   532 		s+="</span>";
   533 
   534 		if (vis)
   535 			imageMap+=QString("  <area shape='rect' coords='%1,%2,%3,%4' href='#%5'>\n")
   536 				.arg(hr.left()-offset.x())
   537 				.arg(hr.top()-offset.y())
   538 				.arg(hr.right()-offset.x())
   539 				.arg(hr.bottom()-offset.y())
   540 				.arg(id);
   541 
   542 		// Include note
   543 		if (!current->getNoteObj().isEmpty())
   544 			s+="<table border=1><tr><td>"+current->getNote()+"</td></tr></table>";
   545 
   546 		return s;
   547 	} 
   548 	return QString();
   549 }
   550 
   551 QString ExportHTML::buildList (BranchItem *current)
   552 {
   553     QString r;
   554 
   555     uint i=0;
   556 	BranchItem *bi=current->getFirstBranch();
   557 
   558 	// Only add itemized list, if we have more than one subitem.
   559 	// For only one subitem, just add a separator to keep page more compact
   560 	bool noSingularsHere=false;
   561 	if (current->branchCount()<2 && noSingulars) noSingularsHere=true;
   562 
   563 	if (bi)
   564     {
   565 		if (!noSingularsHere)
   566 			r+="<ul>\n";
   567 		else
   568 			r+=singularDelimiter;
   569 
   570 		while (bi)
   571 		{
   572 			if (!bi->hasHiddenExportParent() )	
   573 			{
   574 				if (!noSingularsHere) r+="<li>";
   575 				r+=getBranchText (bi);
   576 				if (!bi->getURL().isEmpty() && frameURLs && noSingularsHere)
   577 					// Add frame, if we have subitems to an URL
   578 					r+="<table border=1><tr><td>"+buildList (bi)+"</td></tr></table>";	// recursivly add deeper branches
   579 				else
   580 					r+=buildList (bi);	// recursivly add deeper branches
   581 				if (!noSingularsHere) r+="</li>";
   582 				r+="\n";
   583 			}
   584 			i++;
   585 			bi=current->getBranchNum(i);
   586 		}
   587 
   588 		if (!noSingularsHere) r+="</ul>\n";
   589 	}
   590     return r;
   591 }
   592 
   593 void ExportHTML::setCSSPath(const QString &p)
   594 {
   595 	cssOriginalPath=p;
   596 }
   597 
   598 void ExportHTML::doExport() 
   599 {
   600 	//FIXME-1  check for errors// Copy CSS file
   601 	QFile css_src (cssOriginalPath);
   602 	QFile css_dst (outDir.path()+"/"+cssFileName);
   603 	if (!css_src.open ( QIODevice::ReadOnly))
   604 		QMessageBox::warning( 0, QObject::tr( "Warning","ExportHTML" ),QObject::tr("Could not open %1","ExportHTML").arg(cssOriginalPath));
   605 	else
   606 	{
   607 		if (!css_dst.open( QIODevice::WriteOnly))
   608 			QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr("Could not open %1").arg(css_dst.fileName()));
   609 		else
   610 		{	
   611 		
   612 			QTextStream tsout( &css_dst);
   613 			QTextStream tsin ( &css_src);
   614 			QString s= tsin.read();
   615 			tsout << s;
   616 			css_dst.close();
   617 		}	
   618 		css_src.close();
   619 	}
   620 
   621 
   622 
   623 	// Open file for writing
   624 	QFile file (outputFile);
   625 	if ( !file.open( QIODevice::WriteOnly ) ) 
   626 	{
   627 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not write %1").arg(outputFile));
   628 		mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
   629 		return;
   630 	}
   631 	QTextStream ts( &file );	// use LANG decoding here...
   632 	ts.setEncoding (QTextStream::UnicodeUTF8); // Force UTF8
   633 
   634 	// Write header
   635 	ts<<"<html><title>"+model->getMapName()<<"</title><body>";
   636 	ts<<" <link rel='stylesheet' id='css.stylesheet' href='"<<cssFileName<<"' />\n";
   637 
   638 	// Include image
   639 	ts<<"<center><img src=\""<<model->getMapName()<<".png\" usemap='#imagemap'></center>\n";
   640 
   641 
   642 	// Main loop over all mapcenters
   643 	QString s;
   644 	TreeItem *rootItem=model->getRootItem();
   645 	BranchItem *bi;
   646 	for (int i=0; i<rootItem->branchCount(); i++)
   647 	{
   648 		bi=rootItem->getBranchNum(i);
   649 		if (!bi->hasHiddenExportParent())
   650 		{
   651 			ts<<getBranchText (bi);
   652 			ts<<buildList (bi);
   653 		}
   654 	}	
   655 
   656 	// Imagemap
   657 	ts<<"<map name='imagemap'>\n"+imageMap+"</map>\n";
   658 
   659 	// Write footer 
   660 	ts<<"<hr/>\n";
   661 	ts<<"<table class=\"vym-footer\">   \n\
   662       <tr> \n\
   663         <td class=\"vym-footerL\">"+model->getFileName()+"</td> \n\
   664         <td class=\"vym-footerC\">"+model->getDate()+"</td> \n\
   665         <td class=\"vym-footerR\"> vym "+model->getVersion()+"</td> \n\
   666       </tr> \n \
   667     </table>\n";
   668 	ts<<"</body></html>";
   669 	file.close();
   670 }
   671 
   672 ////////////////////////////////////////////////////////////////////////
   673 void ExportTaskjuggler::doExport() 
   674 {
   675 	model->exportXML(tmpDir.path(),false);
   676 
   677 	XSLTProc p;
   678 	p.setInputFile (tmpDir.path()+"/"+model->getMapName()+".xml");
   679 	p.setOutputFile (outputFile);
   680 	p.setXSLFile (vymBaseDir.path()+"/styles/vym2taskjuggler.xsl");
   681 	p.process();
   682 }
   683 
   684 ////////////////////////////////////////////////////////////////////////
   685 void ExportLaTeX::doExport() 
   686 {
   687 	// Exports a map to a LaTex file.  
   688 	// This file needs to be included 
   689 	// or inported into a LaTex document
   690 	// it will not add a preamble, or anything 
   691 	// that makes a full LaTex document.
   692   QFile file (outputFile);
   693   if ( !file.open( QIODevice::WriteOnly ) ) {
   694 	QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not write %1").arg(outputFile));
   695 	mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
   696     return;
   697   }
   698   QTextStream ts( &file );	// use LANG decoding here...
   699   ts.setEncoding (QTextStream::UnicodeUTF8); // Force UTF8
   700   
   701   // Main loop over all branches
   702   QString s;
   703   // QString curIndent("");
   704   // int i;
   705   BranchObj *bo;
   706   BranchItem *cur=NULL;
   707   BranchItem *prev=NULL;
   708   model->nextBranch(cur,prev);
   709   while (cur) 
   710   {
   711 	bo=(BranchObj*)(cur->getLMO());
   712 
   713 	if (!cur->hasHiddenExportParent() )
   714 	{
   715 		switch (cur->depth() ) 
   716 		{
   717 			case 0: break;
   718 			case 1: 
   719 			  ts << ("\\chapter{" + cur->getHeading()+ "}\n");
   720 			  break;
   721 			case 2: 
   722 			  ts << ("\\section{" + cur->getHeading()+ "}\n");
   723 			  break;
   724 			case 3: 
   725 			  ts << ("\\subsection{" + cur->getHeading()+ "}\n");
   726 			  break;
   727 			case 4: 
   728 			  ts << ("\\subsubsection{" + cur->getHeading()+ "}\n");
   729 			  break;
   730 			default:
   731 			  ts << ("\\paragraph*{" + cur->getHeading()+ "}\n");
   732 			
   733 		}
   734 		// If necessary, write note
   735 		if (!cur->getNoteObj().isEmpty()) {
   736 		  ts << (cur->getNoteASCII());
   737 		  ts << ("\n");
   738 		}
   739 	}
   740     cur=model->nextBranch(cur,prev);
   741    }
   742   file.close();
   743 }
   744 
   745 ////////////////////////////////////////////////////////////////////////
   746 ExportOO::ExportOO()
   747 {
   748 	useSections=false;
   749 }
   750 
   751 ExportOO::~ExportOO()
   752 {
   753 }	
   754 
   755 QString ExportOO::buildList (TreeItem *current)
   756 {
   757     QString r;
   758 
   759     uint i=0;
   760 	BranchItem *bi=current->getFirstBranch();
   761 	if (bi)
   762     {
   763 		// Start list
   764 		r+="<text:list text:style-name=\"vym-list\">\n";
   765 		while (bi)
   766 		{
   767 			if (!bi->hasHiddenExportParent() )	
   768 			{
   769 				r+="<text:list-item><text:p >";
   770 				r+=quotemeta(bi->getHeading());
   771 				// If necessary, write note
   772 				if (!bi->getNoteObj().isEmpty())
   773 					r+=bi->getNoteOpenDoc();
   774 				r+="</text:p>";
   775 				r+=buildList (bi);	// recursivly add deeper branches
   776 				r+="</text:list-item>\n";
   777 			}
   778 			i++;
   779 			bi=current->getBranchNum(i);
   780 		}
   781 		r+="</text:list>\n";
   782     }
   783     return r;
   784 }
   785 
   786 
   787 void ExportOO::exportPresentation()
   788 {
   789 	QString allPages;
   790 
   791 	BranchItem *firstMCO=(BranchItem*)(model->getRootItem()->getFirstBranch());
   792 	if (!firstMCO) 
   793 	{
   794 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("No objects in map!"));
   795 		return;
   796 	}
   797 
   798 	// Insert new content
   799 	// FIXME add extra title in mapinfo for vym 1.13.x
   800 	content.replace ("<!-- INSERT TITLE -->",quotemeta(firstMCO->getHeading()));
   801 	content.replace ("<!-- INSERT AUTHOR -->",quotemeta(model->getAuthor()));
   802 
   803 	QString	onePage;
   804 	QString list;
   805 	
   806 	BranchItem *sectionBI;	
   807     int i=0;
   808 	BranchItem *pagesBI;
   809     int j=0;
   810 
   811 	int mapcenters=model->getRootItem()->branchCount();
   812 
   813 	// useSections already has been set in setConfigFile 
   814 	if (mapcenters>1)	
   815 		sectionBI=firstMCO;
   816 	else
   817 		sectionBI=firstMCO->getFirstBranch();
   818 
   819 	// Walk sections
   820 	while (sectionBI && !sectionBI->hasHiddenExportParent() )
   821 	{
   822 		if (useSections)
   823 		{
   824 			// Add page with section title
   825 			onePage=sectionTemplate;
   826 			onePage.replace ("<!-- INSERT PAGE HEADING -->", quotemeta(sectionBI->getHeading() ) );
   827 			allPages+=onePage;
   828 			pagesBI=sectionBI->getFirstBranch();
   829 		} else
   830 		{
   831 			//i=-2;	// only use inner loop to 
   832 			        // turn mainbranches into pages
   833 			//sectionBI=firstMCO;
   834 			pagesBI=sectionBI;
   835 		}
   836 
   837 		j=0;
   838 		while (pagesBI && !pagesBI->hasHiddenExportParent() )
   839 		{
   840 			// Add page with list of items
   841 			onePage=pageTemplate;
   842 			onePage.replace ("<!-- INSERT PAGE HEADING -->", quotemeta (pagesBI->getHeading() ) );
   843 			list=buildList (pagesBI);
   844 			onePage.replace ("<!-- INSERT LIST -->", list);
   845 			allPages+=onePage;
   846 			if (pagesBI!=sectionBI)
   847 			{
   848 				j++;
   849 				pagesBI=((BranchItem*)pagesBI->parent())->getBranchNum(j);
   850 			} else
   851 				pagesBI=NULL;	// We are already iterating over the sectionBIs
   852 		}
   853 		i++;
   854 		if (mapcenters>1 )
   855 			sectionBI=model->getRootItem()->getBranchNum (i);
   856 		else
   857 			sectionBI=firstMCO->getBranchNum (i);
   858 	}
   859 	
   860 	content.replace ("<!-- INSERT PAGES -->",allPages);
   861 
   862 	// Write modified content
   863 	QFile f (contentFile);
   864     if ( !f.open( QIODevice::WriteOnly ) ) 
   865 	{
   866 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not write %1").arg(contentFile));
   867 		mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
   868 		return;
   869     }
   870 
   871     QTextStream t( &f );
   872     t << content;
   873     f.close();
   874 
   875 	// zip tmpdir to destination
   876 	zipDir (tmpDir,outputFile);	
   877 }
   878 
   879 bool ExportOO::setConfigFile (const QString &cf)
   880 {
   881 	configFile=cf;
   882 	int i=cf.findRev ("/");
   883 	if (i>=0) configDir=cf.left(i);
   884 	SimpleSettings set;
   885 	set.readSettings(configFile);
   886 
   887 	// set paths
   888 	templateDir=configDir+"/"+set.readEntry ("Template");
   889 
   890 	QDir d (templateDir);
   891 	if (!d.exists())
   892 	{
   893 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Check \"%1\" in\n%2").arg("Template="+set.readEntry ("Template")).arg(configFile));
   894 		return false;
   895 
   896 	}
   897 
   898 	contentTemplateFile=templateDir+"content-template.xml";
   899 	contentFile=tmpDir.path()+"/content.xml";
   900 	pageTemplateFile=templateDir+"page-template.xml";
   901 	sectionTemplateFile=templateDir+"section-template.xml";
   902 
   903 	if (set.readEntry("useSections").contains("yes"))
   904 		useSections=true;
   905 
   906 	// Copy template to tmpdir
   907 	system ("cp -r "+templateDir+"* "+tmpDir.path());
   908 
   909 	// Read content-template
   910 	if (!loadStringFromDisk (contentTemplateFile,content))
   911 	{
   912 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(contentTemplateFile));
   913 		return false;
   914 	}
   915 
   916 	// Read page-template
   917 	if (!loadStringFromDisk (pageTemplateFile,pageTemplate))
   918 	{
   919 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(pageTemplateFile));
   920 		return false;
   921 	}
   922 	
   923 	// Read section-template
   924 	if (useSections && !loadStringFromDisk (sectionTemplateFile,sectionTemplate))
   925 	{
   926 		QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(sectionTemplateFile));
   927 		return false;
   928 	}
   929 	return true;
   930 }
   931