Completed single image export function
From "Open" dialog, select an image (single click, or use arrow keys / etc., to highlight the image), then select the "Export" button at the lower right. The image will be saved in the export directory. By default this will be based on the config found via the XDG_CONFIG_HOME environment variable, which is scanned for a "XDG_PICTURES_DIR" setting. If none is found, "Pictures" in the directory specified by the HOME env. var. will be used. In both cases, a new "TuxPaint" subdirectory will be created, and exports will be placed there. The export location may be overridden using the "--exportdir" command-line option or "exportdir" config file option (e.g., "--exportdir /path/to/dir" or "exportdir=/path/to/dir", respectively). In this case, the directory is assumed to preexist, and no "TuxPaint" subdirectory will be made. There's currently no way to disable the export feature altogether. If there's demand, we can add it as a simplification option. Finally, this feature simply copies the PNG file (but no extra data files) from Tux Paint's "saved" directory to the export dir. Closes https://sourceforge.net/p/tuxpaint/feature-requests/192/
This commit is contained in:
parent
28b28d583e
commit
b0a2b4dacc
5 changed files with 205 additions and 50 deletions
BIN
data/images/ui/pict_export.png
Normal file
BIN
data/images/ui/pict_export.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -11,15 +11,22 @@ $Id$
|
|||
2020.July.25 (0.9.25)
|
||||
* New Features
|
||||
------------
|
||||
* [WIP] GIF export option from Open -> Slideshow dialog.
|
||||
* Utilizes "gifenc", public domain by Marcel Rodrigues:
|
||||
https://github.com/lecram/gifenc
|
||||
* Depends on "libimagequant", from the "pngquant2" project:
|
||||
https://github.com/ImageOptim/libimagequant
|
||||
(GPL v3 or later, for Free/Libre Open Source Software)
|
||||
* Uses XDG user dirs settings, if available, to determine
|
||||
where to store them, or "~/Pictures", otherwise.
|
||||
"--exportdir" option can be used to override this.
|
||||
* Export drawings:
|
||||
* GIF export option from the Open -> Slideshow dialog.
|
||||
* Utilizes "gifenc", public domain by Marcel Rodrigues:
|
||||
https://github.com/lecram/gifenc
|
||||
* Depends on "libimagequant", from the "pngquant2" project:
|
||||
https://github.com/ImageOptim/libimagequant
|
||||
(GPL v3 or later, for Free/Libre Open Source Software)
|
||||
* WORK IN PROGRESS
|
||||
(Closes https://sourceforge.net/p/tuxpaint/feature-requests/191/)
|
||||
* Single image (PNG) export from the Open dialog.
|
||||
(Closes https://sourceforge.net/p/tuxpaint/feature-requests/192/)
|
||||
* Both utilize XDG user dirs settings, if available, to determine
|
||||
where to store them, or "~/Pictures", otherwise. In those cases,
|
||||
files are stored in a new "TuxPaint" subdirectory.
|
||||
* The "--exportdir" option can be used to override the default
|
||||
location (but a "TuxPaint" subdir. will NOT be placed there).
|
||||
|
||||
* Ports & Building
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Options Documentation
|
|||
Copyright (c) 2002-2020 by various contributors; see AUTHORS.txt
|
||||
http://www.tuxpaint.org/
|
||||
|
||||
July 25, 2020
|
||||
July 26, 2020
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
@ -581,7 +581,8 @@ Windows Users
|
|||
Use this option to change where Tux Paint exports files —
|
||||
single images, or animated GIF slideshows — for external use.
|
||||
|
||||
If you do not override it, the default location is:
|
||||
If you do not override it, the default location is determined
|
||||
as follows:
|
||||
* Linux & Unix — If available, wherever your desktop
|
||||
environment is configured for pictures to be stored,
|
||||
based on your XDG (X Desktop Group) configuration. (Try
|
||||
|
|
@ -599,6 +600,14 @@ Windows Users
|
|||
* Windows — TBD!
|
||||
* macOS — TBD!
|
||||
|
||||
Note: When the defaults are used, a new "TuxPaint"
|
||||
subdirectory will be created and used. (e.g.,
|
||||
"~/Pictures/TuxPaint") When the "--exportdir" option is used,
|
||||
the exact path specified will be used (no "TuxPaint"
|
||||
subdirectory is created). It is expected that the parent
|
||||
directory exists. (The directory itself will be created, if it
|
||||
doesn't.)
|
||||
|
||||
Example: exportdir=/home/penguin/TuxPaintExports
|
||||
|
||||
datadir=DIRECTORY
|
||||
|
|
@ -1050,6 +1059,7 @@ Windows Users
|
|||
--keyboard
|
||||
--savedir DIRECTORY
|
||||
--datadir DIRECTORY
|
||||
--exportdir DIRECTORY
|
||||
--saveover
|
||||
--saveovernew
|
||||
--nosave
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ version
|
|||
<p>Copyright (c) 2002-2020 by various contributors; see AUTHORS.txt<br/>
|
||||
<a href="http://www.tuxpaint.org/">http://www.tuxpaint.org/</a></p>
|
||||
|
||||
<p>July 25, 2020</p>
|
||||
<p>July 26, 2020</p>
|
||||
|
||||
|
||||
</center>
|
||||
|
|
@ -715,7 +715,8 @@ version
|
|||
<p>Use this option to change where Tux Paint exports files — single
|
||||
images, or animated GIF slideshows — for external use.
|
||||
|
||||
<p>If you do not override it, the <b><i>default</i></b> location is:
|
||||
<p>If you do not override it, the <b><i>default</i></b> location is
|
||||
determined as follows:
|
||||
<ul>
|
||||
<li>Linux & Unix — If available, wherever your desktop environment
|
||||
is configured for pictures to be stored, based on your XDG
|
||||
|
|
@ -737,6 +738,14 @@ version
|
|||
</ul>
|
||||
</p>
|
||||
|
||||
<p><b>Note:</b> When the defaults are used, a new "<code>TuxPaint</code>"
|
||||
subdirectory will be created and used. (e.g., "<code>~/Pictures/TuxPaint</code>")
|
||||
When the "<code>--exportdir</code>" option is used, the exact path specified
|
||||
will be used (no "<code>TuxPaint</code>" subdirectory is created).
|
||||
It is expected that the parent directory exists. (The directory itself
|
||||
will be created, if it doesn't.)
|
||||
</p>
|
||||
|
||||
<p><b>Example:</b> <code>exportdir=/home/penguin/TuxPaintExports</code></p>
|
||||
</dd>
|
||||
|
||||
|
|
@ -1606,6 +1615,7 @@ version
|
|||
--keyboard<br>
|
||||
--savedir <i>DIRECTORY</i><br>
|
||||
--datadir <i>DIRECTORY</i><br>
|
||||
--exportdir <i>DIRECTORY</i><br>
|
||||
--saveover<br>
|
||||
--saveovernew<br>
|
||||
--nosave<br>
|
||||
|
|
|
|||
202
src/tuxpaint.c
202
src/tuxpaint.c
|
|
@ -1985,6 +1985,7 @@ static void play_slideshow(int *selected, int num_selected, char *dirname, char
|
|||
static void draw_selection_digits(int right, int bottom, int n);
|
||||
|
||||
static int export_gif(int *selected, int num_selected, char *dirname, char **d_names, char **d_exts, int speed);
|
||||
static int export_pict(char * fname);
|
||||
static char * get_export_filepath(const char * ext);
|
||||
|
||||
static void wait_for_sfx(void);
|
||||
|
|
@ -13989,7 +13990,8 @@ static int do_open(void)
|
|||
int *d_places;
|
||||
FILE *fi;
|
||||
char fname[1024];
|
||||
int num_files, i, done, slideshow, update_list, want_erase, cur, which, num_files_in_dirs, j, any_saved_files;
|
||||
int num_files, i, done, slideshow, update_list, want_erase, want_export;
|
||||
int cur, which, num_files_in_dirs, j, any_saved_files;
|
||||
SDL_Rect dest;
|
||||
SDL_Event event;
|
||||
SDLKey key;
|
||||
|
|
@ -14323,16 +14325,15 @@ static int do_open(void)
|
|||
/* Let user choose an image: */
|
||||
|
||||
/* Instructions for 'Open' file dialog */
|
||||
char *freeme = textdir(gettext_noop("Choose the picture you want, " "then click “Open”."));
|
||||
|
||||
draw_tux_text(TUX_BORED, freeme, 1);
|
||||
free(freeme);
|
||||
char *instructions = textdir(gettext_noop("Choose the picture you want, then click “Open”."));
|
||||
draw_tux_text(TUX_BORED, instructions, 1);
|
||||
|
||||
/* NOTE: cur is now set above; if file_id'th file is found, it's
|
||||
set to that file's index; otherwise, we default to '0' */
|
||||
|
||||
update_list = 1;
|
||||
want_erase = 0;
|
||||
want_export = 0;
|
||||
|
||||
done = 0;
|
||||
slideshow = 0;
|
||||
|
|
@ -14447,6 +14448,25 @@ static int do_open(void)
|
|||
SDL_BlitSurface(img_openlabels_back, NULL, screen, &dest);
|
||||
|
||||
|
||||
/* "Export" button: */
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96 - 48 - 48 - 48;
|
||||
dest.y = (48 * 7 + 40 + HEIGHTOFFSET) - 48;
|
||||
|
||||
if (d_places[which] != PLACE_STARTERS_DIR && d_places[which] != PLACE_PERSONAL_STARTERS_DIR)
|
||||
SDL_BlitSurface(img_btn_up, NULL, screen, &dest);
|
||||
else
|
||||
SDL_BlitSurface(img_btn_off, NULL, screen, &dest);
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96 - 48 - 48 - 48 + (48 - img_pict_export->w) / 2;
|
||||
dest.y = (48 * 7 + 40 + HEIGHTOFFSET) - 48;
|
||||
SDL_BlitSurface(img_pict_export, NULL, screen, &dest);
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96 - 48 - 48 - 48 + (48 - img_openlabels_pict_export->w) / 2;
|
||||
dest.y = (48 * 7 + 40 + HEIGHTOFFSET) - img_openlabels_pict_export->h;
|
||||
SDL_BlitSurface(img_openlabels_pict_export, NULL, screen, &dest);
|
||||
|
||||
|
||||
/* "Erase" button: */
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96 - 48 - 48;
|
||||
|
|
@ -14683,6 +14703,16 @@ static int do_open(void)
|
|||
|
||||
want_erase = 1;
|
||||
}
|
||||
else if (event.button.x >= (WINDOW_WIDTH - 96 - 48 - 48 - 48) &&
|
||||
event.button.x < (WINDOW_WIDTH - 48 - 48 - 96) &&
|
||||
event.button.y >= (48 * 7 + 40 + HEIGHTOFFSET) - 48 &&
|
||||
event.button.y < (48 * 7 + 40 + HEIGHTOFFSET) &&
|
||||
d_places[which] != PLACE_STARTERS_DIR && d_places[which] != PLACE_PERSONAL_STARTERS_DIR)
|
||||
{
|
||||
/* Export */
|
||||
|
||||
want_export = 1;
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_MOUSEBUTTONDOWN &&
|
||||
event.button.button >= 4 && event.button.button <= 5 && wheely)
|
||||
|
|
@ -14738,8 +14768,9 @@ static int do_open(void)
|
|||
else if (((event.button.x >= 96 && event.button.x < 96 + 48 + 48) ||
|
||||
(event.button.x >= (WINDOW_WIDTH - 96 - 48) &&
|
||||
event.button.x < (WINDOW_WIDTH - 96)) ||
|
||||
(event.button.x >= (WINDOW_WIDTH - 96 - 48 - 48) &&
|
||||
(event.button.x >= (WINDOW_WIDTH - 96 - 48 - 48 - 48) &&
|
||||
event.button.x < (WINDOW_WIDTH - 48 - 96) &&
|
||||
/* Both "Erase" and "Export" only work on our own files... */
|
||||
d_places[which] != PLACE_STARTERS_DIR &&
|
||||
d_places[which] != PLACE_PERSONAL_STARTERS_DIR)) &&
|
||||
event.button.y >= (48 * 7 + 40 + HEIGHTOFFSET) - 48 &&
|
||||
|
|
@ -14897,6 +14928,21 @@ static int do_open(void)
|
|||
update_list = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (want_export)
|
||||
{
|
||||
want_export = 0;
|
||||
|
||||
snprintf(fname, sizeof(fname), "saved/%s%s", d_names[which], d_exts[which]);
|
||||
rfname = get_fname(fname, DIR_SAVE);
|
||||
if (export_pict(rfname))
|
||||
do_prompt_snd(PROMPT_PICT_EXPORT_TXT, PROMPT_EXPORT_YES, "", SND_TUXOK, screen->w / 2, screen->h / 2);
|
||||
else
|
||||
do_prompt_snd(PROMPT_PICT_EXPORT_FAILED_TXT, PROMPT_EXPORT_YES, "", SND_YOUCANNOT, screen->w / 2, screen->h / 2);
|
||||
|
||||
draw_tux_text(TUX_BORED, instructions, 1);
|
||||
update_list = 1;
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
|
||||
|
|
@ -15011,6 +15057,8 @@ static int do_open(void)
|
|||
|
||||
|
||||
update_canvas(0, 0, WINDOW_WIDTH - 96 - 96, 48 * 7 + 40 + HEIGHTOFFSET);
|
||||
|
||||
free(instructions);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -15711,27 +15759,27 @@ static int do_slideshow(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
export_successful = export_gif(selected, num_selected, dirname, d_names, d_exts, speed);
|
||||
export_successful = export_gif(selected, num_selected, dirname, d_names, d_exts, speed);
|
||||
|
||||
/* Redraw entire screen, after export: */
|
||||
SDL_FillRect(screen, NULL, SDL_MapRGB(canvas->format, 255, 255, 255));
|
||||
draw_toolbar();
|
||||
draw_colors(COLORSEL_CLOBBER_WIPE);
|
||||
draw_none();
|
||||
|
||||
/* Show a message depending on success */
|
||||
if (export_successful)
|
||||
do_prompt_snd(PROMPT_GIF_EXPORT_TXT, PROMPT_EXPORT_YES, "", SND_TUXOK, screen->w / 2, screen->h / 2);
|
||||
else
|
||||
do_prompt_snd(PROMPT_GIF_EXPORT_FAILED_TXT, PROMPT_EXPORT_YES, "", SND_YOUCANNOT, screen->w / 2, screen->h / 2);
|
||||
|
||||
freeme = textdir(TUX_TIP_SLIDESHOW);
|
||||
draw_tux_text(TUX_BORED, freeme, 1);
|
||||
free(freeme);
|
||||
|
||||
SDL_Flip(screen);
|
||||
|
||||
update_list = 1;
|
||||
/* Redraw entire screen, after export: */
|
||||
SDL_FillRect(screen, NULL, SDL_MapRGB(canvas->format, 255, 255, 255));
|
||||
draw_toolbar();
|
||||
draw_colors(COLORSEL_CLOBBER_WIPE);
|
||||
draw_none();
|
||||
|
||||
/* Show a message depending on success */
|
||||
if (export_successful)
|
||||
do_prompt_snd(PROMPT_GIF_EXPORT_TXT, PROMPT_EXPORT_YES, "", SND_TUXOK, screen->w / 2, screen->h / 2);
|
||||
else
|
||||
do_prompt_snd(PROMPT_GIF_EXPORT_FAILED_TXT, PROMPT_EXPORT_YES, "", SND_YOUCANNOT, screen->w / 2, screen->h / 2);
|
||||
|
||||
freeme = textdir(TUX_TIP_SLIDESHOW);
|
||||
draw_tux_text(TUX_BORED, freeme, 1);
|
||||
free(freeme);
|
||||
|
||||
SDL_Flip(screen);
|
||||
|
||||
update_list = 1;
|
||||
}
|
||||
}
|
||||
else if (event.button.x >= (WINDOW_WIDTH - 96 - 48) &&
|
||||
|
|
@ -19054,7 +19102,7 @@ static int do_new_dialog(void)
|
|||
if (thumbs[num_files] == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\nError: Couldn't create a thumbnail of " "saved image!\n" "%s\n", fname);
|
||||
"\nError: Couldn't create a thumbnail of saved image!\n" "%s\n", fname);
|
||||
}
|
||||
|
||||
num_files++;
|
||||
|
|
@ -19149,7 +19197,7 @@ static int do_new_dialog(void)
|
|||
if (thumbs[num_files] == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\nError: Couldn't create a thumbnail of " "saved image!\n" "%s\n", fname);
|
||||
"\nError: Couldn't create a thumbnail of saved image!\n" "%s\n", fname);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(img);
|
||||
|
|
@ -19682,7 +19730,7 @@ static int do_new_dialog(void)
|
|||
fprintf(stderr,
|
||||
"\nWarning: Couldn't load the saved image! (3)\n"
|
||||
"%s\n"
|
||||
"The Simple DirectMedia Layer error that occurred " "was:\n" "%s\n\n", fname, SDL_GetError());
|
||||
"The Simple DirectMedia Layer error that occurred was:\n" "%s\n\n", fname, SDL_GetError());
|
||||
|
||||
do_prompt(PROMPT_OPEN_UNOPENABLE_TXT, PROMPT_OPEN_UNOPENABLE_YES, "", 0, 0);
|
||||
}
|
||||
|
|
@ -19740,7 +19788,7 @@ static int do_new_dialog(void)
|
|||
fprintf(stderr,
|
||||
"\nWarning: Couldn't load the saved image! (4)\n"
|
||||
"%s\n"
|
||||
"The Simple DirectMedia Layer error that occurred " "was:\n" "%s\n\n", fname, SDL_GetError());
|
||||
"The Simple DirectMedia Layer error that occurred was:\n" "%s\n\n", fname, SDL_GetError());
|
||||
|
||||
do_prompt(PROMPT_OPEN_UNOPENABLE_TXT, PROMPT_OPEN_UNOPENABLE_YES, "", 0, 0);
|
||||
}
|
||||
|
|
@ -22594,6 +22642,7 @@ static void tmpcfg_merge(struct cfginfo *loser, const struct cfginfo *winner)
|
|||
static void setup_config(char *argv[])
|
||||
{
|
||||
char str[128];
|
||||
char * picturesdir;
|
||||
|
||||
#ifndef _WIN32
|
||||
const char *home = getenv("HOME");
|
||||
|
|
@ -22673,7 +22722,10 @@ static void setup_config(char *argv[])
|
|||
* __HAIKU__
|
||||
* __APPLE__
|
||||
*/
|
||||
exportdir = get_xdg_user_dir("PICTURES", "Pictures");
|
||||
picturesdir = get_xdg_user_dir("PICTURES", "Pictures");
|
||||
snprintf(str, sizeof(str), "%s/TuxPaint", picturesdir);
|
||||
free(picturesdir);
|
||||
exportdir = strdup(str);
|
||||
}
|
||||
|
||||
/* Load options from user's own configuration (".rc" / ".cfg") file: */
|
||||
|
|
@ -24235,10 +24287,11 @@ static void setup(void)
|
|||
|
||||
small_font = TuxPaint_Font_OpenFont(PANGO_DEFAULT_FONT, DATA_PREFIX "fonts/default_font.ttf",
|
||||
#ifdef __APPLE__
|
||||
12 - (only_uppercase * 2));
|
||||
12 - (only_uppercase * 2)
|
||||
#else
|
||||
13 - (only_uppercase * 2));
|
||||
13 - (only_uppercase * 2)
|
||||
#endif
|
||||
);
|
||||
|
||||
if (small_font == NULL)
|
||||
{
|
||||
|
|
@ -24793,10 +24846,10 @@ static int trash(char *path)
|
|||
}
|
||||
while (!feof(fi))
|
||||
{
|
||||
len = fread(buf, sizeof(buf), 1, fi);
|
||||
len = fread(buf, sizeof(unsigned char), sizeof(buf), fi);
|
||||
if (len > 0)
|
||||
{
|
||||
fwrite(buf, sizeof(buf), 1, fo);
|
||||
fwrite(buf, sizeof(unsigned char), sizeof(buf), fo);
|
||||
}
|
||||
}
|
||||
fclose(fi);
|
||||
|
|
@ -25336,6 +25389,12 @@ static int export_gif(int *selected, int num_selected, char *dirname, char **d_n
|
|||
show_progress_bar(screen);
|
||||
|
||||
gif_fname = get_export_filepath("gif");
|
||||
if (gif_fname == NULL)
|
||||
{
|
||||
/* Can't create export dir! Abort! */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: Open GIF */
|
||||
|
||||
|
||||
|
|
@ -25426,9 +25485,69 @@ static int export_gif(int *selected, int num_selected, char *dirname, char **d_n
|
|||
return(!done);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy an image (just the main PNG) from Tux Paint's "saved"
|
||||
* directory to the user's chosen export directory
|
||||
* (e.g., ~/Pictures, or whatever "--exportdir" says).
|
||||
*
|
||||
* Used when exporting a single image from the Open dialog.
|
||||
*
|
||||
* @param char * fname -- full path to the image to export
|
||||
* @return int 1 = success, 0 = failed
|
||||
*/
|
||||
static int export_pict(char * fname) {
|
||||
FILE * fi, * fo;
|
||||
size_t len;
|
||||
unsigned char buf[1024];
|
||||
char * pict_fname;
|
||||
|
||||
fi = fopen(fname, "rb");
|
||||
if (fi == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot export from saved Tux Paint file '%s'\nThe error that occurred was:\n%s\n\n", fname, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pict_fname = get_export_filepath("png");
|
||||
if (pict_fname == NULL)
|
||||
{
|
||||
fclose(fi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fo = fopen(pict_fname, "wb");
|
||||
if (fo == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot export to new file '%s'\nThe error that occurred was:\n%s\n\n", pict_fname, strerror(errno));
|
||||
free(pict_fname);
|
||||
fclose(fi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (!feof(fi))
|
||||
{
|
||||
len = fread(buf, sizeof(unsigned char), sizeof(buf), fi);
|
||||
if (len > 0)
|
||||
{
|
||||
fwrite(buf, sizeof(unsigned char), sizeof(buf), fo);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Probably good to check for errors here and respond accordingly -bjk 2020.07.26 */
|
||||
|
||||
fclose(fi);
|
||||
fclose(fo);
|
||||
|
||||
free(pict_fname);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of a new file, located in the user's chosen
|
||||
* export directory (e.g., ~/Pictures, or whatever "--exportdir" says).
|
||||
* export directory (e.g., ~/Pictures/TuxPaint, or whatever "--exportdir" says).
|
||||
*
|
||||
* Also ensures that the directory exists, in the first place.
|
||||
*
|
||||
* Used when exporting animated GIFs (via "Export GIF" in the
|
||||
* Open->Slideshow dialog) and static PNGs (via "Export" in the
|
||||
|
|
@ -25436,7 +25555,8 @@ static int export_gif(int *selected, int num_selected, char *dirname, char **d_n
|
|||
*
|
||||
* @param const char * ext -- extnesion of the file (e.g., "png" or "gif")
|
||||
* @return char * -- filepath for the new file to be created
|
||||
* (e.g., /home/username/Pictures/2020072620110100.gif")
|
||||
* (e.g., /home/username/Pictures/TuxPaint/2020072620110100.gif")
|
||||
* Or NULL if the directory cannot be created.
|
||||
*/
|
||||
static char * get_export_filepath(const char * ext) {
|
||||
char *rname;
|
||||
|
|
@ -25444,6 +25564,14 @@ static char * get_export_filepath(const char * ext) {
|
|||
char timestamp[16];
|
||||
time_t t;
|
||||
|
||||
|
||||
/* Make sure the export dir exists */
|
||||
if (!make_directory(DIR_EXPORT, "", "Can't create export directory"))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a unique filename, within that dir */
|
||||
t = time(NULL);
|
||||
strftime(timestamp, sizeof(timestamp), "%Y%m%d%H%M%S", localtime(&t));
|
||||
snprintf(fname, sizeof(fname), "%s.%s", timestamp, ext);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue