Enable silent-rules for compilation
[fsviewer.git] / src / FSMCList.c
bloba89c7504d050f1f756724d66b0a695374ae71a86
1 #include <WMaker.h>
2 #include <WINGs/WINGsP.h>
3 #include <grp.h>
4 #include <pwd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8 #include <time.h>
10 #include "FSViewer.h"
11 #include "FSMCList.h"
12 #include "FSUtils.h"
13 #include "FSBrowser.h"
14 #include "DnD.h"
15 #include "files.h"
16 #include "xpm/list_file.xpm"
17 #include "xpm/list_dir.xpm"
19 #define DEFAULT_SEPARATOR "/"
20 #define LISTITEM_HEIGHT 20
22 typedef struct _FSMCList {
24 WMFrame *parent;
25 WMScrollView *scrollV;
26 WMFrame *mainF;
27 FSBrowser *browser;
28 WMSize size;
30 WMLabel *titles[6];
31 char *filter;
33 void *clientData;
34 WMAction *action;
35 void *doubleClientData;
36 WMAction *doubleAction;
38 } _FSMCList;
40 static void handleDoubleAction(WMWidget *self, void *data);
41 static void handleItemSelection(WMWidget *self, void *clientData);
42 static void fillBrowserColumn(FSBrowser *bPtr, int column);
43 static void paintItem(WMList *lPtr, int index, Drawable d, char *text,
44 int state, WMRect *rect);
45 static char *createTruncatedString(WMFont *font, char *text,
46 int *textLen, int width);
47 char *parseItem(WMListItem *item);
49 FSMCList *
50 FSCreateMCList(WMFrame *parent)
52 FSMCList *mPtr;
54 mPtr = (FSMCList *) wmalloc(sizeof(FSMCList));
55 memset(mPtr, 0, sizeof(FSMCList));
57 mPtr->parent = parent;
59 mPtr->scrollV = WMCreateScrollView(mPtr->parent);
60 WMResizeWidget(mPtr->scrollV, 510, 275);
61 WMMoveWidget(mPtr->scrollV, 0, 0);
62 WMSetScrollViewRelief(mPtr->scrollV, WRSunken);
63 WMSetScrollViewHasVerticalScroller(mPtr->scrollV, False);
64 WMSetScrollViewHasHorizontalScroller(mPtr->scrollV, True);
66 mPtr->mainF = WMCreateFrame(mPtr->parent);
67 WMResizeWidget(mPtr->mainF, 637, 255);
68 WMMoveWidget(mPtr->mainF, 0, 0);
69 WMSetFrameRelief(mPtr->mainF, WRFlat);
71 mPtr->size.width = 637;
72 mPtr->size.height = 255;
74 mPtr->titles[0] = WMCreateLabel(mPtr->mainF);
75 WMSetLabelText(mPtr->titles[0], _("Name"));
76 WMSetLabelTextAlignment(mPtr->titles[0], WACenter);
77 WMSetLabelRelief(mPtr->titles[0], WRGroove);
78 WMResizeWidget(mPtr->titles[0], 214, 20);
79 WMMoveWidget(mPtr->titles[0], 0, 0);
81 mPtr->titles[1] = WMCreateLabel(mPtr->mainF);
82 WMSetLabelText(mPtr->titles[1], _("Size"));
83 WMSetLabelTextAlignment(mPtr->titles[1], WACenter);
84 WMSetLabelRelief(mPtr->titles[1], WRGroove);
85 WMResizeWidget(mPtr->titles[1], 82, 20);
86 WMMoveWidget(mPtr->titles[1], 213, 0);
88 mPtr->titles[2] = WMCreateLabel(mPtr->mainF);
89 WMSetLabelText(mPtr->titles[2], _("Last Changed"));
90 WMSetLabelTextAlignment(mPtr->titles[2], WACenter);
91 WMSetLabelRelief(mPtr->titles[2], WRGroove);
92 WMResizeWidget(mPtr->titles[2], 100, 20);
93 WMMoveWidget(mPtr->titles[2], 294, 0);
95 mPtr->titles[3] = WMCreateLabel(mPtr->mainF);
96 WMSetLabelText(mPtr->titles[3], _("Permissions"));
97 WMSetLabelTextAlignment(mPtr->titles[3], WACenter);
98 WMSetLabelRelief(mPtr->titles[3], WRGroove);
99 WMResizeWidget(mPtr->titles[3], 82, 20);
100 WMMoveWidget(mPtr->titles[3], 393, 0);
102 mPtr->titles[4] = WMCreateLabel(mPtr->mainF);
103 WMSetLabelText(mPtr->titles[4], _("Owner"));
104 WMSetLabelTextAlignment(mPtr->titles[4], WACenter);
105 WMSetLabelRelief(mPtr->titles[4], WRGroove);
106 WMResizeWidget(mPtr->titles[4], 82, 20);
107 WMMoveWidget(mPtr->titles[4], 474, 0);
109 mPtr->titles[5] = WMCreateLabel(mPtr->mainF);
110 WMSetLabelText(mPtr->titles[5], _("Group"));
111 WMSetLabelTextAlignment(mPtr->titles[5], WACenter);
112 WMSetLabelRelief(mPtr->titles[5], WRGroove);
113 WMResizeWidget(mPtr->titles[5], 82, 20);
114 WMMoveWidget(mPtr->titles[5], 555, 0);
116 mPtr->browser = FSCreateBrowser(mPtr->mainF);
117 FSSetBrowserHasScroller(mPtr->browser, False);
118 FSSetBrowserTitled(mPtr->browser, False);
119 FSSetBrowserRelief(mPtr->browser, WRFlat);
120 WMMoveWidget(mPtr->browser, 0, 20);
121 WMResizeWidget(mPtr->browser, 637, 235);
122 FSSetBrowserFillColumnProc(mPtr->browser, fillBrowserColumn);
123 FSSetBrowserGetItemNameProc(mPtr->browser, parseItem);
124 FSSetBrowserPathSeparator(mPtr->browser, DEFAULT_SEPARATOR);
125 FSSetBrowserAction(mPtr->browser, handleItemSelection, mPtr);
126 FSSetBrowserDoubleAction(mPtr->browser, handleDoubleAction, mPtr);
127 FSSetBrowserDisplayFileCol(mPtr->browser, 0);
128 WMHangData(mPtr->browser, mPtr);
129 FSSetBrowserMaxVisibleColumns(mPtr->browser, 1);
131 WMMapSubwidgets(mPtr->mainF);
132 WMMapWidget(mPtr->mainF);
133 WMMapWidget(mPtr->scrollV);
135 WMSetScrollViewContentView(mPtr->scrollV, WMWidgetView(mPtr->mainF));
137 return mPtr;
140 char *
141 parseItem(WMListItem *item)
143 int i;
144 char *str;
145 char *tmp;
146 char *text = NULL;
149 i = 0;
150 str = wstrdup(item->text);
151 tmp = strtok(str, "==");
152 while (tmp)
154 if(i==1)
155 text = wstrdup(tmp);
157 tmp = strtok(NULL, "==");
158 i++;
160 free(str);
162 if(!text)
163 text = wstrdup(item->text);
165 return text;
168 static char *
169 formatFileInfo(WMScreen *scr, FileInfo *fileInfo)
171 char sep[3] = "||";
172 char *img = NULL;
173 char *text = NULL;
174 char *name = NULL;
175 char size[128];
176 char time[128];
177 char mode[11] = "----------";
178 char *owner = NULL;
179 char *group = NULL;
180 struct passwd *psswd;
181 struct group *grp;
182 struct tm *st_tm;
184 if(isDirectory(fileInfo->fileType))
186 img = wstrdup("0");
187 mode[0] = 'd';
189 else
190 img = wstrdup("1");
192 if(fileInfo->name)
193 name = wstrdup(fileInfo->name);
194 else
195 name = wstrdup("nameless");
197 snprintf(size, 128, "%ld", (long) fileInfo->st->st_size);
198 st_tm = localtime(&(fileInfo->st->st_ctime));
199 strftime(time, 128, "%b %d %H:%M", st_tm);
201 if(fileInfo->st->st_mode & S_IRUSR)
202 mode[1] = 'r';
203 if(fileInfo->st->st_mode & S_IWUSR)
204 mode[2] = 'w';
205 if(fileInfo->st->st_mode & S_IXUSR)
206 mode[3] = 'x';
207 if(fileInfo->st->st_mode & S_IRGRP)
208 mode[4] = 'r';
209 if(fileInfo->st->st_mode & S_IWGRP)
210 mode[5] = 'w';
211 if(fileInfo->st->st_mode & S_IXGRP)
212 mode[6] = 'x';
213 if(fileInfo->st->st_mode & S_IROTH)
214 mode[7] = 'r';
215 if(fileInfo->st->st_mode & S_IWOTH)
216 mode[8] = 'w';
217 if(fileInfo->st->st_mode & S_IXOTH)
218 mode[9] = 'x';
220 grp = getgrgid(fileInfo->st->st_gid);
221 if(grp)
222 group = wstrdup(grp->gr_name);
223 else
224 group = wstrdup("nogroup");
226 psswd = getpwuid(fileInfo->st->st_uid);
227 if(psswd)
228 owner = wstrdup(psswd->pw_name);
229 else
230 owner = wstrdup("ownerless");
232 text = (char *) wmalloc(strlen(img) + strlen(name) + strlen(size) +
233 strlen(time) + strlen(mode) + strlen(group) +
234 strlen(owner)+13);
235 /* strcpy(text, sep); */
236 /* strcat(text, img); */
237 strcpy(text, img);
238 strcat(text, sep);
239 strcat(text, name);
240 strcat(text, sep);
241 strcat(text, size);
242 strcat(text, sep);
243 strcat(text, time);
244 strcat(text, sep);
245 strcat(text, mode);
246 strcat(text, sep);
247 strcat(text, owner);
248 strcat(text, sep);
249 strcat(text, group);
250 /* strcat(text, sep); */
252 return text;
255 static void
256 fillBrowserColumn(FSBrowser *bPtr, int column)
258 char *path;
259 FileInfo *fileList;
260 FileInfo *start = NULL;
261 WMListItem *listItem;
262 FSMCList *mPtr = (FSMCList *)(WMGetHangedData(bPtr));
263 WMList *list = FSGetBrowserListInColumn(bPtr, column);
264 WMScreen *scr = WMWidgetScreen(list);
267 * Override the FSBrowser drawing procedure
269 if(list)
271 WMSetListUserDrawProc(list, paintItem);
272 WMSetListUserDrawItemHeight(list, LISTITEM_HEIGHT);
275 FSSetBusyCursor(bPtr, True);
277 path = FSGetBrowserPathToColumn(bPtr, column);
278 if(path)
280 start = GetDirList(path);
281 fileList = start;
283 while(fileList != NULL)
285 if( DisplayFile(fileList->name, mPtr->filter, fileList->fileType) )
287 listItem = FSInsertBrowserItem(bPtr, column, -1,
288 fileList->name,
289 isDirectory(fileList->fileType));
290 listItem->clientData = formatFileInfo(scr, fileList);
293 fileList = fileList->next;
297 if (path)
299 free(path);
302 if(start)
303 FSFreeFileInfo(start);
305 FSSetBusyCursor(bPtr, False);
308 static void
309 handleItemSelection(WMWidget *self, void *clientData)
311 /* int col; */
312 /* char *path; */
313 /* FileBrowser *bPtr = (FileBrowser *) clientData; */
315 /* col = FSGetFileBrowserColumnCount(bPtr); */
317 /* FSSetPathViewToColumn(bPtr->pathView, col-1); */
318 /* if(bPtr->text) */
319 /* { */
320 /* wwarning("%s %d: %s", __FILE__, __LINE__, bPtr->text); */
321 /* free(bPtr->text); */
322 /* bPtr->text = NULL; */
323 /* } */
326 static void
327 handleDoubleAction(WMWidget *self, void *clientData)
329 /* FileBrowser *bPtr = (FileBrowser *) clientData; */
331 /* if (bPtr->doubleAction) */
332 /* (*bPtr->doubleAction)(bPtr, bPtr->doubleClientData); */
335 void
336 FSLoadMCListColumnZero(FSMCList *mPtr)
338 FSLoadBrowserColumnZero(mPtr->browser);
341 void
342 FSSetMCListPath(FSMCList *mPtr, char *path)
344 FSSetBrowserPath(mPtr->browser, path);
348 FSGetMCListNumberOfColumns(FSMCList *mPtr)
350 return FSGetBrowserNumberOfColumns(mPtr->browser);
353 void
354 FSResizeMCList(FSMCList *mPtr, unsigned int width, unsigned int height)
356 if(mPtr->size.width < width)
358 WMResizeWidget(mPtr->mainF, width-3, height);
359 WMResizeScrollViewContent(mPtr->scrollV, width-3, height);
360 WMResizeWidget(mPtr->scrollV, width, height);
361 WMResizeWidget(mPtr->browser, width-3, height-40);
363 else
365 WMResizeScrollViewContent(mPtr->scrollV, mPtr->size.width-3, height);
366 WMResizeWidget(mPtr->scrollV, width, height);
367 WMResizeWidget(mPtr->browser, mPtr->size.width, height-40);
368 WMResizeWidget(mPtr->mainF, mPtr->size.width, height);
373 char *
374 FSGetMCListPath(FSMCList *mPtr)
376 int len;
377 char *path = NULL;
378 char *npath = NULL;
380 path = FSGetBrowserPath(mPtr->browser);
381 len = strlen(path);
382 if(len > 1 && path[len-1] == '/')
384 npath = (char *)wmalloc(len);
385 strncpy(npath, path, len-1);
386 npath[len-1] = '\0';
388 else
389 npath = wstrdup(path);
391 if(path)
392 free(path);
393 return npath;
396 char *
397 FSGetMCListPathToColumn(FSMCList *mPtr, int column)
399 return FSGetBrowserPathToColumn(mPtr->browser, column);
402 static char*
403 createTruncatedString(WMFont *font, char *text, int *textLen, int width)
405 int dLen = WMWidthOfString(font, ".", 1);
406 char *textBuf = (char*)wmalloc((*textLen)+4);
408 if (width >= 3*dLen) {
409 int dddLen = 3*dLen;
410 int tmpTextLen = *textLen;
412 strcpy(textBuf, text);
413 while (tmpTextLen
414 && (WMWidthOfString(font, textBuf, tmpTextLen)+dddLen > width))
415 tmpTextLen--;
416 strcpy(textBuf+tmpTextLen, "...");
417 *textLen = tmpTextLen+3;
418 } else if (width >= 2*dLen) {
419 strcpy(textBuf, "..");
420 *textLen = 2;
421 } else if (width >= dLen) {
422 strcpy(textBuf, ".");
423 *textLen = 1;
424 } else {
425 *textBuf = '\0';
426 *textLen = 0;
428 return textBuf;
431 static void
432 paintItem(WMList *lPtr, int index, Drawable d,
433 char *text, int state, WMRect *rect)
435 int i = 0;
436 int j = 0;
437 int k = 0;
438 int img = 1;
439 int fontHeight = 14;
440 char tmp[512];
441 char *items[7];
442 char *str = NULL;
443 WMView *view = W_VIEW(lPtr);
444 W_Screen *scr = view->screen;
445 int width, height, x, y, len;
446 WMListItem *item = WMGetListItem(lPtr, index);
448 width = rect->size.width;
449 height = rect->size.height;
450 x = rect->pos.x;
451 y = rect->pos.y;
452 fontHeight = WMFontHeight(scr->normalFont);
454 /* Highlight the selected area */
455 if (state & WLDSSelected)
456 WMPaintColorSwatch(WMWhiteColor(scr), d, x, y,
457 width, height);
458 else
459 WMPaintColorSwatch(WMGetWidgetBackgroundColor(lPtr), d, x, y,
460 width, height);
462 if(item->clientData)
464 str = wstrdup(item->clientData);
465 len = strlen(str);
467 else
469 str = NULL;
470 len = 0;
473 /* simple parse of the clientdata */
474 for(i = 0; i < len; i++)
476 if(/* str[i-1] != '=' && */str[i] != '|')
478 tmp[k] = str[i];
479 k++;
481 else
483 tmp[k] = '\0';
484 i +=1;
485 k = 0;
486 items[j++] = wstrdup(tmp);
489 tmp[k] = '\0';
490 items[j++] = wstrdup(tmp);
492 /* iterate through items and draw each one */
493 for(i = 0; i < j; i++)
495 if(i == 0)
497 if(strcmp(items[i], "0") == 0)
498 img = 0;
499 else
500 img = 1;
501 /* do nothing for the moment */
503 else if(i==1)
505 WMSize size;
506 WMPixmap *image;
507 int widthC = 168; /*194 - 26*/
508 int textLen = strlen(items[i]);
510 if(FSGetIntegerForName("DisplayMCListPixmap"))
512 if(img == 0)
513 image = WMCreatePixmapFromXPMData(scr, list_dir_xpm);
514 else
515 image = WMCreatePixmapFromXPMData(scr, list_file_xpm);
516 size = WMGetPixmapSize(image);
517 WMDrawPixmap(image, d,
518 x+6+(20-size.width)/2, (height-size.height)/2+y);
519 WMReleasePixmap(image);
522 else
524 char *tmpStr = NULL;
526 if(img == 0)
527 tmpStr = wstrdup("D");
528 else
529 tmpStr = wstrdup("F");
531 W_PaintText(view, d, scr->boldFont,
532 x+6, y+(height-fontHeight)/2, widthC,
533 WALeft, WMDarkGrayColor(scr), False,
534 tmpStr, 1);
536 free(tmpStr);
539 if (WMWidthOfString(scr->normalFont, items[i], textLen) > widthC)
541 char *textBuf = createTruncatedString(scr->normalFont,
542 items[i], &textLen,
543 widthC);
545 W_PaintText(view, d, scr->normalFont,
546 x+26, y+(height-fontHeight)/2, widthC,
547 WALeft, WMBlackColor(scr), False,
548 textBuf, textLen);
550 free(textBuf);
552 else
554 W_PaintText(view, d, scr->normalFont,
555 x+26, y+(height-fontHeight)/2, widthC,
556 WALeft, WMBlackColor(scr), False, items[i],
557 textLen);
559 x += 194;
561 else if(i==3)
563 W_PaintText(view, d, scr->normalFont,
564 x+6, y+(height-fontHeight)/2, 100,
565 WALeft, WMBlackColor(scr), False, items[i],
566 strlen(items[i]));
567 x += 100;
569 else
571 W_PaintText(view, d, scr->normalFont,
572 x+6, y+(height-fontHeight)/2, 82,
573 WALeft, WMBlackColor(scr), False, items[i],
574 strlen(items[i]));
575 x += 82;
577 free(items[i]);
578 items[i] = NULL;
580 free(str);
583 void
584 FSSetMCListFilter(FSMCList *mPtr, char *filter)
586 mPtr->filter = filter;
589 void
590 FSScrollMCListToColumn(FSMCList *mPtr, int col, Bool updateScroller)
592 FSScrollBrowserToColumn(mPtr->browser, col, updateScroller);
595 void
596 FSSetMCListAction(FSMCList *mPtr, WMAction *action, void *clientData)
598 FSSetBrowserAction(mPtr->browser, action, clientData);
601 void
602 FSSetMCListDoubleAction(FSMCList *mPtr, WMAction *action, void *clientData)
604 FSSetBrowserDoubleAction(mPtr->browser, action, clientData);
607 WMListItem*
608 FSGetMCListSelectedItemInColumn(FSMCList *mPtr, int column)
610 return FSGetBrowserSelectedItemInColumn(mPtr->browser, column);
613 WMList*
614 FSGetMCListListInColumn(FSMCList *mPtr, int column)
616 return FSGetBrowserListInColumn(mPtr->browser, column);
619 char *
620 FSMCListFormatFileInfo(FSMCList *mPtr, FileInfo *fileInfo)
622 return formatFileInfo(WMWidgetScreen(mPtr), fileInfo);