src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 23 e6ad4ef83b23
--- a/src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp	Tue Jul 06 14:36:53 2010 +0300
+++ b/src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp	Wed Aug 18 10:05:37 2010 +0300
@@ -66,7 +66,8 @@
       mProcessQueuePending(false),
       mForceRegen(false),
       mMainWindow(0),
-      mFirstRegenerate(true)
+      mFirstRegenerate(true),
+      mSaveSplFailed(false)
 {
 #if defined(Q_OS_SYMBIAN)
     CCoeEnv::Static()->FsSession().CreatePrivatePath(EDriveC);
@@ -214,6 +215,7 @@
             mQueue.enqueue(QueueItem(themeName, Qt::Horizontal));
             queueAppSpecificItems(themeName, Qt::Vertical);
             queueAppSpecificItems(themeName, Qt::Horizontal);
+            mSaveSplFailed = false;
             qDebug() << PRE << "queue preparation time (ms):" << queuePrepTime.elapsed();
             QMetaObject::invokeMethod(this, "processQueue", Qt::QueuedConnection);
         } catch (const std::bad_alloc &) {
@@ -222,6 +224,7 @@
     }
 }
 
+// This function is for the splashviewer tool only, do not use from elsewhere.
 void HbSplashGenerator::regenerateOne(const QString &splashmlFileName, const QString &customTrDir)
 {
     mQueue.clear();
@@ -272,7 +275,17 @@
         mSettings->setValue(last_theme_key, hbInstance->theme()->name());
         mSettings->setValue(last_lang_key, QLocale::system().name());
         QString outDir = hbsplash_output_dir();
-        mSettings->setValue(last_file_count_key, updateOutputDirContents(outDir));
+        // Notify the server and get the number of generated files...
+        int fileCount = updateOutputDirContents(outDir);
+        // ...but store zero if some file writing failed at some point
+        // so there will be a regeneration on next boot at least.
+        if (mSaveSplFailed) {
+            fileCount = 0;
+            qDebug() << PRE << "some files not ok, ignoring file count";
+        } else {
+            qDebug() << PRE << "all files ok";
+        }
+        mSettings->setValue(last_file_count_key, fileCount);
         mSettings->setValue(last_output_dir_key, outDir);
         emit finished();
         qDebug() << PRE << "processQueue() over";
@@ -298,10 +311,13 @@
         QTime setupTime;
         setupTime.start();
         setupAppSpecificWindow();
-        finishWindow();
-        qDebug() << PRE << "content setup time(ms):" << setupTime.elapsed();
+        qDebug() << PRE << "content setup time (ms):" << setupTime.elapsed();
 
-        QMetaObject::invokeMethod(this, "processWindow", Qt::QueuedConnection);
+        // The async call chain goes like this:
+        // processQueue -> finishWindow -> processWindow -> processQueue -> ...
+        // finishWindow() cannot be called directly from here because that would
+        // result in asserts in QGraphicsScene with certain Qt versions.
+        QMetaObject::invokeMethod(this, "finishWindow", Qt::QueuedConnection);
 
     } catch (const std::bad_alloc &) {
         cleanup();
@@ -363,6 +379,7 @@
 #endif
         } else {
             qWarning() << PRE << "file write failed for" << splashFile;
+            mSaveSplFailed = true;
         }
         qDebug() << PRE << "save time (ms):" << t.elapsed();
         log("takeScreenshot() over", mItem.mThemeName, mItem.mOrientation);
@@ -376,8 +393,8 @@
     QString outDirName = hbsplash_output_dir();
     QDir dir(outDirName);
     if (!dir.exists()) {
-        if (!QDir(".").mkdir(outDirName)) {
-            qWarning() << PRE << "mkdir failed for" << outDirName;
+        if (!QDir(".").mkpath(outDirName)) {
+            qWarning() << PRE << "mkpath failed for" << outDirName;
         }
     }
     // "splash_<orientation>_<appid>_<screenid>"
@@ -409,9 +426,9 @@
         f.write((char *) &bpl, sizeof(quint32));
         f.write((char *) &fmt, sizeof(qint32));
         f.write((char *) &extra, sizeof(quint32));
-        f.write((const char *) image.bits(), bpl * h);
+        qint64 wcount = f.write((const char *) image.bits(), bpl * h);
         f.close();
-        return true;
+        return wcount == bpl * h;
     }
     return false;
 }
@@ -747,6 +764,9 @@
 
 void HbSplashGenerator::finishWindow()
 {
+    QTime prepTime;
+    prepTime.start();
+
     // There must be a view always in order to support view-specific settings.
     if (mMainWindow->views().isEmpty()) {
         mMainWindow->addView(new HbWidget);
@@ -826,6 +846,11 @@
 
     // Hide dynamic content from status bar (clock, indicators).
     setStatusBarElementsVisible(mMainWindow, false);
+
+    qDebug() << PRE << "time spent in finishWindow() (ms):" << prepTime.elapsed();
+
+    // Continue with rendering the graphics view in processWindow().
+    QMetaObject::invokeMethod(this, "processWindow", Qt::QueuedConnection);
 }
 
 void HbSplashGenerator::setStatusBarElementsVisible(HbMainWindow *mw, bool visible)