initial import
[vym] / exports.cpp
1 #include "exports.h"
2 #include "file.h"
3 #include "linkablemapobj.h"
4 #include "misc.h"
5 #include "mainwindow.h"
6 #include "warningdialog.h"
7 #include "xsltproc.h"
8
9 extern Main *mainWindow;
10 extern QDir vymBaseDir;
11 extern QString vymName;
12
13 ExportBase::ExportBase()
14 {
15         indentPerDepth="  ";
16         bool ok;
17     tmpDir.setPath (makeTmpDir(ok,"vym-export"));
18         if (!tmpDir.exists() || !ok)
19                 QMessageBox::critical( 0, QObject::tr( "Error" ),
20                                            QObject::tr("Couldn't access temporary directory\n"));
21         cancelFlag=false;                                  
22 }
23
24 ExportBase::~ExportBase()
25 {
26         // Cleanup tmpdir
27         removeDir (tmpDir);
28 }
29
30 void ExportBase::setDir(const QDir &d)
31 {
32         outDir=d;
33 }
34
35 void ExportBase::setFile (const QString &p)
36 {
37         outputFile=p;
38 }
39
40 QString ExportBase::getFile ()
41 {
42         return outputFile;
43 }
44
45 void ExportBase::setModel(VymModel *m)
46 {
47         model=m;
48 }
49
50 void ExportBase::setCaption (const QString &s)
51 {
52         caption=s;
53 }
54
55 void ExportBase::addFilter(const QString &s)
56 {
57         filter=s;
58 }
59
60 bool ExportBase::execDialog()
61 {
62         //MapEditor *me=model.getMapEditor(); FIXME needed?
63         // if (model->mapCenters.count() && me)
64         {
65                 QFileDialog *fd=new QFileDialog( 0, caption);
66                 fd->setFilter (filter);
67                 fd->setCaption(caption);
68                 fd->setMode( QFileDialog::AnyFile );
69                 fd->setDir (outDir);
70                 fd->show();
71
72                 if ( fd->exec() == QDialog::Accepted )
73                 {
74                         if (QFile (fd->selectedFile()).exists() )
75                         {
76                                 QMessageBox mb( vymName,
77                                         QObject::tr("The file %1 exists already.\nDo you want to overwrite it?").arg(fd->selectedFile()), 
78                                 QMessageBox::Warning,
79                                 QMessageBox::Yes | QMessageBox::Default,
80                                 QMessageBox::Cancel | QMessageBox::Escape,
81                                 Qt::NoButton );
82                                 mb.setButtonText( QMessageBox::Yes, QObject::tr("Overwrite") );
83                                 mb.setButtonText( QMessageBox::No, QObject::tr("Cancel"));
84                                 ExportBase ex;
85                                 switch( mb.exec() ) 
86                                 {
87                                         case QMessageBox::Yes:
88                                                 // save 
89                                                 break;;
90                                         case QMessageBox::Cancel:
91                                                 cancelFlag=true;
92                                                 return false;
93                                                 break;
94                                 }
95                         }
96                         outputFile=fd->selectedFile();
97                         cancelFlag=false;
98                         return true;
99                 }
100         }
101         return false;
102 }
103
104 bool ExportBase::canceled()
105 {
106         return cancelFlag;
107 }
108
109 QString ExportBase::getSectionString(BranchObj *bostart)
110 {
111         // Make prefix like "2.5.3" for "bo:2,bo:5,bo:3"
112         QString r;
113         BranchObj *bo=bostart;
114         int depth=bo->getDepth();
115         while (depth>0)
116         {
117                 r=QString("%1").arg(1+bo->getNum(),0,10)+"." + r;
118                 bo=(BranchObj*)(bo->getParObj());
119                 depth=bo->getDepth();
120         }       
121         if (r.isEmpty())
122                 return r;
123         else    
124                 return r + " ";
125 }
126
127 ////////////////////////////////////////////////////////////////////////
128 ExportASCII::ExportASCII()
129 {
130         filter="TXT (*.txt)";
131         caption=vymName+ " -" +QObject::tr("Export as ASCII")+" "+QObject::tr("(still experimental)");
132 }
133
134 void ExportASCII::doExport()
135 {
136         QFile file (outputFile);
137         if ( !file.open( QIODevice::WriteOnly ) )
138         {
139                 qWarning ("ExportBase::exportXML  couldn't open "+outputFile);
140                 return;
141         }
142         QTextStream ts( &file );        // use LANG decoding here...
143
144         // Main loop over all branches
145         QString s;
146         QString curIndent;
147         int i;
148         BranchObj *bo;
149         bo=model->first();
150         while (bo) 
151         {
152                 // Make indentstring
153                 curIndent="";
154                 for (i=0;i<bo->getDepth()-1;i++) curIndent+= indentPerDepth;
155
156                 if (!bo->hasHiddenExportParent() )
157                 {
158                         switch (bo->getDepth())
159                         {
160                                 case 0:
161                                         ts << underline (bo->getHeading(),QString("="));
162                                         ts << "\n";
163                                         break;
164                                 case 1:
165                                         ts << "\n";
166                                         ts << (underline (getSectionString(bo) + bo->getHeading(), QString("-") ) );
167                                         ts << "\n";
168                                         break;
169                                 case 2:
170                                         ts << "\n";
171                                         ts << (curIndent + "* " + bo->getHeading());
172                                         ts << "\n";
173                                         break;
174                                 case 3:
175                                         ts << (curIndent + "- " + bo->getHeading());
176                                         ts << "\n";
177                                         break;
178                                 default:
179                                         ts << (curIndent + "- " + bo->getHeading());
180                                         ts << "\n";
181                                         break;
182                         }
183
184                         // If necessary, write note
185                         if (!bo->getNote().isEmpty())
186                         {
187                                 curIndent +="  | ";
188                                 s=bo->getNoteASCII( curIndent, 80);
189                                 ts << s;
190                         }
191                 }
192                 bo=model->next(bo);
193         }
194         file.close();
195 }
196
197 QString ExportASCII::underline (const QString &text, const QString &line)
198 {
199         QString r=text + "\n";
200         for (int j=0;j<text.length();j++) r+=line;
201         return r;
202 }
203
204
205 ////////////////////////////////////////////////////////////////////////
206 void ExportCSV::doExport()
207 {
208         QFile file (outputFile);
209         if ( !file.open( QIODevice::WriteOnly ) )
210         {
211                 qWarning ("ExportBase::exportXML  couldn't open "+outputFile);
212                 return;
213         }
214         QTextStream ts( &file );        // use LANG decoding here...
215
216         // Write header
217         ts << "\"Note\""  <<endl;
218
219         // Main loop over all branches
220         QString s;
221         QString curIndent("");
222         int i;
223         BranchObj *bo;
224         bo=model->first();
225         while (bo) 
226         {
227                 if (!bo->hasHiddenExportParent() )
228                 {
229                         // If necessary, write note
230                         if (!bo->getNote().isEmpty())
231                         {
232                                 s =bo->getNoteASCII();
233                                 s=s.replace ("\n","\n"+curIndent);
234                                 ts << ("\""+s+"\",");
235                         } else
236                                 ts <<"\"\",";
237
238                         // Make indentstring
239                         for (i=0;i<bo->getDepth();i++) curIndent+= "\"\",";
240
241                         // Write heading
242                         ts << curIndent << "\"" << bo->getHeading()<<"\""<<endl;
243                 }
244                 
245                 bo=model->next(bo);
246                 curIndent="";
247         }
248         file.close();
249 }
250
251 ////////////////////////////////////////////////////////////////////////
252 void ExportKDEBookmarks::doExport() 
253 {
254         MapEditor *me=model->getMapEditor();
255         if (me)
256         {
257                 WarningDialog dia;
258                 dia.showCancelButton (true);
259                 dia.setText(QObject::tr("Exporting the %1 bookmarks will overwrite\nyour existing bookmarks file.").arg("KDE"));
260                 dia.setCaption(QObject::tr("Warning: Overwriting %1 bookmarks").arg("KDE"));
261                 dia.setShowAgainName("/exports/KDE/overwriteKDEBookmarks");
262                 if (dia.exec()==QDialog::Accepted)
263                 {
264                         me->exportXML(tmpDir.path(),false);
265
266                         XSLTProc p;
267                         p.setInputFile (tmpDir.path()+"/"+me->getMapName()+".xml");
268                         p.setOutputFile (tmpDir.home().path()+"/.kde/share/apps/konqueror/bookmarks.xml");
269                         p.setXSLFile (vymBaseDir.path()+"/styles/vym2kdebookmarks.xsl");
270                         p.process();
271
272                         QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
273                         QProcess *proc= new QProcess ;
274                         proc->start( ub);
275                         if (!proc->waitForStarted())
276                         {
277                                 QMessageBox::warning(0, 
278                                         QObject::tr("Warning"),
279                                         QObject::tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
280                         }       
281                 }
282         }
283
284 }
285
286 ////////////////////////////////////////////////////////////////////////
287 void ExportFirefoxBookmarks::doExport() 
288 {
289         MapEditor *me=model->getMapEditor();
290         if (me)
291         {
292                 WarningDialog dia;
293                 dia.showCancelButton (true);
294                 dia.setText(QObject::tr("Exporting the %1 bookmarks will overwrite\nyour existing bookmarks file.").arg("Firefox"));
295                 dia.setCaption(QObject::tr("Warning: Overwriting %1 bookmarks").arg("Firefox"));
296                 dia.setShowAgainName("/vym/warnings/overwriteImportBookmarks");
297                 if (dia.exec()==QDialog::Accepted)
298                 {
299                         me->exportXML(tmpDir.path(),false);
300
301 /*
302                         XSLTProc p;
303                         p.setInputFile (tmpDir.path()+"/"+me->getMapName()+".xml");
304                         p.setOutputFile (tmpDir.home().path()+"/.kde/share/apps/konqueror/bookmarks.xml");
305                         p.setXSLFile (vymBaseDir.path()+"/styles/vym2kdebookmarks.xsl");
306                         p.process();
307
308                         QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
309                         QProcess *proc = new QProcess( );
310                         proc->addArgument(ub);
311
312                         if ( !proc->start() ) 
313                         {
314                                 QMessageBox::warning(0, 
315                                         QObject::tr("Warning"),
316                                         QObject::tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
317                         }       
318
319 */
320
321                 }
322         }
323 }
324
325 ////////////////////////////////////////////////////////////////////////
326 void ExportTaskjuggler::doExport() 
327 {
328         MapEditor *me=model->getMapEditor();
329         if (me)
330         {
331                 me->exportXML(tmpDir.path(),false);
332
333                 XSLTProc p;
334                 p.setInputFile (tmpDir.path()+"/"+me->getMapName()+".xml");
335                 p.setOutputFile (outputFile);
336                 p.setXSLFile (vymBaseDir.path()+"/styles/vym2taskjuggler.xsl");
337                 p.process();
338         }
339
340 }
341
342 ////////////////////////////////////////////////////////////////////////
343 void ExportLaTeX::doExport() 
344 {
345         // Exports a map to a LaTex file.  
346         // This file needs to be included 
347         // or inported into a LaTex document
348         // it will not add a preamble, or anything 
349         // that makes a full LaTex document.
350   QFile file (outputFile);
351   if ( !file.open( QIODevice::WriteOnly ) ) {
352         QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not write %1").arg(outputFile));
353         mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
354     return;
355   }
356   QTextStream ts( &file );      // use LANG decoding here...
357   ts.setEncoding (QTextStream::UnicodeUTF8); // Force UTF8
358   
359   // Main loop over all branches
360   QString s;
361   // QString curIndent("");
362   // int i;
363   BranchObj *bo;
364   bo=model->first();
365   while (bo) {
366         if (!bo->hasHiddenExportParent() )
367         {
368                 if (bo->getDepth()==0);
369                 else if (bo->getDepth()==1) {
370                   ts << ("\\chapter{" + bo->getHeading()+ "}\n");
371                 }
372                 else if (bo->getDepth()==2) {
373                   ts << ("\\section{" + bo->getHeading()+ "}\n");
374                 }
375                 else if (bo->getDepth()==3) {
376                   ts << ("\\subsection{" + bo->getHeading()+ "}\n");
377                 }
378                 else if (bo->getDepth()==4) {
379                   ts << ("\\subsubsection{" + bo->getHeading()+ "}\n");
380                 }
381                 else {
382                   ts << ("\\paragraph*{" + bo->getHeading()+ "}\n");
383                 }
384                 
385                 // If necessary, write note
386                 if (!bo->getNote().isEmpty()) {
387                   ts << (bo->getNoteASCII());
388                   ts << ("\n");
389                 }
390         }
391     bo=model->next(bo);
392    }
393   file.close();
394 }
395
396 ////////////////////////////////////////////////////////////////////////
397 ExportOO::ExportOO()
398 {
399         useSections=false;
400 }
401
402 ExportOO::~ExportOO()
403 {
404 }       
405
406 QString ExportOO::buildList (BranchObj *current)
407 {
408     QString r;
409     BranchObj *bo;
410
411     uint i=0;
412     bo=current->getFirstBranch();
413     if (bo)
414     {
415                 if (!bo->hasHiddenExportParent() )
416                 {
417                         // Start list
418                         r+="<text:list text:style-name=\"vym-list\">\n";
419                         while (bo)
420                         {
421                                 r+="<text:list-item><text:p >";
422                                 r+=quotemeta(bo->getHeading());
423                                 // If necessary, write note
424                                 if (!bo->getNote().isEmpty())
425                                         r+=bo->getNoteOpenDoc();
426                                 r+="</text:p>";
427                                 r+=buildList (bo);      // recursivly add deeper branches
428                                 r+="</text:list-item>\n";
429                                 i++;
430                                 bo=current->getBranchNum(i);
431                         }
432                         r+="</text:list>\n";
433                 }
434     }
435     return r;
436 }
437
438
439 void ExportOO::exportPresentation()
440 {
441         QString allPages;
442
443 /* FIXME not adapted to multiple mapCenters yet
444         // Insert new content
445         content.replace ("<!-- INSERT TITLE -->",quotemeta(mapCenter->getHeading()));
446         content.replace ("<!-- INSERT AUTHOR -->",quotemeta(mapCenter->getAuthor()));
447
448         QString onePage;
449         QString list;
450         
451         BranchObj *sectionBO=mapCenter->getFirstBranch();
452     int i=0;
453         BranchObj *pagesBO;
454     int j=0;
455
456         // Walk sections
457         while (sectionBO && !sectionBO->hasHiddenExportParent() )
458         {
459                 if (useSections)
460                 {
461                         // Add page with section title
462                         onePage=sectionTemplate;
463                         onePage.replace ("<!-- INSERT PAGE HEADING -->", quotemeta(sectionBO->getHeading() ) );
464                         allPages+=onePage;
465                 } else
466                 {
467                         i=-2;   // only use inner loop to 
468                                 // turn mainbranches into pages
469                         sectionBO=mapCenter;
470                 }
471
472                 // Walk mainpages
473                 pagesBO=sectionBO->getFirstBranch();
474                 j=0;
475                 while (pagesBO && !pagesBO->hasHiddenExportParent() )
476                 {
477                         // Add page with list of items
478                         onePage=pageTemplate;
479                         onePage.replace ("<!-- INSERT PAGE HEADING -->", quotemeta (pagesBO->getHeading() ) );
480                         list=buildList (pagesBO);
481                         onePage.replace ("<!-- INSERT LIST -->", list);
482                         allPages+=onePage;
483                         j++;
484                         pagesBO=sectionBO->getBranchNum(j);
485                 }
486                 i++;
487                 sectionBO=mapCenter->getBranchNum(i);
488         }
489         
490         content.replace ("<!-- INSERT PAGES -->",allPages);
491
492         // Write modified content
493         QFile f (contentFile);
494     if ( !f.open( QIODevice::WriteOnly ) ) 
495         {
496                 QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not write %1").arg(contentFile));
497                 mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
498                 return;
499     }
500
501     QTextStream t( &f );
502     t << content;
503     f.close();
504
505         // zip tmpdir to destination
506         zipDir (tmpDir,outputFile);     
507 */
508 }
509
510 bool ExportOO::setConfigFile (const QString &cf)
511 {
512         configFile=cf;
513         int i=cf.findRev ("/");
514         if (i>=0) configDir=cf.left(i);
515         SimpleSettings set;
516         set.readSettings(configFile);
517
518         // set paths
519         templateDir=configDir+"/"+set.readEntry ("Template");
520
521         QDir d (templateDir);
522         if (!d.exists())
523         {
524                 QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Check \"%1\" in\n%2").arg("Template="+set.readEntry ("Template")).arg(configFile));
525                 return false;
526
527         }
528
529         contentTemplateFile=templateDir+"content-template.xml";
530         contentFile=tmpDir.path()+"/content.xml";
531         pageTemplateFile=templateDir+"page-template.xml";
532         sectionTemplateFile=templateDir+"section-template.xml";
533
534         if (set.readEntry("useSections").contains("yes"))
535                 useSections=true;
536
537         // Copy template to tmpdir
538         system ("cp -r "+templateDir+"* "+tmpDir.path());
539
540         // Read content-template
541         if (!loadStringFromDisk (contentTemplateFile,content))
542         {
543                 QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(contentTemplateFile));
544                 return false;
545         }
546
547         // Read page-template
548         if (!loadStringFromDisk (pageTemplateFile,pageTemplate))
549         {
550                 QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(pageTemplateFile));
551                 return false;
552         }
553         
554         // Read section-template
555         if (useSections && !loadStringFromDisk (sectionTemplateFile,sectionTemplate))
556         {
557                 QMessageBox::critical (0,QObject::tr("Critical Export Error"),QObject::tr("Could not read %1").arg(sectionTemplateFile));
558                 return false;
559         }
560         return true;
561 }
562