1######################################################################## 2## 3## Copyright (C) 2010-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uigetfile () 28## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt}) 29## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}) 30## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}, @var{default_file}) 31## @deftypefnx {} {[@dots{}] =} uigetfile (@dots{}, "Position", [@var{px} @var{py}]) 32## @deftypefnx {} {[@dots{}] =} uigetfile (@dots{}, "MultiSelect", @var{mode}) 33## 34## Open a GUI dialog for selecting a file and return the filename @var{fname}, 35## the path to this file @var{fpath}, and the filter index @var{fltidx}. 36## 37## @var{flt} contains a (list of) file filter string(s) in one of the following 38## formats: 39## 40## @table @asis 41## @item @qcode{"/path/to/filename.ext"} 42## If a filename is given then the file extension is extracted and used as 43## filter. In addition, the path is selected as current path in the dialog and 44## the filename is selected as default file. 45## Example: @code{uigetfile ("myfun.m")} 46## 47## @item A single file extension @qcode{"*.ext"} 48## Example: @code{uigetfile ("*.ext")} 49## 50## @item A 2-column cell array 51## containing a file extension in the first column and a brief description in 52## the second column. 53## Example: @code{uigetfile (@{"*.ext", "My Description";"*.xyz", 54## "XYZ-Format"@})} 55## 56## The filter string can also contain a semicolon separated list of filter 57## extensions. 58## Example: @code{uigetfile (@{"*.gif;*.png;*.jpg", "Supported Picture 59## Formats"@})} 60## 61## @item A directory name or path name 62## If the folder name of path name contains a trailing file separator, the 63## contents of that folder will be displayed. If no trailing file separator 64## is present the parent directory is listed. The substring to the right of 65## the rightmost file separator (if any) will be interpreted as a file or 66## directory name and if that file or directory exists it will be highlighted. 67## If the path name or directory name is entirely or partly nonexistent, the 68## current working directory will be displayed. 69## No filter will be active. 70## @end table 71## 72## @var{dialog_name} can be used to customize the dialog title. 73## 74## If @var{default_file} is given then it will be selected in the GUI dialog. 75## If, in addition, a path is given it is also used as current path. 76## 77## The screen position of the GUI dialog can be set using the 78## @qcode{"Position"} key and a 2-element vector containing the pixel 79## coordinates. Two or more files can be selected when setting the 80## @qcode{"MultiSelect"} key to @qcode{"on"}. In that case @var{fname} is a 81## cell array containing the files. 82## 83## The outputs @var{fname} and @var{fpath} are strings returning the chosen 84## name and path, respectively. However, if the @samp{Cancel} button is 85## clicked the outputs are of type double with a value of @code{0}. 86## @var{fltidx} is the index in the list of filter extensions @var{flt} that 87## was selected. 88## 89## @seealso{uiputfile, uigetdir} 90## @end deftypefn 91 92function [retfile, retpath, retindex] = uigetfile (varargin) 93 94 if (nargin > 7) 95 error ("uigetfile: number of input arguments must be less than eight"); 96 endif 97 98 ## Preset default values 99 outargs = {cell(0, 2), # File Filter 100 "Open File", # Dialog Title 101 "", # Default filename 102 [240, 120], # Dialog Position (pixel x/y) 103 "off", # MultiSelect on/off 104 pwd}; # Default directory 105 106 idx1 = idx2 = []; 107 has_opts = false; 108 if (nargin > 0) 109 idx1 = find (strcmpi (varargin, "multiselect"), 1); 110 idx2 = find (strcmpi (varargin, "position"), 1); 111 if (idx1 || idx2) 112 has_opts = true; 113 endif 114 endif 115 116 optidx = min ([idx1, idx2, nargin+1]); 117 118 args = varargin(1:optidx-1); 119 120 len = numel (args); 121 if (len > 0) 122 [outargs{1}, outargs{3}, defdir] = __file_filter__ ("uigetfile", args{1}); 123 if (! isempty (defdir)) 124 outargs{6} = defdir; 125 endif 126 else 127 outargs{1} = __file_filter__ ("uigetfile", outargs{1}); 128 endif 129 130 if (len > 1) 131 if (ischar (args{2})) 132 if (! isempty (args{2})) 133 outargs{2} = args{2}; 134 endif 135 elseif (! isempty (args{2})) 136 print_usage (); 137 endif 138 endif 139 140 if (len > 2) 141 if (ischar (args{3})) 142 if (isfolder (args{3})) 143 fdir = args{3}; 144 fname = fext = ""; 145 else 146 [fdir, fname, fext] = fileparts (varargin{3}); 147 endif 148 if (! isempty (fdir)) 149 outargs{6} = fdir; 150 endif 151 if (! isempty (fname) || ! isempty (fext)) 152 outargs{3} = [fname fext]; 153 endif 154 elseif (! isempty (args{3})) 155 print_usage (); 156 endif 157 endif 158 159 if (has_opts) 160 ## string arguments ("position" or "multiselect") 161 162 ## check for even number of remaining arguments, prop/value pair(s) 163 if (rem (nargin - optidx + 1, 2)) 164 error ("uigetfile: PROPERTY/VALUE arguments must occur in pairs"); 165 endif 166 167 for i = optidx : 2 : nargin 168 prop = varargin{i}; 169 val = varargin{i + 1}; 170 if (strcmpi (prop, "position")) 171 if (! isnumeric (val) || length (val) != 2) 172 error ('uigetfile: "Position" must be a 2-element vector'); 173 endif 174 outargs{4} = val; 175 elseif (strcmpi (prop, "multiselect")) 176 if (! ischar (val)) 177 error ('uigetfile: MultiSelect value must be a string ("on"/"off")'); 178 endif 179 outargs{5} = tolower (val); 180 else 181 error ("uigetfile: unknown argument '%s'", prop); 182 endif 183 endfor 184 endif 185 186 if (__event_manager_enabled__ ()) 187 [retfile, retpath, retindex] = __event_manager_file_dialog__ (outargs{:}); 188 else 189 funcname = __get_funcname__ (mfilename ()); 190 [retfile, retpath, retindex] = feval (funcname, outargs{:}); 191 endif 192 193endfunction 194 195 196%!demo 197%! uigetfile ({'*.gif;*.png;*.jpg', 'Supported Picture Formats'}); 198 199## Remove from test statistics. No real tests possible. 200%!assert (1) 201