From 3983e93c173fb2241aac715a73196825ffd5d7aa Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Mon, 28 May 2012 19:00:11 -0700 Subject: [PATCH 1/9] use Qt window title as default savefig filename --- lib/matplotlib/backends/backend_qt.py | 4 +++- lib/matplotlib/backends/backend_qt4.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 285523fdf6d6..4234f96aae4d 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -419,8 +419,10 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() + default_filename = self.canvas.window().windowTitle() or 'image' + default_filename.replace(' ', '_') - start = "image." + default_filetype + start = default_filename + '.' + default_filetype filters = [] selectedFilter = None for name, exts in sorted_filetypes: diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 08ac77b253d3..1cfcea044846 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -614,8 +614,10 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() + default_filename = self.canvas.window().windowTitle() or 'image' + default_filename.replace(' ', '_') - start = "image." + default_filetype + start = default_filename + '.' + default_filetype filters = [] selectedFilter = None for name, exts in sorted_filetypes: From 16dd72999a9678d851663d63f864982248da72b8 Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Tue, 29 May 2012 18:12:33 -0700 Subject: [PATCH 2/9] convert QString to string, and fix string.replace() oops --- lib/matplotlib/backends/backend_qt.py | 4 ++-- lib/matplotlib/backends/backend_qt4.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 4234f96aae4d..81d7da457c21 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -419,8 +419,8 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - default_filename = self.canvas.window().windowTitle() or 'image' - default_filename.replace(' ', '_') + default_filename = str(self.canvas.window().windowTitle()) or 'image' + default_filename = default_filename.replace(' ', '_') start = default_filename + '.' + default_filetype filters = [] diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 1cfcea044846..e6dfdb538a12 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -614,8 +614,8 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - default_filename = self.canvas.window().windowTitle() or 'image' - default_filename.replace(' ', '_') + default_filename = str(self.canvas.window().windowTitle()) or 'image' + default_filename = default_filename.replace(' ', '_') start = default_filename + '.' + default_filetype filters = [] From 395acc107cbe2d98f83e5509d9b7784a861a17c9 Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Wed, 30 May 2012 14:21:57 -0700 Subject: [PATCH 3/9] in qt4 backend, define get_window_title and call it for default savefig filename revert prior changes to qt backend, since I can't test them --- lib/matplotlib/backend_bases.py | 15 +++++++++++++++ lib/matplotlib/backends/backend_qt.py | 4 +--- lib/matplotlib/backends/backend_qt4.py | 5 ++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 6a2a98ac0253..39bc07a34455 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2092,6 +2092,14 @@ def get_default_filetype(self): """ return rcParams['savefig.format'] + def get_window_title(self): + """ + Get the title text of the window containing the figure. + Return None if there is no window (eg, a PS backend). + """ + if hasattr(self, "manager"): + return self.manager.get_window_title() + def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that @@ -2413,6 +2421,13 @@ def show_popup(self, msg): """ pass + def get_window_title(self): + """ + Get the title text of the window containing the figure. + Return None if there is no window (eg, a PS backend). + """ + pass + def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 81d7da457c21..19c2536559fb 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -419,10 +419,8 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - default_filename = str(self.canvas.window().windowTitle()) or 'image' - default_filename = default_filename.replace(' ', '_') - start = default_filename + '.' + default_filetype + start = 'image.' + default_filetype filters = [] selectedFilter = None for name, exts in sorted_filetypes: diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index e6dfdb538a12..8552cac6e9af 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -481,6 +481,9 @@ def destroy( self, *args ): if DEBUG: print("destroy figure manager") self.window.close() + def get_window_title(self): + return str(self.window.windowTitle()) + def set_window_title(self, title): self.window.setWindowTitle(title) @@ -614,7 +617,7 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - default_filename = str(self.canvas.window().windowTitle()) or 'image' + default_filename = self.canvas.get_window_title() or 'image' default_filename = default_filename.replace(' ', '_') start = default_filename + '.' + default_filetype From 88dbef7898f3832ebd5d43ab1d678c0c742a42bd Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Wed, 30 May 2012 15:13:01 -0700 Subject: [PATCH 4/9] raise NotImplementedError instead of pass for FigureManagerBase window_title methods --- lib/matplotlib/backend_bases.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 39bc07a34455..972eeeb8a68c 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2426,14 +2426,14 @@ def get_window_title(self): Get the title text of the window containing the figure. Return None if there is no window (eg, a PS backend). """ - pass + raise NotImplementedError def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that this has no effect if there is no window (eg, a PS backend). """ - pass + raise NotImplementedError class Cursors: From 41aa5052634ba305801d1f553b0348c6618942f6 Mon Sep 17 00:00:00 2001 From: pelson Date: Thu, 31 May 2012 09:35:06 +0100 Subject: [PATCH 5/9] Supported & tested on wx, gtk, gtk3, qt3, tk. --- lib/matplotlib/backend_bases.py | 9 +++++++++ lib/matplotlib/backends/backend_gtk.py | 9 +++++++-- lib/matplotlib/backends/backend_gtk3.py | 9 +++++++-- lib/matplotlib/backends/backend_qt.py | 7 +++++-- lib/matplotlib/backends/backend_tkagg.py | 8 ++++++-- lib/matplotlib/backends/backend_wx.py | 5 ++++- 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 972eeeb8a68c..b0dc53326c56 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2108,6 +2108,15 @@ def set_window_title(self, title): if hasattr(self, "manager"): self.manager.set_window_title(title) + def get_default_filename(self): + """ + Return a string, which includes extension, suitable for use as + a default filename. + """ + default_filename = self.get_window_title() or 'image' + default_filename = default_filename.lower().replace(' ', '_') + return default_filename + '.' + self.get_default_filetype() + def switch_backends(self, FigureCanvasClass): """ Instantiate an instance of FigureCanvasClass diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index 4ca9ca7deb48..b7199890225a 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -529,7 +529,7 @@ def __init__(self, canvas, num): FigureManagerBase.__init__(self, canvas, num) self.window = gtk.Window() - self.window.set_title("Figure %d" % num) + self.set_window_title("Figure %d" % num) if (window_icon): try: self.window.set_icon_from_file(window_icon) @@ -620,6 +620,9 @@ def _get_toolbar(self, canvas): toolbar = None return toolbar + def get_window_title(self): + return self.window.get_title() + def set_window_title(self, title): self.window.set_title(title) @@ -725,11 +728,13 @@ def _init_toolbar2_4(self): self.show_all() def get_filechooser(self): - return FileChooserDialog( + fc = FileChooserDialog( title='Save the figure', parent=self.win, filetypes=self.canvas.get_supported_filetypes(), default_filetype=self.canvas.get_default_filetype()) + fc.set_current_name(self.canvas.get_default_filename()) + return fc def save_figure(self, *args): fname, format = self.get_filechooser().get_filename_from_user() diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 0c5dd99aaf0a..56ff935e7a29 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -358,7 +358,7 @@ def __init__(self, canvas, num): FigureManagerBase.__init__(self, canvas, num) self.window = Gtk.Window() - self.window.set_title("Figure %d" % num) + self.set_window_title("Figure %d" % num) if (window_icon): try: self.window.set_icon_from_file(window_icon) @@ -447,6 +447,9 @@ def _get_toolbar(self, canvas): toolbar = None return toolbar + def get_window_title(self): + return self.window.get_title() + def set_window_title(self, title): self.window.set_title(title) @@ -532,11 +535,13 @@ def _init_toolbar(self): self.show_all() def get_filechooser(self): - return FileChooserDialog( + fc = FileChooserDialog( title='Save the figure', parent=self.win, filetypes=self.canvas.get_supported_filetypes(), default_filetype=self.canvas.get_default_filetype()) + fc.set_current_name(self.canvas.get_default_filename()) + return fc def save_figure(self, *args): fname, format = self.get_filechooser().get_filename_from_user() diff --git a/lib/matplotlib/backends/backend_qt.py b/lib/matplotlib/backends/backend_qt.py index 19c2536559fb..6acca884e6a0 100644 --- a/lib/matplotlib/backends/backend_qt.py +++ b/lib/matplotlib/backends/backend_qt.py @@ -219,7 +219,7 @@ def __init__( self, canvas, num ): # Give the keyboard focus to the figure instead of the manager self.canvas.setFocusPolicy( qt.QWidget.ClickFocus ) self.canvas.setFocus() - self.window.setCaption( "Figure %d" % num ) + self.set_window_title( "Figure %d" % num ) self.window._destroying = False @@ -293,6 +293,9 @@ def destroy( self, *args ): if DEBUG: print("destroy figure manager") self.window.close(True) + def get_window_title(self): + return str(self.window.caption()) + def set_window_title(self, title): self.window.setCaption(title) @@ -420,7 +423,7 @@ def save_figure(self, *args): sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - start = 'image.' + default_filetype + start = self.canvas.get_default_filename() filters = [] selectedFilter = None for name, exts in sorted_filetypes: diff --git a/lib/matplotlib/backends/backend_tkagg.py b/lib/matplotlib/backends/backend_tkagg.py index 254d3e275f68..2ac741896bf3 100644 --- a/lib/matplotlib/backends/backend_tkagg.py +++ b/lib/matplotlib/backends/backend_tkagg.py @@ -494,7 +494,7 @@ def __init__(self, canvas, num, window): FigureManagerBase.__init__(self, canvas, num) self.window = window self.window.withdraw() - self.window.wm_title("Figure %d" % num) + self.set_window_title("Figure %d" % num) self.canvas = canvas self._num = num _, _, w, h = canvas.figure.bbox.bounds @@ -565,6 +565,9 @@ def destroy(self, *args): self.window.quit() self.window = None + def get_window_title(self): + return self.window.wm_title() + def set_window_title(self, title): self.window.wm_title(title) @@ -874,7 +877,8 @@ def save_figure(self, *args): master=self.window, title='Save the figure', filetypes = tk_filetypes, - defaultextension = defaultextension + defaultextension = defaultextension, + initialfile=self.canvas.get_default_filename(), ) if fname == "" or fname == (): diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 4f942b931c69..bca5066819d8 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -1603,6 +1603,9 @@ def destroy(self, *args): #wx.GetApp().ProcessIdle() wx.WakeUpIdle() + def get_window_title(self): + return self.window.GetTitle() + def set_window_title(self, title): self.window.SetTitle(title) @@ -1840,7 +1843,7 @@ def configure_subplots(self, evt): def save_figure(self, *args): # Fetch the required filename and file type. filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards() - default_file = "image." + self.canvas.get_default_filetype() + default_file = self.canvas.get_default_filename() dlg = wx.FileDialog(self._parent, "Save to file", "", default_file, filetypes, wx.SAVE|wx.OVERWRITE_PROMPT) From f60f942598f149f0673d440d63a2ca8b3fae69bb Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Thu, 31 May 2012 15:41:51 +0100 Subject: [PATCH 6/9] removed lower() on the filename --- lib/matplotlib/backend_bases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index b0dc53326c56..847b1ee0eae7 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2114,7 +2114,7 @@ def get_default_filename(self): a default filename. """ default_filename = self.get_window_title() or 'image' - default_filename = default_filename.lower().replace(' ', '_') + default_filename = default_filename.replace(' ', '_') return default_filename + '.' + self.get_default_filetype() def switch_backends(self, FigureCanvasClass): From c090a9c17b9c00594e93555b484ea2e4c32fab96 Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Fri, 1 Jun 2012 12:47:47 -0700 Subject: [PATCH 7/9] fix qt4 not using get_default_filename in save_figure restore enforcing lowercase in get_default_filename --- lib/matplotlib/backend_bases.py | 2 +- lib/matplotlib/backends/backend_qt4.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 847b1ee0eae7..b0dc53326c56 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2114,7 +2114,7 @@ def get_default_filename(self): a default filename. """ default_filename = self.get_window_title() or 'image' - default_filename = default_filename.replace(' ', '_') + default_filename = default_filename.lower().replace(' ', '_') return default_filename + '.' + self.get_default_filetype() def switch_backends(self, FigureCanvasClass): diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 8552cac6e9af..4adc609a8cc0 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -617,10 +617,8 @@ def save_figure(self, *args): sorted_filetypes = filetypes.items() sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - default_filename = self.canvas.get_window_title() or 'image' - default_filename = default_filename.replace(' ', '_') - start = default_filename + '.' + default_filetype + start = self.canvas.get_default_filename() filters = [] selectedFilter = None for name, exts in sorted_filetypes: From 3b19a1542b81c84a1e81e02431a78db2aae6b6fc Mon Sep 17 00:00:00 2001 From: Martin Spacek Date: Mon, 4 Jun 2012 15:03:46 -0700 Subject: [PATCH 8/9] maintain compatibility with unimplemented backends --- lib/matplotlib/backend_bases.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index b0dc53326c56..aa13b4bc98f9 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2433,16 +2433,16 @@ def show_popup(self, msg): def get_window_title(self): """ Get the title text of the window containing the figure. - Return None if there is no window (eg, a PS backend). + Return None for non-GUI backends (eg, a PS backend). """ - raise NotImplementedError + return 'image' def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that - this has no effect if there is no window (eg, a PS backend). + this has no effect for non-GUI backends (eg, a PS backend). """ - raise NotImplementedError + pass class Cursors: From 23deb00669fb215976b446176993db2d17e81e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Seppa=CC=88nen?= Date: Sat, 9 Jun 2012 10:59:01 +0300 Subject: [PATCH 9/9] Add window title management to MacOSX backend --- lib/matplotlib/backends/backend_macosx.py | 6 +- src/_macosx.m | 70 ++++++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index cfa31d15653c..b06bab2c90d3 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -444,7 +444,8 @@ def zoomy(self, direction): self.canvas.invalidate() def save_figure(self, *args): - filename = _macosx.choose_save_file('Save the figure') + filename = _macosx.choose_save_file('Save the figure', + self.canvas.get_default_filename()) if filename is None: # Cancel return self.canvas.print_figure(filename) @@ -469,7 +470,8 @@ def set_cursor(self, cursor): _macosx.set_cursor(cursor) def save_figure(self, *args): - filename = _macosx.choose_save_file('Save the figure') + filename = _macosx.choose_save_file('Save the figure', + self.canvas.get_default_filename()) if filename is None: # Cancel return self.canvas.print_figure(filename) diff --git a/src/_macosx.m b/src/_macosx.m index 40d41580758f..6c291f792e54 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -3827,6 +3827,56 @@ static void _data_provider_release(void* info, const void* data, size_t size) return Py_None; } +static PyObject* +FigureManager_set_window_title(FigureManager* self, + PyObject *args, PyObject *kwds) +{ + char* title; + if(!PyArg_ParseTuple(args, "es", "UTF-8", &title)) + return NULL; + + Window* window = self->window; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* ns_title = [[NSString alloc] + initWithCString: title + encoding: NSUTF8StringEncoding]; + [window setTitle: ns_title]; + [pool release]; + } + PyMem_Free(title); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +FigureManager_get_window_title(FigureManager* self) +{ + Window* window = self->window; + PyObject* result = NULL; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* title = [window title]; + if (title) { + const char* cTitle = [title UTF8String]; +#if PY3K || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6) + result = PyUnicode_FromString(cTitle); +#else + result = PyString_FromString(cTitle); +#endif + } + [pool release]; + } + if (result) { + return result; + } else { + Py_INCREF(Py_None); + return Py_None; + } +} + static PyMethodDef FigureManager_methods[] = { {"show", (PyCFunction)FigureManager_show, @@ -3838,6 +3888,16 @@ static void _data_provider_release(void* info, const void* data, size_t size) METH_NOARGS, "Closes the window associated with the figure manager." }, + {"set_window_title", + (PyCFunction)FigureManager_set_window_title, + METH_VARARGS, + "Sets the title of the window associated with the figure manager." + }, + {"get_window_title", + (PyCFunction)FigureManager_get_window_title, + METH_NOARGS, + "Returns the title of the window associated with the figure manager." + }, {NULL} /* Sentinel */ }; @@ -4806,11 +4866,19 @@ -(void)save_figure:(id)sender { int result; const char* title; - if(!PyArg_ParseTuple(args, "s", &title)) return NULL; + char* default_filename; + if(!PyArg_ParseTuple(args, "ses", &title, "UTF-8", &default_filename)) + return NULL; NSSavePanel* panel = [NSSavePanel savePanel]; [panel setTitle: [NSString stringWithCString: title encoding: NSASCIIStringEncoding]]; + NSString* ns_default_filename = + [[NSString alloc] + initWithCString: default_filename + encoding: NSUTF8StringEncoding]; + PyMem_Free(default_filename); + [panel setNameFieldStringValue: ns_default_filename]; result = [panel runModal]; if (result == NSOKButton) {