void NoteFormatter::modifyPdfTags(qint32 resLid, QWebElement &enmedia) { enmedia.setAttribute("width", "100%"); enmedia.setAttribute("height", "100%"); enmedia.setAttribute("lid", QString::number(resLid)); QString x = enmedia.toOuterXml(); x.replace("en-media", "object"); enmedia.setOuterXml(x); x = enmedia.toOuterXml(); }
void MainWindow::saveSelected(const QString &filename) { if (_analyses->count() > 0) { QWebElement element = ui->webViewResults->page()->mainFrame()->documentElement(); QString qHTML = element.toOuterXml(); _package->analysesHTML = fq(qHTML); Json::Value analysesData = Json::arrayValue; for (Analyses::iterator itr = _analyses->begin(); itr != _analyses->end(); itr++) { Analysis *analysis = *itr; if (analysis != NULL && analysis->visible()) { Json::Value analysisData = analysis->asJSON(); analysisData["options"] = analysis->options()->asJSON(); analysesData.append(analysisData); } } _package->analysesData = analysesData; _package->hasAnalyses = true; } _loader.save(filename, _package); _alert->show(); }
void HtmlExtractor::move(QWebElement &element, const QString &file, bool outer) { if(!element.isNull()) { WriteFile(file, outer?element.toOuterXml():element.toInnerXml()); element.removeFromDocument(); } }
void EnmlFormatter::processTodo(QWebElement &node) { bool checked=false; if (node.hasAttribute("checked")) checked = true; node.removeAttribute("style"); node.removeAttribute("type"); removeInvalidAttributes(node); if (checked) node.setAttribute("checked", "true"); node.setOuterXml(node.toOuterXml().replace("<input", "<en-todo").replace("</input", "</en-todo")); }
// Modify the en-to tag into an input field void NoteFormatter::modifyTodoTags(QWebElement &todo) { todo.setAttribute("type", "checkbox"); // Checks the en-to tag wheter or not the todo-item is checked or not // and sets up the HTML to keep storing the information in value QString checked = todo.attribute("checked"); if (checked.toLower() == "true") todo.setAttribute("checked", "checked"); else todo.removeAttribute("checked"); todo.setAttribute("onClick", "if(!checked) removeAttribute('checked'); else setAttribute('checked', 'checked'); editorWindow.editAlert();"); todo.setAttribute("style", "cursor: hand;"); todo.setOuterXml(todo.toOuterXml().replace("en-todo","input")); }
QString message_view::selected_html_fragment() { // TODO: check for the selection #if QT_VERSION<0x040600 QVariant res = m_bodyv->page()->mainFrame()->evaluateJavaScript("document.getElementsById('manitou-body').innerHTML"); return res.toString(); #else QWebElement elt = m_bodyv->page()->mainFrame()->findFirstElement("div#manitou-body"); if (!elt.isNull()) { return elt.toOuterXml(); } else return ""; #endif }
void EnmlFormatter::fixImgNode(QWebElement &e) { QString enType = e.attribute("en-tag", ""); // Check if we have an en-crypt tag. Change it from an img to en-crypt if (enType.toLower() == "en-crypt") { QString encrypted = e.attribute("alt"); QString cipher = e.attribute("cipher", "RC2"); QString hint = e.attribute("hint", ""); QString length = e.attribute("length", "64"); e.removeAttribute("onmouseover"); e.removeAttribute("name"); e.removeAttribute("alt"); e.removeAttribute("en-tag"); e.removeAttribute("contenteditable"); e.removeAttribute("style"); removeInvalidAttributes(e); e.setInnerXml(encrypted); e.setOuterXml("<en-crypt cipher=\"" +cipher +"\" length=\"" + length + "\" hint=\"" +hint +"\">"+encrypted+"</en-crypt>"); // e.setOuterXml(e.toOuterXml().replace("<img", "<en-crypt").replace("</img", "</en-crypt")); return; } // Check if we have a temporary image. If so, remove it if (enType.toLower() == "temporary") {; e.removeFromDocument(); return; } // Latex images are really just img tags, so we now handle them later // Check if we have a LaTeX image. Remove the parent link tag // if (enType.toLower() == "en-latex") { // enType = "en-media"; // parent.parentNode().replaceChild(e, parent); // } // If we've gotten this far, we have an en-media tag e.removeAttribute("en-tag"); int lid = e.attribute("lid").toInt(); resources.append(lid); removeInvalidAttributes(e); e.setOuterXml(e.toOuterXml().replace("<img", "<en-media").replace("</img", "</en-media")); }
void EnmlFormatter::fixObjectNode(QWebElement &e) { QString type = e.attribute("type", ""); if (type == "application/pdf") { qint32 lid = e.attribute("lid", "0").toInt(); e.removeAttribute("width"); e.removeAttribute("height"); e.removeAttribute("lid"); e.removeAttribute("border"); if (lid>0) { resources.append(lid); e.setOuterXml(e.toOuterXml().replace("<object", "<en-media").replace("</object", "</en-media")); } removeInvalidAttributes(e); } else { e.removeFromDocument(); } }
/* If we have an ink note, then we need to pull the image and display it */ bool NoteFormatter::buildInkNote(QWebElement &docElem, QString &hash) { ResourceTable resTable(global.db); qint32 resLid = resTable.getLidByHashHex(note.guid, hash); if (resLid <= 0) return false; docElem.setAttribute("en-tag", "en-media"); docElem.setAttribute("lid", QString::number(resLid)); docElem.setAttribute("type", "application/vnd.evernote.ink"); QString filename = QString("file:///") +global.fileManager.getDbaDirPath()+QString::number(resLid)+QString(".png"); docElem.setAttribute("src", filename); QString k = docElem.toOuterXml(); k.replace("<en-media", "<img"); k.replace("enmedia>", "img>");; docElem.setOuterXml(k); return true; }
QStringList EnmlFormatter::findAllTags(QWebElement &element) { QStringList tags; QString body = element.toOuterXml(); body = body.replace("</","<").replace("/>"," ").replace(">", " "); int i = body.indexOf("<body")+1 ; // Look throug and get a list of all possible tags i = body.indexOf("<", i); while (i>0) { int eot = body.indexOf(" ",i); QString tag = body.mid(i+1, eot-i-1); if (!tags.contains(tag) && tag != "body") tags.append(tag); i=body.indexOf("<", eot); if (tag == "body") i=-1; } return tags; }
void EnmlFormatter::fixLinkNode(QWebElement e) { QString enTag = e.attribute("en-tag", ""); if (enTag.toLower() == "en-media") { resources.append(e.attribute("lid").toInt()); e.removeAttribute("style"); e.removeAttribute("href"); e.removeAttribute("title"); removeInvalidAttributes(e); e.removeAllChildren(); QString newXml = e.toOuterXml(); newXml.replace("<a", "<en-media"); newXml.replace("</a>", "</en-media>"); e.setOuterXml(newXml); } QString latex = e.attribute("href", ""); if (latex.toLower().startsWith("latex://")) { removeInvalidAttributes(e); e.removeAttribute("title"); e.removeAttribute("href"); e.setOuterXml(e.toInnerXml()); } removeInvalidAttributes(e); }
/* Take the ENML note and transform it into HTML that WebKit will not complain about */ QByteArray EnmlFormatter::rebuildNoteEnml() { resources.clear(); QByteArray b; qint32 index; content.replace("</input>",""); // Strip off HTML header index = content.indexOf("<body"); index = content.indexOf(">", index)+1; content.remove(0,index); index = content.indexOf("</body"); content.truncate(index); b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); b.append("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>\n"); b.append("<html><head><title></title></head>"); b.append("<body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;\" >"); b.append(content); b.append("</body></html>"); content.clear(); content = b; // Run it through "tidy". It is a program which will fix any invalid HTML // and give us the results back through stdout. In a perfect world this // wouldn't be needed, but WebKit doesn't always give back good HTML. QProcess tidyProcess; tidyProcess.start("tidy -raw -asxhtml -q -m -u -utf8 ", QIODevice::ReadWrite|QIODevice::Unbuffered); QLOG_DEBUG() << "Starting tidy " << tidyProcess.waitForStarted(); tidyProcess.waitForStarted(); tidyProcess.write(content); tidyProcess.closeWriteChannel(); tidyProcess.waitForFinished(); QLOG_DEBUG() << "Stopping tidy " << tidyProcess.waitForFinished() << " Return Code: " << tidyProcess.state(); QLOG_DEBUG() << "Tidy Errors:" << tidyProcess.readAllStandardError(); content.clear(); content.append(tidyProcess.readAllStandardOutput()); if (content == "") { formattingError = true; return ""; } // Tidy puts this in place, but we don't really need it. content.replace("<form>", ""); content.replace("</form>", ""); index = content.indexOf("<body"); content.remove(0,index); content.prepend("<style>img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>"); content.prepend("<head><meta http-equiv=\"content-type\" content=\"text-html; charset=utf-8\"></head>"); content.prepend("<html>"); content.append("</html>"); content = fixEncryptionTags(content); QWebPage page; QEventLoop loop; page.mainFrame()->setContent(content); QObject::connect(&page, SIGNAL(loadFinished(bool)), &loop, SLOT(quit())); QWebElement element = page.mainFrame()->documentElement(); QStringList tags = findAllTags(element); for (int i=0; i<tags.size(); i++) { QString tag = tags[i]; QWebElementCollection anchors = page.mainFrame()->findAllElements(tag); foreach (QWebElement element, anchors) { if (element.tagName().toLower() == "input") { processTodo(element); } else if (element.tagName().toLower() == "a") { fixLinkNode(element); } else if (element.tagName().toLower() == "object") { fixObjectNode(element); } else if (element.tagName().toLower() == "img") { fixImgNode(element); } else if (!isElementValid(element.tagName())) element.removeFromDocument(); } } content.clear(); content.append(element.toOuterXml()); // Strip off HTML header index = content.indexOf("<body"); index = content.indexOf(">", index)+1; content.remove(0,index); index = content.indexOf("</body"); content.truncate(index); b.clear(); b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); b.append("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>"); b.append("<en-note style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;\" >"); b.append(content); b.append("</en-note>"); content.clear(); content = b; postXmlFix(); return content; }
// Modify the en-media tag into an attachment void NoteFormatter::modifyApplicationTags(QWebElement &enmedia, QString &hash, QString appl) { if (appl.toLower() == "vnd.evernote.ink") { inkNote = true; readOnly = true; buildInkNote(enmedia, hash); return; } ResourceTable resTable(global.db); QString contextFileName; qint32 resLid = resTable.getLidByHashHex(note.guid, hash); Resource r; resTable.get(r, resLid, false); if (!r.data.isSet()) resourceError = true; else { // If we are running the formatter and we are not generating a thumbnail QString mimetype = ""; if (r.mime.isSet()) mimetype = r.mime; if (mimetype == "application/pdf" && pdfPreview && !thumbnail) { modifyPdfTags(resLid, enmedia); return; } // If we are running the formatter so we can generate a thumbnail and it is a PDF if (mimetype == "application/pdf" && pdfPreview && thumbnail) { QString printImageFile = global.fileManager.getTmpDirPath() + QString::number(resLid) +QString("-print.jpg"); QString file = global.fileManager.getDbaDirPath() + QString::number(resLid) +".pdf"; Poppler::Document *doc; doc = Poppler::Document::load(file); if (doc == NULL) return; QImage *image = new QImage(doc->page(0)->renderToImage()); image->save(printImageFile,"jpg"); delete image; enmedia.setAttribute("src", printImageFile); enmedia.removeAttribute("hash"); enmedia.removeAttribute("type"); enmedia.setOuterXml(enmedia.toOuterXml().replace("<en-media","<img")); enmedia.setOuterXml(enmedia.toOuterXml().replace("</en-media>","</img>")); return; } QString fileDetails = ""; MimeReference ref; ResourceAttributes attributes; if (r.attributes.isSet()) attributes = r.attributes; if (attributes.fileName.isSet()) fileDetails = ref.getExtensionFromMime(r.mime, fileDetails); enmedia.setAttribute("href", QString("nnres:") +global.fileManager.getDbaDirPath()+QString::number(resLid) +fileDetails); contextFileName = global.fileManager.getTmpDirPath("")+QString::number(resLid) +global.attachmentNameDelimeter + fileDetails; // Setup the context menu. This is useful if we want to do a "save as" or such contextFileName = contextFileName.replace("\\", "/"); enmedia.setAttribute("onContextMenu", "window.browserWindow.resourceContextMenu('" +contextFileName +"');"); enmedia.setAttribute("en-tag", "en-media"); enmedia.setAttribute("lid", QString::number(resLid)); enmedia.appendInside("<img/>"); QWebElement newText = enmedia.lastChild(); // Build an icon of the image QString fileExt; if (attributes.fileName.isSet()) fileExt = attributes.fileName; else fileExt = appl; QString fn; QString mime; if (attributes.fileName.isSet()) fn = attributes.fileName; if (r.mime.isSet()) mime = r.mime; fileExt = ref.getExtensionFromMime(mime, fn); QString icon = findIcon(resLid, r, fileExt); newText.setAttribute("src", "file:///"+icon); if (attributes.fileName.isSet()) newText.setAttribute("title",attributes.fileName); newText.setAttribute("en-tag", "temporary"); //Rename the tag to a <a> link enmedia.setOuterXml(enmedia.toOuterXml().replace("<en-media","<a")); enmedia.setOuterXml(enmedia.toOuterXml().replace("</en-media>","</a>")); } }
/* Modify an image tag. Basically we turn it back into a picture, write out the file, and modify the ENML */ void NoteFormatter::modifyImageTags(QWebElement &enMedia, QString &hash) { QString mimetype = enMedia.attribute("type"); qint32 resLid = 0; resLid = hashMap[hash]; QString highlightString = ""; if (resLid>0) { QLOG_TRACE() << "Getting resource"; Resource r = resourceMap[resLid]; QLOG_TRACE() << "resource retrieved"; MimeReference ref; QString filename; ResourceAttributes attributes; if (r.attributes.isSet()) attributes = r.attributes; if (attributes.fileName.isSet()) filename = attributes.fileName; QString type = ref.getExtensionFromMime(mimetype, filename); Data data; if (r.data.isSet()) data = r.data; if (data.size.isSet() && data.size > 0) { QString imgfile = "file:///"+global.fileManager.getDbDirPath(QString("dba/") +QString::number(resLid) +type); enMedia.setAttribute("src", imgfile); // Check if this is a LaTeX image ResourceAttributes attributes; if (r.attributes.isSet()) attributes = r.attributes; QString sourceUrl = ""; if (attributes.sourceURL.isSet()) sourceUrl = attributes.sourceURL; if (sourceUrl.toLower().startsWith("http://latex.codecogs.com/gif.latex?")) { enMedia.appendInside("<img/>"); QWebElement newText = enMedia.lastChild(); enMedia.setAttribute("en-tag", "en-latex"); newText.setAttribute("onMouseOver", "style.cursor='pointer'"); newText.setAttribute("title", sourceUrl); newText.setAttribute("href", "latex://"+QString::number(resLid)); } enMedia.setAttribute("onContextMenu", "window.browserWindow.imageContextMenu('" +QString::number(resLid) +"', '" +QString::number(resLid) +type +"');"); highlightString = addImageHighlight(resLid, imgfile); if (highlightString != "") enMedia.setAttribute("onload", highlightString); } } else { resourceError = true; readOnly = true; } // Reset the tags to something that WebKit will understand enMedia.setAttribute("en-tag", "en-media"); enMedia.setPlainText(""); enMedia.setAttribute("lid", QString::number(resLid)); // rename the <enmedia> tag to <img> enMedia.setOuterXml(enMedia.toOuterXml().replace("<en-media","<img")); enMedia.setOuterXml(enMedia.toOuterXml().replace("</en-media>","</img>")); }
/* This will go through and modify some of the ENML tags and turn them into HTML tags. Things like en-media & en-crypt have no HTML values, so we turn them into HTML. */ void NoteFormatter::modifyTags(QWebPage &doc) { tempFiles.clear(); // Modify en-media tags QLOG_TRACE() << "Searching for all en-media tags;"; QWebElementCollection anchors = doc.mainFrame()->findAllElements("en-media"); QLOG_TRACE() << "Search complete: " << anchors.toList().size(); foreach (QWebElement enmedia, anchors) { if (enmedia.hasAttribute("type")) { QString attr = enmedia.attribute("type"); QString hash = enmedia.attribute("hash"); QStringList type = attr.split("/"); if (type.size() >= 2) { QString appl = type[1]; QLOG_TRACE() << "En-Media tag type: " << type[0]; if (type[0] == "image") modifyImageTags(enmedia, hash); else modifyApplicationTags(enmedia, hash, appl); QLOG_TRACE() << "Type modified"; } } } // Modify todo tags anchors = doc.mainFrame()->findAllElements("en-todo"); qint32 enTodoCount = anchors.count(); for (qint32 i=enTodoCount-1; i>=0; i--) { QWebElement enmedia = anchors.at(i); modifyTodoTags(enmedia); } anchors = doc.mainFrame()->findAllElements("en-crypt"); qint32 enCryptLen = anchors.count(); for (qint32 i=enCryptLen-1; i>=0; i--) { QWebElement enmedia = anchors.at(i); QString hint = enmedia.attribute("hint"); QString cipher = enmedia.attribute("cipher", "RC2"); QString length = enmedia.attribute("length","64"); enmedia.setAttribute("contentEditable","false"); enmedia.setAttribute("src", QString("file://")+global.fileManager.getImageDirPath("encrypt.png")); enmedia.setAttribute("en-tag","en-crypt"); enmedia.setAttribute("cipher", cipher); enmedia.setAttribute("length", length); enmedia.setAttribute("hint", hint); enmedia.setAttribute("alt", enmedia.toInnerXml()); global.cryptCounter++; enmedia.setAttribute("id", "crypt"+QString().number(global.cryptCounter)); QString encryptedText = enmedia.toInnerXml(); // If the encryption string contains crlf at the end, remove them because they mess up the javascript. if (encryptedText.endsWith("\n")) encryptedText.truncate(encryptedText.length()-1); if (encryptedText.endsWith("\r")) encryptedText.truncate(encryptedText.length()-1); // Add the commands hint = hint.replace("'","'"); enmedia.setAttribute("onClick", "window.browserWindow.decryptText('crypt"+ QString().number(global.cryptCounter)+ "', '"+encryptedText+"', '"+ hint +"', '" + cipher+ "', " + length + ");"); enmedia.setAttribute("onMouseOver", "style.cursor='hand'"); enmedia.setInnerXml(""); QString k = enmedia.toOuterXml(); k.replace("<en-crypt", "<img"); k.replace("img>", "<en-crypt"); enmedia.setOuterXml(k); } // Modify link tags anchors = doc.mainFrame()->findAllElements("a"); enCryptLen = anchors.count(); for (qint32 i=0; i<anchors.count(); i++) { QWebElement element = anchors.at(i); if (!element.attribute("href").toLower().startsWith("latex://")) element.setAttribute("title", element.attribute("href")); else { element.setAttribute("title", element.attribute("title").toLower().replace("http://latex.codecogs.com/gif.latex?","")); } } }