Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / fish / memomaster / listfunc.c
blob5b41cf5e970094357cf89490a60f85ea1d5f906f
1 #include <proto/exec.h>
2 #include <proto/dos.h>
3 #include <proto/intuition.h>
4 #include <proto/alib.h>
6 /* Functions for creating and manipulating the list of memos
8 * Functions in this file are :-
10 * struct MinList *LoadData() \ Not yet included/complete
11 * int SaveData() /
12 * struct MinNode *MoveBackOne(struct MinNode *p)
13 * struct MinNode *MoveBackBlock(struct MinNode *p)
14 * struct MinNode *MoveEnd(struct MinNode *p)
15 * struct MinNode *MoveFwdOne(struct MinNode *p)
16 * struct MinNode *MoveFwdBlock(struct MinNode *p)
17 * void DisplayBlock()
18 * void Toggle(int t_gadget)
20 * (to the memo currently top of the display)
21 * The pointer ^ is generally held as a pointer to a MinNode structure since
22 * this makes the code clearer and more efficient(?) since it does not
23 * need to be cast into this form from the Memo_In_Mem form all over the
24 * place.
26 * Use them like so:-
27 * struct MinNode *x,*DisplayFirst;
28 * x=MoveFwdBlock(DisplayFirst);
29 * if (x != DisplayFirst)
30 * {
31 * DisplayFirst=x;
32 * DisplayBlock(DisplayFirst);
33 * }
36 #include <exec/types.h>
37 #include <exec/nodes.h>
38 #include <exec/lists.h>
39 #include <exec/memory.h>
41 /*#include "mm2_test.h"*/
43 #include "mm2.h"
44 #include <stdio.h>
45 #include <string.h>
47 #ifdef __AROS__
48 #define remove DeleteFile
49 #define rename Rename
50 #endif
52 extern void Display_One(), Display_Blank();
54 extern struct MinNode *DisplayFirst;
55 extern struct Remember *RK;
56 extern struct MinList *MemListPtr;
58 void Toggle();
60 /* ==========================================================================
61 * LoadData() - version using exec list handling
64 struct MinList *LoadData()
66 FILE *fp;
67 struct MinList *mlp;
68 struct Memo_Item mi;
69 struct MI_Mem *p;
70 int OK;
72 mlp=(struct MinList *)AllocRemember(&RK,sizeof(struct MinList),MEMF_PUBLIC);
73 if (mlp == NULL) return mlp; /* Failed. No memory to start list */
74 NewList((struct List *)mlp);
75 fp=fopen("memos:memodata.dat","r");
77 if (fp == NULL ) return mlp; /* File isn't there. Return empty list */
78 OK=fread((char *)&mi,sizeof(struct Memo_Item),1,fp);
79 while (OK)
81 p=(struct MI_Mem *)AllocRemember(&RK,sizeof(struct MI_Mem),MEMF_PUBLIC);
82 if (p == NULL)
84 /* Take some ABORT!!!! type action here due to loss of memory */
86 memcpy((char *)&(p->mim_MI),(char *)&mi,sizeof(struct Memo_Item) );
87 p->mim_Select = 0; /* All memos start off deselected */
88 p->mim_MI.mi_Text[60]='\0';
89 AddTail((struct List *)mlp,(struct Node *)p);
90 OK=fread((char *)&mi,sizeof(struct Memo_Item),1,fp);
92 fclose(fp);
93 return mlp;
96 /*=====================================================================
97 * SaveData()
99 * Writes structures in list to file memodata.dat . Previous version of
100 * memodata.dat is renamed .bak
102 * !!!!!!! Currently no error checking !!!!!!!
104 int SaveData()
106 FILE *fp;
107 int Save_Status=1; /* Assume success */
108 struct MinNode *n;
109 struct MI_Mem *m;
111 remove("memos:memodata.bak");
112 rename("memos:memodata.dat","memos:memodata.bak");
113 if (LISTEMPTY) return Save_Status;
114 fp=fopen("memos:memodata.dat","w");
115 n=MemListPtr->mlh_Head;
116 while (n->mln_Succ)
118 m=(struct MI_Mem *)n;
119 fwrite((char *)&(m->mim_MI),sizeof(struct Memo_Item),1,fp);
120 n = n->mln_Succ;
122 fclose(fp);
123 return Save_Status;
128 /* =========================================================================
129 * Move the 'current' memo back one
131 struct MinNode *MoveBackOne(struct MinNode *p)
133 if (p->mln_Pred != (struct MinNode *)MemListPtr)
135 p=p->mln_Pred;
137 return p;
140 /* =========================================================================
141 *Move the 'current' memo back a block
144 struct MinNode *MoveBackBlock(struct MinNode *p)
146 int moved;
148 moved=0;
149 while ((moved < MEMOS_IN_BLOCK) && (p->mln_Pred != (struct MinNode *)MemListPtr))
151 p=p->mln_Pred;
152 moved ++;
154 return p;
157 /*=========================================================================
158 * Move the 'current' memo forward one. More complicated than at first apparent
159 * because the current pointer is the one at the start of the block and the
160 * end of the list has to be checked relative to the last in the block.
161 * Actually move the current pointer MEMOS_IN_BLOCK+1 forward (or until
162 * the end of the list) and then MEMOS_IN_BLOCK backward (or the number
163 * moved forwards if smaller) */
165 struct MinNode *MoveFwdOne(struct MinNode *p)
167 int cf;
169 cf=0;
170 while ((cf<MEMOS_IN_BLOCK+1) && (p->mln_Succ))
172 p=p->mln_Succ;
173 cf++;
175 cf=MIN(cf,MEMOS_IN_BLOCK);
176 while (cf > 0)
178 p=p->mln_Pred;
179 cf--;
181 return p;
184 /*=========================================================================
185 * Move the 'current' memo forward one block.
186 * Actually move the current pointer MEMOS_IN_BLOCK*2 forward (or until
187 * the end of the list) and then MEMOS_IN_BLOCK backward (or the number
188 * moved forwards if smaller) */
190 struct MinNode *MoveFwdBlock(struct MinNode *p)
192 int cf;
194 cf=0;
195 while ((cf < MEMOS_IN_BLOCK+MEMOS_IN_BLOCK) && (p->mln_Succ))
197 p=p->mln_Succ;
198 cf++;
200 cf=MIN(cf,MEMOS_IN_BLOCK);
201 while (cf > 0)
203 p=p->mln_Pred;
204 cf--;
206 return p;
208 /*========================================================================
209 * Makes succesive calls to Display_One() to display a block of memos.
210 * Param is pointer to a node structure attached to first memo
211 * to be displayed. Value of parameter is DisplayFirst which may need to
212 * be reset prior to call to Display_Block(). If param is NULL then list
213 * must be empty so display all blank memos
214 =========================================================================*/
215 void Display_Block(struct MinNode *m)
217 int p;
219 p=0;
220 if (m)
222 /* while ( (p<MEMOS_IN_BLOCK) && ( m != NULL ) ) */
223 while ( (p<MEMOS_IN_BLOCK) && ( m->mln_Succ ) )
225 Display_One( p, (struct MI_mem *)m );
226 p++;
227 m=m->mln_Succ;
231 while ( p<MEMOS_IN_BLOCK )
233 Display_Blank( p );
234 p++;
237 /*=========================================================================
238 * If memo display gadget clicked on is currently showing a memo, toggle
239 * the memos selected indicator and redisplay.
241 void Toggle(int t_gadget)
243 int g;
244 struct MinNode *n;
246 n=DisplayFirst;
247 for (g=0 ; g < t_gadget ; g++)
249 n=n->mln_Succ;
250 if (!n) break;
252 if (n) if (n->mln_Succ)
254 if ( ((struct MI_Mem *)n)->mim_Select == 0) /* ie if not currently selected */
255 ((struct MI_Mem *)n)->mim_Select=1;
256 else
257 ((struct MI_Mem *)n)->mim_Select=0;
258 Display_One(g,(struct MI_Mem *)n);
263 /*=========================================================================
264 * Move the 'current' memo forward to end
265 * Actually move the current pointer forward to
266 * the end of the list) and then MEMOS_IN_BLOCK backward
269 struct MinNode *MoveEnd(struct MinNode *p)
271 int b;
273 while (p->mln_Succ)
275 p=p->mln_Succ;
277 b=MEMOS_IN_BLOCK;
278 while (b > 0)
280 p=p->mln_Pred;
281 b--;
283 return p;