1 #include "export-html.h"
6 #include "mainwindow.h"
7 #include "warningdialog.h"
9 extern QString flagsPath;
10 extern Main *mainWindow;
11 extern QString vymVersion;
12 extern QString vymHome;
14 extern FlagRowMaster *standardFlagsMaster;
15 extern FlagRowMaster *userFlagsMaster;
17 ExportHTML::ExportHTML() : ExportBase() { init(); }
19 ExportHTML::ExportHTML(VymModel *m) : ExportBase(m) { init(); }
21 void ExportHTML::init()
28 QString ExportHTML::getBranchText(BranchItem *current)
33 LinkableMapObj *lmo = current->getLMO();
35 hr = ((BranchObj *)lmo)->getBBoxHeading();
36 vis = lmo->isVisibleObj();
39 QString id = model->getSelectString(current);
41 col = QString("style='color:%1'")
42 .arg(current->getHeadingColor().name());
43 QString s = QString("<span class='vym-branch-%1' %2 id='%3'>")
44 .arg(current->depth())
47 QString url = current->getURL();
48 QString heading = quoteMeta(current->getHeadingPlain());
52 if (dia.useTaskFlags) {
53 Task *task = current->getTask();
55 QString taskName = task->getIconString();
57 QString("<img src=\"flags/flag-%1.png\" alt=\"%2\">")
59 .arg(QObject::tr("Flag: %1", "Alt tag in HTML export")
64 // Standard and user flags
66 if (dia.useUserFlags) {
68 foreach (QUuid uid, current->activeFlagUids()) {
71 f = standardFlagsMaster->findFlagByUid(uid);
73 f = userFlagsMaster->findFlagByUid(uid);
78 "<img width=\"32px\" alt=\"%1\" src=\"flags/%2\">")
79 .arg(QObject::tr("Flag: %1",
80 "Alt tag in HTML export")
83 f->getImageObj()->getExtension());
90 number = getSectionString(current) + " ";
94 s += QString("<a href=\"%1\">%2<img src=\"flags/flag-url.png\" "
97 .arg(number + taskFlags + heading + flags)
98 .arg(QObject::tr("Flag: url", "Alt tag in HTML export"));
100 QRectF fbox = current->getBBoxURLFlag();
102 imageMap += QString(" <area shape='rect' coords='%1,%2,%3,%4' "
103 "href='%5' alt='External link: %6'>\n")
104 .arg(fbox.left() - offset.x())
105 .arg(fbox.top() - offset.y())
106 .arg(fbox.right() - offset.x())
107 .arg(fbox.bottom() - offset.y())
112 s += number + taskFlags + heading + flags;
117 if (vis && dia.includeMapImage)
118 imageMap += QString(" <area shape='rect' coords='%1,%2,%3,%4' "
119 "href='#%5' alt='%6'>\n")
120 .arg(hr.left() - offset.x())
121 .arg(hr.top() - offset.y())
122 .arg(hr.right() - offset.x())
123 .arg(hr.bottom() - offset.y())
127 // Include images experimental
128 if (dia.includeImages) {
129 int imageCount = current->imageCount();
132 for (int i = 0; i < imageCount; i++) {
133 image = current->getImageNum(i);
134 imageName = image->getUniqueFilename();
135 image->saveImage(dirPath + "/" + imageName);
136 s += "</br><img src=\"" + imageName;
138 QObject::tr("Image: %1", "Alt tag in HTML export")
139 .arg(image->getOriginalFilename());
145 if (!current->isNoteEmpty()) {
146 VymNote note = current->getNote();
148 if (note.isRichText()) {
152 if (current->getNote().getFontHint() == "fixed")
153 n.replace(re, "<p class=\"vym-fixed-note-paragraph\">");
155 n.replace(re, "<p class=\"vym-note-paragraph\">");
157 re.setPattern("</?html>");
160 re.setPattern("</?head.*>");
163 re.setPattern("</?body.*>");
166 re.setPattern("</?meta.*>");
169 re.setPattern("<style.*>.*</style>");
172 // re.setPattern("<!DOCTYPE.*>");
176 n = current->getNoteASCII(0, 0)
177 .replace("<", "<")
178 .replace(">", ">");
179 n.replace("\n", "<br/>");
180 if (current->getNote().getFontHint() == "fixed")
181 n = "<pre>" + n + "</pre>";
183 s += "\n<table class=\"vym-note\"><tr><td "
184 "class=\"vym-note-flag\">\n<td>\n" +
185 n + "\n</td></tr></table>\n";
192 QString ExportHTML::buildList(BranchItem *current)
199 BranchItem *bi = current->getFirstBranch();
201 QString ind = "\n" + indent(current->depth() + 1, false);
203 QString sectionBegin;
208 switch (current->depth() + 1) {
224 QString("class=\"vym-list-ul-%1\"").arg(current->depth() + 1) + ">";
225 sectionEnd = "</ul>";
231 if (bi && !bi->hasHiddenExportParent() && !bi->isHidden()) {
232 r += ind + sectionBegin;
234 if (!bi->hasHiddenExportParent() && !bi->isHidden()) {
236 r += ind + itemBegin;
237 r += getBranchText(bi);
239 if (itemBegin.startsWith("<h"))
240 r += itemEnd + buildList(bi);
242 r += buildList(bi) + itemEnd;
245 bi = current->getBranchNum(i);
247 r += ind + sectionEnd;
253 QString ExportHTML::createTOC()
257 toc += "<table class=\"vym-toc\">\n";
258 toc += "<tr><td class=\"vym-toc-title\">\n";
259 toc += QObject::tr("Contents:", "Used in HTML export");
261 toc += "</td></tr>\n";
263 BranchItem *cur = NULL;
264 BranchItem *prev = NULL;
265 model->nextBranch(cur, prev);
267 if (!cur->hasHiddenExportParent() && !cur->hasScrolledParent()) {
268 if (dia.useNumbering)
269 number = getSectionString(cur);
271 QString("<div class=\"vym-toc-branch-%1\">").arg(cur->depth());
272 toc += QString("<a href=\"#%1\"> %2 %3</a></br>\n")
273 .arg(model->getSelectString(cur))
275 .arg(quoteMeta(cur->getHeadingPlain()));
278 model->nextBranch(cur, prev);
280 toc += "</td></tr>\n";
285 void ExportHTML::doExport(bool useDialog)
287 // Setup dialog and read settings
288 dia.setMapName(model->getMapName());
289 dia.setFilePath(model->getFilePath());
292 if (dirPath != defaultDirPath)
293 dia.setDirectory(dirPath);
296 if (dia.exec() != QDialog::Accepted)
301 // Check, if warnings should be used before overwriting
302 // the output directory
303 if (dia.getDir().exists() && dia.getDir().count() > 0) {
305 warn.showCancelButton(true);
306 warn.setText(QString("The directory %1 is not empty.\n"
307 "Do you risk to overwrite some of its contents?")
308 .arg(dia.getDir().absolutePath()));
309 warn.setCaption("Warning: Directory not empty");
310 warn.setShowAgainName("mainwindow/export-XML-overwrite-dir");
312 if (warn.exec() != QDialog::Accepted) {
313 mainWindow->statusMessage(QString(QObject::tr("Export aborted.")));
318 dirPath = dia.getDir().absolutePath();
319 filePath = getFilePath();
323 cssSrc = dia.getCssSrc();
324 cssDst = dirPath + "/" + basename(cssSrc);
325 if (cssSrc.isEmpty()) {
326 QMessageBox::critical(
327 0, QObject::tr("Critical"),
328 QObject::tr("Could not find stylesheet %1").arg(cssSrc));
336 if (!src.copy(cssDst)) {
337 QMessageBox::critical(
338 0, QObject::tr("Error", "ExportHTML"),
339 QObject::tr("Could not copy\n%1 to\n%2", "ExportHTML")
346 // Open file for writing
347 QFile file(filePath);
348 if (!file.open(QIODevice::WriteOnly)) {
349 QMessageBox::critical(
350 0, QObject::tr("Critical Export Error"),
351 QObject::tr("Trying to save HTML file:") + "\n\n" +
352 QObject::tr("Could not write %1").arg(filePath));
353 mainWindow->statusMessage(QString(QObject::tr("Export failed.")));
356 QTextStream ts(&file);
357 ts.setCodec("UTF-8");
359 // Hide stuff during export
360 model->setExportMode(true);
364 ts << "\n<meta http-equiv=\"content-type\" content=\"text/html; "
366 ts << "\n<meta name=\"generator=\" content=\" vym - view your mind - " +
367 vymVersion + " - " + vymHome + "\">";
368 ts << "\n<meta name=\"author\" content=\"" + quoteMeta(model->getAuthor()) +
370 ts << "\n<meta name=\"description\" content=\"" +
371 quoteMeta(model->getComment()) + "\"> ";
372 ts << "\n<link rel='stylesheet' id='css.stylesheet' href='"
373 << basename(cssDst) << "' />\n";
374 QString title = model->getTitle();
376 title = model->getMapName();
377 ts << "\n<head><title>" + quoteMeta(title) + "</title></head>";
381 // (be careful: this resets Export mode, so call before exporting branches)
382 if (dia.includeMapImage) {
383 QString mapName = getMapName();
384 ts << "<center><img src=\"" << mapName << ".png\"";
386 << QString("Image of map: %1.vym").arg(mapName)
388 ts << " usemap='#imagemap'></center>\n";
390 model->exportImage(dirPath + "/" + mapName + ".png", false, "PNG");
393 // Include table of contents
398 model->resetUsedFlags();
400 // Main loop over all mapcenters
401 ts << buildList(model->getRootItem()) << "\n";
404 ts << "<map name='imagemap'>\n" + imageMap + "</map>\n";
408 ts << "<table class=\"vym-footer\"> \n\
410 <td class=\"vym-footerL\">" +
411 filePath + "</td> \n\
412 <td class=\"vym-footerC\">" +
413 model->getDate() + "</td> \n\
414 <td class=\"vym-footerR\"> <a href='" +
415 vymHome + "'>vym " + vymVersion + "</a></td> \n\
418 ts << "</body></html>";
421 QString flagsBasePath = dia.getDir().absolutePath() + "/flags";
422 QDir d(flagsBasePath);
424 if (!dia.getDir().mkdir("flags")) {
425 QMessageBox::critical(
426 0, QObject::tr("Critical"),
427 QObject::tr("Trying to create directory for flags:") + "\n\n" +
428 QObject::tr("Could not create %1").arg(flagsBasePath));
433 foreach (QUuid uid, activeFlags) {
434 f = standardFlagsMaster->findFlagByUid(uid);
436 f = userFlagsMaster->findFlagByUid(uid);
439 ImageObj *io = f->getImageObj();
441 io->save(flagsBasePath + "/" + uid.toString() +
446 if (!dia.postscript.isEmpty()) {
448 p.runScript(dia.postscript, dirPath + "/" + filePath);
451 displayedDestination = filePath;
453 result = ExportBase::Success;
458 completeExport(args);
461 model->setExportMode(false);