From: <prn...@us...> - 2011-05-06 14:39:05
|
Revision: 8246 http://octave.svn.sourceforge.net/octave/?rev=8246&view=rev Author: prnienhuis Date: 2011-05-06 14:38:58 +0000 (Fri, 06 May 2011) Log Message: ----------- strfind call bug fixes; experimental UNO support (currently only reading) Modified Paths: -------------- trunk/octave-forge/main/io/inst/chk_spreadsheet_support.m trunk/octave-forge/main/io/inst/odsclose.m trunk/octave-forge/main/io/inst/odsopen.m Modified: trunk/octave-forge/main/io/inst/chk_spreadsheet_support.m =================================================================== --- trunk/octave-forge/main/io/inst/chk_spreadsheet_support.m 2011-05-06 12:24:17 UTC (rev 8245) +++ trunk/octave-forge/main/io/inst/chk_spreadsheet_support.m 2011-05-06 14:38:58 UTC (rev 8246) @@ -1,15 +1,26 @@ % Check Octave / Matlab environment for spreadsheet I/O support. % -% usage: [ RETVAL ] = chk_spreadsheet_support ( [/PATH/TO/JARS], [,DEBUG_LEVEL] ) +% usage: [ RETVAL ] = chk_spreadsheet_support ( [/PATH/TO/JARS], [,DEBUG_LEVEL] [,PATH_TO_OOO]) % -% /PATH/TO/JARS = path (relative or absolute) to a subdirectory where -% java class libraries (.jar) for spreadsheet I/O reside -% DEBUG_LEVEL = integer between [0 (no output) .. 3 (full output] -% returns: +% Input arguments (all are optional): +% /PATH/TO/JARS = (string) path (relative or absolute) to a +% subdirectory where java class libraries (.jar) +% for spreadsheet I/O reside +% DEBUG_LEVEL = (integer) between [0 (no output) .. 3 (full output] +% PATH_TO_OOO = (string) installation directory of Openffice.org, +% usually (but not guaranteed): +% - Windows: C:\Program Files\OpenOffice.org +% - *nix: /usr/lib/ooo +% - Mac OSX: ????? +% IMPORTANT: PATH_TO_OOO should be such that both: +% 1. PATH_TO_OOO/program/ and +% 2. PATH_TO_OOO/ure/share/java/ridl.jar +% resolve OK +% Returns: % RETVAL = 0 No spreadsheet I/O support found % = 1 At least one spreadsheet I/O interface found % -% CHK_SPREADSHEET_SUPPORT first check ActiveX (native MS-Excel); then +% CHK_SPREADSHEET_SUPPORT first checks ActiveX (native MS-Excel); then % Java JRE presence, then Java support (builtin/activated - Matlab or % added tru octave-forge Java package (Octave); then check existing % javaclasspath for Java class libraries (.jar) needed for spreadsheet @@ -18,9 +29,11 @@ % javaclasspath. In that case the path name to the directory % containing these classes should be specified as input argument % with -TAKE NOTICE- /forward/ slashes. -% A second optional argument is the default debug level +% A second (optional) argument is the default debug level. +% A third (optional) argument is the installation directory of +% OpenOffice.org or clones. -function [ retval ] = chk_spreadsheet_support (path_to_jars, dbug=0) +function [ retval ] = chk_spreadsheet_support (path_to_jars, dbug, path_to_ooo) % Copyright (C) 2009,2010,2011 Philip Nienhuis <prnienhuis at users.sf.net> % @@ -46,12 +59,14 @@ % 2011-01-04 Adapted for general checks, debugging & set up, both Octave & ML % 2011-04-04 Rebuilt into general setup/debug tool for spreadsheet I/O support % and renamed chk_spreadsheet_support() -% +% 2011-05-04 Added in UNO support (OpenOffice.org & clones) +% '' Improved finding jar names in javaclasspath +% 2011-05-07 Improved help text jcp = []; retval = 0; + if (nargin < 2), dbug = 0; end %if isOctave = exist ('OCTAVE_VERSION', 'builtin') ~= 0; if (ispc), filesep = '\'; else, filesep = '/'; end %if - dbug = min (max (dbug, 0), 3); fprintf ('\n'); % Check if MS-Excel COM ActiveX server runs @@ -63,12 +78,11 @@ % Close Excel to avoid zombie Excel invocation app.Quit(); delete(app); - if (dbug), fprintf ('OK.\n\n'); end %if - retval = 1; + if (dbug), fprintf ('OK.\n\n'); retval = 1; end %if catch % COM not supported if (dbug), fprintf ('not working.\n\n'); end %if - end_try_catch + end %try_catch % Check Java if (dbug), fprintf ('Checking Java support...\n'); end %if @@ -76,24 +90,25 @@ % Try if Java is installed at all if (isOctave) if (ispc) - jtst = (!system ('java -version 2> nul')); + jtst = (system ('java -version 2> nul')); else - jtst = (!system ('java -version 2> /dev/null')); + jtst = (system ('java -version 2> /dev/null')); end %if else - jtst = (version -java) + tst1 = version ('-java'); + jtst = isempty (strfind (tst1, 'Java')); end %if - if (~jtst) - error ("\nApparently no Java JRE installed."); + if (jtst) + error ('Apparently no Java JRE installed.'); else if (dbug > 1), fprintf ('OK, found one.\n'); end %if end %if - if (dbug > 1), fprintf (' 2. Checking Octave Java support... '); end %if + if (dbug > 1 && isOctave), fprintf (' 2. Checking Octave Java support... '); end %if try - jcp = javaclasspath ('-all'); # For Octave java pkg > 1.2.7 - if (isempty (jcp)), jcp = javaclasspath; endif # For Octave java pkg < 1.2.8 + jcp = javaclasspath ('-all'); %# For Octave java pkg > 1.2.7 + if (isempty (jcp)), jcp = javaclasspath; end %if %# For Octave java pkg < 1.2.8 % If we get here, at least Java works. - if (dbug > 1), fprintf ('Java package seems to work OK.\n'); end %if + if (dbug > 1 && isOctave), fprintf ('Java package seems to work OK.\n'); end %if % Now check for proper version % (> 1.6.x.x) jver = char (javaMethod ('getProperty', 'java.lang.System', 'java.version')); @@ -117,8 +132,9 @@ if (isunix) jcp = strsplit (char (jcp), ':'); end %if if (dbug > 1) % Check JVM virtual memory settings - jmem = javaMethod ('getRuntime', 'java.lang.Runtime'); - jmem = jmem.maxMemory().doubleValue(); + jrt = javaMethod ('getRuntime', 'java.lang.Runtime'); + jmem = jrt.maxMemory (); + if (isOctave), jmem = jmem.doubleValue(); end %if jmem = int16 (jmem/1024/1024); fprintf (' Maximum JVM memory: %5d MiB; ', jmem); if (jmem < 400) @@ -134,14 +150,53 @@ end %if end %if if (dbug), fprintf ('Java support OK\n'); end %if - catch + catch error ('No Java support found.'); end %try_catch - if (dbug), fprintf ('\nChecking javaclasspath for .jar libraries needed for spreadsheet I/O...:\n'); end %if + if (dbug), fprintf ('\nChecking javaclasspath for .jar class libraries needed for spreadsheet I/O...:\n'); end %if + % Try Java & UNO + if (dbug > 1), fprintf ('UNO/Java (.ods, .xls, .xlsx, .sxc) <OpenOffice.org>:\n'); end %if + # entries0(1) = not a jar but a directory (<000_install_dir/program/>) + jpchk = 0; entries0 = {'program', 'unoil', 'jurt', 'juh', 'unoloader', 'ridl'}; + missing0 = zeros (1, numel (entries0)); + % Only under *nix we might use brute force: e.g., strfind (javaclasspath, classname) + % as javaclasspath is one long string. Under Windows however classpath is a cell array + % so we need the following more subtle, platform-independent approach: + for jj=1:numel (entries0) + found = 0; + for ii=1:numel (jcp) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries0{jj})))) + jpchk = jpchk + 1; found = 1; + if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if + end %if + end %for + if (~found) + if (dbug > 2) + if (jj == 1) + # Just a dir + fprintf (' %s.... (directory) not found\n', entries0{jj}); + else + fprintf (' %s....jar missing\n', entries0{jj}); + end %if + end %if + missing0(jj) = 1; + end %if + end %for + if (dbug > 1) + if (jpchk >= numel (entries0)) + fprintf (' => UNO (OOo) OK\n'); + retval = 1; + else + fprintf (' => One or more UNO classes (.jar) missing in javaclasspath\n'); + end %if + end %if + % Try Java & Apache POI. First Check basic .xls (BIFF8) support - if (dbug > 1), fprintf ('Basic POI (.xls) <poi-3> <poi-ooxml>:\n'); end %if + if (dbug > 1), fprintf ('\nBasic POI (.xls) <poi-3> <poi-ooxml>:\n'); end %if jpchk1 = 0; entries1 = {'poi-3', 'poi-ooxml-3'}; missing1 = zeros (1, numel (entries1)); % Only under *nix we might use brute force: e.g., strfind (javaclasspath, classname) % as javaclasspath is one long string. Under Windows however classpath is a cell array @@ -149,7 +204,9 @@ for jj=1:length (entries1) found = 0; for ii=1:length (jcp) - if (strfind (lower (jcp{ii}), lower (entries1{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries1{jj})))) jpchk1 = jpchk1 + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end %if @@ -159,10 +216,10 @@ missing1(jj) = 1; end %if end %for - retval = jpchk1 > 1; if (dbug > 1) - if (jpchk1 > 1) + if (jpchk1 >= numel (entries1)) fprintf (' => Apache (POI) OK\n'); + retval = 1; else fprintf (' => Not all classes (.jar) required for POI in classpath\n'); end %if @@ -174,7 +231,9 @@ for jj=1:length (entries2) found = 0; for ii=1:length (jcp) - if (strfind (lower (jcp{ii}), lower (entries2{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries2{jj})))) jpchk2 = jpchk2 + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end %if @@ -185,7 +244,7 @@ end %if end % for if (dbug > 1) - if (jpchk2 > 2) + if (jpchk2 >= numel (entries2)) fprintf (' => POI OOXML OK\n'); else fprintf (' => Some classes for POI OOXML support missing\n'); @@ -198,7 +257,9 @@ for jj=1:length (entries3) found = 0; for ii=1:length (jcp) - if (strfind (lower (jcp{ii}), lower (entries3{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries3{jj})))) jpchk = jpchk + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end % if @@ -208,9 +269,8 @@ missing3(jj) = 1; end %if end %for - retval = jpchk > 0; if (dbug > 1) - if (jpchk > 0) + if (jpchk >= numel (entries3)) fprintf (' => Java/JExcelAPI (JXL) OK.\n'); retval = 1; else @@ -218,13 +278,15 @@ end %if end %if - % Try Java & OpenXLS (experimental) - if (dbug > 1), fprintf ('\nOpenXLS (.xls (BIFF8)) <OpenXLS> (experimental):\n'); end %if + % Try Java & OpenXLS + if (dbug > 1), fprintf ('\nOpenXLS (.xls (BIFF8)) <OpenXLS>:\n'); end %if jpchk = 0; entries6 = {'OpenXLS'}; missing6 = zeros (1, numel (entries3)); for jj=1:length (entries6) found = 0; for ii=1:length (jcp) - if (strfind (lower (jcp{ii}), lower (entries6{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries6{jj})))) jpchk = jpchk + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end % if @@ -234,9 +296,8 @@ missing6(jj) = 1; end %if end %for - retval = jpchk > 0; if (dbug > 1) - if (jpchk > 0) + if (jpchk >= numel (entries6)) fprintf (' => Java/OpenXLS (OXS) OK.\n'); retval = 1; else @@ -253,7 +314,9 @@ for jj=1:length (entries4) found = 0; for ii=1:length (jcp) - if (strfind ( lower (jcp{ii}), lower (entries4{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind ( lower (jcpentry), lower (entries4{jj})))) jpchk = jpchk + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end %if @@ -263,7 +326,7 @@ missing4(jj) = 1; end %if end %for - if (jpchk >= 2) % Apparently all requested classes present. + if (jpchk >= numel (entries4)) % Apparently all requested classes present. % Only now we can check for proper odfdom version (only 0.7.5 & 0.8.6 work OK). % The odfdom team deemed it necessary to change the version call so we need this: odfvsn = ' '; @@ -274,8 +337,8 @@ % Worked in 0.7.5 odfvsn = javaMethod ('getApplicationVersion', 'org.odftoolkit.odfdom.Version'); end %try_catch - if ~(strcmp (odfvsn, '0.7.5') || strcmp (odfvsn, '0.8.6') || strcmp (odfvsn, '0.8.7')) - warning (' *** odfdom version (%s) is not supported - use v. 0.7.5, or 0.8.6+.\n', odfvsn); + if ~(strcmp (odfvsn, '0.7.5') || strcmp (odfvsn, '0.8.6')) + warning (' *** odfdom version (%s) is not supported - use v. 0.7.5 or 0.8.6.\n', odfvsn); else if (dbug > 1), fprintf (' => ODFtoolkit (OTK) OK.\n'); end %if retval = 1; @@ -290,7 +353,9 @@ for jj=1:length (entries5) found = 0; for ii=1:length (jcp) - if (strfind (lower (jcp{ii}), lower (entries5{jj}))) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries5{jj})))) jpchk = jpchk + 1; found = 1; if (dbug > 2), fprintf (' - %s OK\n', jcp{ii}); end %if end %if @@ -300,15 +365,106 @@ missing5(jj) = 1; end %if end %for - retval = jpchk >= 1; if (dbug > 1) - if (jpchk >= 1) + if (jpchk >= numel(entries5)) fprintf (' => jOpenDocument (JOD) OK.\n'); + retval = 1; else fprintf (' => Not all required classes (.jar) in classpath for JOD\n'); end %if end %if + # If requested, try to add UNO stuff to javaclasspath + ujars_complete = isempty (find (missing0)); + if (dbug > 1) + if (ujars_complete) + fprintf ('UNO bridge (OpenOffice.org) supported.\n\n'); + else + fprintf ('Some UNO class libs lacking yet...\n\n'); + end %if + end %if + + if (~ujars_complete && nargin > 0 && ~isempty (path_to_ooo)) + if (dbug), fprintf ('Trying to add missing UNO java class libs to javaclasspath...\n'); end %if + if (~ischar (path_to_jars)), error ('Path expected for arg # 1'); end %if + % Add missing jars to javaclasspath. First combine all entries + targt = sum (missing0); + if (missing0(1)) + # Add program dir (= where soffice or soffice.exe or ooffice resides) + programdir = [path_to_ooo filesep entries0{1}]; + if (fexist (programdir, 'd')) + if (dbug > 2), fprintf (' Found %s, adding it to javaclasspath ... ', programdir); end %if + try + javaaddpath (programdir); + targt = targt - 1; + if (dbug > 2), fprintf ('OK\n'); end %if + catch + if (dbug > 2), fprintf ('FAILED\n'); end %if + end% try_catch + else + if (dbug > 2), fprintf (' ? %s directory ?\n', entries0{1}); end %if + end %if + end %if + % Rest of missing entries. Find where URE is located + uredirlst = dir ([path_to_ooo]); + jj = 1; + while (jj < size (uredirlst, 1) && jj > 0) + uredir = uredirlst(jj).name; + if (uredirlst(jj).isdir && ~isempty (strfind (lower (uredirlst(jj).name), 'ure'))) + uredir = uredirlst(jj).name; + jj = 0; + else + ++jj; + endif + endwhile + # Now search for UNO jars + for ii=2:length (entries0) + if (missing0(ii)) + if (ii == 2) + # Special case as unoil.jar usuaally resides in ./Basis.../program/classes + # Find out the exact name of Basis..... + basisdirlst = dir ([path_to_ooo filesep 'basis' '*']); + jj = 1; + while (jj < size (basisdirlst, 1) && jj > 0) + # basisdir = basisdirlst(jj).name; + if (basisdirlst(jj).isdir) + basisdir = basisdirlst(jj).name; + jj = 0; + else + ++jj; + endif + endwhile + unojarpath = [ path_to_ooo filesep basisdir filesep 'program' filesep 'classes' filesep ] + file = dir ([ unojarpath entries0{ii} '*' ]); + else + # Rest of jars in ./ure/share/java (case not sure) + unojarpath = [ path_to_ooo filesep uredir filesep 'java' filesep ]; + file = dir ([unojarpath entries0{ii} '*']); + end %if + if (isempty (file)) + if (dbug > 2), fprintf (' ? %s<...>.jar ?\n', entries0{ii}); end %if + else + if (dbug > 2), fprintf (' Found %s, adding it to javaclasspath ... ', file.name); end %if + try + javaaddpath ([unojarpath file.name]); + targt = targt - 1; + if (dbug > 2), fprintf ('OK\n'); end %if + catch + if (dbug > 2), fprintf ('FAILED\n'); end %if + end %try_catch + end %if + end %if + end %for + if (dbug) + if (targt) + fprintf ('Some class libs still lacking...\n\n'); + else + fprintf ('All interfaces fully supported.now.\n\n'); + retval = 1; + end %f + end %if + + # Rest of Java interfaces missing = [missing1 missing2 missing3 missing4 missing5 missing6]; jars_complete = isempty (find (missing)); if (dbug) @@ -319,7 +475,7 @@ end %if end %if - if (~jars_complete && nargin > 0) + if (~jars_complete && nargin > 0 && ~isempty (path_to_jars)) if (dbug), fprintf ('Trying to add missing java class libs to javaclasspath...\n'); end %if if (~ischar (path_to_jars)), error ('Path expected for arg # 1'); end %if % Add missing jars to javaclasspath. First combine all entries @@ -330,15 +486,16 @@ if (missing(ii)) file = dir ([path_to_jars filesep entries{ii} '*']); if (isempty (file)) - if (dbug > 2), fprintf ('\n'); end %if + if (dbug > 2), fprintf (' ? %s<...>.jar ?\n', entries{ii}); end %if else - if (dbug > 2), fprintf (' Found %s, adding it to javaclasspath\n', file.name); end %if + if (dbug > 2), fprintf (' Found %s, adding it to javaclasspath ... ', file.name); end %if try javaaddpath ([path_to_jars filesep file.name]); targt = targt - 1; + if (dbug > 2), fprintf ('OK\n'); end %if catch - if (dbug > 2), fprintf ('\n'); end %if - end_try_catch + if (dbug > 2), fprintf ('FAILED\n'); end %if + end% try_catch end %if end %if end %for @@ -348,6 +505,7 @@ else fprintf ('All interfaces fully supported.now.\n\n'); retval = 1; + end %if end %f end %if Modified: trunk/octave-forge/main/io/inst/odsclose.m =================================================================== --- trunk/octave-forge/main/io/inst/odsclose.m 2011-05-06 12:24:17 UTC (rev 8245) +++ trunk/octave-forge/main/io/inst/odsclose.m 2011-05-06 14:38:58 UTC (rev 8246) @@ -1,4 +1,4 @@ -## Copyright (C) 2009,2010 Philip Nienhuis <prnienhuis at users.sf.net> +## Copyright (C) 2009,2010,2011 Philip Nienhuis <prnienhuis at users.sf.net> ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -28,6 +28,9 @@ ## You need the Java package > 1.2.6 plus odfdom.jar + xercesImpl.jar ## and/or jopendocument-<version>.jar installed on your computer + ## proper javaclasspath set, to make this function work at all. +## For UNO support, Octave-Java package 1.2.8 + latest fixes is imperative; +## furthermore the relevant classes had best be added to the javaclasspath by +## utility function chk_spreadsheet_support(). ## ## @var{ods} must be a valid pointer struct made by odsopen() in the same ## octave session. @@ -53,6 +56,8 @@ ## 2010-10-27 Improved file change tracking tru ods.changed ## 2010-11-12 Keep ods file pointer when write errors occur. ## " Added optional filename arg to change filename to be written to +## 2011-05-06 Experimental UNO support +## 2011-05-07 Soffice now properly closed using xDesk function [ ods ] = odsclose (ods, filename=[]) @@ -95,6 +100,39 @@ catch end_try_catch + elseif (strcmp (ods.xtype, 'UNO')) + # Java & UNO bridge + try + if (ods.changed && ods.changed < 3) +keyboard + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel'); + xModel = ods.workbook.queryInterface (unotmp); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XModifiable'); + xModified = xModel.queryInterface (unotmp); + if (xModified.isModified ()) + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XStorable'); # isReadonly() ? + xStore = ods.app.queryInterface (unotmp); + xStore.store; # storeAsURL ? + endif + endif + ods.changed = -1; # Needed for check op properly shutting down OOo + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel'); + xModel = ods.app.xComp.queryInterface (unotmp); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XCloseable'); + xClosbl = xModel.queryInterface (unotmp); + xClosbl.close (true); + # xModel.dispose(); # Is this needed? Consistently gives com.sun.star.lang.DisposedException + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XDesktop'); + xDesk = ods.app.aLoader.queryInterface (unotmp); + xDesk.terminate(); + ods.changed = 0; + catch + warning ("Error closing ods pointer (UNO)"); + return + end_try_catch + # elseif ---- < Other interfaces here > else Modified: trunk/octave-forge/main/io/inst/odsopen.m =================================================================== --- trunk/octave-forge/main/io/inst/odsopen.m 2011-05-06 12:24:17 UTC (rev 8245) +++ trunk/octave-forge/main/io/inst/odsopen.m 2011-05-06 14:38:58 UTC (rev 8246) @@ -1,4 +1,4 @@ -## Copyright (C) 2009,2010 Philip Nienhuis <prnienhuis at users.sf.net> +## Copyright (C) 2009,2010,2011 Philip Nienhuis <prnienhuis at users.sf.net> ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ ## @deftypefnx {Function File} @var{ods} = odsopen (@var{filename}, @var{readwrite}) ## @deftypefnx {Function File} @var{ods} = odsopen (@var{filename}, @var{readwrite}, @var{reqintf}) ## Get a pointer to an OpenOffice_org spreadsheet in the form of return -## argument (file pointer struct) @var{ods}. +## argument @var{ods}. ## ## Calling odsopen without specifying a return argument is fairly useless! ## @@ -28,6 +28,9 @@ ## installed on your computer + proper javaclasspath set. These interfaces are ## referred to as OTK and JOD, resp., and are preferred in that order by default ## (depending on their presence). +## For (currently experimental) UNO support, Octave-Java package 1.2.8 + latest +## fixes is imperative; furthermore the relevant classes had best be added to +## the javaclasspath by utility function chk_spreadsheet_support(). ## ## @var{filename} must be a valid .ods OpenOffice.org file name including ## .ods suffix. If @var{filename} does not contain any directory path, @@ -76,15 +79,15 @@ ## 2010-10-27 Improved tracking of file changes tru ods.changed ## 2010-11-12 Small changes to help text ## " Added try-catch to file open sections to create fallback to other intf -## 2010-12-06 Textual changes to info header +## 2011-05-06 Experimental UNO support ## -## Latest change on subfunction below: 2011-02-15 +## Latest change on subfunction below: 2011-05-06 function [ ods ] = odsopen (filename, rw=0, reqinterface=[]) persistent odsinterfaces; persistent chkintf; if (isempty (chkintf)) - odsinterfaces = struct ( "OTK", [], "JOD", [] ); + odsinterfaces = struct ( "OTK", [], "JOD", [], "UNO", [] ); chkintf = 1; endif @@ -99,10 +102,13 @@ # is supported anyway by emptying the corresponding var. if (strcmp (tolower (reqinterface), tolower ('OTK'))) printf ("Java/ODFtoolkit interface requested... "); - odsinterfaces.OTK = []; odsinterfaces.JOD = 0; + odsinterfaces.OTK = []; odsinterfaces.JOD = 0; odsinterfaces.UNO = 0; elseif (strcmp (tolower (reqinterface), tolower ('JOD'))) printf ("Java/jOpenDocument interface requested... "); - odsinterfaces.OTK = 0; odsinterfaces.JOD = []; + odsinterfaces.OTK = 0; odsinterfaces.JOD = []; odsinterfaces.UNO = 0; + elseif (strcmp (tolower (reqinterface), tolower ('UNO'))) + printf ("Java/UNO bridge interface requested... "); + odsinterfaces.OTK = 0; odsinterfaces.JOD = 0; odsinterfaces.UNO = []; else usage (sprintf ("Unknown .ods interface \"%s\" requested. Only OTK or JOD supported", reqinterface)); endif @@ -181,7 +187,7 @@ ods.odfvsn = odsinterfaces.odfvsn; odssupport += 1; catch - if (odsinterfaces.JOD && ~rw && chk2) + if (xlsinterfaces.JOD && ~rw && chk2) printf ('Couldn''t open file %s using OTK; trying .sxc format with JOD...\n', filename); else error ('Couldn''t open file %s using OTK', filename); @@ -223,6 +229,38 @@ end_try_catch endif + if (odsinterfaces.UNO && ~odssupport) + # First the file name must be transformed into a URL + filename = 'file:///c:/Home/philip/MyDocs/octave/spreadsheet-tst/foo3_.ods'; + try + xContext = java_invoke ("com.sun.star.comp.helper.Bootstrap", "bootstrap") + xMCF = xContext.getServiceManager () + oDesktop = xMCF.createInstanceWithContext ("com.sun.star.frame.Desktop", xContext); + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XComponentLoader'); + aLoader = oDesktop.queryInterface (unotmp); + # Some trickery as Octave Java cannot create non-numeric arrays + lProps = javaArray ('com.sun.star.beans.PropertyValue', 1); + lProp = java_new ('com.sun.star.beans.PropertyValue', "Hidden", 0, true, []); + lProps(1) = lProp; + # save in ods struct: + xComp = aLoader.loadComponentFromURL (filename, "_blank", 0, lProps); + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XSpreadsheetDocument'); + # save in ods struct: + xSpdoc = xComp.queryInterface (unotmp); + ods.workbook = xSpdoc; # Needed to be able to close soffice in odsclose() + ods.filename = filename; + ods.xtype = 'UNO'; + ods.app.xComp = xComp; # Needed to be able to close soffice in odsclose() + ods.app.aLoader = aLoader; # Needed to be able to close soffice in odsclose() + ods.odfvsn = 'UNO'; + odssupport += 4; + catch + error ('Couldn''t open file %s using UNO', filename); + end_try_catch + endif + # if # <other interfaces here> @@ -249,7 +287,7 @@ endfunction -## Copyright (C) 2009,2010 Philip Nienhuis <prnienhuis at users.sf.net> +## Copyright (C) 2009,2010,2011 Philip Nienhuis <prnienhuis at users.sf.net> ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -277,6 +315,7 @@ ## Currently implemented interfaces comprise: ## - Java & ODFtoolkit (www.apache.org) ## - Java & jOpenDocument (www.jopendocument.org) +## - Java & UNO bridge (OpenOffice.org) ## ## Examples: ## @@ -301,7 +340,8 @@ ## " Rearranged code a bit; fixed typos in OTK detection code (odfdvsn -> odfvsn) ## 2010-09-27 More code cleanup ## 2010-11-12 Warning added about waning support for odfdom v. 0.7.5 -## 2011-02-15 Adapted to new java-1.2.8 javaclasspath() calling style +## 2011-05-06 Fixed wrong strfind tests +## " Experimental UNO support added function [odsinterfaces] = getodsinterfaces (odsinterfaces) @@ -314,26 +354,51 @@ # Check Java support try - tmp1 = javaclasspath ('-all'); # For java pkg > 1.2.7 - if (isempty (tmp1)), tmp1 = javaclasspath; endif # For java pkg < 1.2.8 + jcp = javaclasspath; # If we get here, at least Java works. Now check for proper entries # in class path. Under *nix the classpath must first be split up - if (isunix) tmp1 = strsplit (char(tmp1), ":"); endif + if (isunix) jcp = strsplit (char(tmp1), ":"); endif ## FIXME implement more rigid Java version check a la xlsopen. ## ods / Java stuff is less critical than xls / Java, however catch # No Java support - odsinterfaces.OTK = 0; - odsinterfaces.JOD = 0; - if ~(isempty (odsinterfaces.POI) && isempty (odsinterfaces.JXL)) + if ~(isempty (odsinterfaces.OTK) && isempty (odsinterfaces.JOD)) # Some Java-based interface requested but Java support is absent error ('No Java support found.'); else # No specific Java-based interface requested. Just return return; endif + odsinterfaces.OTK = 0; + odsinterfaces.JOD = 0; + odsinterfaces.UNO = 0; end_try_catch + # Try Java & UNO + if (isempty (odsinterfaces.UNO)) + # entries0(1) = not a jar but a directory (<000_install_dir/program/>) + jpchk = 0; entries = {'program', 'unoil', 'jurt', 'juh', 'unoloader', 'ridl'}; + # Only under *nix we might use brute force: e.g., strfind (javaclasspath, classname) + # as javaclasspath is one long string. Under Windows however classpath is a cell array + # so we need the following more subtle, platform-independent approach: + for jj=1:numel (entries) + for ii=1:numel (jcp) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries{jj})))) + jpchk = jpchk + 1; + endif + endfor + endfor + if (jpchk >= numel (entries)) + odsinterfaces.UNO = 1; + fprintf (' => UNO (OOo) OK\n'); + chk1 = 1; + else + warning ('\nOne or more UNO classes (.jar) missing in javaclasspath'); + endif + endif + # Try Java & ODF toolkit if (isempty (odsinterfaces.OTK)) odsinterfaces.OTK = 0; @@ -342,10 +407,10 @@ # under Windows we need the following more subtle, platform-independent approach: for ii=1:length (tmp1) for jj=1:length (entries) - if (strfind ( tmp1{ii}, entries{jj})), ++jpchk; endif + if (~isempty (strfind ( tmp1{ii}, entries{jj}))), ++jpchk; endif endfor endfor - if (jpchk >= 2) # Apparently all requested classes present. + if (jpchk >= numel(entries)) # Apparently all requested classes present. # Only now we can check for proper odfdom version (only 0.7.5 & 0.8.6 work OK). # The odfdom team deemed it necessary to change the version call so we need this: odfvsn = ' '; @@ -377,10 +442,10 @@ jpchk = 0; entries = {"jOpenDocument"}; for ii=1:length (tmp1) for jj=1:length (entries) - if (strfind (tmp1{ii}, entries{jj})), ++jpchk; endif + if (~isempty (strfind (tmp1{ii}, entries{jj}))), ++jpchk; endif endfor endfor - if (jpchk >= 1) + if (jpchk >= numel(entries)) odsinterfaces.JOD = 1; printf (" Java/jOpenDocument (JOD) OK. "); chk1 = 1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |