Repository: spyder-ide/spyder

Issue:
Add (0) to first image stored when saving all images from IDE
## Problem Description

When saving a group of images from the plot pane in the IDE, the first file has no (#) suffix, and is therefore sorted incorrectly by some file systems and text sorting.

### What steps reproduce the problem?

1. Generate multiple plots in the IDE
2. Use the button to "save all plots"
3. First file name is like Figure 2020-07-10 221755.png, subsequent are Figure 2020-07-10 221755 (1) etc.

### What is the expected output? What do you see instead?

First file would be Figure 2020-07-10 221755 (0)

## Error Traceback  
```python-traceback

N/A

```

## Versions

Spyder 4.1.2  
Python 3.7.6 64-bit  
Qt 5.9.6  
PyQt5 5.9.2  
Windows 10  

### Dependencies
Note: I don't think this matters, but this is what I have at the moment

```

# Mandatory:
atomicwrites >=1.2.0           :  1.3.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.3.0 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.12.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  0.9.2 (OK)
paramiko >=2.4.0               :  2.7.1 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.6.7 (OK)
pygments >=2.0                 :  2.5.2 (OK)
pylint >=0.25                  :  2.4.4 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.9 (OK)
qdarkstyle >=2.8               :  2.8 (OK)
qtawesome >=0.5.7              :  0.6.1 (OK)
qtconsole >=4.6.0              :  4.6.0 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.3 (OK)
sphinx >=0.6.6                 :  2.3.1 (OK)
spyder_kernels >=1.9.0;<1.10.0 :  1.9.0 (OK)
watchdog                       :  None (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.13 (OK)
matplotlib >=2.0.0             :  3.2.1 (OK)
numpy >=1.7                    :  1.17.4 (OK)
pandas >=0.13.1                :  1.0.3 (OK)
scipy >=0.17.0                 :  1.5.0 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)

# Spyder plugins:
spyder_terminal                :  0.3.1 (OK)

```



Discussion:
You're right. We'll work on this for 4.2

Resolving patch:
diff --git a/spyder/plugins/plots/widgets/figurebrowser.py b/spyder/plugins/plots/widgets/figurebrowser.py
--- a/spyder/plugins/plots/widgets/figurebrowser.py
+++ b/spyder/plugins/plots/widgets/figurebrowser.py
@@ -55,13 +55,17 @@ def save_figure_tofile(fig, fmt, fname):
             f.write(fig)
 
 
-def get_unique_figname(dirname, root, ext):
+def get_unique_figname(dirname, root, ext, start_at_zero=False):
     """
     Append a number to "root" to form a filename that does not already exist
     in "dirname".
     """
     i = 1
     figname = '{}{}'.format(root, ext)
+    if start_at_zero:
+        i = 0
+        figname = '{} ({}){}'.format(root, i, ext)
+
     while True:
         if osp.exists(osp.join(dirname, figname)):
             figname = '{} ({}){}'.format(root, i, ext)
@@ -762,7 +766,8 @@ def save_all_figures_todir(self, dirname):
                     'image/jpeg': '.jpg',
                     'image/svg+xml': '.svg'}[fmt]
 
-            figname = get_unique_figname(dirname, figname_root, fext)
+            figname = get_unique_figname(dirname, figname_root, fext,
+                                         start_at_zero=True)
             save_figure_tofile(fig, fmt, figname)
             fignames.append(figname)
         return fignames


Test patch:
diff --git a/spyder/plugins/plots/widgets/tests/test_plots_widgets.py b/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
--- a/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
+++ b/spyder/plugins/plots/widgets/tests/test_plots_widgets.py
@@ -13,6 +13,7 @@
 # Standard library imports
 from __future__ import division
 import os.path as osp
+import datetime
 try:
     from unittest.mock import Mock
 except ImportError:
@@ -30,6 +31,7 @@
 # Local imports
 from spyder.plugins.plots.widgets.figurebrowser import (FigureBrowser,
                                                         FigureThumbnail)
+from spyder.plugins.plots.widgets.figurebrowser import get_unique_figname
 from spyder.py3compat import to_text_string
 
 
@@ -176,6 +178,33 @@ def test_save_all_figures(figbrowser, tmpdir, mocker, fmt):
         assert expected_qpix.toImage() == saved_qpix.toImage()
 
 
+def test_get_unique_figname(tmpdir):
+    """
+    Test that the unique fig names work when saving only one and when
+    saving multiple figures.
+    """
+    fext = '.png'
+    # Saving only one figure
+    figname_root = ('Figure ' +
+                    datetime.datetime.now().strftime('%Y-%m-%d %H%M%S'))
+    figname = get_unique_figname(tmpdir, figname_root, fext)
+    expected = osp.join(tmpdir, '{}{}'.format(figname_root, fext))
+    assert figname == expected
+
+    # Saving multiple figures
+    figname_root = ('Figure ' +
+                    datetime.datetime.now().strftime('%Y-%m-%d %H%M%S'))
+    for i in range(5):
+        figname = get_unique_figname(tmpdir, figname_root, fext,
+                                     start_at_zero=True)
+        # Create empty file with figname
+        with open(figname, 'w') as _:
+            pass
+
+        expected = osp.join(tmpdir, '{} ({}){}'.format(figname_root, i, fext))
+        assert figname == expected
+
+
 @pytest.mark.parametrize("fmt", ['image/png', 'image/svg+xml'])
 def test_close_current_figure(figbrowser, tmpdir, fmt):
     """