From: <md...@us...> - 2008-03-27 14:42:29
|
Revision: 5026 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5026&view=rev Author: mdboom Date: 2008-03-27 07:42:26 -0700 (Thu, 27 Mar 2008) Log Message: ----------- Merged revisions 5024-5025 via svnmerge from https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_91_maint ........ r5025 | mdboom | 2008-03-27 10:26:19 -0400 (Thu, 27 Mar 2008) | 4 lines Fix saving to Unicode filenames in Agg backend. Fix Qt and Qt4 GUI's to support saving to Unicode filenames in file save dialogs. Wx, Gtk and Tk GUIs already appear to work. ........ Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_qt.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py trunk/matplotlib/src/_backend_agg.cpp Property Changed: ---------------- trunk/matplotlib/ Property changes on: trunk/matplotlib ___________________________________________________________________ Name: svnmerge-integrated - /branches/v0_91_maint:1-5023 + /branches/v0_91_maint:1-5025 Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008-03-27 14:26:19 UTC (rev 5025) +++ trunk/matplotlib/CHANGELOG 2008-03-27 14:42:26 UTC (rev 5026) @@ -1,3 +1,7 @@ +2008-03-27 Fix saving to Unicode filenames with Agg backend + (other backends appear to already work...) + (Thanks, Christopher Barker) - MGD + 2008-03-26 Fix SVG backend bug that prevents copying and pasting in Inkscape (thanks Kaushik Ghose) - MGD Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2008-03-27 14:26:19 UTC (rev 5025) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2008-03-27 14:42:26 UTC (rev 5026) @@ -286,19 +286,23 @@ def get_default_filetype(self): return 'png' - def print_raw(self, filename, *args, **kwargs): + def print_raw(self, filename_or_obj, *args, **kwargs): FigureCanvasAgg.draw(self) + renderer = self.get_renderer() original_dpi = renderer.dpi renderer.dpi = self.figure.dpi - renderer._renderer.write_rgba(str(filename)) + if type(filename_or_obj) in (str, unicode): + filename_or_obj = open(filename_or_obj, 'w') + renderer._renderer.write_rgba(filename_or_obj) renderer.dpi = original_dpi print_rgba = print_raw - def print_png(self, filename, *args, **kwargs): + def print_png(self, filename_or_obj, *args, **kwargs): FigureCanvasAgg.draw(self) renderer = self.get_renderer() original_dpi = renderer.dpi renderer.dpi = self.figure.dpi - filename = str(filename) # until we figure out unicode handling - renderer._renderer.write_png(filename, self.figure.dpi) + if type(filename_or_obj) in (str, unicode): + filename_or_obj = open(filename_or_obj, 'w') + self.get_renderer()._renderer.write_png(filename_or_obj, self.figure.dpi) renderer.dpi = original_dpi Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2008-03-27 14:26:19 UTC (rev 5025) +++ trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2008-03-27 14:42:26 UTC (rev 5026) @@ -427,7 +427,7 @@ selectedFilter) if fname: try: - self.canvas.print_figure( fname.latin1() ) + self.canvas.print_figure( unicode(fname) ) except Exception, e: qt.QMessageBox.critical( self, "Error saving file", str(e), Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2008-03-27 14:26:19 UTC (rev 5025) +++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2008-03-27 14:42:26 UTC (rev 5026) @@ -376,7 +376,7 @@ self, "Choose a filename to save to", start, filters, selectedFilter) if fname: try: - self.canvas.print_figure( str(fname.toLatin1()) ) + self.canvas.print_figure( unicode(fname) ) except Exception, e: QtGui.QMessageBox.critical( self, "Error saving file", str(e), Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2008-03-27 14:26:19 UTC (rev 5025) +++ trunk/matplotlib/src/_backend_agg.cpp 2008-03-27 14:42:26 UTC (rev 5026) @@ -1286,12 +1286,33 @@ _VERBOSE("RendererAgg::write_rgba"); args.verify_length(1); - std::string fname = Py::String(args[0]); - std::ofstream of2( fname.c_str(), std::ios::binary|std::ios::out); - for (size_t i=0; i<NUMBYTES; i++) { - of2.write((char*)&(pixBuffer[i]), sizeof(char)); + FILE *fp = NULL; + bool close_file = false; + Py::Object py_fileobj = Py::Object(args[0]); + if (py_fileobj.isString()) { + std::string fileName = Py::String(py_fileobj); + const char *file_name = fileName.c_str(); + if ((fp = fopen(file_name, "wb")) == NULL) + throw Py::RuntimeError( Printf("Could not open file %s", file_name).str() ); + fwrite(pixBuffer, 1, NUMBYTES, fp); + close_file = true; + fclose(fp); + } else if (PyFile_CheckExact(py_fileobj.ptr())) { + fp = PyFile_AsFile(py_fileobj.ptr()); + fwrite(pixBuffer, 1, NUMBYTES, fp); + } else { + PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(), "write"); + if (!(write_method && PyCallable_Check(write_method))) { + Py_XDECREF(write_method); + throw Py::TypeError("Object does not appear to be a 8-bit string path or a Python file-like object"); + } + + PyObject_CallFunction(write_method, "s#", pixBuffer, NUMBYTES); + + Py_XDECREF(write_method); } + return Py::Object(); } @@ -1326,18 +1347,22 @@ args.verify_length(1, 2); FILE *fp = NULL; + bool close_file = false; Py::Object py_fileobj = Py::Object(args[0]); if (py_fileobj.isString()) { std::string fileName = Py::String(py_fileobj); const char *file_name = fileName.c_str(); if ((fp = fopen(file_name, "wb")) == NULL) throw Py::RuntimeError( Printf("Could not open file %s", file_name).str() ); + close_file = true; + } else if (PyFile_CheckExact(py_fileobj.ptr())) { + fp = PyFile_AsFile(py_fileobj.ptr()); } else { PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(), "write"); if (!(write_method && PyCallable_Check(write_method))) { Py_XDECREF(write_method); - throw Py::TypeError("Object does not appear to be a path or a Python file-like object"); + throw Py::TypeError("Object does not appear to be a 8-bit string path or a Python file-like object"); } Py_XDECREF(write_method); } @@ -1406,7 +1431,7 @@ */ } catch (...) { - if (fp) fclose(fp); + if (fp && close_file) fclose(fp); delete [] row_pointers; if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); throw; @@ -1414,7 +1439,7 @@ png_destroy_write_struct(&png_ptr, &info_ptr); delete [] row_pointers; - if (fp) fclose(fp); + if (fp && close_file) fclose(fp); return Py::Object(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |