home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / nodes.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  11.5 KB  |  533 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20.  
  21. #include <proto/all.h>
  22. #include <exec/types.h>
  23. #include <exec/memory.h>
  24. #include <strings.h>
  25. #include <stdarg.h>
  26. #include <dos.h>
  27. #include "child.h"
  28. #include "fmnode.h"
  29. #include "fmdos.h"
  30. #include "fmlocale.h"
  31.  
  32. void setsliders(struct FMList*);
  33. extern void __asm RealTimeScroll(register __a0 struct ReqScrollStruct*);
  34. struct FMNode *iteratenode(struct FMNode**);
  35. UBYTE *scanchar(UBYTE*,UBYTE);
  36.  
  37. void shellsortlist(struct FMList*,struct FMNode*,struct Library*,WORD,WORD,WORD);
  38.  
  39. extern struct FMMain fmmain;
  40. extern struct FMConfig *fmconfig;
  41. extern struct FMList fmlist[];
  42.  
  43. void clearlisti(struct List *list)
  44. {
  45. struct Node *node;
  46.  
  47. while (list->lh_Head->ln_Succ) {
  48.     node=(struct Node*)list->lh_Head;
  49.     Remove(node);
  50.     freevecpooled(node);
  51. }
  52. }
  53.  
  54. void clearlist(struct FMList *list)
  55. {
  56. list->lastclicked=0; list->fmmessage1[0]=0; list->fmmessage2[0]=0;
  57. list->firstline=0;
  58. list->keyline=0;
  59. clearlisti((struct List*)list);
  60. }
  61.  
  62.  
  63. void shellsortlist(struct FMList *list,struct FMNode *node,struct Library *ub,WORD fo,WORD stype,WORD sud)
  64. {
  65. struct FMNode *node2;
  66. struct FMNode **sortbuf,**ptr1,*ptr2;
  67. WORD nodes;
  68. WORD range,i,j,apu;
  69.  
  70. node2=node;
  71. nodes=0;
  72. while(node2->succ) {
  73.     node2=node2->succ;
  74.     nodes++;
  75. }
  76.  
  77. if(nodes<=1) return;
  78.  
  79. sortbuf=allocmem((LONG)nodes*4);
  80. if(!sortbuf) return;
  81.  
  82. ptr1=sortbuf+nodes; i=nodes;
  83. while(i--) *--ptr1=(struct FMNode*)RemTail((struct List*)list);
  84.  
  85. for(range=nodes/2;range>0;range/=2) {
  86.     for(i=range;i<nodes;i++) {
  87.         j=i-range;
  88.         while(j>=0) {
  89.             apu=0;
  90.             switch(stype)
  91.             {
  92.             case 0:
  93.             if(Stricmp(NDFILE(sortbuf[j]),NDFILE(sortbuf[j+range]))>0) apu=1;
  94.             break;
  95.             case 1:
  96.             if(sortbuf[j]->numlen>sortbuf[j+range]->numlen) apu=1;
  97.             break;
  98.             case 2:
  99.             if(sortbuf[j]->numdate>sortbuf[j+range]->numdate) apu=1;
  100.             break;
  101.             case 3:
  102.             if(Stricmp(NDCOMM(sortbuf[j]),NDCOMM(sortbuf[j+range]))>0) apu=1;
  103.             break;
  104.             }
  105.             if(apu^sud) {
  106.                 ptr2=sortbuf[j];
  107.                 sortbuf[j]=sortbuf[j+range];
  108.                 sortbuf[j+range]=ptr2;
  109.                 j-=range;
  110.                 continue;
  111.             }
  112.             break;
  113.         }
  114.     }
  115. }
  116.  
  117. ptr1=sortbuf; i=nodes;
  118. while(i--) AddTail((struct List*)list,(struct Node*)*ptr1++);
  119.  
  120. freemem(sortbuf);
  121. }
  122.  
  123. void csortlist(struct FMList *list)
  124. {
  125. struct FMList list2;
  126. struct FMNode *node,*node2;
  127. struct Match *match;
  128. extern struct Library *UtilityBase;
  129. UWORD ftest;
  130.  
  131. if((list->flags&LDEVLIST)||(!list->li)) return;
  132. NewList((struct List*)&list2);
  133. match=getconfignumber(PARSECONFIG)->moreconfig;
  134. shellsortlist(list,list->head,UtilityBase,fmmain.fileoffset,0,0);
  135. if(match->msortby||match->msortud) shellsortlist(list,list->head,UtilityBase,fmmain.fileoffset,match->msortby,match->msortud);
  136. if(match->mdrawersfirst) ftest=NFILE; else ftest=NDIRECTORY;
  137. if(!match->mmix) {
  138.     node=list->head;
  139.     while(node->succ) {
  140.         node2=node->succ;
  141.         if(node->flags&ftest) {
  142.             Remove((struct Node*)node);
  143.             AddTail((struct List*)&list2,(struct Node*)node);
  144.         }
  145.         node=node2;
  146.     }
  147.     if(match->msortby==1&&ftest==NDIRECTORY) shellsortlist(&list2,list2.head,UtilityBase,fmmain.fileoffset,0,0);
  148.     while(list->head->succ) {
  149.         node=list->head;
  150.         Remove((struct Node*)node);
  151.         AddTail((struct List*)&list2,(struct Node*)node);
  152.     }
  153.     if(list2.head->succ) {
  154.         list->head=list2.head;
  155.         list->tailpred=list2.tailpred;
  156.         list->head->pred=(struct FMNode*)&list->head;
  157.         list->tailpred->succ=(struct FMNode*)&list->tail;
  158.     } else {
  159.         NewList((struct List*)list);
  160.     }
  161. }
  162. }
  163.  
  164. struct FMNode *disknode(struct FMList *list,UBYTE *newname)
  165. {
  166. struct FMNode *node,*node2,*node3;
  167. BPTR lock;
  168.  
  169. if(!currentdir(list)) return(0);
  170. lock=Lock(newname,SHARED_LOCK);
  171. if(!lock) return(0);
  172. UnLock(lock);
  173. node=allocnode();
  174. if(!node) return(0);
  175. siirran(NDFILE(node),newname,fmmain.filelen);
  176. examinefile(list,node);
  177. node->flags|=NMATCHED;
  178.  
  179. node2=list->head;
  180. while(node2->succ) {
  181.     node3=node2->succ;
  182.     if (!Stricmp(NDFILE(node2),newname)) removenode(list,node2);
  183.     node2=node3;
  184. }
  185. AddTail((struct List*)list,(struct Node*)node);
  186. list->totlines++;
  187. return(node);
  188. }
  189.  
  190. struct FMNode* dupnode(struct FMNode *node)
  191. {
  192. struct FMNode *newnode;
  193. if ((newnode=(struct FMNode*)allocvecpooled(fmmain.totnodelen))) {
  194.     CopyMem(node,newnode,fmmain.totnodelen);
  195.     newnode->succ=0;newnode->pred=0;
  196. }
  197. return(newnode);
  198. }
  199.  
  200. WORD duplist(struct FMList *list1,struct FMList *list2)
  201. {
  202. struct FMNode *node1;
  203. struct FMNode *node2;
  204.  
  205. for(node1=list1->head;node1->succ;node1=node1->succ) {
  206.     if (!(node2=dupnode(node1))) {
  207.         clearlist(list2);
  208.         return(FALSE);
  209.     } else {
  210.         AddTail((struct List*)list2,(struct Node*)node2);
  211.     }
  212. }
  213. return(TRUE);
  214. }
  215.  
  216. void removenode(struct FMList *list,struct FMNode *node)
  217. {
  218. Remove((struct Node*)node);
  219. freevecpooled(node);
  220. list->totlines--;
  221. if (list->totlines-list->firstline<list->li->visiblelines) list->firstline=list->totlines-list->li->visiblelines;
  222. if (list->firstline<0) list->firstline=0;
  223. setsliders(list);
  224. }
  225.  
  226. struct FMNode* scrollifneeded(struct FMList *l,UWORD *keyline,UWORD *keylinew)
  227. {
  228. struct FMNode *node;
  229. struct ReqScrollStruct *rss, *rssw;
  230. WORD apu1;
  231. UWORD rfl,rflw;
  232. WORD vscroll=0,hscroll=0;
  233. LONG apu2;
  234. LONG kline,klinew;
  235.  
  236. rss=&l->li->rscroll1;
  237. rssw=&l->li->rscroll2;
  238.  
  239. if(*keyline>65000) *keyline=0;
  240. if(*keyline>=l->totlines) *keyline=l->totlines-1;
  241. if(*keylinew>65000) *keylinew=0;
  242. if(*keylinew>=l->totlinesw) *keylinew=l->totlinesw-1;
  243. kline=*keyline;
  244. klinew=*keylinew;
  245.  
  246. node=(struct FMNode*)l;
  247. iteratenode(&node);
  248. apu1=kline;
  249. while(apu1--) iteratenode(&node);
  250.  
  251. if(kline>=l->firstline+l->li->visiblelines) {
  252.     l->firstline=kline-1;
  253.     vscroll=1;
  254. } else if (kline<l->firstline) {
  255.     apu2=kline-(LONG)(l->li->visiblelines-2);
  256.     if(apu2<0) apu2=0;
  257.     l->firstline=apu2;
  258.     vscroll=1;
  259. }
  260. if(vscroll) {
  261.     rfl=rss->TopEntryNumber;
  262.     updatelist(l);
  263.     rss->TopEntryNumber=rfl;
  264.     RealTimeScroll(rss);
  265.     rss->fmlist->firstline=rss->TopEntryNumber;
  266. }
  267.  
  268. if(klinew>=l->firstlinew+l->li->visiblelinesw) {
  269.     l->firstlinew=klinew-1;
  270.     hscroll=1;
  271. } else if (klinew<l->firstlinew) {
  272.     apu2=klinew-(LONG)(l->li->visiblelinesw-2);
  273.     if(apu2<0) apu2=0;
  274.     l->firstlinew=apu2;
  275.     hscroll=1;
  276. }
  277. if(hscroll) {
  278.     rflw=rssw->TopEntryNumber;
  279.     updatelist(l);
  280.     rssw->TopEntryNumber=rflw;
  281.     RealTimeScroll(rssw);
  282.     rssw->fmlist->firstlinew=rssw->TopEntryNumber;
  283. }
  284. return(node);
  285. }
  286.  
  287. struct FMNode* findselnodeall(struct FMList *list)
  288. {
  289. struct FMNode *node;
  290. UWORD line=0,linew;
  291.  
  292. node=(struct FMNode*)list;
  293. for(;;) {
  294.     iteratenode(&node);
  295.     if(!node) break;
  296.     line++;
  297.     if (node->flags&NSELECTED) {
  298.         linew=list->firstlinew;
  299.         scrollifneeded(list,&line,&linew);
  300.         return(node);
  301.     }
  302. }
  303. return(0);
  304. }
  305.  
  306. struct FMNode* findselnode(struct FMList *list)
  307. {
  308. struct FMNode *node;
  309. UWORD line=0,linew;
  310.  
  311. if (list->flags&LDIRLIST) {
  312.     node=(struct FMNode*)list;
  313.     for(;;) {
  314.         iteratenode(&node);
  315.         if(!node) break;
  316.         line++;
  317.         if (node->flags&NSELECTED&&node->flags&NFILE) {
  318.             linew=list->firstlinew;
  319.             scrollifneeded(list,&line,&linew);
  320.             return(node);
  321.         }
  322.     }
  323. }
  324. return(0);
  325. }
  326.  
  327. void __asm formathook(void);
  328. void __asm rawdo(register __a0 UBYTE*,register __a1 void*,register __a3 UBYTE*);
  329.  
  330. void sformatmsg(UBYTE *ptr,LONG form,...)
  331. {
  332. va_list args;
  333. va_start(args,form);
  334. sformatti(ptr,getstring(form),args);
  335. }
  336. void sformat(UBYTE *ptr,UBYTE *form,...)
  337. {
  338. va_list args;
  339. va_start(args,form);
  340. sformatti(ptr,form,args);
  341. }
  342.  
  343. void sformatti(UBYTE *ptr,UBYTE *form,UBYTE *args)
  344. {
  345. struct Hook hook;
  346. extern struct Locale *locale;
  347. ObtainSemaphore(&fmmain.msgsema);
  348. if(locale&&!(fmconfig->flags&MLOCALE)) {
  349.     hook.h_Data=ptr;
  350.     hook.h_Entry=(HOOKFUNC)formathook;
  351.     FormatString(locale,form,args,&hook);
  352. } else {
  353.     rawdo(form,args,ptr);
  354. }
  355. ReleaseSemaphore(&fmmain.msgsema);
  356. }
  357.  
  358. UBYTE scanus(UBYTE *ptr)
  359. {
  360. while(*ptr) {
  361.     if (*ptr=='_') return(ToUpper(*(ptr+1)));
  362.     ptr++;
  363. }
  364. return(0);
  365. }
  366.  
  367. void copyus(UBYTE *ptr1,UBYTE *ptr2)
  368. {
  369. while(*ptr2) {
  370.     if(*ptr2!='_') *ptr1++=*ptr2;
  371.     ptr2++;
  372. }
  373. *ptr1=0;
  374. }
  375.  
  376. struct FMNode *allocnode(void)
  377. {
  378. struct FMNode *node;
  379.  
  380. node=(struct FMNode*)allocvecpooled(fmmain.totnodelen);
  381. if(node) node->nodelen=fmmain.totnodelen;
  382. return(node);
  383. }
  384.  
  385. void strcpymsg(UBYTE *ptr,WORD msg)
  386. {
  387. strcpy(ptr,getstring(msg));
  388. }
  389.  
  390. struct FMNode *iteratenode(struct FMNode **node)
  391. {
  392. struct FMNode *node2;
  393.  
  394. node2=*node;
  395. if (node2&&(node2->succ)) node2=node2->succ;
  396. while(node2&&node2->succ&&!(node2->flags&NMATCHED)) node2=node2->succ;
  397. if(node2==0||node2->succ==0) node2=0;
  398. *node=node2;
  399. return(node2);
  400. }
  401.  
  402.  
  403. WORD sselected(struct FMList *list,WORD mode)
  404. {
  405. struct FMNode *node;
  406.  
  407. if(!(list->flags&LDIRLIST)) {
  408.     strcpymsg(list->fmmessage1,MSG_MAIN_NOSOURCE);
  409.     fmmessage(list);
  410. } else {
  411.     if(!mode) return(1);
  412.     node=(struct FMNode*)list;
  413.     for(;;) {
  414.         iteratenode(&node);
  415.         if(!node) break;
  416.         if(node->flags&NSELECTED) {
  417.             if(mode>0&&node->flags&NFILE) return(1);
  418.             if(mode<0&&node->flags&(NFILE|NDIRECTORY)) return(1);
  419.         }
  420.     }
  421.     strcpymsg(list->fmmessage1,MSG_MAIN_NOSOURCEFILE);
  422.     fmmessage(list);
  423. }
  424. return(0);
  425. }
  426.  
  427. ULONG dstolong(struct DateStamp *ds)
  428. {
  429. return(((ULONG)ds->ds_Days*24*60+(ULONG)ds->ds_Minute)*60+(ULONG)ds->ds_Tick/TICKS_PER_SECOND);
  430. }
  431. void longtods(struct DateStamp *ds,ULONG date)
  432. {
  433. ds->ds_Tick=(date%60)*TICKS_PER_SECOND;
  434. date/=60;
  435. ds->ds_Minute=date%(60*24);
  436. date/=60*24;
  437. ds->ds_Days=date;
  438. }
  439.  
  440. ULONG datestringtolong(UBYTE *date)
  441. {
  442. struct DateTime dt;
  443. UBYTE varatime[34];
  444.  
  445. if(!date[0]) return(0xffffffff);
  446. memseti(&dt,0,sizeof(struct DateTime));
  447. dt.dat_Format=4;
  448. strcpy(varatime,date);
  449. dt.dat_StrDate=varatime;
  450. dt.dat_StrTime=scanchar(varatime,' ');
  451. if(dt.dat_StrTime) {
  452.     *dt.dat_StrTime++=0;
  453. }
  454. if(StrToDate(&dt)) return(dstolong(&dt.dat_Stamp));
  455. return(0xffffffff);
  456. }
  457.  
  458. void longtodatestring(UBYTE *sdate,ULONG date)
  459. {
  460. struct DateTime dt;
  461. UBYTE pattime[18];
  462. UBYTE patdate[34];
  463.  
  464. memseti(sdate,0,fmmain.datelen);
  465. if(date==0xffffffff) return;
  466. longtods(&dt.dat_Stamp,date);
  467. dt.dat_Format=4;
  468. dt.dat_Flags=0;
  469. dt.dat_StrDay=0;
  470. dt.dat_StrDate=patdate;
  471. dt.dat_StrTime=pattime;
  472. if(!(DateToStr(&dt))) return;
  473. strcpy(patdate+strlen(patdate)+1,pattime);
  474. patdate[strlen(patdate)]=32;
  475. siirran(sdate,patdate,fmmain.datelen);
  476. }
  477.  
  478. void siirran(UBYTE *dst,UBYTE *src,WORD len)
  479. {
  480. strncpy(dst,src,len);
  481. *(dst+len)=0;
  482. }
  483.  
  484. void fittext(struct RastPort *rp,UBYTE *txt,WORD txtlen,WORD x,WORD y,WORD width,WORD mode)
  485. {
  486. WORD len;
  487. struct TextExtent txtext;
  488.  
  489. width--;
  490. if(txtlen<0) txtlen=strlen(txt);
  491. len=TextFit(rp,txt,txtlen,&txtext,0,1,width,32767);
  492. ObtainSemaphore(&fmmain.gfxsema);
  493. SetAPen(rp,fmconfig->backpen);
  494. WaitTOF();
  495. RectFill(rp,x,y,width+x,y+fmmain.txtysize-1);
  496. if(!mode)
  497.     Move(rp,x,y+fmmain.txtbaseline);
  498.     else
  499.     Move(rp,x+(width-txtext.te_Width)/2,y+fmmain.txtbaseline);
  500. SetAPen(rp,fmconfig->txtpen);
  501. Text(rp,txt,len);
  502. ReleaseSemaphore(&fmmain.gfxsema);
  503. }
  504.  
  505. WORD strtohex(UBYTE *ptr)
  506. {
  507. UBYTE bapu1,bapu2;
  508.  
  509. bapu1=ToUpper(ptr[0]);
  510. bapu2=ToUpper(ptr[1]);
  511. if(((bapu2<'0'||bapu2>'9')&&(bapu2<'A'||bapu2>'F'))||((bapu1<'0'||bapu1>'9')&&(bapu1<'A'||bapu1>'F'))) return(-1);
  512. if(bapu1>='A') bapu1-=7;
  513. if(bapu2>='A') bapu2-=7;
  514. bapu1-='0';
  515. bapu2-='0';
  516. return((WORD)(bapu1<<4|bapu2));
  517. }
  518.  
  519. void memseti(void *dst,UBYTE ch,LONG len)
  520. {
  521. UBYTE *dst2=(UBYTE*)dst;
  522. while(len--) *dst2++=ch;
  523. }
  524.  
  525. UBYTE *scanchar(UBYTE *ptr,UBYTE ch)
  526. {
  527. while(*ptr) {
  528.     if (*ptr==ch) return(ptr);
  529.     ptr++;
  530. }
  531. return(0);
  532. }
  533.