root / programs / qtjsruntime / pagerunner.cpp @ 62f4506a
History | View | Annotate | Download (6.1 kB)
| 1 | 9cf13184 | Jos van den Oever | #include "pagerunner.h" |
|---|---|---|---|
| 2 | 9cf13184 | Jos van den Oever | |
| 3 | 9cf13184 | Jos van den Oever | #include "nam.h" |
| 4 | 9cf13184 | Jos van den Oever | #include "nativeio.h" |
| 5 | 9cf13184 | Jos van den Oever | #include <QtCore/QFileInfo> |
| 6 | 9cf13184 | Jos van den Oever | #include <QtCore/QTemporaryFile> |
| 7 | 9cf13184 | Jos van den Oever | #include <QtCore/QTimer> |
| 8 | 9cf13184 | Jos van den Oever | #include <QtCore/QCoreApplication> |
| 9 | 9cf13184 | Jos van den Oever | #include <QtGui/QPainter> |
| 10 | 9cf13184 | Jos van den Oever | #include <QtGui/QPrinter> |
| 11 | 9cf13184 | Jos van den Oever | #include <QtWebKit/QWebFrame> |
| 12 | 9cf13184 | Jos van den Oever | |
| 13 | 9cf13184 | Jos van den Oever | QByteArray getRuntimeBindings() {
|
| 14 | 9cf13184 | Jos van den Oever | return
|
| 15 | 9cf13184 | Jos van den Oever | "if (typeof(runtime) !== 'undefined') {"
|
| 16 | 9cf13184 | Jos van den Oever | " runtime.readFileSync = function (path, encoding) {"
|
| 17 | 9cf13184 | Jos van den Oever | " return nativeio.readFileSync(path, encoding);"
|
| 18 | 9cf13184 | Jos van den Oever | " };"
|
| 19 | 9cf13184 | Jos van den Oever | " runtime.read = function (path, offset, length, callback) {"
|
| 20 | 9cf13184 | Jos van den Oever | " var data = nativeio.read(path, offset, length);"
|
| 21 | 9cf13184 | Jos van den Oever | " data = runtime.byteArrayFromString(data, 'binary');"
|
| 22 | 9cf13184 | Jos van den Oever | " callback(nativeio.error()||null, data);"
|
| 23 | 9cf13184 | Jos van den Oever | " };"
|
| 24 | 9cf13184 | Jos van den Oever | " runtime.writeFile = function (path, data, callback) {"
|
| 25 | 9cf13184 | Jos van den Oever | " data = runtime.byteArrayToString(data, 'binary');"
|
| 26 | 9cf13184 | Jos van den Oever | " nativeio.writeFile(path, data);"
|
| 27 | 9cf13184 | Jos van den Oever | " callback(nativeio.error()||null);"
|
| 28 | 9cf13184 | Jos van den Oever | " };"
|
| 29 | 9cf13184 | Jos van den Oever | " runtime.deleteFile = function (path, callback) {"
|
| 30 | 9cf13184 | Jos van den Oever | " nativeio.unlink(path);"
|
| 31 | 9cf13184 | Jos van den Oever | " callback(nativeio.error()||null);"
|
| 32 | 9cf13184 | Jos van den Oever | " };"
|
| 33 | 9cf13184 | Jos van den Oever | " runtime.getFileSize = function (path, callback) {"
|
| 34 | 9cf13184 | Jos van den Oever | " callback(nativeio.getFileSize(path));"
|
| 35 | 9cf13184 | Jos van den Oever | " };"
|
| 36 | 9cf13184 | Jos van den Oever | " runtime.exit = function (exitCode) {"
|
| 37 | 9cf13184 | Jos van den Oever | " nativeio.exit(exitCode);"
|
| 38 | 9cf13184 | Jos van den Oever | " };"
|
| 39 | 9cf13184 | Jos van den Oever | "}";
|
| 40 | 9cf13184 | Jos van den Oever | } |
| 41 | 9cf13184 | Jos van den Oever | |
| 42 | 9cf13184 | Jos van den Oever | PageRunner::PageRunner(const QStringList& args)
|
| 43 | 9cf13184 | Jos van den Oever | : QWebPage(0),
|
| 44 | 9cf13184 | Jos van den Oever | out(stdout), |
| 45 | 9cf13184 | Jos van den Oever | err(stderr), |
| 46 | 9cf13184 | Jos van den Oever | view(new QWidget()),
|
| 47 | 9cf13184 | Jos van den Oever | nativeio(new NativeIO(this)) { |
| 48 | 9cf13184 | Jos van den Oever | |
| 49 | 9cf13184 | Jos van den Oever | QMap<QString, QString> settings = parseArguments(args); |
| 50 | 9cf13184 | Jos van den Oever | QStringList arguments = args.mid(settings.size() * 2);
|
| 51 | 9cf13184 | Jos van den Oever | exportpdf = settings.value("export-pdf");
|
| 52 | 9cf13184 | Jos van den Oever | exportpng = settings.value("export-png");
|
| 53 | 9cf13184 | Jos van den Oever | url = QUrl(arguments[0]);
|
| 54 | 9cf13184 | Jos van den Oever | if (url.scheme() == "file" || url.isRelative()) { |
| 55 | 9cf13184 | Jos van den Oever | QFileInfo info(url.toLocalFile()); |
| 56 | 9cf13184 | Jos van den Oever | if (!info.isReadable() || !info.isFile()) {
|
| 57 | 9cf13184 | Jos van den Oever | QTextStream err(stderr); |
| 58 | 9cf13184 | Jos van den Oever | err << "Cannot read file '" + url.toString() + "'.\n"; |
| 59 | 9cf13184 | Jos van den Oever | qApp->exit(1);
|
| 60 | 9cf13184 | Jos van den Oever | } |
| 61 | 9cf13184 | Jos van den Oever | } |
| 62 | 9cf13184 | Jos van den Oever | nam = new NAM(this, QUrl(url).host(), QUrl(url).port()); |
| 63 | 9cf13184 | Jos van den Oever | |
| 64 | 9cf13184 | Jos van den Oever | setNetworkAccessManager(nam); |
| 65 | 9cf13184 | Jos van den Oever | connect(this, SIGNAL(loadFinished(bool)), this, SLOT(finished(bool))); |
| 66 | 9cf13184 | Jos van den Oever | connect(mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), |
| 67 | 9cf13184 | Jos van den Oever | this, SLOT(slotInitWindowObjects()));
|
| 68 | 9cf13184 | Jos van den Oever | |
| 69 | 9cf13184 | Jos van den Oever | setView(view); |
| 70 | 9cf13184 | Jos van den Oever | scriptMode = arguments[0].endsWith(".js"); |
| 71 | 9cf13184 | Jos van den Oever | if (scriptMode) {
|
| 72 | 9cf13184 | Jos van den Oever | QByteArray html = "'" + arguments[0].toUtf8().replace('\'', "\\'") |
| 73 | 9cf13184 | Jos van den Oever | + "'";
|
| 74 | 9cf13184 | Jos van den Oever | for (int i = 1; i < arguments.length(); ++i) { |
| 75 | 9cf13184 | Jos van den Oever | html += ",'" + arguments[i].toUtf8().replace('\'', "\\'") + "'"; |
| 76 | 9cf13184 | Jos van den Oever | } |
| 77 | 9cf13184 | Jos van den Oever | html = "<html>"
|
| 78 | 9cf13184 | Jos van den Oever | "<head><base href=\".\"></base><title></title>"
|
| 79 | 9cf13184 | Jos van den Oever | "<script>var arguments=[" + html + "];</script>" |
| 80 | 9cf13184 | Jos van den Oever | "<script src=\"" + arguments[0].toUtf8() + "\"></script>"; |
| 81 | 9cf13184 | Jos van den Oever | if (arguments[0].endsWith("runtime.js")) { |
| 82 | 9cf13184 | Jos van den Oever | // add runtime modification
|
| 83 | 9cf13184 | Jos van den Oever | html += "<script>" + getRuntimeBindings() + "</script>"; |
| 84 | 9cf13184 | Jos van den Oever | } |
| 85 | 9cf13184 | Jos van den Oever | html += "</head><body></body></html>\n";
|
| 86 | 9cf13184 | Jos van den Oever | QTemporaryFile tmp("XXXXXX.html");
|
| 87 | 9cf13184 | Jos van den Oever | tmp.setAutoRemove(true);
|
| 88 | 9cf13184 | Jos van den Oever | tmp.open(); |
| 89 | 9cf13184 | Jos van den Oever | tmp.write(html); |
| 90 | 9cf13184 | Jos van den Oever | tmp.close(); |
| 91 | 9cf13184 | Jos van den Oever | mainFrame()->load(tmp.fileName()); |
| 92 | 9cf13184 | Jos van den Oever | } else {
|
| 93 | 9cf13184 | Jos van den Oever | // Make the url absolute. If it is not done here, QWebFrame will do
|
| 94 | 9cf13184 | Jos van den Oever | // it, and it will lose the query and fragment part.
|
| 95 | 9cf13184 | Jos van den Oever | QUrl absurl; |
| 96 | 9cf13184 | Jos van den Oever | if (url.isRelative()) {
|
| 97 | 9cf13184 | Jos van den Oever | absurl = QUrl::fromLocalFile(QFileInfo(url.toLocalFile()).absoluteFilePath()); |
| 98 | 9cf13184 | Jos van den Oever | absurl.setQueryItems(url.queryItems()); |
| 99 | 9cf13184 | Jos van den Oever | absurl.setFragment(url.fragment()); |
| 100 | 9cf13184 | Jos van den Oever | } else {
|
| 101 | 9cf13184 | Jos van den Oever | absurl = url; |
| 102 | 9cf13184 | Jos van den Oever | } |
| 103 | 9cf13184 | Jos van den Oever | mainFrame()->load(absurl); |
| 104 | 9cf13184 | Jos van den Oever | } |
| 105 | 9cf13184 | Jos van den Oever | } |
| 106 | 9cf13184 | Jos van den Oever | PageRunner::~PageRunner() {
|
| 107 | 9cf13184 | Jos van den Oever | delete view;
|
| 108 | 9cf13184 | Jos van den Oever | } |
| 109 | 9cf13184 | Jos van den Oever | void PageRunner::finished(bool ok) { |
| 110 | 9cf13184 | Jos van den Oever | // bind nativeio
|
| 111 | 9cf13184 | Jos van den Oever | if (!ok) {
|
| 112 | 9cf13184 | Jos van den Oever | qApp->exit(1);
|
| 113 | 9cf13184 | Jos van den Oever | } |
| 114 | 9cf13184 | Jos van den Oever | mainFrame()->evaluateJavaScript(getRuntimeBindings()); |
| 115 | 9cf13184 | Jos van den Oever | |
| 116 | 9cf13184 | Jos van den Oever | // connect signals
|
| 117 | 9cf13184 | Jos van den Oever | connect(this, SIGNAL(contentsChanged()), this, SLOT(noteChange())); |
| 118 | 9cf13184 | Jos van den Oever | connect(this, SIGNAL(downloadRequested(QNetworkRequest)),
|
| 119 | 9cf13184 | Jos van den Oever | this, SLOT(noteChange()));
|
| 120 | 9cf13184 | Jos van den Oever | connect(this, SIGNAL(repaintRequested(QRect)),
|
| 121 | 9cf13184 | Jos van den Oever | this, SLOT(noteChange()));
|
| 122 | 9cf13184 | Jos van den Oever | connect(mainFrame(), SIGNAL(pageChanged()), this, SLOT(noteChange()));
|
| 123 | 9cf13184 | Jos van den Oever | connect(this, SIGNAL(geometryChangeRequested(QRect)),
|
| 124 | 9cf13184 | Jos van den Oever | this, SLOT(noteChange()));
|
| 125 | 9cf13184 | Jos van den Oever | QTimer::singleShot(150, this, SLOT(reallyFinished())); |
| 126 | 9cf13184 | Jos van den Oever | changed = false;
|
| 127 | 9cf13184 | Jos van den Oever | time.start(); |
| 128 | 9cf13184 | Jos van den Oever | } |
| 129 | 9cf13184 | Jos van den Oever | void PageRunner::reallyFinished() {
|
| 130 | 9cf13184 | Jos van den Oever | int latency = time.restart();
|
| 131 | 9cf13184 | Jos van den Oever | // err << latency << " " << changed << " " << nam->hasOutstandingRequests() << endl;
|
| 132 | 9cf13184 | Jos van den Oever | if (changed || latency >= 152 || nam->hasOutstandingRequests()) { |
| 133 | 9cf13184 | Jos van den Oever | QTimer::singleShot(150, this, SLOT(reallyFinished())); |
| 134 | 9cf13184 | Jos van den Oever | changed = false;
|
| 135 | 9cf13184 | Jos van den Oever | return;
|
| 136 | 9cf13184 | Jos van den Oever | } |
| 137 | 9cf13184 | Jos van den Oever | if (!exportpdf.isEmpty() || !exportpng.isEmpty()) {
|
| 138 | 9cf13184 | Jos van den Oever | setViewportSize(mainFrame()->contentsSize()); |
| 139 | 9cf13184 | Jos van den Oever | } |
| 140 | 9cf13184 | Jos van den Oever | if (!exportpng.isEmpty()) {
|
| 141 | 9cf13184 | Jos van den Oever | renderToFile(exportpng); |
| 142 | 9cf13184 | Jos van den Oever | } |
| 143 | 9cf13184 | Jos van den Oever | if (!exportpdf.isEmpty()) {
|
| 144 | 9cf13184 | Jos van den Oever | printToFile(exportpdf); |
| 145 | 9cf13184 | Jos van den Oever | } |
| 146 | 9cf13184 | Jos van den Oever | qApp->exit(0);
|
| 147 | 9cf13184 | Jos van den Oever | } |
| 148 | 9cf13184 | Jos van den Oever | QMap<QString, QString> PageRunner::parseArguments(const QStringList& args) {
|
| 149 | 9cf13184 | Jos van den Oever | int i = 0; |
| 150 | 9cf13184 | Jos van den Oever | QMap<QString, QString> settings; |
| 151 | 9cf13184 | Jos van den Oever | while (i + 2 < args.length()) { |
| 152 | 9cf13184 | Jos van den Oever | if (args[i].startsWith("--")) { |
| 153 | 9cf13184 | Jos van den Oever | settings[args[i].mid(2)] = args[i+1]; |
| 154 | 9cf13184 | Jos van den Oever | } |
| 155 | 9cf13184 | Jos van den Oever | i += 2;
|
| 156 | 9cf13184 | Jos van den Oever | } |
| 157 | 9cf13184 | Jos van den Oever | return settings;
|
| 158 | 9cf13184 | Jos van den Oever | } |
| 159 | 9cf13184 | Jos van den Oever | void PageRunner::slotInitWindowObjects() {
|
| 160 | 9cf13184 | Jos van den Oever | mainFrame()->addToJavaScriptWindowObject("nativeio", nativeio);
|
| 161 | 9cf13184 | Jos van den Oever | } |
| 162 | 9cf13184 | Jos van den Oever | void PageRunner::renderToFile(const QString& filename) { |
| 163 | 9cf13184 | Jos van den Oever | QImage pixmap(mainFrame()->contentsSize().boundedTo(QSize(10000,10000)), |
| 164 | 9cf13184 | Jos van den Oever | QImage::Format_ARGB32_Premultiplied); |
| 165 | 9cf13184 | Jos van den Oever | QPainter painter(&pixmap); |
| 166 | 9cf13184 | Jos van den Oever | mainFrame()->render(&painter, QWebFrame::ContentsLayer); |
| 167 | 9cf13184 | Jos van den Oever | painter.end(); |
| 168 | 9cf13184 | Jos van den Oever | pixmap.save(filename); |
| 169 | 9cf13184 | Jos van den Oever | } |
| 170 | 9cf13184 | Jos van den Oever | void PageRunner::printToFile(const QString& filename) { |
| 171 | 9cf13184 | Jos van den Oever | QPrinter printer(QPrinter::HighResolution); |
| 172 | 62f4506a | Jos van den Oever | printer.setFontEmbeddingEnabled(true);
|
| 173 | 9cf13184 | Jos van den Oever | printer.setOutputFormat(QPrinter::PdfFormat); |
| 174 | 9cf13184 | Jos van den Oever | printer.setOutputFileName(filename); |
| 175 | 9cf13184 | Jos van den Oever | mainFrame()->print(&printer); |
| 176 | 9cf13184 | Jos van den Oever | } |