changeset 11283:58f175d39a7a

GUI file functions
author Kai Habel <kai.habel@gmx.de>
date Sun, 21 Nov 2010 14:25:32 +0100
parents acebc0e675c1
children b9bc32327c4d
files ChangeLog NEWS scripts/ChangeLog scripts/miscellaneous/unimplemented.m scripts/plot/module.mk scripts/plot/private/__fltk_file_filter__.m scripts/plot/uigetdir.m scripts/plot/uigetfile.m scripts/plot/uiputfile.m src/ChangeLog src/DLD-FUNCTIONS/fltk_backend.cc src/graphics.cc
diffstat 12 files changed, 516 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Nov 20 16:33:14 2010 -0800
+++ b/ChangeLog	Sun Nov 21 14:25:32 2010 +0100
@@ -1,3 +1,7 @@
+2010-11-21  Kai Habel  <kai.habel@gmx.de>
+
+	* NEWS: Add uigetdir, uigetfile, uiputfile.
+
 2010-11-19  John W. Eaton  <jwe@octave.org>
 
 	* Makefile.am (bin_SCRIPTS): Remove run-octave from the list.
--- a/NEWS	Sat Nov 20 16:33:14 2010 -0800
+++ b/NEWS	Sun Nov 21 14:25:32 2010 +0100
@@ -313,13 +313,15 @@
 
   ** The following functions are new in Octave 3.4:
 
-       accumdim   erfcx        luupdate     ppder      rsf2csf
-       bitpack    fileread     merge        ppint      saveas
-       bitunpack  fminbnd      nfields      ppjumps    sizemax
-       blkmm      fskipl       nth_element  pqpnonneg  strread
-       cbrt       ifelse       onCleanup    randi      textread
-       chop       ishermitian  pbaspect     repelems   uimenu
-       daspect    isindex      powerset     reset      whitebg
+       accumdim   fileread     nfields      pqpnonneg  textread
+       bitpack    fminbnd      nth_element  randi      uigetdir
+       bitunpack  fskipl       onCleanup    repelems   uigetfile
+       blkmm      ifelse       pbaspect     reset      uiputfile
+       cbrt       ishermitian  powerset     rsf2csf    uimenu
+       chop       isindex      ppder        saveas     whitebg
+       daspect    luupdate     ppint        sizemax    
+       erfcx      merge        ppjumps      strread    
+
 
   ** Using the image function to view images with external programs such
      as display, xv, and xloadimage is no longer supported.  The
--- a/scripts/ChangeLog	Sat Nov 20 16:33:14 2010 -0800
+++ b/scripts/ChangeLog	Sun Nov 21 14:25:32 2010 +0100
@@ -1,3 +1,9 @@
+2010-11-21  Kai Habel  <kai.habel@gmx.de>
+
+	* (plot/uigetdir.m, plot/uigetfile.m, plot/uiputfile.m, 
+ plot/private/__fltk_file_filter__.m): New files.
+	* plot/module.mk: Add new files
+
 2010-11-20  Rik  <octave@nomad.inbox5.com>
 
 	* plot/gnuplot_drawnow.m: Remove spurious line causing 'ans=1' to be
--- a/scripts/miscellaneous/unimplemented.m	Sat Nov 20 16:33:14 2010 -0800
+++ b/scripts/miscellaneous/unimplemented.m	Sun Nov 21 14:25:32 2010 +0100
@@ -385,15 +385,12 @@
   "tstool", 
   "uibuttongroup", 
   "uicontextmenu", 
-  "uicontrol", 
-  "uigetdir", 
-  "uigetfile", 
+  "uicontrol",  
   "uigetpref", 
   "uiimport", 
   "uiopen", 
   "uipanel", 
   "uipushtool", 
-  "uiputfile", 
   "uiresume", 
   "uisave", 
   "uisetcolor", 
--- a/scripts/plot/module.mk	Sat Nov 20 16:33:14 2010 -0800
+++ b/scripts/plot/module.mk	Sun Nov 21 14:25:32 2010 +0100
@@ -18,6 +18,7 @@
   plot/private/__errcomm__.m \
   plot/private/__errplot__.m \
   plot/private/__ezplot__.m \
+  plot/private/__fltk_file_filter__.m \
   plot/private/__ghostscript__.m \
   plot/private/__gnuplot_has_terminal__.m\
   plot/private/__interp_cube__.m \
@@ -163,6 +164,9 @@
   plot/surfnorm.m \
   plot/text.m \
   plot/title.m \
+  plot/uigetdir.m \
+  plot/uigetfile.m \
+  plot/uiputfile.m \
   plot/uimenu.m \
   plot/view.m \
   plot/waitforbuttonpress.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/private/__fltk_file_filter__.m	Sun Nov 21 14:25:32 2010 +0100
@@ -0,0 +1,70 @@
+## Copyright (C) 2010 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __fltk_file_filter__ (@var{file_filter})
+## Undocumented internal function.
+## @end deftypefn
+
+## Author: Kai Habel
+
+function retval = __fltk_file_filter__ (file_filter)
+  # converts octave's file filter format into fltk's.
+  if (iscell (file_filter))
+    [r, c] = size (file_filter);
+    if ((c == 0) || (c > 2))
+      error ("expecting 1 or to 2 columns for file filter cell.");
+    endif
+    fltk_str = "";
+    for idx = 1 : r
+
+      curr_ext = file_filter{idx, 1};                    
+      curr_ext = strsplit (curr_ext, ";");
+
+      if (length (curr_ext) > 1)
+        curr_ext = regexprep (curr_ext, '\*\.', ',');
+        curr_ext = strcat (curr_ext{:})(2 : end);
+        curr_ext = strcat ("*.{", curr_ext, "}");
+      else
+        curr_ext = curr_ext{:};
+      endif
+
+      curr_desc = strcat (curr_ext(3:end), "-Files");
+
+      if (c == 2)
+        curr_desc = file_filter{idx, 2};
+        curr_desc = regexprep (curr_desc, '\(', '<');
+        curr_desc = regexprep (curr_desc, '\)', '>');
+      endif
+
+      if (length (fltk_str) > 0)
+        fltk_str = strcat (fltk_str, "\t", curr_desc, " (", curr_ext, ")");
+      else
+        fltk_str = strcat (curr_desc, " (", curr_ext, ")");
+      endif
+
+    endfor
+    retval = fltk_str;
+  elseif (ischar (file_filter))
+    outargs{3} = file_filter;
+    [fdir, fname, fext] = fileparts (file_filter);
+    if (length (fext) > 0)
+      retval = strcat ("*", fext, "\t*");
+    endif
+  endif  
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/uigetdir.m	Sun Nov 21 14:25:32 2010 +0100
@@ -0,0 +1,50 @@
+## Copyright (C) 2010 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{dirname} =} uigetdir (@var{init_path}, @var{dialog_name})
+## @deftypefnx {Function File} {@var{dirname} =} uigetdir (@var{init_path})
+## @deftypefnx {Function File} {@var{dirname} =} uigetdir ()
+## Open a GUI dialog to select a directory. If @var{init_path} is not given
+## the working directory is taken. @var{dialog_name} can be used to
+## customize the dialog title.
+## @end deftypefn
+
+## Author: Kai Habel
+
+function [retdir] = uigetdir (init_path = pwd, name = "Choose directory?")
+
+  if (!ischar(init_path) || !ischar(name))
+    error ("Expecting string arguments.");
+  endif
+  
+  if (nargin > 2)
+    print_usage ();
+  endif
+
+  if (any (cellfun(@(x)strcmp (x, "fltk"), available_backends)))
+      init_path = fileparts (init_path);
+      retdir = __fltk_uigetfile__ ("", name, init_path, [240, 120], "dir");
+  else
+    error ("uigetdir requires fltk backend.");
+  endif
+
+endfunction
+
+%!demo 
+%! uigetdir(pwd, "Select Directory")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/uigetfile.m	Sun Nov 21 14:25:32 2010 +0100
@@ -0,0 +1,161 @@
+## Copyright (C) 2010 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uigetfile (@var{flt})
+## @deftypefnx  {Function File} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}, @var{default_file})
+## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name})
+## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@dots{},"Position",[@var{px}, @var{py}])
+## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@dots{},"Multiselect",@var{mode})
+##
+## Open a GUI dialog to select a file. It returns the filename @var{fname},
+## the path to this file @var{fpath} and the filter index @var{fltidx}.
+## @var{flt} contains a (list of) file filter string(s) in one of the following
+## formats:
+##
+## @table @code
+## @item "/path/to/filename.ext"
+## If a filename is given the file extension is extracted and used as filter.
+## In addtion the path is selected as current path and the filname is selected
+## as default file.
+## Example: uigetfile("myfun.m");
+##
+## @item A single file extension "*.ext". 
+## Example: uigetfile("*.ext");
+##
+## @item A 2-column cell array,
+## containing the file extension in the 1st column and a brief description
+## in the 2nd column.
+## Example: uigetfile(@{"*.ext","My Description";"*.xyz","XYZ-Format"@});
+## 
+## The filter string can also contain a semicolon separated list of filter
+## extensions.
+## Example: uigetfile(@{"*.gif;*.png;*.jpg", "Supported Picture Formats"@});
+## @end table
+##
+## @var{dialog_name} can be used to customize the dialog title.
+## If @var{default_file} is given it is selected in the GUI dialog. 
+## If in addtion a path is given it is also used as current path.
+## 
+## The screen position of the GUI dialog can be set by using the "Position" key
+## and a 2-valued vector containing the pixel coordinates.
+## Two or more files can be selected when setting the "Multiselect" key to "on".
+## In that case @var{fname} is a cell array containing the files. 
+## @end deftypefn
+
+## Author: Kai Habel
+
+function [retfile, retpath, retindex] = uigetfile (varargin)
+
+  if (nargin <= 7)
+
+    defaultvals = {"All Files(*)", #FLTK File Filter
+                   "Open File?",   #Dialog Title
+                   "",             #FLTK default file name
+                   [240, 120],     #Dialog Position (pixel x/y)
+                   "off"};         #Multiselect on/off
+
+    outargs = cell (5, 1);
+    for i = 1 : 5
+      outargs{i} = defaultvals{i};
+    endfor
+
+    idx1 = idx2 = [];
+    if (length (varargin) > 0)
+      for i = 1 : length (varargin)
+        val = varargin{i};
+        if (ischar (val))
+          if (strncmp (tolower (val), "multiselect", 11))
+            idx1 = i;
+          elseif (strncmp(tolower (val), "position", 8))
+            idx2 = i;
+          endif
+        endif
+      endfor
+    endif
+
+    stridx = [idx1, idx2, 0];
+    if (length (stridx) > 1)
+      stridx = min (stridx(1 : end - 1));
+    endif
+
+    args = varargin;
+    if (stridx)
+      args = varargin(1 : stridx - 1);
+    endif
+
+    len = length (args);
+    if (len > 0)
+      file_filter = args{1};
+      outargs{1} = __fltk_file_filter__ (file_filter);
+      if (ischar (file_filter))
+        outargs{3} = file_filter;
+      endif
+    endif
+    
+    if (len > 1)
+      outargs{2} = args{2};
+    endif
+
+    if (len > 2)
+      outargs{3} = args{3};
+    endif
+
+    if (stridx)
+      ## we have string arguments ("position" or "multiselect")
+
+      ## check for even number of remaining arguments, prop/value pair(s)
+      if (rem (nargin - stridx + 1, 2))
+        error ("expecting property/value pairs");
+      endif
+
+      for i = stridx : 2 : nargin
+        prop = varargin{i};
+        val = varargin{i + 1};
+        if (strncmp (tolower (prop), "position", 8)) 
+          if (ismatrix (val) && length(val) == 2)
+            outargs{4} = val;
+          else
+            error ("expecting 2-element vector for position argument")
+          endif
+        elseif (strncmp (tolower (prop), "multiselect", 11))
+          if (ischar (val))
+            outargs{5} = tolower (val);
+          else
+            error ("expecting string argument (on/off) for multiselect")
+          endif
+        else
+          error ("unknown argument");
+        endif
+      endfor
+    endif
+  else
+    error ("number of input arguments must be less than eight");
+  endif
+
+  if (any (cellfun(@(x)strcmp (x, "fltk"), available_backends)))
+    [retfile, retpath, retindex] = __fltk_uigetfile__ (outargs{:});  
+  else
+    error ("uigetfile requires fltk backend.");
+  endif
+
+         
+endfunction
+
+%!demo 
+%! uigetfile({"*.gif;*.png;*.jpg", "Supported Picture Formats"})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/uiputfile.m	Sun Nov 21 14:25:32 2010 +0100
@@ -0,0 +1,101 @@
+## Copyright (C) 2010 Kai Habel
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt}, @var{dialog_name}, @var{default_file})
+## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt}, @var{dialog_name})
+## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt})
+## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile ())
+## Open a GUI dialog to select a file. @var{flt} contains a (list of) file
+## filter string(s) in one of the following formats:
+##
+## @table @code
+## @item "/path/to/filename.ext"
+## If a filename is given the file extension is 
+## extracted and used as filter.
+## In addtion the path is selected as current path and the filname is selected
+## as default file.
+## Example: uiputfile("myfun.m");
+##
+## @item "*.ext"
+## A single file extension. 
+## Example: uiputfile("*.ext");
+##
+## @item @{"*.ext","My Description"@}
+## A 2-column cell array containing the file extension in the 1st column and
+## a brief description in the 2nd column.
+## Example: uiputfile(@{"*.ext","My Description";"*.xyz","XYZ-Format"@});
+## @end table
+## 
+## The filter string can also contain a semicolon separated list of filter
+## extensions.
+## Example: uiputfile(@{"*.gif;*.png;*.jpg", "Supported Picture Formats"@});
+##
+## @var{dialog_name} can be used to customize the dialog title.
+## If @var{default_file} is given it is preselected in the GUI dialog. 
+## If in addtion a path is given it is also used as current path.
+## @end deftypefn
+
+## Author: Kai Habel
+
+function [retfile, retpath, retindex] = uiputfile (varargin)
+
+
+  if (nargin <= 3)
+
+    defaultvals = {"All Files(*)", #FLTK File Filter
+                   "Save File?",   #Dialog Title
+                   "",             #FLTK default file name
+                   [240, 120],     #Dialog Position (pixel x/y)
+                   "create"};
+
+    outargs = cell(5, 1);
+    for i = 1 : 5
+      outargs{i} = defaultvals{i};
+    endfor
+
+    if (nargin > 0)
+      file_filter = varargin{1};
+      outargs{1} = __fltk_file_filter__ (file_filter);
+      if (ischar (file_filter))
+        outargs{3} = file_filter;
+      endif
+    endif
+    
+    if (nargin > 1)
+      outargs{2} = varargin{2};
+    endif
+
+    if (nargin > 2)
+      outargs{3} = varargin{3};
+    endif
+
+  else
+    error ("Number of input arguments must be less than four.");
+  endif
+
+  if (any (cellfun(@(x)strcmp (x, "fltk"), available_backends)))
+    [retfile, retpath, retindex] = __fltk_uigetfile__ (outargs{:});  
+  else
+    error ("uiputfile requires fltk backend.");
+  endif
+
+endfunction
+
+%!demo 
+%! uiputfile({"*.gif;*.png;*.jpg", "Supported Picture Formats"})
--- a/src/ChangeLog	Sat Nov 20 16:33:14 2010 -0800
+++ b/src/ChangeLog	Sun Nov 21 14:25:32 2010 +0100
@@ -1,3 +1,9 @@
+2010-11-21  Kai Habel  <kai.habel@gmx.de>
+
+	* DLD-FUNCTIONS/fltk-backend.cc (__fltk_uigetfile__): New function
+	for GUI file dialogs. graphics.cc (property_list::set): Indentation
+	fix.
+
 2010-11-20  Ben Abbott <bpabbott@mac.com>
 
 	* graphics.h.in: Change intended for 11272.
--- a/src/DLD-FUNCTIONS/fltk_backend.cc	Sat Nov 20 16:33:14 2010 -0800
+++ b/src/DLD-FUNCTIONS/fltk_backend.cc	Sun Nov 21 14:25:32 2010 +0100
@@ -44,11 +44,11 @@
 #include <FL/Fl_Box.H>
 #include <FL/Fl_Button.H>
 #include <FL/Fl_Choice.H>
+#include <Fl/Fl_File_Chooser.H>
 #include <FL/Fl_Gl_Window.H>
 #include <FL/Fl_Menu_Bar.H>
 #include <FL/Fl_Menu_Button.H>
 #include <FL/Fl_Output.H>
-#include <Fl/Fl_File_Chooser.H>
 #include <FL/Fl_Window.H>
 #include <FL/fl_ask.H>
 #include <FL/fl_draw.H>
@@ -1967,4 +1967,106 @@
   return retval;
 }
 
+#include "file-ops.h"
+DEFUN_DLD (__fltk_uigetfile__, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __fltk_uigetfile__ ([@var{...}])\n\
+Internal Function.\n\
+\n\
+\n\
+@end deftypefn")
+{
+  // This function should be called by uigetfile.m
+  // Error checking should be done in uigetfile.m!
+  //
+  // Expected argument list
+  // args(0) ... FileFilter in fltk format
+  // args(1) ... Title
+  // args(2) ... Default Filename
+  // args(3) ... PostionValue [x,y] 
+  // args(4) ... SelectValue "on"/"off"/"dir"/"create"
+  
+  std::string file_filter, title, default_name, multi;
+  if (args(0).is_string ())
+    file_filter = args(0).string_value();
+    
+  if (args(1).is_string ())
+    title = args(1).string_value();
+    
+  if (args(2).is_string ())
+    default_name = args(2).string_value();
+    
+  if (args(3).is_real_matrix ())
+    Matrix pos = args(3).matrix_value();
+    
+  int multi_type = Fl_File_Chooser::SINGLE;
+  std::string flabel = "Filename:";
+  if (args(4).is_string ())
+    {
+      multi = args(4).string_value();
+      if (multi == "on")
+        multi_type = Fl_File_Chooser::MULTI;
+      else if (multi == "dir")
+        {
+          multi_type = Fl_File_Chooser::DIRECTORY;
+          flabel = "Directory:";
+        }
+      else if (multi == "create")
+        multi_type = Fl_File_Chooser::CREATE;
+    }
+  
+  Fl_File_Chooser::filename_label = flabel.c_str ();  
+  Fl_File_Chooser *fc = new Fl_File_Chooser(default_name.c_str (), file_filter.c_str (), multi_type, title.c_str ());
+  fc->preview(0);
+  
+  if (multi_type == Fl_File_Chooser::CREATE)
+    fc->ok_label("Save");
+  
+  fc->show();
+  while (fc->shown ())
+        { Fl::wait (); }
+
+  octave_value_list fargs, retval;
+  
+  retval(0) = octave_value(0);
+  retval(1) = octave_value(0);
+  retval(2) = octave_value(0);
+  
+  if (fc->value() != NULL)
+    {
+      int file_count = fc->count ();
+      std::string fname;
+      std::string sep = file_ops::dir_sep_str ();
+      std::size_t idx;
+      
+      if ((file_count == 1) && (multi_type != Fl_File_Chooser::DIRECTORY))
+        {
+          fname = fc->value ();    
+          idx = fname.find_last_of(sep);
+          retval(0) = fname.substr(idx + 1);
+        }
+      else  
+        {
+          Cell file_cell = Cell(file_count, 1);
+          for (octave_idx_type n = 1; n <= file_count; n++)
+            {
+              fname = fc->value (n);    
+              idx = fname.find_last_of(sep);
+              file_cell(n - 1) = fname.substr(idx + 1);
+            }
+          retval(0) = file_cell;
+        }
+        
+      if (multi_type == Fl_File_Chooser::DIRECTORY)
+        retval(0) = std::string(fc->value ());
+      else
+        {
+          retval(1) = std::string(fc->directory ());
+          retval(2) = fc->filter_value();
+        }
+    }
+  
+  return retval;
+}
+
 #endif
--- a/src/graphics.cc	Sat Nov 20 16:33:14 2010 -0800
+++ b/src/graphics.cc	Sun Nov 21 14:25:32 2010 +0100
@@ -1490,7 +1490,7 @@
             has_property = surface::properties::has_core_property (pname);
           else if (pfx == "hggroup")
             has_property = hggroup::properties::has_core_property (pname);
-	  else if (pfx == "uimenu")
+          else if (pfx == "uimenu")
             has_property = uimenu::properties::has_core_property (pname);
 
           if (has_property)