Home > marsbar > @mardo_5 > private > pr_spm_select.m

pr_spm_select

PURPOSE ^

File selector

SYNOPSIS ^

function [t,sts] = pr_spm_select(varargin)

DESCRIPTION ^

 File selector
 FORMAT [t,sts] = pr_spm_select(n,typ,mesg,sel,wd,filt,frames)
     n    - Number of files
            A single value or a range.  e.g.
            1       - Select one file
            Inf     - Select any number of files
            [1 Inf] - Select 1 to Inf files
            [0 1]   - select 0 or 1 files
            [10 12] - select from 10 to 12 files
     typ  - file type
           'any'   - all files
           'image' - Image files (".img" and ".nii")
                     Note that it gives the option to select
                     individual volumes of the images.
           'xml'   - XML files
           'mat'   - Matlab .mat files
           'batch' - SPM batch files (.mat and XML)
           'dir'   - select a directory
           Other strings act as a filter to regexp.  This means
           that e.g. DCM*.mat files should have a typ of '^DCM.*\.mat$'
      mesg - a prompt (default 'Select files...')
      sel  - list of already selected files
      wd   - Directory to start off in
      filt - value for user-editable filter (default '.*')
      frames - Image frame numbers to include (default '1')

      t    - selected files
      sts  - status (1 means OK, 0 means window quit)

 Files can be selected from disk, but "virtual" files can also be selected.
 Virtual filenames are passed by
     pr_spm_select('addvfiles',list)
         where list is a cell array of filenames
 The list can be cleared by
     pr_spm_select('clearvfiles')

 FORMAT cpath = pr_spm_select('CPath',path,cwd)
 function to canonicalise paths: Prepends cwd to relative paths, processes
 '..' & '.' directories embedded in path.
 path     - string matrix containing path name
 cwd      - current working directory [defaut '.']
 cpath    - conditioned paths, in same format as input path argument

 FORMAT [files,dirs]=pr_spm_select('List',direc,filt)
 Returns files matching the filter (filt) and directories within dire
 direc    - directory to search
 filt     - filter to select files with (see regexp) e.g. '^w.*\.img$'
 files    - files matching 'filt' in directory 'direc'
 dirs     - subdirectories of 'direc'
____________________________________________________________________________
 Copyright (C) 2005 Wellcome Department of Imaging Neuroscience

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [t,sts] = pr_spm_select(varargin)
0002 % File selector
0003 % FORMAT [t,sts] = pr_spm_select(n,typ,mesg,sel,wd,filt,frames)
0004 %     n    - Number of files
0005 %            A single value or a range.  e.g.
0006 %            1       - Select one file
0007 %            Inf     - Select any number of files
0008 %            [1 Inf] - Select 1 to Inf files
0009 %            [0 1]   - select 0 or 1 files
0010 %            [10 12] - select from 10 to 12 files
0011 %     typ  - file type
0012 %           'any'   - all files
0013 %           'image' - Image files (".img" and ".nii")
0014 %                     Note that it gives the option to select
0015 %                     individual volumes of the images.
0016 %           'xml'   - XML files
0017 %           'mat'   - Matlab .mat files
0018 %           'batch' - SPM batch files (.mat and XML)
0019 %           'dir'   - select a directory
0020 %           Other strings act as a filter to regexp.  This means
0021 %           that e.g. DCM*.mat files should have a typ of '^DCM.*\.mat$'
0022 %      mesg - a prompt (default 'Select files...')
0023 %      sel  - list of already selected files
0024 %      wd   - Directory to start off in
0025 %      filt - value for user-editable filter (default '.*')
0026 %      frames - Image frame numbers to include (default '1')
0027 %
0028 %      t    - selected files
0029 %      sts  - status (1 means OK, 0 means window quit)
0030 %
0031 % Files can be selected from disk, but "virtual" files can also be selected.
0032 % Virtual filenames are passed by
0033 %     pr_spm_select('addvfiles',list)
0034 %         where list is a cell array of filenames
0035 % The list can be cleared by
0036 %     pr_spm_select('clearvfiles')
0037 %
0038 % FORMAT cpath = pr_spm_select('CPath',path,cwd)
0039 % function to canonicalise paths: Prepends cwd to relative paths, processes
0040 % '..' & '.' directories embedded in path.
0041 % path     - string matrix containing path name
0042 % cwd      - current working directory [defaut '.']
0043 % cpath    - conditioned paths, in same format as input path argument
0044 %
0045 % FORMAT [files,dirs]=pr_spm_select('List',direc,filt)
0046 % Returns files matching the filter (filt) and directories within dire
0047 % direc    - directory to search
0048 % filt     - filter to select files with (see regexp) e.g. '^w.*\.img$'
0049 % files    - files matching 'filt' in directory 'direc'
0050 % dirs     - subdirectories of 'direc'
0051 %____________________________________________________________________________
0052 % Copyright (C) 2005 Wellcome Department of Imaging Neuroscience
0053 
0054 % John Ashburner
0055 % $Id: spm_select.m 400 2006-01-11 18:41:15Z john $
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 % Code from Brian Lenoski for dealing with multiple monitors
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), % Loop over monitors
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         % Use the monitor containing the pointer
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); % Horizontal
0149     Rect(2) = (ver_max - 0.5*ver_len)   - 0.5*Rect(4); % Vertical
0150     set(fg,'Position',Rect);
0151 end
0152 
0153 
0154 fh = 0.05;
0155 %fs = 10;
0156 
0157 sbh = 0.03; % Scroll-bar height.  This should be worked out properly
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 % Selected Files
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 % Messages
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 % 'ForegroundGolor',col3,...
0215 end;
0216 
0217 % Help
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 % Done
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 % Filter Button
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 % Filter
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 % Directories
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 % Files
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 % Drives
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     %drivestr = {'A:','B:','C:','D:'};
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 % Previous dirs
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 % Directory
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);      % Remove any trailing fileseps
0504 end 
0505 sel = deblank(str(vl,:));
0506 if strcmp(sel,'..'),     % Parent directory
0507     dr = fileparts(pd);
0508 elseif strcmp(sel,'.'),  % Current directory
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 %r   = get(lb,'UserData');
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 %if isempty(obj),
0652 %    error(['Can''t find object with tag "' tag '".']);
0653 %elseif length(obj)>1,
0654 %    error(['Found ' num2str(length(obj)) ' objects with tag "' tag '".']);
0655 %end;
0656 %return;
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 %if size(str2,1) == 1, ss = ''; else ss = 's'; end;
0676 %msg(lb,[num2str(size(str2,1)) ' file' ss ' remaining.']);
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         % f = d(3:end);
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         %cb = get(ob,'Callback');
1023         %set(ob,'Callback',[]);
1024         set(ob,'ListboxTop',fset);
1025         %set(ob,'Callback',cb);
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 % Replace occurences of '/./' by '/' (problems with e.g. /././././././')
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 % Replace occurences of '/abc/../' by '/'
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 % Replace '//'
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 

Generated on Wed 11-May-2022 15:34:44 by m2html © 2003-2019