1 ## Copyright (C) 2009,2010,2011,2012 Philip Nienhuis <prnienhuis at users.sf.net>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} [@var{ods}] = odsclose (@var{ods})
18 ## @deftypefnx {Function File} [@var{ods}] = odsclose (@var{ods}, @var{filename})
19 ## @deftypefnx {Function File} [@var{ods}] = odsclose (@var{ods}, "FORCE")
20 ## Close the OpenOffice_org Calc spreadsheet pointed to in struct
21 ## @var{ods}, if needed write the file to disk.
22 ## odsclose will determine if the file must be written to disk based on
23 ## information contained in @var{ods}.
24 ## An empty pointer struct will be returned if no errors occurred.
25 ## Optional argument @var{filename} can be used to write changed spreadsheet
26 ## files to an other file than opened by odsopen().
27 ## Optional string argument "FORCE" can be specified to force resetting the
28 ## file pointer struct. However, in case of UNO, a hidden OOo invocation
29 ## may linger on in memory then, preventing proper closing of Octave.
31 ## You need the Java package >= 1.2.6 plus odfdom.jar + xercesImpl.jar
32 ## and/or jopendocument-<version>.jar installed on your computer +
33 ## proper javaclasspath set, to make this function work at all.
34 ## For UNO support, Octave-Java package >= 1.2.8 + latest fixes is imperative;
35 ## furthermore the relevant classes had best be added to the javaclasspath by
36 ## utility function chk_spreadsheet_support().
38 ## @var{ods} must be a valid pointer struct made by odsopen() in the same
44 ## ods1 = odsclose (ods1);
45 ## (Close spreadsheet file pointed to in pointer struct ods1; ods1 is reset)
48 ## @seealso {odsopen, odsread, odswrite, ods2oct, oct2ods, odsfinfo, chk_spreadsheet_support}
52 ## Author: Philip Nienhuis
53 ## Created: 2009-12-13
55 ## 2010-01-08 (OTK ODS write support)
56 ## 2010-04-13 Improved help text a little bit
57 ## 2010-08-25 Swapped in texinfo help text
58 ## 2010-10-17 Fixed typo in error message about unknown interface
59 ## 2010-10-27 Improved file change tracking tru ods.changed
60 ## 2010-11-12 Keep ods file pointer when write errors occur.
61 ## '' Added optional filename arg to change filename to be written to
62 ## 2011-05-06 Experimental UNO support
63 ## 2011-05-07 In case of UNO, soffice now properly closed using xDesk
64 ## 2011-05-18 Saving newly created files using UNO supported now
65 ## 2011-09-08 FIXME - closing OOo kills all other OOo invocations (known Java-UNO issue)
66 ## 2012-01-26 Fixed "seealso" help string
67 ## 2012-06-08 tabs replaced by double space
69 function [ ods ] = odsclose (ods, varargs)
71 # If needed warn that dangling spreadsheet pointers may be left
72 if (nargout < 1) warning ("return argument missing - ods invocation not reset."); endif
78 if (strcmp (lower (varargin{ii}), "force"))
79 # Close .ods anyway even if write errors occur
81 elseif (~isempty (strfind (tolower (varargin{ii}), '.ods')) || ...
82 ~isempty (strfind (tolower (varargin{ii}), '.sxc')))
83 # Apparently a file name
84 if (ods.changed == 0 || ods.changed > 2)
85 warning ("File %s wasn't changed, new filename ignored.", ods.filename);
87 if (strfind (tolower (filename), '.sxc') || strfind (tolower (filename), '.ods'))
88 ods.filename = filename;
90 error ('No .sxc or .ods filename extension specified');
97 if (strcmp (ods.xtype, 'OTK'))
100 if (ods.changed && ods.changed < 3)
101 ods.app.save (ods.filename);
111 elseif (strcmp (ods.xtype, 'JOD'))
112 # Java & jOpenDocument
114 if (ods.changed && ods.changed < 3)
115 ofile = java_new ('java.io.File', ods.filename);
116 ods.workbook.saveAs (ofile);
122 elseif (strcmp (ods.xtype, 'UNO'))
125 if (ods.changed && ods.changed < 3)
127 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel');
128 xModel = ods.workbook.queryInterface (unotmp);
129 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XModifiable');
130 xModified = xModel.queryInterface (unotmp);
131 if (xModified.isModified ())
132 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XStorable'); # isReadonly() ?
133 xStore = ods.app.xComp.queryInterface (unotmp);
134 if (ods.changed == 2)
135 # Some trickery as Octave Java cannot create non-numeric arrays
136 lProps = javaArray ('com.sun.star.beans.PropertyValue', 1);
137 lProp = java_new ('com.sun.star.beans.PropertyValue', "Overwrite", 0, true, []);
139 # OK, save file to disk
140 xStore.storeAsURL (ods.filename, lProps);
146 ods.changed = -1; # Needed for check op properly shutting down OOo
148 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel');
149 xModel = ods.app.xComp.queryInterface (unotmp);
150 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XCloseable');
151 xClosbl = xModel.queryInterface (unotmp);
152 xClosbl.close (true);
153 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XDesktop');
154 xDesk = ods.app.aLoader.queryInterface (unotmp);
160 unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XDesktop');
161 xDesk = ods.app.aLoader.queryInterface (unotmp);
164 warning ("Error dbclosing ods pointer (UNO)");
169 # elseif ---- < Other interfaces here >
172 error (sprintf ("ods2close: unknown OpenOffice.org .ods interface - %s.", ods.xtype));
176 if (ods.changed && ods.changed < 3)
177 error ( sprintf ("Could not save file %s - read-only or in use elsewhere?\nFile pointer preserved", ods.filename));