| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
|---|
| 4 | ** All rights reserved. | 
|---|
| 5 | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
|---|
| 6 | ** | 
|---|
| 7 | ** This file is part of the tools applications of the Qt Toolkit. | 
|---|
| 8 | ** | 
|---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$ | 
|---|
| 10 | ** Commercial Usage | 
|---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in | 
|---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the | 
|---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in | 
|---|
| 14 | ** a written agreement between you and Nokia. | 
|---|
| 15 | ** | 
|---|
| 16 | ** GNU Lesser General Public License Usage | 
|---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
|---|
| 18 | ** General Public License version 2.1 as published by the Free Software | 
|---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
|---|
| 20 | ** packaging of this file.  Please review the following information to | 
|---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
|---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | 
|---|
| 23 | ** | 
|---|
| 24 | ** In addition, as a special exception, Nokia gives you certain additional | 
|---|
| 25 | ** rights.  These rights are described in the Nokia Qt LGPL Exception | 
|---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
|---|
| 27 | ** | 
|---|
| 28 | ** GNU General Public License Usage | 
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU | 
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software | 
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the | 
|---|
| 32 | ** packaging of this file.  Please review the following information to | 
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be | 
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html. | 
|---|
| 35 | ** | 
|---|
| 36 | ** If you have questions regarding the use of this file, please contact | 
|---|
| 37 | ** Nokia at qt-info@nokia.com. | 
|---|
| 38 | ** $QT_END_LICENSE$ | 
|---|
| 39 | ** | 
|---|
| 40 | ****************************************************************************/ | 
|---|
| 41 |  | 
|---|
| 42 | #include "qdeclarative.h" | 
|---|
| 43 | #include "qmlruntime.h" | 
|---|
| 44 | #include "qdeclarativeengine.h" | 
|---|
| 45 | #include "loggerwidget.h" | 
|---|
| 46 | #include <QWidget> | 
|---|
| 47 | #include <QDir> | 
|---|
| 48 | #include <QApplication> | 
|---|
| 49 | #include <QTranslator> | 
|---|
| 50 | #include <QDebug> | 
|---|
| 51 | #include <QMessageBox> | 
|---|
| 52 | #include <QAtomicInt> | 
|---|
| 53 | #include "qdeclarativetester.h" | 
|---|
| 54 |  | 
|---|
| 55 | QT_USE_NAMESPACE | 
|---|
| 56 |  | 
|---|
| 57 | QtMsgHandler systemMsgOutput = 0; | 
|---|
| 58 |  | 
|---|
| 59 | static QDeclarativeViewer *openFile(const QString &fileName); | 
|---|
| 60 | static void showViewer(QDeclarativeViewer *viewer); | 
|---|
| 61 |  | 
|---|
| 62 | QString warnings; | 
|---|
| 63 | void exitApp(int i) | 
|---|
| 64 | { | 
|---|
| 65 | #if defined(Q_OS_WIN) || defined(Q_OS_OS2) | 
|---|
| 66 | // Debugging output is not visible by default on Windows - | 
|---|
| 67 | // therefore show modal dialog with errors instead. | 
|---|
| 68 | if (!warnings.isEmpty()) { | 
|---|
| 69 | QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); | 
|---|
| 70 | } | 
|---|
| 71 | #endif | 
|---|
| 72 | exit(i); | 
|---|
| 73 | } | 
|---|
| 74 |  | 
|---|
| 75 | #if defined (Q_OS_SYMBIAN) | 
|---|
| 76 | #include <unistd.h> | 
|---|
| 77 | #include <sys/types.h> | 
|---|
| 78 | #include <sys/stat.h> | 
|---|
| 79 | #include <fcntl.h> | 
|---|
| 80 |  | 
|---|
| 81 | void myMessageOutput(QtMsgType type, const char *msg) | 
|---|
| 82 | { | 
|---|
| 83 | static int fd = -1; | 
|---|
| 84 | if (fd == -1) | 
|---|
| 85 | fd = ::open("E:\\qml.log", O_WRONLY | O_CREAT); | 
|---|
| 86 |  | 
|---|
| 87 | ::write(fd, msg, strlen(msg)); | 
|---|
| 88 | ::write(fd, "\n", 1); | 
|---|
| 89 | ::fsync(fd); | 
|---|
| 90 |  | 
|---|
| 91 | switch (type) { | 
|---|
| 92 | case QtFatalMsg: | 
|---|
| 93 | abort(); | 
|---|
| 94 | } | 
|---|
| 95 | } | 
|---|
| 96 |  | 
|---|
| 97 | #else // !defined (Q_OS_SYMBIAN) | 
|---|
| 98 |  | 
|---|
| 99 | QWeakPointer<LoggerWidget> logger; | 
|---|
| 100 |  | 
|---|
| 101 | static QAtomicInt recursiveLock(0); | 
|---|
| 102 |  | 
|---|
| 103 | void myMessageOutput(QtMsgType type, const char *msg) | 
|---|
| 104 | { | 
|---|
| 105 | QString strMsg = QString::fromLatin1(msg); | 
|---|
| 106 |  | 
|---|
| 107 | if (!QCoreApplication::closingDown()) { | 
|---|
| 108 | if (!logger.isNull()) { | 
|---|
| 109 | if (recursiveLock.testAndSetOrdered(0, 1)) { | 
|---|
| 110 | QMetaObject::invokeMethod(logger.data(), "append", Q_ARG(QString, strMsg)); | 
|---|
| 111 | recursiveLock = 0; | 
|---|
| 112 | } | 
|---|
| 113 | } else { | 
|---|
| 114 | warnings += strMsg; | 
|---|
| 115 | warnings += QLatin1Char('\n'); | 
|---|
| 116 | } | 
|---|
| 117 | } | 
|---|
| 118 | if (systemMsgOutput) { // Windows | 
|---|
| 119 | systemMsgOutput(type, msg); | 
|---|
| 120 | } else { // Unix | 
|---|
| 121 | fprintf(stderr, "%s\n", msg); | 
|---|
| 122 | fflush(stderr); | 
|---|
| 123 | } | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | #endif | 
|---|
| 127 |  | 
|---|
| 128 | static QDeclarativeViewer* globalViewer = 0; | 
|---|
| 129 |  | 
|---|
| 130 | // The qml file that is shown if the user didn't specify a QML file | 
|---|
| 131 | QString initialFile = "qrc:/startup/startup.qml"; | 
|---|
| 132 |  | 
|---|
| 133 | void usage() | 
|---|
| 134 | { | 
|---|
| 135 | qWarning("Usage: qmlviewer [options] <filename>"); | 
|---|
| 136 | qWarning(" "); | 
|---|
| 137 | qWarning(" options:"); | 
|---|
| 138 | qWarning("  -v, -version ............................. display version"); | 
|---|
| 139 | qWarning("  -frameless ............................... run with no window frame"); | 
|---|
| 140 | qWarning("  -maximized................................ run maximized"); | 
|---|
| 141 | qWarning("  -fullscreen............................... run fullscreen"); | 
|---|
| 142 | qWarning("  -stayontop................................ keep viewer window on top"); | 
|---|
| 143 | qWarning("  -sizeviewtorootobject .................... the view resizes to the changes in the content"); | 
|---|
| 144 | qWarning("  -sizerootobjecttoview .................... the content resizes to the changes in the view (default)"); | 
|---|
| 145 | qWarning("  -qmlbrowser .............................. use a QML-based file browser"); | 
|---|
| 146 | qWarning("  -warnings [show|hide]..................... show warnings in a separate log window"); | 
|---|
| 147 | qWarning("  -recordfile <output> ..................... set video recording file"); | 
|---|
| 148 | qWarning("                                              - ImageMagick 'convert' for GIF)"); | 
|---|
| 149 | qWarning("                                              - png file for raw frames"); | 
|---|
| 150 | qWarning("                                              - 'ffmpeg' for other formats"); | 
|---|
| 151 | qWarning("  -recorddither ordered|threshold|floyd .... set GIF dither recording mode"); | 
|---|
| 152 | qWarning("  -recordrate <fps> ........................ set recording frame rate"); | 
|---|
| 153 | qWarning("  -record arg .............................. add a recording process argument"); | 
|---|
| 154 | qWarning("  -autorecord [from-]<tomilliseconds> ...... set recording to start and stop"); | 
|---|
| 155 | qWarning("  -devicekeys .............................. use numeric keys (see F1)"); | 
|---|
| 156 | qWarning("  -dragthreshold <size> .................... set mouse drag threshold size"); | 
|---|
| 157 | qWarning("  -netcache <size> ......................... set disk cache to size bytes"); | 
|---|
| 158 | qWarning("  -translation <translationfile> ........... set the language to run in"); | 
|---|
| 159 | qWarning("  -I <directory> ........................... prepend to the module import search path,"); | 
|---|
| 160 | qWarning("                                             display path if <directory> is empty"); | 
|---|
| 161 | qWarning("  -P <directory> ........................... prepend to the plugin search path"); | 
|---|
| 162 | #if defined(Q_WS_MAC) | 
|---|
| 163 | qWarning("  -no-opengl ............................... don't use a QGLWidget for the viewport"); | 
|---|
| 164 | #else | 
|---|
| 165 | qWarning("  -opengl .................................. use a QGLWidget for the viewport"); | 
|---|
| 166 | #endif | 
|---|
| 167 | qWarning("  -script <path> ........................... set the script to use"); | 
|---|
| 168 | qWarning("  -scriptopts <options>|help ............... set the script options to use"); | 
|---|
| 169 |  | 
|---|
| 170 | qWarning(" "); | 
|---|
| 171 | qWarning(" Press F1 for interactive help"); | 
|---|
| 172 |  | 
|---|
| 173 | exitApp(1); | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | void scriptOptsUsage() | 
|---|
| 177 | { | 
|---|
| 178 | qWarning("Usage: qmlviewer -scriptopts <option>[,<option>...] ..."); | 
|---|
| 179 | qWarning(" options:"); | 
|---|
| 180 | qWarning("  record ................................... record a new script"); | 
|---|
| 181 | qWarning("  play ..................................... playback an existing script"); | 
|---|
| 182 | qWarning("  testimages ............................... record images or compare images on playback"); | 
|---|
| 183 | qWarning("  testerror ................................ test 'error' property of root item on playback"); | 
|---|
| 184 | qWarning("  testskip  ................................ test 'skip' property of root item on playback"); | 
|---|
| 185 | qWarning("  snapshot ................................. file being recorded is static,"); | 
|---|
| 186 | qWarning("                                             only one frame will be recorded or tested"); | 
|---|
| 187 | qWarning("  exitoncomplete ........................... cleanly exit the viewer on script completion"); | 
|---|
| 188 | qWarning("  exitonfailure ............................ immediately exit the viewer on script failure"); | 
|---|
| 189 | qWarning("  saveonexit ............................... save recording on viewer exit"); | 
|---|
| 190 | qWarning(" "); | 
|---|
| 191 | qWarning(" One of record, play or both must be specified."); | 
|---|
| 192 |  | 
|---|
| 193 | exitApp(1); | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|
| 196 | enum WarningsConfig { ShowWarnings, HideWarnings, DefaultWarnings }; | 
|---|
| 197 |  | 
|---|
| 198 | struct ViewerOptions | 
|---|
| 199 | { | 
|---|
| 200 | ViewerOptions() | 
|---|
| 201 | : frameless(false), | 
|---|
| 202 | fps(0.0), | 
|---|
| 203 | autorecord_from(0), | 
|---|
| 204 | autorecord_to(0), | 
|---|
| 205 | dither("none"), | 
|---|
| 206 | runScript(false), | 
|---|
| 207 | devkeys(false), | 
|---|
| 208 | cache(0), | 
|---|
| 209 | useGL(false), | 
|---|
| 210 | fullScreen(false), | 
|---|
| 211 | stayOnTop(false), | 
|---|
| 212 | maximized(false), | 
|---|
| 213 | useNativeFileBrowser(true), | 
|---|
| 214 | experimentalGestures(false), | 
|---|
| 215 | warningsConfig(DefaultWarnings), | 
|---|
| 216 | sizeToView(true) | 
|---|
| 217 | { | 
|---|
| 218 | #if defined(Q_OS_SYMBIAN) | 
|---|
| 219 | maximized = true; | 
|---|
| 220 | useNativeFileBrowser = false; | 
|---|
| 221 | #endif | 
|---|
| 222 |  | 
|---|
| 223 | #if defined(Q_WS_MAC) | 
|---|
| 224 | useGL = true; | 
|---|
| 225 | #endif | 
|---|
| 226 | } | 
|---|
| 227 |  | 
|---|
| 228 | bool frameless; | 
|---|
| 229 | double fps; | 
|---|
| 230 | int autorecord_from; | 
|---|
| 231 | int autorecord_to; | 
|---|
| 232 | QString dither; | 
|---|
| 233 | QString recordfile; | 
|---|
| 234 | QStringList recordargs; | 
|---|
| 235 | QStringList imports; | 
|---|
| 236 | QStringList plugins; | 
|---|
| 237 | QString script; | 
|---|
| 238 | QString scriptopts; | 
|---|
| 239 | bool runScript; | 
|---|
| 240 | bool devkeys; | 
|---|
| 241 | int cache; | 
|---|
| 242 | QString translationFile; | 
|---|
| 243 | bool useGL; | 
|---|
| 244 | bool fullScreen; | 
|---|
| 245 | bool stayOnTop; | 
|---|
| 246 | bool maximized; | 
|---|
| 247 | bool useNativeFileBrowser; | 
|---|
| 248 | bool experimentalGestures; | 
|---|
| 249 |  | 
|---|
| 250 | WarningsConfig warningsConfig; | 
|---|
| 251 | bool sizeToView; | 
|---|
| 252 |  | 
|---|
| 253 | QDeclarativeViewer::ScriptOptions scriptOptions; | 
|---|
| 254 | }; | 
|---|
| 255 |  | 
|---|
| 256 | static ViewerOptions opts; | 
|---|
| 257 | static QStringList fileNames; | 
|---|
| 258 |  | 
|---|
| 259 | class Application : public QApplication | 
|---|
| 260 | { | 
|---|
| 261 | Q_OBJECT | 
|---|
| 262 | public: | 
|---|
| 263 | Application(int &argc, char **&argv) | 
|---|
| 264 | : QApplication(argc, argv) | 
|---|
| 265 | {} | 
|---|
| 266 |  | 
|---|
| 267 | protected: | 
|---|
| 268 | bool event(QEvent *ev) | 
|---|
| 269 | { | 
|---|
| 270 | if (ev->type() != QEvent::FileOpen) | 
|---|
| 271 | return QApplication::event(ev); | 
|---|
| 272 |  | 
|---|
| 273 | QFileOpenEvent *fev = static_cast<QFileOpenEvent *>(ev); | 
|---|
| 274 |  | 
|---|
| 275 | globalViewer->open(fev->file()); | 
|---|
| 276 | if (!globalViewer->isVisible()) | 
|---|
| 277 | showViewer(globalViewer); | 
|---|
| 278 |  | 
|---|
| 279 | return true; | 
|---|
| 280 | } | 
|---|
| 281 |  | 
|---|
| 282 | private Q_SLOTS: | 
|---|
| 283 | void showInitialViewer() | 
|---|
| 284 | { | 
|---|
| 285 | QApplication::processEvents(); | 
|---|
| 286 |  | 
|---|
| 287 | QDeclarativeViewer *viewer = globalViewer; | 
|---|
| 288 | if (!viewer) | 
|---|
| 289 | return; | 
|---|
| 290 | if (viewer->currentFile().isEmpty()) { | 
|---|
| 291 | if(opts.useNativeFileBrowser) | 
|---|
| 292 | viewer->open(initialFile); | 
|---|
| 293 | else | 
|---|
| 294 | viewer->openFile(); | 
|---|
| 295 | } | 
|---|
| 296 | if (!viewer->isVisible()) | 
|---|
| 297 | showViewer(viewer); | 
|---|
| 298 | } | 
|---|
| 299 | }; | 
|---|
| 300 |  | 
|---|
| 301 | static void parseScriptOptions() | 
|---|
| 302 | { | 
|---|
| 303 | QStringList options = | 
|---|
| 304 | opts.scriptopts.split(QLatin1Char(','), QString::SkipEmptyParts); | 
|---|
| 305 |  | 
|---|
| 306 | QDeclarativeViewer::ScriptOptions scriptOptions = 0; | 
|---|
| 307 | for (int i = 0; i < options.count(); ++i) { | 
|---|
| 308 | const QString &option = options.at(i); | 
|---|
| 309 | if (option == QLatin1String("help")) { | 
|---|
| 310 | scriptOptsUsage(); | 
|---|
| 311 | } else if (option == QLatin1String("play")) { | 
|---|
| 312 | scriptOptions |= QDeclarativeViewer::Play; | 
|---|
| 313 | } else if (option == QLatin1String("record")) { | 
|---|
| 314 | scriptOptions |= QDeclarativeViewer::Record; | 
|---|
| 315 | } else if (option == QLatin1String("testimages")) { | 
|---|
| 316 | scriptOptions |= QDeclarativeViewer::TestImages; | 
|---|
| 317 | } else if (option == QLatin1String("testerror")) { | 
|---|
| 318 | scriptOptions |= QDeclarativeViewer::TestErrorProperty; | 
|---|
| 319 | } else if (option == QLatin1String("testskip")) { | 
|---|
| 320 | scriptOptions |= QDeclarativeViewer::TestSkipProperty; | 
|---|
| 321 | } else if (option == QLatin1String("exitoncomplete")) { | 
|---|
| 322 | scriptOptions |= QDeclarativeViewer::ExitOnComplete; | 
|---|
| 323 | } else if (option == QLatin1String("exitonfailure")) { | 
|---|
| 324 | scriptOptions |= QDeclarativeViewer::ExitOnFailure; | 
|---|
| 325 | } else if (option == QLatin1String("saveonexit")) { | 
|---|
| 326 | scriptOptions |= QDeclarativeViewer::SaveOnExit; | 
|---|
| 327 | } else if (option == QLatin1String("snapshot")) { | 
|---|
| 328 | scriptOptions |= QDeclarativeViewer::Snapshot; | 
|---|
| 329 | } else { | 
|---|
| 330 | scriptOptsUsage(); | 
|---|
| 331 | } | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 | opts.scriptOptions = scriptOptions; | 
|---|
| 335 | } | 
|---|
| 336 |  | 
|---|
| 337 | static void parseCommandLineOptions(const QStringList &arguments) | 
|---|
| 338 | { | 
|---|
| 339 | for (int i = 1; i < arguments.count(); ++i) { | 
|---|
| 340 | bool lastArg = (i == arguments.count() - 1); | 
|---|
| 341 | QString arg = arguments.at(i); | 
|---|
| 342 | if (arg == "-frameless") { | 
|---|
| 343 | opts.frameless = true; | 
|---|
| 344 | } else if (arg == "-maximized") { | 
|---|
| 345 | opts.maximized = true; | 
|---|
| 346 | } else if (arg == "-fullscreen") { | 
|---|
| 347 | opts.fullScreen = true; | 
|---|
| 348 | } else if (arg == "-stayontop") { | 
|---|
| 349 | opts.stayOnTop = true; | 
|---|
| 350 | } else if (arg == "-netcache") { | 
|---|
| 351 | if (lastArg) usage(); | 
|---|
| 352 | opts.cache = arguments.at(++i).toInt(); | 
|---|
| 353 | } else if (arg == "-recordrate") { | 
|---|
| 354 | if (lastArg) usage(); | 
|---|
| 355 | opts.fps = arguments.at(++i).toDouble(); | 
|---|
| 356 | } else if (arg == "-recordfile") { | 
|---|
| 357 | if (lastArg) usage(); | 
|---|
| 358 | opts.recordfile = arguments.at(++i); | 
|---|
| 359 | } else if (arg == "-record") { | 
|---|
| 360 | if (lastArg) usage(); | 
|---|
| 361 | opts.recordargs << arguments.at(++i); | 
|---|
| 362 | } else if (arg == "-recorddither") { | 
|---|
| 363 | if (lastArg) usage(); | 
|---|
| 364 | opts.dither = arguments.at(++i); | 
|---|
| 365 | } else if (arg == "-autorecord") { | 
|---|
| 366 | if (lastArg) usage(); | 
|---|
| 367 | QString range = arguments.at(++i); | 
|---|
| 368 | int dash = range.indexOf('-'); | 
|---|
| 369 | if (dash > 0) | 
|---|
| 370 | opts.autorecord_from = range.left(dash).toInt(); | 
|---|
| 371 | opts.autorecord_to = range.mid(dash+1).toInt(); | 
|---|
| 372 | } else if (arg == "-devicekeys") { | 
|---|
| 373 | opts.devkeys = true; | 
|---|
| 374 | } else if (arg == "-dragthreshold") { | 
|---|
| 375 | if (lastArg) usage(); | 
|---|
| 376 | qApp->setStartDragDistance(arguments.at(++i).toInt()); | 
|---|
| 377 | } else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) { | 
|---|
| 378 | qWarning("Qt QML Viewer version %s", QT_VERSION_STR); | 
|---|
| 379 | exitApp(0); | 
|---|
| 380 | } else if (arg == "-translation") { | 
|---|
| 381 | if (lastArg) usage(); | 
|---|
| 382 | opts.translationFile = arguments.at(++i); | 
|---|
| 383 | #if defined(Q_WS_MAC) | 
|---|
| 384 | } else if (arg == "-no-opengl") { | 
|---|
| 385 | opts.useGL = false; | 
|---|
| 386 | #else | 
|---|
| 387 | } else if (arg == "-opengl") { | 
|---|
| 388 | opts.useGL = true; | 
|---|
| 389 | #endif | 
|---|
| 390 | } else if (arg == "-qmlbrowser") { | 
|---|
| 391 | opts.useNativeFileBrowser = false; | 
|---|
| 392 | } else if (arg == "-warnings") { | 
|---|
| 393 | if (lastArg) usage(); | 
|---|
| 394 | QString warningsStr = arguments.at(++i); | 
|---|
| 395 | if (warningsStr == QLatin1String("show")) { | 
|---|
| 396 | opts.warningsConfig = ShowWarnings; | 
|---|
| 397 | } else if (warningsStr == QLatin1String("hide")) { | 
|---|
| 398 | opts.warningsConfig = HideWarnings; | 
|---|
| 399 | } else { | 
|---|
| 400 | usage(); | 
|---|
| 401 | } | 
|---|
| 402 | } else if (arg == "-I" || arg == "-L") { | 
|---|
| 403 | if (arg == "-L") | 
|---|
| 404 | qWarning("-L option provided for compatibility only, use -I instead"); | 
|---|
| 405 | if (lastArg) { | 
|---|
| 406 | QDeclarativeEngine tmpEngine; | 
|---|
| 407 | QString paths = tmpEngine.importPathList().join(QLatin1String(":")); | 
|---|
| 408 | qWarning("Current search path: %s", paths.toLocal8Bit().constData()); | 
|---|
| 409 | exitApp(0); | 
|---|
| 410 | } | 
|---|
| 411 | opts.imports << arguments.at(++i); | 
|---|
| 412 | } else if (arg == "-P") { | 
|---|
| 413 | if (lastArg) usage(); | 
|---|
| 414 | opts.plugins << arguments.at(++i); | 
|---|
| 415 | } else if (arg == "-script") { | 
|---|
| 416 | if (lastArg) usage(); | 
|---|
| 417 | opts.script = arguments.at(++i); | 
|---|
| 418 | } else if (arg == "-scriptopts") { | 
|---|
| 419 | if (lastArg) usage(); | 
|---|
| 420 | opts.scriptopts = arguments.at(++i); | 
|---|
| 421 | } else if (arg == "-savescript") { | 
|---|
| 422 | if (lastArg) usage(); | 
|---|
| 423 | opts.script = arguments.at(++i); | 
|---|
| 424 | opts.runScript = false; | 
|---|
| 425 | } else if (arg == "-playscript") { | 
|---|
| 426 | if (lastArg) usage(); | 
|---|
| 427 | opts.script = arguments.at(++i); | 
|---|
| 428 | opts.runScript = true; | 
|---|
| 429 | } else if (arg == "-sizeviewtorootobject") { | 
|---|
| 430 | opts.sizeToView = false; | 
|---|
| 431 | } else if (arg == "-sizerootobjecttoview") { | 
|---|
| 432 | opts.sizeToView = true; | 
|---|
| 433 | } else if (arg == "-experimentalgestures") { | 
|---|
| 434 | opts.experimentalGestures = true; | 
|---|
| 435 | } else if (!arg.startsWith('-')) { | 
|---|
| 436 | fileNames.append(arg); | 
|---|
| 437 | } else if (true || arg == "-help") { | 
|---|
| 438 | usage(); | 
|---|
| 439 | } | 
|---|
| 440 | } | 
|---|
| 441 |  | 
|---|
| 442 | if (!opts.scriptopts.isEmpty()) { | 
|---|
| 443 |  | 
|---|
| 444 | parseScriptOptions(); | 
|---|
| 445 |  | 
|---|
| 446 | if (opts.script.isEmpty()) | 
|---|
| 447 | usage(); | 
|---|
| 448 |  | 
|---|
| 449 | if (!(opts.scriptOptions & QDeclarativeViewer::Record) && !(opts.scriptOptions & QDeclarativeViewer::Play)) | 
|---|
| 450 | scriptOptsUsage(); | 
|---|
| 451 | }  else if (!opts.script.isEmpty()) { | 
|---|
| 452 | usage(); | 
|---|
| 453 | } | 
|---|
| 454 |  | 
|---|
| 455 | } | 
|---|
| 456 |  | 
|---|
| 457 | static QDeclarativeViewer *createViewer() | 
|---|
| 458 | { | 
|---|
| 459 | Qt::WFlags wflags = (opts.frameless ? Qt::FramelessWindowHint : Qt::Widget); | 
|---|
| 460 | if (opts.stayOnTop) | 
|---|
| 461 | wflags |= Qt::WindowStaysOnTopHint; | 
|---|
| 462 |  | 
|---|
| 463 | QDeclarativeViewer *viewer = new QDeclarativeViewer(0, wflags); | 
|---|
| 464 | viewer->setAttribute(Qt::WA_DeleteOnClose, true); | 
|---|
| 465 | viewer->setUseGL(opts.useGL); | 
|---|
| 466 |  | 
|---|
| 467 | if (!opts.scriptopts.isEmpty()) { | 
|---|
| 468 | viewer->setScriptOptions(opts.scriptOptions); | 
|---|
| 469 | viewer->setScript(opts.script); | 
|---|
| 470 | } | 
|---|
| 471 |  | 
|---|
| 472 | #if !defined(Q_OS_SYMBIAN) | 
|---|
| 473 | logger = viewer->warningsWidget(); | 
|---|
| 474 | if (opts.warningsConfig == ShowWarnings) { | 
|---|
| 475 | logger.data()->setDefaultVisibility(LoggerWidget::ShowWarnings); | 
|---|
| 476 | logger.data()->show(); | 
|---|
| 477 | } else if (opts.warningsConfig == HideWarnings){ | 
|---|
| 478 | logger.data()->setDefaultVisibility(LoggerWidget::HideWarnings); | 
|---|
| 479 | } | 
|---|
| 480 | #endif | 
|---|
| 481 |  | 
|---|
| 482 | if (opts.experimentalGestures) | 
|---|
| 483 | viewer->enableExperimentalGestures(); | 
|---|
| 484 |  | 
|---|
| 485 | foreach (QString lib, opts.imports) | 
|---|
| 486 | viewer->addLibraryPath(lib); | 
|---|
| 487 |  | 
|---|
| 488 | foreach (QString plugin, opts.plugins) | 
|---|
| 489 | viewer->addPluginPath(plugin); | 
|---|
| 490 |  | 
|---|
| 491 | viewer->setNetworkCacheSize(opts.cache); | 
|---|
| 492 | viewer->setRecordFile(opts.recordfile); | 
|---|
| 493 | viewer->setSizeToView(opts.sizeToView); | 
|---|
| 494 | if (opts.fps > 0) | 
|---|
| 495 | viewer->setRecordRate(opts.fps); | 
|---|
| 496 | if (opts.autorecord_to) | 
|---|
| 497 | viewer->setAutoRecord(opts.autorecord_from, opts.autorecord_to); | 
|---|
| 498 | if (opts.devkeys) | 
|---|
| 499 | viewer->setDeviceKeys(true); | 
|---|
| 500 | viewer->setRecordDither(opts.dither); | 
|---|
| 501 | if (opts.recordargs.count()) | 
|---|
| 502 | viewer->setRecordArgs(opts.recordargs); | 
|---|
| 503 |  | 
|---|
| 504 | viewer->setUseNativeFileBrowser(opts.useNativeFileBrowser); | 
|---|
| 505 |  | 
|---|
| 506 | return viewer; | 
|---|
| 507 | } | 
|---|
| 508 |  | 
|---|
| 509 | void showViewer(QDeclarativeViewer *viewer) | 
|---|
| 510 | { | 
|---|
| 511 | if (opts.fullScreen) | 
|---|
| 512 | viewer->showFullScreen(); | 
|---|
| 513 | else if (opts.maximized) | 
|---|
| 514 | viewer->showMaximized(); | 
|---|
| 515 | else | 
|---|
| 516 | viewer->show(); | 
|---|
| 517 | viewer->raise(); | 
|---|
| 518 | } | 
|---|
| 519 |  | 
|---|
| 520 | QDeclarativeViewer *openFile(const QString &fileName) | 
|---|
| 521 | { | 
|---|
| 522 | QDeclarativeViewer *viewer = globalViewer; | 
|---|
| 523 |  | 
|---|
| 524 | viewer->open(fileName); | 
|---|
| 525 | showViewer(viewer); | 
|---|
| 526 |  | 
|---|
| 527 | return viewer; | 
|---|
| 528 | } | 
|---|
| 529 |  | 
|---|
| 530 | int main(int argc, char ** argv) | 
|---|
| 531 | { | 
|---|
| 532 | #if defined (Q_OS_SYMBIAN) | 
|---|
| 533 | qInstallMsgHandler(myMessageOutput); | 
|---|
| 534 | #else | 
|---|
| 535 | systemMsgOutput = qInstallMsgHandler(myMessageOutput); | 
|---|
| 536 | #endif | 
|---|
| 537 |  | 
|---|
| 538 | #if defined (Q_WS_X11) || defined (Q_WS_MAC) | 
|---|
| 539 | //### default to using raster graphics backend for now | 
|---|
| 540 | bool gsSpecified = false; | 
|---|
| 541 | for (int i = 0; i < argc; ++i) { | 
|---|
| 542 | QString arg = argv[i]; | 
|---|
| 543 | if (arg == "-graphicssystem") { | 
|---|
| 544 | gsSpecified = true; | 
|---|
| 545 | break; | 
|---|
| 546 | } | 
|---|
| 547 | } | 
|---|
| 548 |  | 
|---|
| 549 | if (!gsSpecified) | 
|---|
| 550 | QApplication::setGraphicsSystem("raster"); | 
|---|
| 551 | #endif | 
|---|
| 552 |  | 
|---|
| 553 | Application app(argc, argv); | 
|---|
| 554 | app.setApplicationName("QtQmlViewer"); | 
|---|
| 555 | app.setOrganizationName("Nokia"); | 
|---|
| 556 | app.setOrganizationDomain("nokia.com"); | 
|---|
| 557 |  | 
|---|
| 558 | QDeclarativeViewer::registerTypes(); | 
|---|
| 559 | QDeclarativeTester::registerTypes(); | 
|---|
| 560 |  | 
|---|
| 561 | parseCommandLineOptions(app.arguments()); | 
|---|
| 562 |  | 
|---|
| 563 | QTranslator qmlTranslator; | 
|---|
| 564 | if (!opts.translationFile.isEmpty()) { | 
|---|
| 565 | qmlTranslator.load(opts.translationFile); | 
|---|
| 566 | app.installTranslator(&qmlTranslator); | 
|---|
| 567 | } | 
|---|
| 568 |  | 
|---|
| 569 | if (opts.fullScreen && opts.maximized) | 
|---|
| 570 | qWarning() << "Both -fullscreen and -maximized specified. Using -fullscreen."; | 
|---|
| 571 |  | 
|---|
| 572 | if (fileNames.isEmpty()) { | 
|---|
| 573 | QFile qmlapp(QLatin1String("qmlapp")); | 
|---|
| 574 | if (qmlapp.exists() && qmlapp.open(QFile::ReadOnly)) { | 
|---|
| 575 | QString content = QString::fromUtf8(qmlapp.readAll()); | 
|---|
| 576 | qmlapp.close(); | 
|---|
| 577 |  | 
|---|
| 578 | int newline = content.indexOf(QLatin1Char('\n')); | 
|---|
| 579 | if (newline >= 0) | 
|---|
| 580 | fileNames += content.left(newline); | 
|---|
| 581 | else | 
|---|
| 582 | fileNames += content; | 
|---|
| 583 | } | 
|---|
| 584 | } | 
|---|
| 585 |  | 
|---|
| 586 | globalViewer = createViewer(); | 
|---|
| 587 |  | 
|---|
| 588 | if (fileNames.isEmpty()) { | 
|---|
| 589 | // show the initial viewer delayed. | 
|---|
| 590 | // This prevents an initial viewer popping up while there | 
|---|
| 591 | // are FileOpen events coming through the event queue | 
|---|
| 592 | QTimer::singleShot(1, &app, SLOT(showInitialViewer())); | 
|---|
| 593 | } else { | 
|---|
| 594 | foreach (const QString &fileName, fileNames) | 
|---|
| 595 | openFile(fileName); | 
|---|
| 596 | } | 
|---|
| 597 |  | 
|---|
| 598 | QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); | 
|---|
| 599 |  | 
|---|
| 600 | return app.exec(); | 
|---|
| 601 | } | 
|---|
| 602 |  | 
|---|
| 603 | #include "main.moc" | 
|---|