ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/crossedit/Cnv/CnvPath.c
Revision: 1.2
Committed: Sun Aug 13 17:16:01 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# Content
1 /*
2 * CnvPath - file selector
3 * Copyright (C) 1993 Petri Heinila
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * Author can be connected by email from hevi@lut.fi
20 */
21
22 #include <Cnv.h>
23 #include <debug.h>
24 #include <assert.h>
25
26 /**********************************************************************
27 * declarations
28 **********************************************************************/
29
30 static void CnvPathListInit(CnvPath p);
31 static void CnvPathListGet(CnvPath p,String path);
32 static void CnvPathEnter(CnvPath self);
33 static Boolean hasActions = False;
34 static CnvPath tmpCnvPath = NULL;
35
36 /**********************************************************************
37 * actions
38 **********************************************************************/
39
40 static void CnvPathReturn(Widget w,XEvent *e,String *argv, Cardinal *argc);
41
42 static XtActionsRec actions[] = {
43 {"CnvPathReturn", CnvPathReturn} /* when user accept */
44 };
45
46 static void CnvPathReturn(Widget w,XEvent *e,String *argv, Cardinal *argc)
47 {
48 CnvPath self = (CnvPath)tmpCnvPath;
49 assert(self);
50 CnvPathEnter(self);
51 }
52
53 /**********************************************************************
54 * widgets
55 **********************************************************************/
56
57 static void CnvPathCancelCb(Widget w,XtPointer client,XtPointer call)
58 {
59 CnvPath p = (CnvPath)client;
60 p->hold = CnvPathCancel;
61 }
62
63 static void CnvPathEnterCb(Widget w,XtPointer client,XtPointer call)
64 {
65 CnvPath self = (CnvPath)client;
66 CnvPathEnter(self);
67 }
68
69 static void CnvPathSelectFileCb(Widget w,XtPointer client,XtPointer call)
70 {
71 CnvPath p = (CnvPath)client;
72 XawListReturnStruct *ret = (XawListReturnStruct*)call;
73
74 XtVaSetValues(p->text,
75 XtNstring,ret->string,
76 NULL);
77 }
78
79 static void CnvPathSelectDirCb(Widget w,XtPointer client,XtPointer call)
80 {
81 CnvPath p = (CnvPath)client;
82 XawListReturnStruct *ret = (XawListReturnStruct*)call;
83 char path[PATH_MAX+1];
84
85 if(strcmp(ret->string,"..") == 0) {
86 char *str;
87 pathcpy(path,p->current);
88 str = path + strlen(path);
89 while(*str != '/' && str > path) str--;
90 *str = 0;
91 } else if(strcmp(ret->string,".") == 0) {
92 sprintf(path,"%s",p->current);
93 } else {
94 sprintf(path,"%s/%s",p->current,ret->string);
95 }
96 p->hold = CnvPathHold;
97 CnvPathListGet(p,path);
98 }
99
100 /**********************************************************************
101 * Layout
102 **********************************************************************/
103
104 static void Layout(CnvPath self,String name)
105 {
106 Widget cont,cancel,fileView,dirView,ok;
107
108 self->shell = XtVaCreatePopupShell
109 (name,transientShellWidgetClass,cnv->shell,NULL);
110 cont = XtVaCreateManagedWidget
111 ("cont",formWidgetClass,self->shell,
112 NULL);
113 self->cwd = XtVaCreateManagedWidget
114 ("cwd",labelWidgetClass,cont,
115 /*
116 XtNfromHoriz,NULL,
117 XtNfromVert,NULL,
118 */
119 NULL);
120 self->text = XtVaCreateManagedWidget
121 ("text",asciiTextWidgetClass,cont,
122 XtNtype,XawAsciiString,
123 XtNeditType,XawtextEdit,
124 XtNfromHoriz,self->cwd,
125 XtNfromVert,NULL,
126 XtNaccelerators,XtParseAcceleratorTable
127 ("#override <Key>Return: CnvPathReturn() \n"),
128 XtNtranslations,XtParseTranslationTable
129 ("#override <Key>Tab: CnvNop()\n"
130 "<Key>Return: CnvPathReturn() \n"),
131 NULL);
132 fileView = XtVaCreateManagedWidget
133 ("fileView",viewportWidgetClass,cont,
134 XtNfromHoriz,NULL,
135 XtNfromVert,self->cwd,
136 NULL);
137 self->fileList = XtVaCreateManagedWidget
138 ("fileList",listWidgetClass,fileView,
139 XtNtranslations,XtParseTranslationTable
140 ("#override <Btn1Up>(2): Set() Notify() CnvPathReturn()\n"
141 "<Btn1Down>: Set() Notify() \n"),
142 NULL);
143 XtAddCallback(self->fileList,XtNcallback,CnvPathSelectFileCb,
144 (XtPointer)self);
145 dirView = XtVaCreateManagedWidget
146 ("dirView",viewportWidgetClass,cont,
147 XtNfromHoriz,fileView,
148 XtNfromVert,self->cwd,
149 NULL);
150 self->dirList = XtVaCreateManagedWidget
151 ("dirList",listWidgetClass,dirView,
152 NULL);
153 XtAddCallback(self->dirList,XtNcallback,CnvPathSelectDirCb,(XtPointer)self);
154 ok = XtVaCreateManagedWidget
155 ("ok",commandWidgetClass,cont,
156 XtNfromHoriz,NULL,
157 XtNfromVert,fileView,
158 NULL);
159 XtAddCallback(ok,XtNcallback,CnvPathEnterCb,(XtPointer)self);
160 cancel = XtVaCreateManagedWidget
161 ("cancel",commandWidgetClass,cont,
162 XtNfromHoriz,ok,
163 XtNfromVert,fileView,
164 NULL);
165 XtAddCallback(cancel,XtNcallback,CnvPathCancelCb,(XtPointer)self);
166 XtInstallAllAccelerators(cont,cont);
167 }
168
169 /**********************************************************************
170 *
171 **********************************************************************/
172
173 /*
174 * function: select a filepath
175 */
176 static void CnvPathEnter(CnvPath self)
177 {
178 String str;
179
180 self->hold = CnvPathOk;
181 XtVaGetValues(self->text,
182 XtNstring,&str,
183 NULL);
184 namecpy(self->filename,str);
185 }
186
187 /*
188 * implicit: App app
189 */
190 static void CnvPathListInit(CnvPath p)
191 {
192 int i;
193
194 for(i=0; i < EntryMax; i++) {
195 /* debug1("i:%i\n",i); */
196 p->fileTable[i] = NULL;
197 }
198 for(i=0; i < EntryMax; i++) {
199 /* debug1("i2:%i\n",i); */
200 p->dirTable[i] = NULL;
201 }
202 p->fileNro = 0;
203 p->dirNro = 0;
204 *(p->filename) = 0;
205 }
206
207 /*
208 * compare funtion for sorting in CnvPathListGet()
209 */
210 static int StrCmp (const void **s1, const void **s2)
211 {
212 return strcmp (*s1, *s2);
213 }
214
215 /*
216 * read files and directories from given absolute dir
217 * update them into Path structure. directoty is a crossfire
218 * part of file name ie. LibDir/MapDir<dirname>, althought
219 * it is absolute name in it part, ie it have to begin with '/'.
220 */
221 static void CnvPathListGet(CnvPath self,String directory)
222 {
223 DIR *dir;
224 #ifdef NeXT
225 struct direct *dirent;
226 #else
227 struct dirent *dirent;
228 #endif
229 struct stat statbuf;
230 Cardinal i,fileOld,dirOld;
231 char path[PATH_MAX+1],full[PATH_MAX+1];
232
233 /*** form full dir name ***/
234 sprintf(full,"%s%s",self->root,directory);
235 debug1("CnvPathListGet(), rescan %s\n",full);
236
237 /*** open it ***/
238 if(CnvPathNoAccess(self->shell, full)) return;
239 if((dir = opendir(full)) == NULL) CnvDie(self->shell,full);
240 XtVaSetValues(self->cwd,
241 XtNlabel,directory,
242 NULL);
243 pathcpy(self->current,directory);
244
245 /*** read dir & files ***/
246 fileOld = self->fileNro;
247 dirOld = self->dirNro;
248 self->fileNro = 0;
249 self->dirNro = 0;
250 while((dirent = readdir(dir)) != NULL) {
251 sprintf(path,"%s/%s",full,dirent->d_name);
252
253 if (stat ((char *) path, &statbuf) == -1) {
254 perror (path);
255 continue;
256 }
257 if(S_ISDIR(statbuf.st_mode)) {
258 if(self->dirNro >= EntryMax) continue;
259
260 XtFree(self->dirTable[self->dirNro]);
261 self->dirTable[self->dirNro] = XtNewString(dirent->d_name);
262
263 self->dirNro++;
264 } else {
265 if(self->fileNro >= EntryMax) continue;
266
267 XtFree(self->fileTable[self->fileNro]);
268 self->fileTable[self->fileNro] = XtNewString(dirent->d_name);
269
270 self->fileNro++;
271 }
272 }
273 closedir(dir);
274
275 /*** free strings ***/
276 for(i = self->fileNro; i < fileOld; i++) {
277 XtFree(self->fileTable[i]);
278 self->fileTable[i] = NULL;
279 }
280 for(i = self->dirNro; i < dirOld; i++) {
281 XtFree(self->dirTable[i]);
282 self->dirTable[i] = NULL;
283 }
284
285 /*** sort tables ***/
286 qsort(self->fileTable,self->fileNro,sizeof(String),(int (*)())StrCmp);
287 qsort(self->dirTable,self->dirNro,sizeof(String),(int (*)())StrCmp);
288
289 /*** update ***/
290 XawListChange(self->fileList,self->fileTable,self->fileNro,0,True);
291 XawListChange(self->dirList,self->dirTable,self->dirNro,0,True);
292 }
293
294 /**********************************************************************
295 * public
296 **********************************************************************/
297
298 /*
299 * create new instance of file-selector, no show
300 * dir is crossfire path eg "/"
301 * name: name of this module
302 * root: all
303 * dir : starting directory
304 */
305 CnvPath CnvPathCreate(String name,String root,String dir)
306 {
307
308
309 CnvPath self;
310
311 debug3("CnvPathCreate() %s %s %s\n",name,root,dir);
312 self = (CnvPath) XtMalloc (sizeof (struct CnvPath));
313 memset(self,0,sizeof(struct CnvPath));
314 pathcpy(self->root,root);
315
316 /*** initialize translations if not done ***/
317 if(hasActions == False) {
318 XtAppAddActions(XtWidgetToApplicationContext(cnv->shell),
319 actions,
320 XtNumber(actions));
321 hasActions = True;
322 }
323 Layout(self,name);
324 CnvPathListInit(self);
325 CnvCenterWidget(self->shell);
326 CnvPathListGet(self,dir);
327 return self;
328 }
329
330 /*
331 * remove instance of file-selector
332 */
333 void CnvPathDestroy(CnvPath self)
334 {
335 Cardinal i;
336 debug("CnvPathDestroy()\n");
337
338 for(i=0;i<self->dirNro;i++) XtFree(self->dirTable[i]);
339 for(i=0;i<self->fileNro;i++) XtFree(self->fileTable[i]);
340 XtDestroyWidget(self->shell);
341 }
342
343 /*
344 * member: select a filepath
345 * return: PathResponce & results are in Path-structure
346 */
347 CnvPathResponce CnvPathSelect(CnvPath self)
348 {
349 if(tmpCnvPath) {
350 CnvNotify("File Selector already in use",
351 "Continue",NULL);
352 return CnvPathCancel;
353 }
354 XtVaSetValues(self->text,
355 XtNstring,self->filename,
356 NULL);
357 /*** round ***/
358 tmpCnvPath = self;
359 self->hold = CnvPathHold;
360 XtPopup(self->shell,XtGrabExclusive);
361 while(self->hold == CnvPathHold) {
362 XtAppProcessEvent(XtWidgetToApplicationContext(self->shell),XtIMXEvent);
363 }
364 XtPopdown(self->shell);
365 tmpCnvPath = NULL;
366 return self->hold;
367 }
368
369 /*
370 * member: select a filepath
371 * return: PathResponce & results are in Path-structure
372 */
373 CnvPathResponce CnvPathSelectAbs(CnvPath self,String path)
374 {
375 if(tmpCnvPath) {
376 CnvNotify("File Selector already in use",
377 "Continue",NULL);
378 return CnvPathCancel;
379 }
380 XtVaSetValues(self->text,
381 XtNstring,self->filename,
382 NULL);
383 /*** round ***/
384 tmpCnvPath = self;
385 self->hold = CnvPathHold;
386 XtPopup(self->shell,XtGrabExclusive);
387 while(self->hold == CnvPathHold) {
388 XtAppProcessEvent(XtWidgetToApplicationContext(self->shell),XtIMXEvent);
389 }
390 XtPopdown(self->shell);
391 tmpCnvPath = NULL;
392 sprintf(path,"%s%s/%s",self->root,self->current,self->filename);
393 return self->hold;
394 }
395
396 /**********************************************************************
397 * utility
398 **********************************************************************/
399
400 /*
401 * - path is full absolute name
402 * - return true if NO access
403 */
404 Boolean CnvPathNoAccess(Widget w, String path)
405 {
406 char buf[BUFSIZ];
407
408 if (access (path, R_OK | X_OK) == -1) {
409 switch (errno) {
410 case EACCES:
411 sprintf (buf, "Permission denied for %s", path);
412 CnvNotify (buf,Continue,NULL);
413 break;
414 case ENOENT:
415 sprintf (buf, "%s does not exist", path);
416 CnvNotify (buf,Continue,NULL);
417 break;
418 case EIO:
419 sprintf (buf, "IO error in accessing %s", path);
420 CnvNotify (buf,Continue,NULL);
421 break;
422 case ENAMETOOLONG:
423 case ENOTDIR:
424 sprintf (buf, "Error in pathname for %s", path);
425 CnvNotify (buf,Continue);
426 break;
427 default:
428 sprintf (buf, "Error accessing to %s", path);
429 CnvNotify (buf,Continue,NULL);
430 break;
431 }
432 return True;
433 } else {
434 return False;
435 }
436 }
437
438 /*
439 * - path is full absolute name
440 * - return true if NO access
441 */
442 Boolean CnvPathNoWrite(Widget w, String path)
443 {
444 char buf[BUFSIZ];
445
446 if (access (path, R_OK | W_OK) == -1) {
447 switch (errno) {
448 case EACCES:
449 sprintf (buf, "Permission denied for %s", path);
450 CnvNotify (buf,Continue,NULL);
451 break;
452 case ENOENT:
453 sprintf (buf, "%s does not exist", path);
454 CnvNotify (buf,Continue,NULL);
455 break;
456 case EIO:
457 sprintf (buf, "IO error in accessing %s", path);
458 CnvNotify (buf,Continue,NULL);
459 break;
460 case ENAMETOOLONG:
461 case ENOTDIR:
462 sprintf (buf, "Error in pathname for %s", path);
463 CnvNotify (buf,Continue);
464 break;
465 default:
466 sprintf (buf, "Error accessing to %s", path);
467 CnvNotify (buf,Continue,NULL);
468 break;
469 }
470 return True;
471 } else {
472 return False;
473 }
474 }
475
476 /*** end of CnvPath.c ***/
477
478