0001 function [t,sts] = nic_spm_select(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 if nargin > 0 && ischar(varargin{1})
0070 switch lower(varargin{1})
0071 case 'addvfiles'
0072 error(nargchk(2,Inf,nargin));
0073 vfiles('add',varargin{2:end});
0074 case 'clearvfiles'
0075 error(nargchk(1,1,nargin));
0076 vfiles('clear');
0077 case 'vfiles'
0078 error(nargchk(1,1,nargin));
0079 t = vfiles('all');
0080 case 'cpath'
0081 error(nargchk(2,Inf,nargin));
0082 t = cpath(varargin{2:end});
0083 case 'filter'
0084 filt = mk_filter(varargin{3:end});
0085 cs = iscell(varargin{2});
0086 if ~cs
0087 t = cellstr(varargin{2});
0088 else
0089 t = varargin{2};
0090 end;
0091 [t,sts] = do_filter(t,filt.ext);
0092 [t,sts] = do_filter(t,filt.filt);
0093 if ~cs
0094 t = strvcat(t);
0095 end;
0096 case {'list', 'fplist', 'extlist', 'extfplist'}
0097 if nargin > 3
0098 frames = varargin{4};
0099 else
0100 frames = 1;
0101 end;
0102 if regexpi(varargin{1}, 'ext')
0103 typ = 'extimage';
0104 else
0105 typ = 'any';
0106 end
0107 filt = mk_filter(typ, varargin{3}, frames);
0108 [t sts] = listfiles(varargin{2}, filt);
0109 if regexpi(varargin{1}, 'fplist')
0110 direc = nic_spm_get('cpath', varargin{2});
0111
0112 direc = regexprep(direc, [filesep '$'], '');
0113 t = strcat(repmat(direc, size(t, 1), 1), filesep, t);
0114 if nargout > 1
0115
0116 nsd = size(sts, 1);
0117 sts = strcat(repmat(direc, nsd, 1), filesep, sts);
0118
0119 sts = cellstr(sts);
0120 mch = [filesep '\.$'];
0121 sts = regexprep(sts, mch, '');
0122 mch = [filesep '[^' filesep ']+' filesep '\.\.$'];
0123 sts = regexprep(sts, mch, '');
0124 sts = char(sts);
0125 end
0126 end
0127 otherwise
0128 error('Inappropriate usage.');
0129 end
0130 else
0131 [t,sts] = selector(varargin{:});
0132 end
0133
0134
0135
0136 function [t,ok] = selector(n,typ,mesg,already,wd,filt,frames,varargin)
0137 if nargin<7, frames = '1'; end;
0138 if nargin<6, filt = '.*'; end;
0139 if nargin<5, wd = pwd; end;
0140 if nargin<4, already = {''}; end;
0141 if nargin<3, mesg = 'Select files...'; end;
0142 if nargin<2, typ = 'any'; end;
0143 if nargin<1, n = [0 Inf]; end;
0144 ok = 0;
0145 if numel(n)==1, n = [n n]; end;
0146 if n(1)>n(2), n = n([2 1]); end;
0147 if ~isfinite(n(1)), n(1) = 0; end;
0148 already = strvcat(already);
0149
0150 t = '';
0151 sfilt = mk_filter(typ,filt,frames);
0152
0153 [col1,col2,col3,fs] = colours;
0154
0155 fg = figure('IntegerHandle','off',...
0156 'Tag','Select',...
0157 'Name',strvcat(mesg),...
0158 'NumberTitle','off',...
0159 'Units','Pixels',...
0160 'MenuBar','none',...
0161 'DefaultTextInterpreter','none',...
0162 'DefaultUicontrolInterruptible','on',...
0163 'ResizeFcn',@resize_fun,...
0164 'KeyPressFcn',@hitkey);
0165
0166
0167 if spm_matlab_version_chk('7') >=0
0168 S = get(0, 'MonitorPosition');
0169 Rect = get(fg,'Position');
0170 pointer_loc = get(0,'PointerLocation');
0171
0172 for i = 1:size(S,1),
0173 h_min = S(i,1);
0174 h_width = S(i,3);
0175 h_max = h_width + h_min - 1;
0176 v_min = S(i,2);
0177 v_len = S(i,4);
0178 v_max = v_min + v_len;
0179
0180
0181 if pointer_loc(1) >= h_min && pointer_loc(1) < h_max && ...
0182 pointer_loc(2) >= v_min && pointer_loc(2) < v_max,
0183 hor_min = h_min;
0184 hor_width = h_width;
0185 hor_max = h_max;
0186 ver_min = v_min;
0187 ver_len = v_len;
0188 ver_max = v_max;
0189 end
0190 end
0191 Rect(1) = (hor_max - 0.5*hor_width) - 0.5*Rect(3);
0192 Rect(2) = (ver_max - 0.5*ver_len) - 0.5*Rect(4);
0193 set(fg,'Position',Rect);
0194 end
0195
0196
0197 fh = 0.05;
0198
0199
0200 sbh = 0.03;
0201 h1 = (0.96-4*fh-5*0.01)/2;
0202 if n(2)*fh+sbh<h1,
0203 h1 = min([max([n(2) size(already,1)+.2])*fh+sbh, h1]);
0204 end;
0205 h2 = 0.96-4*fh-5*0.01-h1;
0206
0207 SPMdir = fileparts(which(mfilename));
0208 if ( spm_matlab_version_chk('7') >= 0 ) && isdeployed,
0209 ind = findstr(SPMdir,'_mcr')-1;
0210 [SPMdir,junk] = fileparts(SPMdir(1:ind(1)));
0211 end;
0212 prevdirs([SPMdir filesep]);
0213 [pd,vl] = prevdirs([wd filesep]);
0214
0215
0216 hp = 0.02;
0217 sel = uicontrol(fg,...
0218 'style','listbox',...
0219 'units','normalized',...
0220 'Position',[0.02 hp 0.96 h1],...
0221 'FontSize',fs,...
0222 'Callback',@unselect,...
0223 'tag','selected',...
0224 'BackgroundColor',col1,...
0225 'ForegroundColor',col3,...
0226 'Max',10000,...
0227 'Min',0,...
0228 'String',already,...
0229 'Value',1);
0230 c0 = uicontextmenu('Parent',fg);
0231 set(sel,'uicontextmenu',c0);
0232 uimenu('Label','Unselect All', 'Parent',c0,'Callback',@unselect_all);
0233
0234
0235 hp = hp+h1+0.01;
0236 uicontrol(fg,...
0237 'style','text',...
0238 'units','normalized',...
0239 'Position',[0.02 hp 0.96 fh],...
0240 'FontSize',fs,...
0241 'BackgroundColor',get(fg,'Color'),...
0242 'ForegroundColor',col3,...
0243 'HorizontalAlignment','left',...
0244 'Tag','msg',...
0245 'String',mesg);
0246
0247 if strcmpi(typ,'image'),
0248 uicontrol(fg,...
0249 'style','edit',...
0250 'units','normalized',...
0251 'Position',[0.61 hp 0.37 fh],...
0252 'Callback',@update_frames,...
0253 'tag','frame',...
0254 'FontSize',fs,...
0255 'BackgroundColor',col1,...
0256 'String',frames,'UserData',eval(frames));
0257
0258 end;
0259
0260
0261 hp = hp+fh+0.01;
0262 uicontrol(fg,...
0263 'Style','pushbutton',...
0264 'units','normalized',...
0265 'Position',[0.02 hp fh fh],...
0266 'FontSize',fs,...
0267 'Callback',@heelp,...
0268 'tag','?',...
0269 'ForegroundColor',col3,...
0270 'BackgroundColor',col1,...
0271 'String','?',...
0272 'FontWeight','bold',...
0273 'ToolTipString','Show Help',...
0274 'FontSize',fs);
0275
0276 uicontrol(fg,...
0277 'Style','pushbutton',...
0278 'units','normalized',...
0279 'Position',[0.03+fh hp fh fh],...
0280 'FontSize',fs,...
0281 'Callback',@editwin,...
0282 'tag','Ed',...
0283 'ForegroundColor',col3,...
0284 'BackgroundColor',col1,...
0285 'String','Ed',...
0286 'FontWeight','bold',...
0287 'ToolTipString','Edit Selected Files',...
0288 'FontSize',fs);
0289
0290 uicontrol(fg,...
0291 'Style','pushbutton',...
0292 'units','normalized',...
0293 'Position',[0.04+2*fh hp fh fh],...
0294 'FontSize',fs,...
0295 'Callback',@select_rec,...
0296 'tag','Rec',...
0297 'ForegroundColor',col3,...
0298 'BackgroundColor',col1,...
0299 'String','Rec',...
0300 'FontWeight','bold',...
0301 'ToolTipString','Recursively Select Files with Current Filter',...
0302 'FontSize',fs);
0303
0304
0305 dne = uicontrol(fg,...
0306 'Style','pushbutton',...
0307 'units','normalized',...
0308 'Position',[0.05+3*fh hp 0.45-3*fh fh],...
0309 'FontSize',fs,...
0310 'Callback',@delete,...
0311 'tag','D',...
0312 'ForegroundColor',col3,...
0313 'BackgroundColor',col1,...
0314 'String','Done',...
0315 'FontWeight','bold',...
0316 'FontSize',fs,...
0317 'Enable','off',...
0318 'DeleteFcn',@null);
0319
0320 if size(already,1)>=n(1) && size(already,1)<=n(2),
0321 set(dne,'Enable','on');
0322 end;
0323
0324
0325 uicontrol(fg,...
0326 'Style','pushbutton',...
0327 'units','normalized',...
0328 'Position',[0.51 hp 0.1 fh],...
0329 'FontSize',fs,...
0330 'ForegroundColor',col3,...
0331 'BackgroundColor',col1,...
0332 'Callback',@clearfilt,...
0333 'String','Filt',...
0334 'FontSize',fs);
0335
0336
0337 uicontrol(fg,...
0338 'style','edit',...
0339 'units','normalized',...
0340 'Position',[0.61 hp 0.37 fh],...
0341 'ForegroundColor',col3,...
0342 'BackgroundColor',col1,...
0343 'FontSize',fs,...
0344 'Callback',@update,...
0345 'tag','regexp',...
0346 'String',filt,...
0347 'UserData',sfilt);
0348
0349
0350 hp = hp + fh+0.01;
0351 db = uicontrol(fg,...
0352 'style','listbox',...
0353 'units','normalized',...
0354 'Position',[0.02 hp 0.47 h2],...
0355 'FontSize',fs,...
0356 'Callback',@click_dir_box,...
0357 'tag','dirs',...
0358 'BackgroundColor',col1,...
0359 'ForegroundColor',col3,...
0360 'Max',1,...
0361 'Min',0,...
0362 'String','',...
0363 'UserData',wd,...
0364 'Value',1);
0365
0366
0367 tmp = uicontrol(fg,...
0368 'style','listbox',...
0369 'units','normalized',...
0370 'Position',[0.51 hp 0.47 h2],...
0371 'FontSize',fs,...
0372 'Callback',@click_file_box,...
0373 'tag','files',...
0374 'BackgroundColor',col1,...
0375 'ForegroundColor',col3,...
0376 'UserData',n,...
0377 'Max',10240,...
0378 'Min',0,...
0379 'String','',...
0380 'Value',1);
0381 c0 = uicontextmenu('Parent',fg);
0382 set(tmp,'uicontextmenu',c0);
0383 uimenu('Label','Select All', 'Parent',c0,'Callback',@select_all);
0384
0385
0386 if strcmpi(computer,'PCWIN') || strcmpi(computer,'PCWIN64'),
0387 dr = spm_platform('drives');
0388 drivestr = cell(1,numel(dr));
0389 for i=1:numel(dr),
0390 drivestr{i} = [dr(i) ':'];
0391 end;
0392
0393 sz = get(db,'Position');
0394 sz(4) = sz(4)-fh-2*0.01;
0395 set(db,'Position',sz);
0396 uicontrol(fg,...
0397 'style','text',...
0398 'units','normalized',...
0399 'Position',[0.02 hp+h2-fh-0.01 0.10 fh],...
0400 'FontSize',fs,...
0401 'BackgroundColor',get(fg,'Color'),...
0402 'ForegroundColor',col3,...
0403 'String','Drive');
0404 uicontrol(fg,...
0405 'style','popupmenu',...
0406 'units','normalized',...
0407 'Position',[0.12 hp+h2-fh-0.01 0.37 fh],...
0408 'FontSize',fs,...
0409 'Callback',@setdrive,...
0410 'tag','drive',...
0411 'BackgroundColor',col1,...
0412 'ForegroundColor',col3,...
0413 'String',drivestr,...
0414 'Value',1);
0415 end;
0416
0417
0418 hp = hp+h2+0.01;
0419 uicontrol(fg,...
0420 'style','popupmenu',...
0421 'units','normalized',...
0422 'Position',[0.12 hp 0.86 fh],...
0423 'FontSize',fs,...
0424 'Callback',@click_dir_list,...
0425 'tag','previous',...
0426 'BackgroundColor',col1,...
0427 'ForegroundColor',col3,...
0428 'String',pd,...
0429 'Value',vl);
0430 uicontrol(fg,...
0431 'style','text',...
0432 'units','normalized',...
0433 'Position',[0.02 hp 0.10 fh],...
0434 'FontSize',fs,...
0435 'BackgroundColor',get(fg,'Color'),...
0436 'ForegroundColor',col3,...
0437 'String','Prev');
0438
0439
0440 hp = hp + fh+0.01;
0441 uicontrol(fg,...
0442 'style','edit',...
0443 'units','normalized',...
0444 'Position',[0.12 hp 0.86 fh],...
0445 'FontSize',fs,...
0446 'Callback',@edit_dir,...
0447 'tag','edit',...
0448 'BackgroundColor',col1,...
0449 'ForegroundColor',col3,...
0450 'String','');
0451 uicontrol(fg,...
0452 'style','text',...
0453 'units','normalized',...
0454 'Position',[0.02 hp 0.10 fh],...
0455 'FontSize',fs,...
0456 'BackgroundColor',get(fg,'Color'),...
0457 'ForegroundColor',col3,...
0458 'String','Dir');
0459
0460 resize_fun(fg);
0461 update(sel,wd)
0462
0463 waitfor(dne);
0464 drawnow;
0465 if ishandle(sel),
0466 t = get(sel,'String');
0467 if sfilt.code == -1
0468 t = cellstr(t);
0469 for k = 1:numel(t);
0470 t{k} = cpath(t{k},pwd);
0471 end;
0472 t = char(t);
0473 end;
0474 ok = 1;
0475 end;
0476 if ishandle(fg), delete(fg); end;
0477 drawnow;
0478 return;
0479
0480
0481
0482 function null(varargin)
0483
0484
0485
0486 function msg(ob,str)
0487 ob = sib(ob,'msg');
0488 set(ob,'String',str);
0489 if nargin>=3,
0490 set(ob,'ForegroundColor',[1 0 0],'FontWeight','bold');
0491 else
0492 set(ob,'ForegroundColor',[0 0 0],'FontWeight','normal');
0493 end;
0494 drawnow;
0495 return;
0496
0497
0498
0499 function setdrive(ob,varargin)
0500 st = get(ob,'String');
0501 vl = get(ob,'Value');
0502 update(ob,st{vl});
0503 return;
0504
0505
0506
0507 function resize_fun(fg,varargin)
0508 ob = findobj(fg,'String','Filt','Style','pushbutton');
0509 if ~isempty(ob),
0510 ofs = get(ob,'FontSize');
0511 ex = get(ob,'Extent');
0512 ps = get(ob,'Position');
0513 fs = floor(ofs*min(ps(4)./ex(4))+1);
0514 fs = max(min(fs,30),4);
0515 ob = findobj(fg,'Fontsize',ofs);
0516 set(ob,'FontSize',fs);
0517 end;
0518 return;
0519
0520
0521
0522 function [d,mch] = prevdirs(d)
0523 persistent pd
0524 if ~iscell(pd), pd = {}; end;
0525 d = deblank(d);
0526 mch = find(strcmp(d,pd));
0527 if isempty(mch),
0528 pd = {pd{:},d};
0529 mch = length(pd);
0530 end;
0531 d = pd;
0532 return;
0533
0534
0535
0536 function clearfilt(ob,varargin)
0537 set(sib(ob,'regexp'),'String','.*');
0538 update(ob);
0539 return;
0540
0541
0542
0543 function click_dir_list(ob,varargin)
0544 vl = get(ob,'Value');
0545 ls = get(ob,'String');
0546 update(ob,deblank(ls{vl}));
0547 return;
0548
0549
0550
0551 function edit_dir(ob,varargin)
0552 update(ob,get(ob,'String'));
0553 return;
0554
0555
0556
0557 function click_dir_box(lb,varargin)
0558 update(lb,current_dir(lb));
0559 return;
0560
0561
0562
0563 function dr = current_dir(lb,varargin)
0564 vl = get(lb,'Value');
0565 str = get(lb,'String');
0566 pd = get(sib(lb,'edit'),'String');
0567 while ~isempty(pd) & strcmp(pd(end),filesep)
0568 pd=pd(1:end-1);
0569 end
0570 sel = deblank(str(vl,:));
0571 if strcmp(sel,'..'),
0572 dr = fileparts(pd);
0573 elseif strcmp(sel,'.'),
0574 dr = pd;
0575 else
0576 dr = fullfile(pd,sel);
0577 end;
0578 return;
0579
0580
0581
0582 function re = getfilt(ob)
0583 ob = sib(ob,'regexp');
0584 ud = get(ob,'UserData');
0585 re = struct('code',ud.code,...
0586 'frames',get(sib(ob,'frame'),'UserData'),...
0587 'ext',{ud.ext},...
0588 'filt',{{get(sib(ob,'regexp'),'String')}});
0589 return;
0590
0591
0592
0593 function update(lb,dr)
0594 lb = sib(lb,'dirs');
0595 if nargin<2 || isempty(dr),
0596 dr = get(lb,'UserData');
0597 end;
0598 if ~(strcmpi(computer,'PCWIN') || strcmpi(computer,'PCWIN64'))
0599 dr = [filesep dr filesep];
0600 else
0601 dr = [dr filesep];
0602 end;
0603 dr(findstr([filesep filesep],dr)) = [];
0604 [f,d] = listfiles(dr,getfilt(lb));
0605 if isempty(d),
0606 dr = get(lb,'UserData');
0607 [f,d] = listfiles(dr,getfilt(lb));
0608 else
0609 set(lb,'UserData',dr);
0610 end;
0611 set(lb,'Value',1,'String',d);
0612 set(sib(lb,'files'),'Value',1,'String',f);
0613 [ls,mch] = prevdirs(dr);
0614 set(sib(lb,'previous'),'String',ls,'Value',mch);
0615 set(sib(lb,'edit'),'String',dr);
0616
0617 if numel(dr)>1 && dr(2)==':',
0618 str = get(sib(lb,'drive'),'String');
0619 str = cat(1,char(str));
0620 mch = find(lower(str(:,1))==lower(dr(1)));
0621 if ~isempty(mch),
0622 set(sib(lb,'drive'),'Value',mch);
0623 end;
0624 end;
0625 return;
0626
0627
0628
0629 function update_frames(lb,varargin)
0630 str = get(lb,'String');
0631
0632 try
0633 r = eval(['[',str,']']);
0634 catch
0635 msg(lb,['Failed to evaluate "' str '".'],'r');
0636 beep;
0637 return;
0638 end;
0639 if ~isnumeric(r),
0640 msg(lb,['Expression non-numeric "' str '".'],'r');
0641 beep;
0642 else
0643 set(lb,'UserData',r);
0644 msg(lb,'');
0645 update(lb);
0646 end;
0647
0648
0649
0650 function select_all(ob,varargin)
0651 lb = findobj(get(get(ob,'Parent'),'Parent'),'Tag','files');
0652 str = get(lb,'String');
0653 set(lb,'Value',1:size(str,1));
0654 drawnow;
0655 click_file_box(lb);
0656 return;
0657
0658
0659
0660 function click_file_box(lb,varargin)
0661 lim = get(lb,'UserData');
0662 ob = sib(lb,'selected');
0663 str3 = get(ob,'String');
0664
0665 str = get(lb,'String');
0666 vlo = get(lb,'Value');
0667 lim1 = min(max(lim(2)-size(str3,1),0),length(vlo));
0668 if isempty(vlo),
0669 msg(lb,'Nothing selected');
0670 return;
0671 end;
0672 if lim1==0,
0673 msg(lb,['Selected ' num2str(size(str3,1)) '/' num2str(lim(2)) ' already.']);
0674 beep;
0675 set(sib(lb,'D'),'Enable','on');
0676 return;
0677 end;
0678
0679 vl = vlo(1:lim1);
0680 msk = false(size(str,1),1);
0681 if vl>0, msk(vl) = true; else msk = []; end;
0682 str1 = str( msk,:);
0683 str2 = str(~msk,:);
0684 dr = [current_dir(sib(lb,'dirs')) filesep];
0685 str1 = [repmat(dr,size(str1,1),1) str1];
0686
0687 set(lb,'Value',min(vl(1),size(str2,1)),'String',str2);
0688 r = (1:size(str1,1))+size(str3,1);
0689 str3 = deblank(strvcat(str3,str1));
0690 set(ob,'String',str3,'Value',r);
0691 if length(vlo)>lim1,
0692 msg(lb,['Retained ' num2str(lim1) '/' num2str(length(vlo))...
0693 ' of selection.']);
0694 beep;
0695 elseif isfinite(lim(2))
0696 if lim(1)==lim(2),
0697 msg(lb,['Selected ' num2str(size(str3,1)) '/' num2str(lim(2)) ' files.']);
0698 else
0699 msg(lb,['Selected ' num2str(size(str3,1)) '/' num2str(lim(1)) '-' num2str(lim(2)) ' files.']);
0700 end;
0701 else
0702 if size(str3,1) == 1, ss = ''; else ss = 's'; end;
0703 msg(lb,['Selected ' num2str(size(str3,1)) ' file' ss '.']);
0704 end;
0705 if ~isfinite(lim(1)) || size(str3,1)>=lim(1),
0706 set(sib(lb,'D'),'Enable','on');
0707 end;
0708
0709 return;
0710
0711
0712
0713 function obj = sib(ob,tag)
0714 obj = findobj(get(ob,'Parent'),'Tag',tag);
0715 return;
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 function unselect(lb,varargin)
0726 vl = get(lb,'Value');
0727 if isempty(vl), return; end;
0728 str = get(lb,'String');
0729 msk = ones(size(str,1),1);
0730 if vl~=0, msk(vl) = 0; end;
0731 str2 = str(logical(msk),:);
0732 set(lb,'Value',min(vl(1),size(str2,1)),'String',str2);
0733 lim = get(sib(lb,'files'),'UserData');
0734 if size(str2,1)>= lim(1) && size(str2,1)<= lim(2),
0735 set(sib(lb,'D'),'Enable','on');
0736 else
0737 set(sib(lb,'D'),'Enable','off');
0738 end;
0739
0740 if size(str2,1) == 1, ss1 = ''; else ss1 = 's'; end;
0741
0742 if numel(vl) == 1, ss = ''; else ss = 's'; end;
0743 msg(lb,['Unselected ' num2str(numel(vl)) ' file' ss '. ' ...
0744 num2str(size(str2,1)) ' file' ss1 ' remaining.']);
0745 return;
0746
0747
0748
0749 function unselect_all(ob,varargin)
0750 lb = findobj(get(get(ob,'Parent'),'Parent'),'Tag','selected');
0751 set(lb,'Value',[],'String','','ListBoxTop',1);
0752 msg(lb,'Unselected all files.');
0753 lim = get(sib(lb,'files'),'UserData');
0754 if lim(1)>0, set(sib(lb,'D'),'Enable','off'); end;
0755 return;
0756
0757
0758
0759 function varargout = vfiles(option,varargin)
0760 persistent vfs
0761 if isempty(vfs),
0762 vfs = newvfs;
0763 end;
0764
0765 switch option,
0766 case {'clear'}
0767 vfs = newvfs;
0768 case {'add'}
0769 for j=1:numel(varargin),
0770 pth = {};
0771 fle = {};
0772 if ischar(varargin{j}),
0773 for i=1:size(varargin{j},1),
0774 [pth{i} n e v] = spm_fileparts(deblank(varargin{j}(i,:)));
0775 fle{i} = [n e v];
0776 end;
0777 elseif iscell(varargin{j}),
0778 for i=1:numel(varargin{j}),
0779 [pth{i} n e v] = spm_fileparts(deblank(varargin{j}{i}));
0780 fle{i} = [n e v];
0781 end;
0782 end;
0783 [pu pi pj] = unique(pth);
0784 for k = 1:numel(pu)
0785 vfs = addvfile(vfs,pu{k},fle(pj==k));
0786 end;
0787 end;
0788 case {'list'}
0789 [varargout{1:3}] = listvfiles(vfs,varargin{:});
0790 case {'all'}
0791 varargout{1} = vfs;
0792 otherwise
0793 error('Unknown option.');
0794 end;
0795 return;
0796
0797
0798
0799 function vfs = newvfs(nam)
0800 if nargin==0, nam = ''; end;
0801 vfs = struct('name',nam,'dirs',struct('name',{},'dirs',{},'files',{}),'files',struct('name',{},'ind',{}));
0802 return;
0803
0804
0805
0806 function vfs = addvfile(vfs,pth,fle)
0807 if isempty(pth),
0808 for k = 1:numel(fle)
0809 [unused,nam,ext,num] = spm_fileparts(fle{k});
0810 if ~isempty(num),
0811 ind = [str2num(num) 1 1];
0812 ind = ind(1);
0813 else
0814 ind = [];
0815 end;
0816 fname = [nam ext];
0817 mch = strcmp(fname,{vfs.files.name});
0818 if any(mch),
0819 mch = find(mch);
0820 vfs.files(mch).ind = [vfs.files(mch).ind ind];
0821 else
0822 vfs.files(end+1).name = fname;
0823 vfs.files(end).ind = ind;
0824 end;
0825 end;
0826 else
0827 ind = find(pth==filesep);
0828 if isempty(ind)
0829 dr = pth;
0830 pth = '';
0831 else
0832 if any(ind==1),
0833 ind = ind(2:end)-1;
0834 pth = pth(2:end);
0835 end;
0836 if isempty(ind)
0837 dr = pth;
0838 pth = '';
0839 else
0840 dr = pth(1:(ind(1)-1));
0841 pth = pth((ind(1)+1):end);
0842 end;
0843 end;
0844 mch = strcmp(dr,{vfs.dirs.name});
0845 if any(mch),
0846 mch = find(mch);
0847 else
0848 mch = numel(vfs.dirs)+1;
0849 vfs.dirs(mch) = newvfs(dr);
0850 end;
0851 vfs.dirs(mch) = addvfile(vfs.dirs(mch),pth,fle);
0852 end;
0853 return;
0854
0855
0856
0857 function [f,d] = listfiles(dr,filt)
0858 ob = gco;
0859 msg(ob,'Listing directory...');
0860 if nargin<2, filt = ''; end;
0861 if nargin<1, dr = '.'; end;
0862 de = dir(dr);
0863 if ~isempty(de),
0864 d = {de([de.isdir]).name};
0865 if ~any(strcmp(d, '.'))
0866 d = {'.', d{:}};
0867 end;
0868 if filt.code~=-1,
0869 f = {de(~[de.isdir]).name};
0870 else
0871
0872 f = d;
0873 end;
0874 else
0875 d = {'.','..'};
0876 f = {};
0877 end;
0878
0879 msg(ob,['Filtering ' num2str(numel(f)) ' files...']);
0880 f = do_filter(f,filt.ext);
0881 f = do_filter(f,filt.filt);
0882 ii = cell(1,numel(f));
0883 if filt.code==1 && (numel(filt.frames)~=1 || filt.frames(1)~=1),
0884 msg(ob,['Reading headers of ' num2str(numel(f)) ' images...']);
0885 for i=1:numel(f),
0886 try
0887 ni = nifti(fullfile(dr,f{i}));
0888 dm = [ni.dat.dim 1 1 1 1 1];
0889 d4 = (1:dm(4))';
0890 catch
0891 d4 = 1;
0892 end;
0893 msk = false(size(filt.frames));
0894 for j=1:numel(msk), msk(j) = any(d4==filt.frames(j)); end;
0895 ii{i} = filt.frames(msk);
0896 end;
0897 elseif filt.code==1 && (numel(filt.frames)==1 && filt.frames(1)==1),
0898 for i=1:numel(f),
0899 ii{i} = 1;
0900 end;
0901 end;
0902
0903 msg(ob,'Listing virtual files...');
0904 [fv,dv,iv] = vfiles('list',dr);
0905 if filt.code==-1,
0906 fv = dv;
0907 iv = cell(size(fv));
0908 end;
0909 msg(ob,['Filtering ' num2str(numel(fv)) ' virtual files...']);
0910 [fv,ind] = do_filter(fv,filt.ext);
0911 iv = iv(ind);
0912 [fv,ind] = do_filter(fv,filt.filt);
0913 iv = iv(ind);
0914 if filt.code==1,
0915 for i=1:numel(iv),
0916 msk = false(size(filt.frames));
0917 for j=1:numel(msk), msk(j) = any(iv{i}==filt.frames(j)); end;
0918 iv{i} = filt.frames(msk);
0919 end;
0920 end;
0921
0922 d = { d{:},dv{:}};
0923 f = { f{:},fv{:}};
0924 ii = {ii{:},iv{:}};
0925
0926 msg(ob,['Listing ' num2str(numel(f)) ' files...']);
0927
0928 [f,ind] = sortrows(f(:));
0929 ii = ii(ind);
0930 msk = true(1,numel(f));
0931 if ~isempty(f), f{1} = deblank(f{1}); end;
0932 for i=2:numel(f),
0933 f{i} = deblank(f{i});
0934 if strcmp(f{i-1},f{i}),
0935 if filt.code==1,
0936 tmp = sort([ii{i}(:) ; ii{i-1}(:)]);
0937 tmp(~diff(tmp,1)) = [];
0938 ii{i} = tmp;
0939 end;
0940 msk(i-1) = false;
0941 end;
0942 end;
0943 f = f(msk);
0944 if filt.code==1,
0945 ii = ii(msk);
0946 c = cell(size(f));
0947 for i=1:numel(f),
0948 c{i} = [repmat([f{i} ','],numel(ii{i}),1) num2str(ii{i}(:)) ];
0949 end;
0950 f = c;
0951 elseif filt.code==-1,
0952 fs = filesep;
0953 for i=1:numel(f),
0954 f{i} = [f{i} fs];
0955 end;
0956 end;
0957 f = strvcat(f{:});
0958
0959 d = sortrows(d(:));
0960 d = strvcat(d);
0961 sam = find(~any(diff(d+0,1),2));
0962 d(sam,:) = [];
0963
0964 msg(ob,'');
0965 return;
0966
0967
0968
0969 function [f,ind] = do_filter(f,filt)
0970 t2 = false(numel(f),1);
0971
0972
0973
0974
0975
0976
0977
0978
0979 for j=1:numel(filt),
0980 t1 = regexp(f,filt{j});
0981 if numel(f)==1 && ~iscell(t1), t1 = {t1}; end;
0982 for i=1:numel(t1),
0983 t2(i) = t2(i) || ~isempty(t1{i});
0984 end;
0985 end;
0986 ind = find(t2);
0987 f = f(ind);
0988 return;
0989
0990
0991
0992 function [f,d,ii] = listvfiles(vfs,dr)
0993 f = {};
0994 d = {};
0995 ii = {};
0996 if isempty(dr),
0997 f = {vfs.files.name};
0998 ii = {vfs.files.ind};
0999 d = {vfs.dirs.name};
1000 else
1001 if dr(1)==filesep, dr = dr(2:end); end;
1002 ind = find(dr==filesep);
1003 if isempty(ind),
1004 d1 = dr;
1005 d2 = '';
1006 else
1007 d1 = dr(1:(ind(1)-1));
1008 d2 = dr((ind(1)+1):end);
1009 end;
1010 for i=1:length(vfs.dirs),
1011 if strcmp(d1,vfs.dirs(i).name),
1012 [f,d,ii] = listvfiles(vfs.dirs(i),d2);
1013 break;
1014 end;
1015 end;
1016 end;
1017 return;
1018
1019
1020
1021 function heelp(ob,varargin)
1022 [col1,col2,col3,fs] = colours;
1023 fg = get(ob,'Parent');
1024 t = uicontrol(fg,...
1025 'style','listbox',...
1026 'units','normalized',...
1027 'Position',[0.01 0.01 0.98 0.98],...
1028 'FontSize',fs,...
1029 'FontName','FixedWidthFont',...
1030 'BackgroundColor',col2,...
1031 'ForegroundColor',col3,...
1032 'Max',0,...
1033 'Min',0,...
1034 'tag','HelpWin',...
1035 'String',' ');
1036 c0 = uicontextmenu('Parent',fg);
1037 set(t,'uicontextmenu',c0);
1038 uimenu('Label','Done', 'Parent',c0,'Callback',@helpclear);
1039
1040 ext = get(t,'Extent');
1041 pw = floor(0.98/ext(3)*20-4);
1042 str = spm_justify(pw,{[...
1043 'File Selection help. You can return to selecting files via the right mouse button (the "Done" option). ',...
1044 'Because of a bug in Matlab (on some machines), don''t resize this window when viewing the help.'],...
1045 '',[...
1046 'The panel at the bottom shows files that are already selected. ',...
1047 'Clicking a selected file will un-select it. To un-select several, you can ',...
1048 'drag the cursor over the files, and they will be gone on release. ',...
1049 'You can use the right mouse button to un-select everything.'],...
1050 '',[...
1051 'Directories are navigated by editing the name of the current directory (where it says "Dir"), ',...
1052 'by going to one of the previously entered directories ("Prev"), or by navigating around ',...
1053 'the parent or subdirectories listed in the left side panel.'],...
1054 '',[...
1055 'Files matching the filter ("Filt") are shown in the panel on the right. ',...
1056 'These can be selected by clicking or dragging. Use the right mouse button if ',...
1057 'you would like to select all files. Note that when selected, the files disappear ',...
1058 'from this panel. They can be made to reappear by re-specifying the directory ',...
1059 'or the filter. ',...
1060 'Note that the syntax of the filter differs from that used by previous versions of ',...
1061 'SPM. The following is a list of symbols with special meaning for filtering the filenames:'],...
1062 ' ^ start of string',...
1063 ' $ end of string',...
1064 ' . any character',...
1065 ' \ quote next character',...
1066 ' * match zero or more',...
1067 ' + match one or more',...
1068 ' ? match zero or one, or match minimally',...
1069 ' {} match a range of occurrances',...
1070 ' [] set of characters',...
1071 ' [^] exclude a set of characters',...
1072 ' () group subexpression',...
1073 ' \w match word [a-z_A-Z0-9]',...
1074 ' \W not a word [^a-z_A-Z0-9]',...
1075 ' \d match digit [0-9]',...
1076 ' \D not a digit [^0-9]',...
1077 ' \s match white space [ \t\r\n\f]',...
1078 ' \S not a white space [^ \t\r\n\f]',...
1079 ' \<WORD\> exact word match',...
1080 '',[...
1081 'Individual time frames of image files can also be selected. The frame filter ',...
1082 'allows specified frames to be shown, which is useful for image files that ',...
1083 'contain multiple time points. If your images are only single time point, then ',...
1084 'reading all the image headers can be avoided by specifying a frame filter of "1". ',...
1085 'The filter should contain a list of integers indicating the frames to be used. ',...
1086 'This can be generated by e.g. "1:100", or "1:2:100".'],...
1087 '',[...
1088 'The recursive selection button (Rec) allows files matching the regular expression to ',...
1089 'be recursively selected. If there are many directories to search, then this can take ',...
1090 'a while to run.'],...
1091 '',[...
1092 'There is also an edit button (Ed), which allows you to edit your selection of files. ',...
1093 'When you are done, then use the menu-button of your mouse to either cancel or accept your changes'],''});
1094 pad = cellstr(char(zeros(max(0,floor(1.2/ext(4) - numel(str))),1)));
1095 str = {str{:}, pad{:}};
1096 set(t,'String',str);
1097 return;
1098
1099
1100
1101 function helpclear(ob,varargin)
1102 ob = get(ob,'Parent');
1103 ob = get(ob,'Parent');
1104 ob = findobj(ob,'Tag','HelpWin');
1105 delete(ob);
1106
1107
1108
1109 function hitkey(fg,varargin)
1110 ch = get(fg,'CurrentCharacter');
1111 if isempty(ch), return; end;
1112
1113 ob = findobj(fg,'Tag','files');
1114 if ~isempty(ob),
1115 f = get(ob,'String');
1116 f = f(:,1);
1117 fset = find(f>=ch);
1118 if ~isempty(fset),
1119 fset = fset(1);
1120
1121
1122 set(ob,'ListboxTop',fset);
1123
1124 else
1125 set(ob,'ListboxTop',length(f));
1126 end;
1127 end;
1128 return;
1129
1130
1131
1132 function t = cpath(t,d)
1133 switch spm_platform('filesys'),
1134 case 'unx',
1135 mch = '^/';
1136 fs = '/';
1137 fs1 = '/';
1138 case 'win',
1139 mch = '^.:\\';
1140 fs = '\';
1141 fs1 = '\\';
1142 otherwise;
1143 error('What is this filesystem?');
1144 end
1145
1146 if isempty(regexp(t,mch,'once')),
1147 if (nargin<2)||isempty(d), d = pwd; end;
1148 t = [d fs t];
1149 end;
1150
1151
1152 re = [fs1 '\.' fs1];
1153 while ~isempty(regexp(t,re)),
1154 t = regexprep(t,re,fs);
1155 end;
1156 t = regexprep(t,[fs1 '\.' '$'], fs);
1157
1158
1159 re = [fs1 '[^' fs1 ']+' fs1 '\.\.' fs1];
1160 while ~isempty(regexp(t,re)),
1161 t = regexprep(t,re,fs,'once');
1162 end;
1163 t = regexprep(t,[fs1 '[^' fs1 ']+' fs1 '\.\.' '$'],fs,'once');
1164
1165
1166 t = regexprep(t,[fs1 '+'], fs);
1167
1168
1169
1170 function editwin(ob,varargin)
1171 [col1,col2,col3,fs] = colours;
1172 fg = get(ob,'Parent');
1173 lb = findobj(fg,'Tag','selected');
1174 str = get(lb,'String');
1175 str = cellstr(str);
1176 h = uicontrol(fg,'Style','Edit',...
1177 'units','normalized',...
1178 'String',str,...
1179 'FontSize',16,...
1180 'Max',2,...
1181 'Tag','EditWindow',...
1182 'HorizontalAlignment','Left',...
1183 'ForegroundColor',col3,...
1184 'BackgroundColor',col1,...
1185 'Position',[0.01 0.01 0.98 0.98]);
1186 c0 = uicontextmenu('Parent',fg);
1187 set(h,'uicontextmenu',c0);
1188 uimenu('Label','Cancel', 'Parent',c0,'Callback',@editclear);
1189 uimenu('Label','Accept', 'Parent',c0,'Callback',@editdone);
1190
1191
1192
1193 function editdone(ob,varargin)
1194 ob = get(ob,'Parent');
1195 ob = sib(ob,'EditWindow');
1196 str = get(ob,'String');
1197 str = deblank(cellstr(strvcat(str)));
1198 if isempty(str{1}), str = {}; end;
1199
1200 lim = get(sib(ob,'files'),'UserData');
1201 if numel(str)>lim(2),
1202 msg(ob,['Retained ' num2str(lim(2)) ' of the ' num2str(numel(str)) ' files.']);
1203 beep;
1204 str = str(1:lim(2));
1205 elseif isfinite(lim(2)),
1206 if lim(1)==lim(2),
1207 msg(ob,['Specified ' num2str(numel(str)) '/' num2str(lim(2)) ' files.']);
1208 else
1209 msg(ob,['Selected ' num2str(numel(str)) '/' num2str(lim(1)) '-' num2str(lim(2)) ' files.']);
1210 end;
1211 else
1212 if numel(str) == 1, ss = ''; else ss = 's'; end;
1213 msg(ob,['Specified ' num2str(numel(str)) ' file' ss '.']);
1214 end;
1215 if ~isfinite(lim(1)) || numel(str)>=lim(1),
1216 set(sib(ob,'D'),'Enable','on');
1217 else
1218 set(sib(ob,'D'),'Enable','off');
1219 end;
1220 set(sib(ob,'selected'),'String',strvcat(str),'Value',[]);
1221 delete(ob);
1222
1223
1224
1225 function editclear(ob,varargin)
1226 ob = get(ob,'Parent');
1227 ob = get(ob,'Parent');
1228 ob = findobj(ob,'Tag','EditWindow');
1229 delete(ob);
1230
1231
1232
1233 function [c1,c2,c3,fs] = colours
1234 global defaults
1235 c1 = [1 1 1];
1236 c2 = [1 1 1];
1237 c3 = [0 0 0];
1238 fs = 14;
1239 if isfield(defaults,'ui'),
1240 ui = defaults.ui;
1241 if isfield(ui,'colour1'), c1 = ui.colour1; end;
1242 if isfield(ui,'colour2'), c2 = ui.colour2; end;
1243 if isfield(ui,'colour3'), c3 = ui.colour3; end;
1244 if isfield(ui,'fs'), fs = ui.fs; end;
1245 end;
1246
1247
1248
1249 function select_rec(ob, varargin)
1250 sel = [];
1251 top = get(ob,'Parent');
1252 start = get(findobj(top,'Tag','edit'),'String');
1253 filt = get(findobj(top,'Tag','regexp'),'Userdata');
1254 filt.filt = {get(findobj(top,'Tag','regexp'), 'String')};
1255 fob = findobj(top,'Tag','frame');
1256 if ~isempty(fob)
1257 filt.frames = get(fob,'Userdata');
1258 else
1259 filt.frames = [];
1260 end;
1261 ptr = get(top,'Pointer');
1262 try,
1263 set(top,'Pointer','watch');
1264 sel = select_rec1(start,filt);
1265 catch,
1266 set(top,'Pointer',ptr);
1267 sel = '';
1268 end;
1269 set(top,'Pointer',ptr);
1270 already= get(findobj(top,'Tag','selected'),'String');
1271 fb = sib(ob,'files');
1272 lim = get(fb,'Userdata');
1273 limsel = min(lim(2)-size(already,1),size(sel,1));
1274 set(findobj(top,'Tag','selected'),'String',strvcat(already,sel(1:limsel,:)),'Value',[]);
1275 msg(ob,sprintf('Added %d/%d matching files to selection.', limsel, size(sel,1)));
1276 if ~isfinite(lim(1)) || size(sel,1)>=lim(1),
1277 set(sib(ob,'D'),'Enable','on');
1278 else
1279 set(sib(ob,'D'),'Enable','off');
1280 end;
1281
1282
1283
1284 function sel=select_rec1(cdir,filt)
1285 sel='';
1286 [t,d] = listfiles(cdir,filt);
1287 if ~isempty(t)
1288 sel = [repmat([cdir,filesep],size(t,1),1),t];
1289 end;
1290 for k = 1:size(d,1)
1291 if ~strcmp(deblank(d(k,:)),'.') && ~strcmp(deblank(d(k,:)),'..')
1292 sel1 = select_rec1(fullfile(cdir,deblank(d(k,:))),filt);
1293 if ~isempty(sel1) && ~isempty(sel),
1294 sel = strvcat(sel, sel1);
1295 elseif ~isempty(sel1),
1296 sel = sel1;
1297 end;
1298 end;
1299 end;
1300
1301
1302
1303 function sfilt=mk_filter(typ,filt,frames)
1304 if nargin<3, frames = '1'; end;
1305 if nargin<2, filt = '.*'; end;
1306 if nargin<1, typ = 'any'; end;
1307 switch lower(typ),
1308 case {'any','*'}, code = 0; ext = {'.*'};
1309 case {'image'}, code = 1; ext = {'.*\.nii$','.*\.img$','.*\.NII$','.*\.IMG$'};
1310 case {'nifti'}, code = 0; ext = {'.*\.nii$','.*\.img$','.*\.NII$','.*\.IMG$'};
1311 case {'extimage'}, code = 1; ext = {'.*\.nii(,[0-9]*){0,1}$',...
1312 '.*\.img(,[0-9]*){0,1}$',...
1313 '.*\.NII(,[0-9]*){0,1}$',...
1314 '.*\.IMG(,[0-9]*){0,1}$'};
1315 case {'xml'}, code = 0; ext = {'.*\.xml$','.*\.XML$'};
1316 case {'mat'}, code = 0; ext = {'.*\.mat$','.*\.MAT$'};
1317 case {'batch'}, code = 0; ext = {'.*\.mat$','.*\.MAT$','.*\.m$','.*\.M$','.*\.xml$','.*\.XML$'};
1318 case {'dir'}, code =-1; ext = {'.*'};
1319 case {'extdir'}, code =-1; ext = {['.*' filesep '$']};
1320 otherwise, code = 0; ext = {typ};
1321 end;
1322 sfilt = struct('code',code,'frames',frames,'ext',{ext},...
1323 'filt',{{filt}});
1324
1325
1326
1327