Don't copy DirectoryOpus.CFG because that file works
[AROS-Contrib.git] / dopus / Program / main19.c
blob61806f793165359232ee2ac3f67e7b02b4bb2c25
1 /*
3 Directory Opus 4
4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 All users of Directory Opus 4 (including versions distributed
22 under the GPL) are entitled to upgrade to the latest version of
23 Directory Opus version 5 at a reduced price. Please see
24 http://www.gpsoft.com.au for more information.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
31 #include "dopus.h"
33 void makereselect(winpar,win)
34 struct DirWindowPars *winpar;
35 int win;
37 int a,num;
38 struct Directory *dir,*top;
40 if (winpar->reselection_list) {
41 FreeMem(winpar->reselection_list,winpar->reselection_size);
42 winpar->reselection_list=NULL;
44 if (win==-1 ||
45 (dopus_curwin[win]->firstentry &&
46 dopus_curwin[win]->firstentry->type==ENTRY_CUSTOM)) return;
48 winpar->reselection_dir=dopus_curwin[win];
49 winpar->reselection_win=win;
50 winpar->reselection_size=(dopus_curwin[win]->dirsel+
51 dopus_curwin[win]->filesel+1)*FILEBUF_SIZE;
53 /* Mungwall HIT! 0 size request for AllocMem */
54 D(if (winpar->reselection_size == 0) bug("makereselect: dirs:%ldt\tfiles:%ld\tsize:%ld\n",dopus_curwin[win]->dirsel,dopus_curwin[win]->filesel,winpar->reselection_size));
55 if (!(winpar->reselection_list=AllocMem(winpar->reselection_size,MEMF_CLEAR))) return;
57 dir=winpar->reselection_dir->firstentry;
58 a=num=0; top=NULL;
59 while (dir) {
60 if (dir->selected) {
61 CopyMem(dir->name,&winpar->reselection_list[a],FILEBUF_SIZE);
62 a+=FILEBUF_SIZE;
64 if (!top && num==dopus_curwin[win]->offset)
65 top=dir;
66 dir=dir->next;
67 ++num;
69 if (top) strcpy(winpar->top_name,top->name);
70 else winpar->top_name[0]=0;
71 winpar->offset=dopus_curwin[win]->offset;
72 winpar->hoffset=dopus_curwin[win]->hoffset;
75 void doreselect(winpar,moveold)
76 struct DirWindowPars *winpar;
77 int moveold;
79 int a,num=0,top=-1;
80 struct Directory *dir;
82 if (winpar->reselection_list &&
83 winpar->reselection_dir==dopus_curwin[winpar->reselection_win]) {
84 dir=dopus_curwin[winpar->reselection_win]->firstentry;
85 while (dir) {
86 if (dir->selected) {
87 dir->selected=0;
88 updateselectinfo(dir,winpar->reselection_win,0);
90 if (top==-1 &&
91 winpar->top_name[0] &&
92 (Stricmp(dir->name,winpar->top_name))==0) top=num;
93 ++num;
94 dir=dir->next;
96 for (a=0;a<winpar->reselection_size;a+=FILEBUF_SIZE) {
97 if (winpar->reselection_list[a]) {
98 dir=dopus_curwin[winpar->reselection_win]->firstentry;
99 while (dir) {
100 if (Stricmp(&winpar->reselection_list[a],dir->name)==0) {
101 dir->selected=1;
102 updateselectinfo(dir,winpar->reselection_win,0);
103 break;
105 dir=dir->next;
109 if (!moveold) {
110 if (top<0) top=winpar->offset;
111 dopus_curwin[winpar->reselection_win]->offset=top;
112 dopus_curwin[winpar->reselection_win]->hoffset=winpar->hoffset;
114 refreshwindow(winpar->reselection_win,1);
116 if (moveold && config->dynamicflags&UPDATE_SCROLL)
117 findfirstsel(winpar->reselection_win,-2);
119 doselinfo(winpar->reselection_win);
123 void shutthingsdown(louise)
124 int louise;
126 remclock();
128 main_proc->pr_WindowPtr=windowptr_save;
129 if (!status_iconified && status_publicscreen && Window) {
130 if (MainScreen) {
131 config->scr_winx=Window->LeftEdge;
132 config->scr_winy=Window->TopEdge;
134 else {
135 config->wbwinx=Window->LeftEdge;
136 config->wbwiny=Window->TopEdge;
139 if (louise<1) closedisplay();
142 void setupwindreq(wind)
143 struct Window *wind;
145 SetFont(wind->RPort,scr_font[FONT_GENERAL]);
146 SetAPen(wind->RPort,screen_pens[config->requestbg].pen);
147 RectFill(wind->RPort,
148 wind->BorderLeft+2,
149 wind->BorderTop+1,
150 wind->Width-wind->BorderRight-3,
151 wind->Height-wind->BorderBottom-2);
152 if (!(wind->Flags&WFLG_DRAGBAR))
153 do3dbox(wind->RPort,2,1,wind->Width-4,wind->Height-2);
154 SetDrawModes(wind->RPort,config->requestfg,config->requestbg,JAM2);
157 void hilite_req_gadget(win,gadid)
158 struct Window *win;
159 UWORD gadid;
161 struct Gadget *gad;
163 gad=win->FirstGadget;
164 while (gad) {
165 if (gad->GadgetID==gadid && gad->GadgetType==GTYP_BOOLGADGET) {
166 SelectGadget(win,gad);
167 return;
169 gad=gad->NextGadget;
173 int simplerequest(char *txt,...)
175 char *gads[11],*cancelgad=NULL,*gad;
176 int a,r,rets[10],gnum,rnum;
177 va_list ap;
178 struct DOpusSimpleRequest request;
180 va_start(ap,txt); r=1; gnum=rnum=0;
181 for (a=0;a<10;a++) {
182 if (!(gad=(char *)va_arg(ap,char *))) break;
183 if (a==1) cancelgad=gad;
184 else {
185 gads[gnum++]=gad;
186 if (gad[0] != '\n') rets[rnum++] = r++;
189 if (cancelgad) {
190 gads[gnum]=cancelgad;
191 rets[rnum]=0;
192 a=gnum+1;
194 for (;a<11;a++) gads[a]=NULL;
196 //D(KDump(gads,32));
197 //D(KDump(rets,32));
198 request.strbuf=NULL;
199 request.flags=0;
200 return(dorequest(&request,txt,gads,rets,NULL));
203 int whatsit(txt,max,buffer,skiptxt)
204 char *txt;
205 int max;
206 char *buffer,*skiptxt;
208 char *gads[4];
209 int a=1,rets[3];
210 struct DOpusSimpleRequest request;
212 request.strbuf=buffer;
213 request.strlen=max;
214 request.flags=0;
216 gads[0]=str_okaystring; rets[0]=1;
217 if (skiptxt==(char *)-1) request.flags=SRF_GLASS|SRF_DIRGLASS;
218 else if (skiptxt==(char *)-2) request.flags=SRF_GLASS;
219 else if (skiptxt) {
220 rets[1]=2;
221 gads[a++]=skiptxt;
223 rets[a]=0;
224 gads[a++]=str_cancelstring;
225 for (;a<4;a++) gads[a]=NULL;
227 return(dorequest(&request,txt,gads,rets,NULL));
230 int dorequest(request,txt,gads,rets,window)
231 struct DOpusSimpleRequest *request;
232 char *txt,**gads;
233 int *rets;
234 struct Window *window;
236 int a;
237 struct Window *win=NULL;
239 request->text=txt;
240 request->gads=gads;
241 request->rets=rets;
243 if (window) {
244 win=window;
245 request->font=window->RPort->Font;
247 else if (reqoverride) {
248 request->font=scr_font[FONT_GENERAL];
249 request->hi=2;
250 request->lo=1;
251 request->fg=1;
252 request->bg=0;
253 win=reqoverride;
255 else {
256 if (!status_iconified || status_flags&STATUS_ISINBUTTONS) win=Window;
257 if (win) {
258 request->hi=screen_pens[config->gadgettopcol].pen;
259 request->lo=screen_pens[config->gadgetbotcol].pen;
260 request->fg=screen_pens[config->requestfg].pen;
261 request->bg=screen_pens[config->requestbg].pen;
263 else {
264 request->hi=-1;
265 request->lo=-1;
266 request->fg=-1;
267 request->bg=-1;
269 request->font=scr_font[FONT_REQUEST];
271 if (config->generalscreenflags&SCR_GENERAL_REQDRAG) {
272 request->flags|=SRF_BORDERS;
273 request->title=globstring[STR_DIRECTORY_OPUS_REQUEST];
275 else request->flags&=~SRF_BORDERS;
277 request->flags|=SRF_RECESSHI|SRF_EXTEND;
278 request->value=(long)&requester_stringex;
279 fix_stringex(&requester_stringex);
281 a=DoSimpleRequest(win,request);
282 return(((a==65535)?1:a));
285 int checkfiletypefunc(name,fn)
286 char *name;
287 int fn;
289 struct dopusfiletype *type;
290 struct dopusfuncpar par;
292 if ((type=checkfiletype(name,fn,1))) {
293 char title[256];
295 par.which=type->which[fn]; par.stack=type->stack[fn];
296 par.key=par.qual=0;
297 par.pri=type->pri[fn]; par.delay=type->delay[fn];
299 if (type->actionstring[fn][0]) {
300 do_title_string(type->actionstring[fn],title,0,BaseName(name));
301 dostatustext(title);
303 else title[0]=0;
305 dofunctionstring(type->function[fn],BaseName(name),title,&par);
306 return(1);
308 return(0);
311 struct dopusfiletype *checkfiletype(fullname,ftype,funconly)
312 char *fullname;
313 int ftype,funconly;
315 struct FileInfoBlock __aligned info;
316 struct dopusfiletype *type;
317 BPTR file;
319 if (!(lockandexamine(fullname,&info))) return(NULL);
320 if (!(file=Open(fullname,MODE_OLDFILE))) return(NULL);
322 type=dopus_firsttype;
323 while (type) {
324 if (status_haveaborted) break;
325 if (ftype==-2) {
326 if (type->iconpath && type->recognition &&
327 (dochecktype(type,fullname,file,&info))) {
328 Close(file);
329 return(type);
332 else {
333 if (!funconly || (type->function[ftype] && type->function[ftype][0])) {
334 //D(bug("type->function[ftype]: %s\n",type->function[ftype]));
335 //D(bug("type->recognition: %s\n",type->recognition));
336 //D(bug("dochecktype: %ld\n",dochecktype(type,fullname,file,&info)));
337 if (type->recognition && dochecktype(type,fullname,file,&info) &&
338 (ftype==-1 || (type->function[ftype] && type->function[ftype][0]))) {
339 Close(file);
340 return(type);
344 type=type->next;
346 Close(file);
347 return(NULL);
350 int dochecktype(type,name,fileparam,info)
351 struct dopusfiletype *type;
352 char *name;
353 BPTR fileparam;
354 struct FileInfoBlock *info;
356 unsigned char buf[514],buf2[1024],*recog;
358 a,b,c,d,len,operation,fail,prot[2],tprot,equ,val,oldpos,
359 err,gotone=0,test;
360 struct DateStamp ds1,ds2;
361 BPTR file = (BPTR)fileparam;
363 len=strlen((recog=type->recognition))+1; b=operation=0;
365 Seek(file,0,OFFSET_BEGINNING);
366 for (a=0;a<len;a++) {
367 if (!operation) {
368 if (recog[a]>0 && recog[a]<FTYC_COMMANDOK)
369 operation=recog[a];
371 else if (b==511 || recog[a]>FTYC_ENDLIMIT || !recog[a]) {
372 buf[b]=0;
373 fail=0; test=1;
374 switch (operation) {
375 case FTYC_MATCH:
376 case FTYC_MATCHI:
377 if (!(checktypechars(file,buf,(operation == FTYC_MATCHI) ? 1 : 0))) fail=1;
378 D(bug("checktypechars(): %ld\n",!fail));
379 break;
380 case FTYC_MATCHNAME:
381 LParsePatternI(buf,buf2);
382 if (!(LMatchPatternI(buf2,info->fib_FileName))) fail=1;
383 break;
384 case FTYC_MATCHBITS:
385 getprotselvals(buf,prot);
386 tprot=((~info->fib_Protection)&15)+(info->fib_Protection&~15);
387 if (!((tprot&prot[0])==prot[0] && ((tprot&~prot[0])&prot[1])==0))
388 fail=1;
389 break;
390 case FTYC_MATCHCOMMENT:
391 LParsePatternI(buf,buf2);
392 if (!(LMatchPatternI(buf2,info->fib_Comment))) fail=1;
393 break;
394 case FTYC_MATCHSIZE:
395 d=strlen(buf); equ=2;
396 for (c=0;c<d;c++) {
397 if (equ==2 && !(_isspace(buf[c]))) {
398 if (buf[c]=='<') equ=-1;
399 else if (buf[c]=='=') equ=0;
400 else if (buf[c]=='>') equ=1;
401 else {
402 fail=1;
403 break;
406 else if (equ!=2 && (_isdigit(buf[c]))) {
407 val=atoi(&buf[c]);
408 break;
411 if (equ!=2) {
412 if (equ==-1 && info->fib_Size>=val) fail=1;
413 else if (equ==0 && info->fib_Size!=val) fail=1;
414 else if (equ==1 && info->fib_Size<=val) fail=1;
416 break;
417 case FTYC_MATCHDATE:
418 getseldatestamps(buf,&ds1,&ds2);
419 if (CompareDate(&(info->fib_Date),&ds1)<0 ||
420 CompareDate(&ds2,&(info->fib_Date))<0) fail=1;
421 break;
422 case FTYC_MOVETO:
423 test=0;
424 if (buf[0]=='$') val=Atoh(&buf[1],-1);
425 else val=atoi(buf);
426 if (val==-1) err=Seek(file,0,OFFSET_END);
427 else if (val>-1) err=Seek(file,val,OFFSET_BEGINNING);
428 else err=-1;
429 if (err==-1 /*|| (system_version2==OSVER_37 && IoErr())*/) fail=1;
430 break;
431 case FTYC_MOVE:
432 test=0;
433 if (buf[0]=='$') val=Atoh(&buf[1],-1);
434 else val=atoi(buf);
435 if ((Seek(file,val,OFFSET_CURRENT))==-1 /*||
436 (system_version2==OSVER_37 && IoErr())*/) fail=1;
437 if (err==-1) fail=1;
438 break;
439 case FTYC_SEARCHFOR:
440 oldpos=Seek(file,0,OFFSET_CURRENT);
441 if ((val=typesearch(file,buf,SEARCH_NOCASE|SEARCH_WILDCARD,NULL,0))==-1) {
442 fail=1;
443 Seek(file,oldpos,OFFSET_BEGINNING);
445 else Seek(file,val,OFFSET_BEGINNING);
446 break;
447 default:
448 test=0;
449 break;
451 if (!fail && test && recog[a]==FTYC_OR) gotone=1;
452 else if (fail) {
453 while (recog[a]!=FTYC_OR && recog[a]!=FTYC_AND && recog[a]) ++a;
454 if (recog[a]==FTYC_AND) break;
456 operation=b=0;
458 else buf[b++]=recog[a];
460 if (!fail || gotone) return(1);
461 return(0);
464 int checktypechars(fileparam,match,nocase)
465 BPTR fileparam;
466 unsigned char *match;
467 int nocase;
469 unsigned char matchbuf[258],c1,c2;
470 int len,clen,a,first=1,m,val,bpos;
471 BPTR file=fileparam;
473 len=strlen(match);
475 switch (match[0]) {
476 case '$':
477 clen=(len-1)/2;
478 break;
479 case '%':
480 clen=(len-1)/8;
481 break;
482 default:
483 clen=len; first=0;
484 break;
486 if (clen>256) clen=256;
487 if ((Read(file,matchbuf,clen))!=clen) return(0);
488 m=0; bpos=0;
489 switch (match[0]) {
490 case '$':
491 for (a=first;a<len;a+=2,m++) {
492 if (match[a]!='?') {
493 val=Atoh(&match[a],2);
494 if (val!=matchbuf[m]) return(0);
497 break;
498 case '%':
499 for (a=first;a<len;a++) {
500 if (match[a]!='?') {
501 if (match[a]=='1' && !(matchbuf[m]&(1<<bpos))) return(0);
502 else if (match[a]=='0' && (matchbuf[m]&(1<<bpos))) return(0);
504 if ((++bpos)==8) {
505 bpos=0; ++m;
508 break;
509 default:
510 D(bug("match: %s\tpattern: %s (match[0] = %ld)\n",match+first,matchbuf+m,match[0]));
511 for (a=first;a<len;a++,m++) {
512 if (match[a]!='?' && match[a]!=matchbuf[m])
514 if (nocase)
516 c1=ToUpper(match[a]);
517 c2=ToUpper(matchbuf[m]);
518 //D(bug("matchchar: %ld - %ld\n",c1,c2));
519 if (c1 == c2) continue;
521 return(0);
524 break;
526 return(1);
529 int typesearch(fileparam,find,flags,buffer,bufsize)
530 BPTR fileparam;
531 char *find;
532 int flags;
533 char *buffer;
534 int bufsize;
536 unsigned char *findbuf,matchbuf[256];
537 int matchsize,a,len,size,oldpos;
538 BPTR file=fileparam;
540 len=strlen(find);
541 if (find[0]=='$') {
542 for (a=1,matchsize=0;a<len;a+=2,matchsize++) {
543 if (find[a]=='?') matchbuf[matchsize]='?';
544 else matchbuf[matchsize]=Atoh(&find[a],2);
546 flags&=~(SEARCH_NOCASE|SEARCH_ONLYWORDS);
548 else {
549 for (a=0,matchsize=0;a<len;a++) {
550 if (find[a]=='\\') {
551 if (find[a+1]=='\\') {
552 matchbuf[matchsize++]='\\';
553 ++a;
555 else {
556 matchbuf[matchsize++]=atoi(&find[a+1]);
557 a+=3;
560 else if (flags&SEARCH_NOCASE) matchbuf[matchsize++]=ToUpper(find[a]);
561 else matchbuf[matchsize++]=find[a];
565 search_found_lines=search_last_line_pos=0;
566 if (buffer) return(searchbuffer(buffer,bufsize,matchbuf,matchsize,flags));
567 else {
568 if (!(findbuf=AllocMem(32004,MEMF_CLEAR))) return(-1);
569 FOREVER {
570 if (status_haveaborted) {
571 myabort();
572 break;
574 oldpos=Seek(file,0,OFFSET_CURRENT);
575 if ((size=Read(file,findbuf,32000))<1) break;
576 if ((searchbuffer(findbuf,size,matchbuf,matchsize,flags))==1) {
577 oldpos+=((long)search_found_position-(long)findbuf);
578 FreeMem(findbuf,32004);
579 return(oldpos);
581 if (status_haveaborted) continue;
582 if (size<32000) break;
583 Seek(file,-matchsize,OFFSET_CURRENT);
585 FreeMem(findbuf,32004);
587 return(-1);
590 int searchbuffer(findbuf,size,matchbuf,matchsize,flags)
591 char *findbuf;
592 int size;
593 char *matchbuf;
594 int matchsize,flags;
596 char lastchar,mchar;
597 int a,matchchar,matchstart,lastlines,lastpos;
599 matchchar=matchstart=lastchar=0;
600 lastlines=search_found_lines; lastpos=search_last_line_pos;
602 for (a=0;a<size;a++) {
603 if (status_haveaborted) return(-1);
604 if ((mchar=(flags&SEARCH_NOCASE)?ToUpper(findbuf[a]):findbuf[a])==10) {
605 ++search_found_lines;
606 search_last_line_pos=a+1;
608 if ((!(flags&SEARCH_WILDCARD) || matchbuf[matchchar]!='?') &&
609 matchbuf[matchchar]!=mchar) {
610 if (matchchar>0) {
611 a=matchstart;
612 search_found_lines=lastlines;
613 search_last_line_pos=lastpos;
614 matchchar=matchstart=0;
617 else {
618 if (!(flags&SEARCH_ONLYWORDS) || matchchar || isonlyword(lastchar)) {
619 if (matchchar==0) {
620 matchstart=a;
621 lastlines=search_found_lines;
622 lastpos=search_last_line_pos;
624 if ((++matchchar)==matchsize) {
625 if (!(flags&SEARCH_ONLYWORDS) || isonlyword(findbuf[a+1])) {
626 search_found_position=findbuf+matchstart;
627 search_found_size=matchchar;
628 return(1);
630 a=matchstart;
631 search_found_lines=lastlines;
632 search_last_line_pos=lastpos;
633 matchchar=matchstart=0;
637 lastchar=mchar;
639 return(-1);