Change format of screenshot names
authorCraig Robbins <kde.psych@gmail.com>
Tue, 31 Mar 2015 06:13:42 +0000 (16:13 +1000)
committerCraig Robbins <kde.psych@gmail.com>
Tue, 31 Mar 2015 06:24:25 +0000 (16:24 +1000)
Filename screenshot_ + ISO 8601 format + [-serial]

i.e. screenshot_YYYY-MM-DDTHH::MM::SS[-serial].png

Serial is added if the filename + timestamp already exists and is in the range 1 to 999

src/client.cpp
src/constants.h

index 6ee918ad02e57c477d56175c589321652cfa9fc5..611a73bb1a36fd1daafba49bf418fa02c44adbe4 100644 (file)
@@ -1704,25 +1704,42 @@ void Client::makeScreenshot(IrrlichtDevice *device)
 {
        irr::video::IVideoDriver *driver = device->getVideoDriver();
        irr::video::IImage* const raw_image = driver->createScreenShot();
-       if (raw_image) {
-               irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8,
-                       raw_image->getDimension());
 
-               if (image) {
-                       raw_image->copyTo(image);
+       if (!raw_image)
+               return;
 
-                       std::string filename;
+       time_t t = time(NULL);
+       struct tm *tm = localtime(&t);
 
-                       time_t t = time(NULL);
-                       struct tm *tm = localtime(&t);
-                       char timetstamp_c[16]; // YYYYMMDD_HHMMSS + '\0'
-                       strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", tm);
+       char timetstamp_c[64];
+       strftime(timetstamp_c, sizeof(timetstamp_c), "%FT%T", tm);
 
-                       filename = g_settings->get("screenshot_path")
-                                + DIR_DELIM
-                                + std::string("screenshot_")
-                                + std::string(timetstamp_c)
-                                + ".png";
+       std::string filename_base = g_settings->get("screenshot_path")
+                       + DIR_DELIM
+                       + std::string("screenshot_")
+                       + std::string(timetstamp_c);
+       std::string filename_ext = ".png";
+       std::string filename;
+
+       // Try to find a unique filename
+       unsigned serial = 0;
+
+       while (serial < SCREENSHOT_MAX_SERIAL_TRIES) {
+               filename = filename_base + (serial > 0 ? ("-" + itos(serial)) : "") + filename_ext;
+               std::ifstream tmp(filename.c_str());
+               if (!tmp.good())
+                       break;  // File did not apparently exist, we'll go with it
+               serial++;
+       }
+
+       if (serial == SCREENSHOT_MAX_SERIAL_TRIES) {
+               infostream << "Could not find suitable filename for screenshot" << std::endl;
+       } else {
+               irr::video::IImage* const image =
+                               driver->createImage(video::ECF_R8G8B8, raw_image->getDimension());
+
+               if (image) {
+                       raw_image->copyTo(image);
 
                        std::ostringstream sstr;
                        if (driver->writeImageToFile(image, filename.c_str())) {
@@ -1734,8 +1751,9 @@ void Client::makeScreenshot(IrrlichtDevice *device)
                        infostream << sstr.str() << std::endl;
                        image->drop();
                }
-               raw_image->drop();
        }
+
+       raw_image->drop();
 }
 
 // IGameDef interface
index d7163bf682d1b5b4de9ace4ca323a2dc8334fb35..22cadc5a81642823fce0e2f6ef2b67eee253079c 100644 (file)
@@ -97,6 +97,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 // TODO: Use case-insensitive player names instead of this hack.
 #define PLAYER_FILE_ALTERNATE_TRIES 1000
 
+// For screenshots a serial number is appended to the filename + datetimestamp
+// if filename + datetimestamp is not unique.
+// This is the maximum number of attempts to try and add a serial to the end of
+// the file attempting to ensure a unique filename
+#define SCREENSHOT_MAX_SERIAL_TRIES 1000
+
 /*
     GUI related things
 */