1 #include "export-confluence.h"
5 #include "attributeitem.h"
7 #include "mainwindow.h"
9 #include "warningdialog.h"
12 extern QString flagsPath;
13 extern Main *mainWindow;
14 extern QString vymName;
15 extern QString vymVersion;
16 extern QString vymHome;
17 extern Settings settings;
19 ExportConfluence::ExportConfluence() : ExportBase() { init(); }
21 ExportConfluence::ExportConfluence(VymModel *m) : ExportBase(m) { init(); }
23 void ExportConfluence::init()
26 exportName = "ConfluenceNewPage";
36 void ExportConfluence::setCreateNewPage(bool b) {createNewPage = b; }
38 void ExportConfluence::setURL(const QString &u) { url = u; }
40 void ExportConfluence::setPageName(const QString &t) { pageName = t;}
42 QString ExportConfluence::getBranchText(BranchItem *current)
46 LinkableMapObj *lmo = current->getLMO();
48 hr = ((BranchObj *)lmo)->getBBoxHeading();
50 QString id = model->getSelectString(current);
51 QString heading = quoteMeta(current->getHeadingPlain());
55 if (dia.useNumbering()) number = getSectionString(current) + " ";
57 // Long headings are will have linebreaks by default
58 heading = heading.replace("\\n", " ");
60 if (dia.useTextColor()) {
61 QColor c = current->getHeadingColor();
62 QString cs = QString("rgb(%1,%2,%3);")
66 heading = QString("<span style='color: %1'>%2</span>")
68 .arg(number + heading);
78 Task *task = current->getTask();
81 QString taskName = task->getIconString();
82 taskFlags += QString("<img src=\"flags/flag-%1.png\"
83 alt=\"%2\">") .arg(taskName) .arg(QObject::tr("Flag: %1","Alt tag in
84 HTML export").arg(taskName));
94 foreach (QString flag, current->activeFlagNames()) //
95 better don't use activeFlagNames, won't work for userflags userFlags +=
96 QString("<img src=\"flags/flag-%1.png\" alt=\"%2\">") .arg(flag)
97 .arg(QObject::tr("Flag: %1","Alt tag in HTML
104 //<ri:user ri:userkey="55df23264acf166a014b54c57792009b"/>
107 // For URLs check, if there is already a Confluence user in an attribute
109 AttributeItem *ai = current->getAttributeByKey("ConfluenceUser.userKey");
112 s += QString(" <ac:link> <ri:user ri:userkey=\"%1\"/></ac:link>").arg(ai->getValue().toString());
114 url = current->getURL();
116 if (!url.isEmpty()) {
117 if (url.contains(settings.value("/atlassian/confluence/url",
118 "---undefined---").toString()) && url.contains("&")) {
120 // Fix ampersands in URL to Confluence itself
121 url = quoteMeta(url);
124 s += QString("<a href=\"%1\">%2</a>")
126 .arg(taskFlags + heading + userFlags);
128 s += taskFlags + heading + userFlags;
132 if (dia.includeImages())
134 int imageCount = current->imageCount();
137 for (int i=0; i< imageCount; i++)
139 image = current->getImageNum(i);
140 imagePath = "image-" + image->getUuid().toString() + ".png";
141 image->saveImage( dirPath + "/" + imagePath);
142 agent->addUploadAttachmentPath(imagePath);
143 s += "<p> <span style=\"color: rgb(0,170,255);\">";
145 if (image->width() > 250)
146 s+= "<ac:image ac:width=\"250\" >";
149 s += QString("<ri:attachment ri:filename=\"%1\"/></ac:image></span></p>").arg(imagePath);
155 if (!current->isNoteEmpty()) {
156 VymNote note = current->getNote();
158 if (note.isRichText()) {
162 re.setPattern("</?html>");
165 re.setPattern("</?head.*>");
168 re.setPattern("</?body.*>");
171 re.setPattern("</?meta.*>");
174 re.setPattern("<style.*>.*</style>");
177 re.setPattern("<!DOCTYPE.*>");
180 re.setPattern("&(?!\\w*;)");
181 n.replace(re, "&");
184 n = current->getNoteASCII(0, 0);
185 n.replace("&", "&");
186 n.replace("<", "<");
187 n.replace(">", ">");
188 if (current->getNote().getFontHint() == "fixed")
189 n = "<pre>" + n + "</pre>";
191 n = "<p>" + n + "</p>";
192 n.replace("\n", "</p><p>");
196 s += "\n<table class=\"vym-note\"><tr><td>\n" + n +
197 "\n</td></tr></table>\n";
204 QString ExportConfluence::buildList(BranchItem *current)
211 BranchItem *bi = current->getFirstBranch();
213 QString ind = "\n" + indent(current->depth() + 1, false);
215 QString sectionBegin = "";
216 QString sectionEnd = "" ;
223 switch (current->depth() + 1) {
239 QString("class=\"vym-list-ul-%1\"").arg(current->depth() + 1) + ">";
240 sectionEnd = "</ul>";
247 if (bi && !bi->hasHiddenExportParent() && !bi->isHidden()) {
248 r += ind + sectionBegin;
249 if ( bi && bi->isScrolled())
251 expandBegin = "\n" + ind;
252 expandBegin += QString("<ac:structured-macro ac:macro-id=\"%1\" ac:name=\"expand\" ac:schema-version=\"1\">").arg(bi->getUuid().toString()) ;
253 expandBegin += "<ac:rich-text-body>";
254 expandEnd = "\n" + ind + "</ac:rich-text-body>";
255 expandEnd += "</ac:structured-macro>";
262 if (!bi->hasHiddenExportParent() && !bi->isHidden() ) {
267 // Check if first mapcenter is already usded for pageName
268 if ( !(bi == model->getRootItem()->getFirstBranch() && dia.mapCenterToPageName()))
269 r += getBranchText(bi);
271 if (itemBegin.startsWith("<h"))
273 // Current item is heading
281 // Current item is list item
288 r += ind + sectionEnd;
291 bi = current->getBranchNum(i);
297 QString ExportConfluence::createTOC()
301 toc += "<table class=\"vym-toc\">\n";
302 toc += "<tr><td class=\"vym-toc-title\">\n";
303 toc += QObject::tr("Contents:", "Used in HTML export");
305 toc += "</td></tr>\n";
307 BranchItem *cur = NULL;
308 BranchItem *prev = NULL;
309 model->nextBranch(cur, prev);
311 if (!cur->hasHiddenExportParent() && !cur->hasScrolledParent()) {
312 if (dia.useNumbering())
313 number = getSectionString(cur);
315 QString("<div class=\"vym-toc-branch-%1\">").arg(cur->depth());
316 toc += QString("<a href=\"#%1\"> %2 %3</a><br />\n")
317 .arg(model->getSelectString(cur))
319 .arg(quoteMeta(cur->getHeadingPlain()));
322 model->nextBranch(cur, prev);
324 toc += "</td></tr>\n";
329 void ExportConfluence::doExport(bool useDialog)
331 // Initialize tmp directory below tmp dir of map vym itself
334 filePath = tmpDir.path() + "/export.html";
336 // Setup dialog and read settings
337 dia.setMapName(model->getMapName());
338 dia.setFilePath(model->getFilePath());
340 dia.setPageName(pageName);
341 BranchItem *bi = (BranchItem*)(model->findBySelectString("mc0"));
343 dia.setPageNameHint(bi->getHeadingPlain());
348 if (dia.exec() != QDialog::Accepted)
352 createNewPage = dia.getCreateNewPage();
353 pageName = dia.getPageName();
356 // Open file for writing
357 QFile file(filePath);
358 if (!file.open(QIODevice::WriteOnly)) {
359 QMessageBox::critical(
360 0, QObject::tr("Critical Export Error"),
361 QObject::tr("Trying to save HTML file:") + "\n\n" +
362 QObject::tr("Could not write %1").arg(filePath));
365 QTextStream ts(&file);
366 ts.setCodec("UTF-8");
368 // Hide stuff during export
369 model->setExportMode(true);
371 // Create Confluence agent
372 agent = new ConfluenceAgent();
374 agent->setJobType(ConfluenceAgent::CreatePage);
376 agent->setJobType(ConfluenceAgent::UpdatePage);
377 agent->setPageURL(url);
378 agent->setNewPageName(pageName);
379 agent->setUploadPagePath(filePath);
380 agent->setModelID(model->getModelID());
382 // Include image of map
383 QString mapImageFilePath = tmpDir.path() + "/mapImage.png";
384 if (dia.includeMapImage())
386 offset = model->exportImage (mapImageFilePath, false, "PNG");
387 QImage img(mapImageFilePath);
389 ts << " <span style=\"color: rgb(0,170,255);\">\n";
390 if (img.width() > 800)
391 ts << " <ac:image ac:width=\"800\" >";
393 ts << " <ac:image >";
394 ts << " <ri:attachment ri:filename=\"mapImage.png\"/>";
395 ts << " </ac:image>\n";
400 agent->addUploadAttachmentPath(mapImageFilePath);
403 // Include table of contents
404 // if (dia.useTOC) ts << createTOC();
406 // Main loop over all mapcenters
407 ts << buildList(model->getRootItem()) << "\n";
409 ts << "<p style=\"text-align: center;\"> <sub> <em>Page created with ";
410 ts << "<a href=\"https://sourceforge.net/projects/vym/\">" << vymName << " " << vymVersion<< "</a>";
411 ts << "</em> </sub> </p>";
419 exportName = (createNewPage) ? "ConfluenceNewPage" : "ConfluenceUpdatePage";
421 if (!pageName.isEmpty())
424 result = ExportBase::Ongoing;
426 // Prepare human readable info in tooltip of LastExport:
427 displayedDestination = QString("Page name: \"%1\" Url: \"%2\"").arg(pageName).arg(url);
429 completeExport(args);
432 model->setExportMode(false);
434 // Note: ConfluenceAgent professionally destroys itself after completion