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