0001 function [s,mod] = imod_struct_jd(s,sname,d_opt,opt_gui,sextra,style)
0002
0003
0004
0005 if nargin < 6,
0006 style = struct;
0007 end
0008 if nargin < 5,
0009 sextra = struct;
0010 end
0011 if nargin < 4,
0012 opt_gui = false;
0013 end
0014 if nargin < 3,
0015 d_opt = 1;
0016 end
0017 if nargin < 2,
0018 sname = '';
0019 end
0020
0021 if length(s) ~= 1,
0022 error('This function applies only to (1,1) structures')
0023 end
0024
0025 if ~isfield(style,'fontname')
0026 style.fontname = 'fixedwidth';
0027 end
0028
0029 if ~isfield(style,'fontsize')
0030 style.fontsize = 10;
0031 end
0032
0033 if ~isfield(style,'titlefontsize')
0034 style.titlefontsize = 2*style.fontsize;
0035 end
0036
0037 fexcept = {'info','expert','values'};
0038
0039 for ifield = 1:length(fexcept),
0040 if isfield(s,fexcept{ifield}),
0041 s = rmfield(s,fexcept{ifield});
0042 end
0043 end
0044
0045 numlim = 10;
0046 ftsize = 10;
0047 if islogical(opt_gui) || ~ishandle(opt_gui) || opt_gui == 0,
0048 scsz = get(0,'screensize');
0049 else
0050 scsz = get(opt_gui,'position');
0051 end
0052
0053 margin = 50;
0054 nspaces = 1.5;
0055 lfactor = 1.0;
0056 lmaxmin = 18;
0057
0058 fnames_all = fieldnames(s);
0059 nf_all = length(fnames_all);
0060
0061 s = putinfo_yp(s,sname,fexcept);
0062
0063 s = conc_struct_jd(s,sextra);
0064
0065 expert = zeros(1,nf_all);
0066 for iname = 1:nf_all,
0067 expert(iname) = s.expert.(fnames_all{iname});
0068 end
0069
0070 nexplist = find(~expert);
0071 fnames_nexp = fnames_all(nexplist);
0072
0073 isel = NaN;
0074 mod = zeros(1,nf_all);
0075 expmode = 0;
0076
0077 sinit = s;
0078 sinitvalues = '';
0079 sinitstrings = '';
0080
0081 while isel ~= 0,
0082
0083 if expmode == 0,
0084 fnames = fnames_nexp;
0085 switchstr = 'Enter expert mode (more parameters).';
0086 guistr = 'expert fields';
0087 else
0088 fnames = fnames_all;
0089 switchstr = 'Leave expert mode (main parameters).';
0090 guistr = 'main fields';
0091 end
0092
0093 buttonstr = {guistr,['reset ',sname],['return ',sname]};
0094 isellist = [-2,-4,0];
0095
0096 nf = length(fnames);
0097
0098 lmax = lmaxmin;
0099
0100 for iname = 1:nf,
0101 lmax = max([lmax,length(fnames{iname})]);
0102 end
0103 emptstr = repmat(' ',[1,lmax]);
0104
0105 nmax = length(num2str(nf))+1;
0106 emptnstr = repmat(' ',[1,nmax]);
0107
0108 if ~opt_gui,
0109
0110 disp(' ');
0111 disp(['====> Fields of the structure ',sname]);
0112 disp(' ')
0113
0114 else
0115
0116 cwidth = 5*margin + 2*lfactor*lmax*ftsize;
0117 nfh = fix((scsz(4) - 2*margin)/(3*ftsize) - nspaces);
0118 ncl = ceil(max([nf,1])/nfh);
0119 width = cwidth*ncl;
0120
0121 if width > (scsz(3) - 2*margin),
0122 error('Too many fields... improve GUI!')
0123 end
0124
0125 nfh = ceil(nf/ncl);
0126 height = (nfh+nspaces)*3*ftsize;
0127
0128 cguipos = [(scsz(3) - width)/2,(scsz(4) - height)/2,width,height];
0129
0130 if islogical(opt_gui) || ~ishandle(opt_gui),
0131 cgui = figure('visible','on','name',sname,'Position',cguipos,'menubar','none','numbertitle','off','resize','off');
0132 else
0133 cguipos(4) = cguipos(4) + 2*ftsize + style.titlefontsize;
0134 cgui = uipanel('Parent',opt_gui,'Title',sname,'units','pixels','Position',cguipos,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.titlefontsize);
0135 end
0136
0137 cguis = zeros(1,nf);
0138 cguic = zeros(1,nf);
0139 cguir = zeros(1,nf+3);
0140
0141 end
0142
0143 stype = zeros(1,nf);
0144 rev = zeros(1,nf);
0145
0146 for iname = 1:nf,
0147 fname = fnames{iname};
0148 fval = s.(fname);
0149 values = s.values.(fname);
0150
0151 if islogical(fval) || (iscell(values) && length(values) == 2 && islogical(values{1})),
0152 stype(iname) = 0;
0153 if fval,
0154 sval = 'true';
0155 else
0156 sval = 'false';
0157 end
0158 if isempty(values),
0159 values = {true,false};
0160 end
0161 elseif ischar(fval),
0162 stype(iname) = 1;
0163 sval = fval;
0164 elseif isnumeric(fval),
0165
0166 valsize = size(fval);
0167 stype(iname) = 6;
0168
0169 if length(valsize) > 2 || min(valsize) > 1,
0170 sval = ['< ',num2str(length(valsize)),'-D array >'];
0171 elseif numel(fval) > numlim
0172 sval = ['< ',num2str(numel(fval)),' elements vector>'];
0173 else
0174 if valsize(1) > 1,
0175 rev(iname) = 1;
0176 fval = fval(:).';
0177 end
0178 stype(iname) = 2;
0179 sval = num2str(fval);
0180 if isempty(values),
0181 values = [-Inf;Inf];
0182 end
0183 end
0184
0185 elseif isstruct(fval),
0186 stype(iname) = 3;
0187 sval = '< fields structure >';
0188 elseif iscell(fval),
0189 stype(iname) = 4;
0190 sval = '< cell array >';
0191 else
0192 stype(iname) = 5;
0193 sval = '< unidentified type >';
0194 end
0195
0196 istr = num2str(iname);
0197
0198 if ~opt_gui,
0199
0200 disp(['[',istr,']',emptnstr(1:nmax-length(istr)),' : ',fname,emptstr(1:lmax - length(fname)),' : ',sval]);
0201
0202 else
0203
0204 lref = cwidth*fix((iname - 1)/nfh);
0205 bref = (((nfh - rem(iname - 1,nfh) - 1)+nspaces)*3 + 0.5)*ftsize;
0206
0207 sposition = [lref + margin,bref,cwidth/2 - 2.5*margin,2*ftsize];
0208 cposition = [lref + cwidth/2 - 0.5*margin,bref,cwidth/2 - 2.5*margin,2*ftsize];
0209 rposition = [lref + cwidth - 2*margin,bref,margin,2*ftsize];
0210
0211 cguis(iname) = uicontrol(cgui,'style','text','string',fname,'position',sposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'tooltipstring',sprintf(s.info.(fname)));
0212
0213 if stype(iname) == 0,
0214 cguic(iname) = uicontrol(cgui,'style','checkbox','string','','value',fval,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0215 elseif stype(iname) == 1,
0216 if iscell(values),
0217 for ielem = 1:length(values),
0218 if strcmp(fval,values{ielem}),
0219 break
0220 end
0221 end
0222
0223 cguic(iname) = uicontrol(cgui,'style','popupmenu','string',values,'value',ielem,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0224 else
0225 cguic(iname) = uicontrol(cgui,'style','edit','string',sval,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0226 end
0227 elseif stype(iname) == 2,
0228 if iscell(values) || size(values,1) == 1,
0229 if iscell(values),
0230 for ielem = 1:length(values),
0231 if fval == values{ielem},
0232 break
0233 end
0234 end
0235 else
0236 ielem = find(fval == values,1,'first');
0237 end
0238
0239 cguic(iname) = uicontrol(cgui,'style','popupmenu','string',values,'value',ielem,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0240 elseif size(values,1) == 2,
0241 cguic(iname) = uicontrol(cgui,'style','edit','string',sval,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0242 else
0243 error('GUI error');
0244 end
0245 elseif any(stype(iname) == [3:6]),
0246 cguic(iname) = uicontrol(cgui,'style','pushbutton','string',sval,'position',cposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@field_cbf);
0247 if d_opt == 0,
0248 set(cguic(iname),'enable','off');
0249 end
0250 else
0251 error('GUI error');
0252 end
0253
0254 if ~isfield(sinitvalues,fname),
0255 sinitvalues.(fname) = get(cguic(iname),'value');
0256 end
0257 if ~isfield(sinitstrings,fname),
0258 sinitstrings.(fname) = get(cguic(iname),'string');
0259 end
0260
0261 cguir(iname) = uicontrol(cgui,'style','pushbutton','string','reset','position',rposition,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'tooltipstring','Reset field to original value','callback',@pushbutton_cbf);
0262
0263 end
0264
0265 end
0266
0267 if ~opt_gui,
0268
0269 disp(' ')
0270
0271 disp(['[-4]',emptnstr(1:nmax-2),' : Reset structure'])
0272 disp(['[-3]',emptnstr(1:nmax-2),' : Reset one field'])
0273 disp(['[-2]',emptnstr(1:nmax-2),' : ',switchstr])
0274 disp(['[-1]',emptnstr(1:nmax-2),' : Get fields info'])
0275 disp(['[0]',emptnstr(1:nmax-1),' : Return structure'])
0276 disp(' ')
0277
0278 isel = input_dke_yp('',0,-6:nf);
0279 disp(' ');
0280
0281 else
0282
0283 pwidth = min([lfactor*ftsize*(7 + length(sname)),width/3]);
0284
0285 rposition1 = [width/6 - pwidth/2,0.5*ftsize,pwidth,2*ftsize];
0286 rposition2 = [width/2 - pwidth/2,0.5*ftsize,pwidth,2*ftsize];
0287 rposition3 = [5*width/6 - pwidth/2,0.5*ftsize,pwidth,2*ftsize];
0288
0289 cguir(nf+1) = uicontrol(cgui,'style','pushbutton','string',buttonstr{1},'position',rposition1,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'callback',@pushbutton_cbf);
0290 cguir(nf+2) = uicontrol(cgui,'style','pushbutton','string',buttonstr{2},'position',rposition2,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'tooltipstring','Reset all fields to original value','callback',@pushbutton_cbf);
0291 cguir(nf+3) = uicontrol(cgui,'style','pushbutton','string',buttonstr{3},'position',rposition3,'FontName',style.fontname,'FontUnits','pixels','FontSize',style.fontsize,'tooltipstring','Press to continue when done modifying the structure','callback',@pushbutton_cbf,'BackgroundColor',[0 0.75 0]);
0292
0293 end
0294
0295 if opt_gui,
0296 uiwait;
0297 delete(cgui);
0298 end
0299
0300 if isel == -4,
0301 s = sinit;
0302 mod = zeros(1,nf_all);
0303 end
0304
0305 if isel == -3,
0306 locisel = input_dke_yp('Number of the field to reset (enter 0 to cancel)',0,0:nf);
0307 if locisel > 0,
0308 s.(fnames{locisel}) = sinit.(fnames{locisel});
0309 if expmode,
0310 mod(locisel) = 0;
0311 else
0312 mod(nexplist(locisel)) = 0;
0313 end
0314 end
0315 end
0316
0317 if isel == -2,
0318 expmode = ~expmode;
0319 end
0320
0321 if isel == -1,
0322
0323 for iname = 1:nf,
0324
0325 fname = fnames{iname};
0326 disp(['- ',fname,emptstr(1:lmax - length(fname)),' : ',getfieldinfo_jd(s,fname)]);
0327
0328 end
0329 end
0330
0331 if isel > 0,
0332
0333 fname = fnames{isel};
0334 fval = s.(fname);
0335 values = s.values.(fname);
0336 locmod = 0;
0337
0338 if stype(isel) <= 2,
0339
0340 disp(['Field : ',fname,' : ',getfieldinfo_jd(s,fname)]);
0341 [fval,locmod] = input_dke_yp(['New value for field : ',fname,' '],fval,values);
0342
0343 if stype(isel) == 0,
0344
0345 s.(fname) = logical(fval);
0346
0347 elseif stype(isel) == 1 || rev(isel) == 0,
0348
0349 s.(fname) = fval;
0350
0351 else
0352 s.(fname) = fval(:);
0353 end
0354
0355 elseif stype(isel) == 3,
0356
0357 if d_opt == 1
0358
0359 [fval,locmod] = imod_struct_jd(fval,fname,1,opt_gui,struct,style);
0360 s.(fname) = fval;
0361
0362 else
0363
0364 disp(['The substructure ',fname,' cannot be modified.'])
0365
0366 end
0367
0368 elseif stype(isel) == 4,
0369
0370 if d_opt == 1
0371
0372 [fval,locmod] = imod_cell_jd(fval,fname,1,opt_gui);
0373 s.(fname) = fval;
0374
0375 else
0376
0377 disp(['The subcell ',fname,' cannot be modified.'])
0378
0379 end
0380
0381 elseif stype(isel) == 5,
0382
0383 disp(['The type of field ',fname,' cannot be identified.'])
0384
0385 elseif stype(isel) == 6,
0386
0387 disp(['Field ',fname,' can be changed on command line only.'])
0388
0389 end
0390
0391 if locmod == 1,
0392 if expmode,
0393 mod(isel) = 1;
0394 else
0395 mod(nexplist(isel)) = 1;
0396 end
0397 end
0398
0399 end
0400
0401 end
0402
0403 mod = any(mod);
0404 s = rminfo(s,fexcept);
0405
0406 function pushbutton_cbf(hObject,eventdata)
0407
0408 iname = find(hObject == cguir);
0409
0410 if iname > nf,
0411
0412 isel = isellist(iname - nf);
0413 uiresume
0414
0415 else
0416
0417 fname = fnames{iname};
0418 s.(fname) = sinit.(fname);
0419 set(cguic(iname),'value',sinitvalues.(fname));
0420 set(cguic(iname),'string',sinitstrings.(fname));
0421 if expmode,
0422 mod(iname) = 0;
0423 else
0424 mod(nexplist(iname)) = 0;
0425 end
0426
0427 end
0428
0429 end
0430
0431 function field_cbf(hObject,eventdata)
0432
0433 iname = find(hObject == cguic);
0434 fname = fnames{iname};
0435 values = s.values.(fname);
0436 if expmode,
0437 imod = iname;
0438 else
0439 imod = (nexplist(iname));
0440 end
0441
0442 if stype(iname) == 0,
0443 s.(fname) = get(hObject,'value');
0444
0445 if s.(fname) ~= sinit.(fname),
0446 mod(imod) = 1;
0447 end
0448 elseif stype(iname) == 1,
0449 if iscell(values),
0450 s.(fname) = values{get(hObject,'value')};
0451 else
0452 s.(fname) = get(hObject,'string');
0453 end
0454
0455 if ~strcmp(s.(fname),sinit.(fname)),
0456 mod(imod) = 1;
0457 end
0458 elseif stype(iname) == 2,
0459
0460 if iscell(values),
0461 s.(fname) = values{get(hObject,'value')};
0462 elseif size(values,1) == 1,
0463 s.(fname) = values(get(hObject,'value'));
0464 else
0465 s.(fname) = str2num(get(hObject,'string'));
0466 end
0467
0468 if rev(iname) == 1,
0469 s.(fname) = s.(fname).';
0470 end
0471
0472 if any(size(s.(fname)) ~= size(sinit.(fname))) || any(s.(fname) ~= sinit.(fname)),
0473 mod(imod) = 1;
0474 end
0475
0476 elseif stype(iname) == 3,
0477 set(cgui,'Visible','off');
0478 [s.(fname),mod(imod)] = imod_struct_jd(s.(fname),fname,d_opt,opt_gui,struct,style);
0479 set(cgui,'Visible','on');
0480 elseif stype(iname) == 4,
0481 [s.(fname),mod(imod)] = imod_cell_jd(s.(fname),fname,d_opt,opt_gui);
0482 elseif stype(iname) == 5,
0483 disp([' ---> you can change the field ',fname,' manually. It is stored in the variable ''field''. Press ''return'' to validate.'])
0484 field = s.(fname);
0485 keyboard
0486 s.(fname) = field;
0487 mod(imod) = 1;
0488 elseif stype(iname) == 6,
0489 disp([' ---> you can change the array ',fname,' manually. It is stored in the variable ''field''. Press ''return'' to validate.'])
0490 field = s.(fname);
0491 keyboard
0492 s.(fname) = field;
0493 if any(size(s.(fname)) ~= size(sinit.(fname))) || any(s.(fname)(:) ~= sinit.(fname)(:)),
0494 mod(imod) = 1;
0495 end
0496 else
0497 error('GUI error');
0498 end
0499
0500 end
0501
0502 end
0503
0504 function s = rminfo(s,fexcept)
0505 for ifield = 1:length(fexcept),
0506 if isfield(s,fexcept{ifield}),
0507 s = rmfield(s,fexcept{ifield});
0508 end
0509 end
0510
0511 fnames = fieldnames(s);
0512 for iname = 1:length(fnames);
0513 if isstruct(s.(fnames{iname})),
0514 s.(fnames{iname}) = rminfo(s.(fnames{iname}),fexcept);
0515 end
0516 end
0517 end