UNIXworkcode

1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 3 * ***** BEGIN LICENSE BLOCK ***** 4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 7 * 1.1 (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * http://www.mozilla.org/MPL/ 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 * 16 * The Original Code is the Microline Widget Library, originally made available under the NPL by Neuron Data <http://www.neurondata.com>. 17 * 18 * The Initial Developer of the Original Code is 19 * Netscape Communications Corporation. 20 * Portions created by the Initial Developer are Copyright (C) 1998 21 * the Initial Developer. All Rights Reserved. 22 * 23 * Contributor(s): 24 * 25 * Alternatively, the contents of this file may be used under the terms of 26 * either the GNU General Public License Version 2 or later (the "GPL"), or 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 * in which case the provisions of the GPL or the LGPL are applicable instead 29 * of those above. If you wish to allow use of your version of this file only 30 * under the terms of either the GPL or the LGPL, and not to allow others to 31 * use your version of this file under the terms of the MPL, indicate your 32 * decision by deleting the provisions above and replace them with the notice 33 * and other provisions required by the GPL or the LGPL. If you do not delete 34 * the provisions above, a recipient may use your version of this file under 35 * the terms of any one of the MPL, the GPL or the LGPL. 36 * 37 * In addition, as a special exception to the GNU GPL, the copyright holders 38 * give permission to link the code of this program with the Motif and Open 39 * Motif libraries (or with modified versions of these that use the same 40 * license), and distribute linked combinations including the two. You 41 * must obey the GNU General Public License in all respects for all of 42 * the code used other than linking with Motif/Open Motif. If you modify 43 * this file, you may extend this exception to your version of the file, 44 * but you are not obligated to do so. If you do not wish to do so, 45 * delete this exception statement from your version. 46 * 47 * ***** END LICENSE BLOCK ***** */ 48 49 50 #include <Xm/Xm.h> 51 #include <Xm/Form.h> 52 #include <XmL/Grid.h> 53 #include <XmL/Tree.h> 54 55 #include <sys/types.h> 56 #include <sys/stat.h> 57 #include <dirent.h> 58 59 void rowExpand(); 60 void rowCollapse(); 61 void rowDelete(); 62 void cellSelect(); 63 64 Widget grid; 65 66 main(argc, argv) 67 int argc; 68 char *argv[]; 69 { 70 XtAppContext app; 71 Widget shell, form, tree; 72 XmString str; 73 74 shell = XtAppInitialize(&app, "Tree4", NULL, 0, 75 &argc, argv, NULL, NULL, 0); 76 77 form = XtVaCreateManagedWidget("form", 78 xmFormWidgetClass, shell, 79 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 80 XmNshadowThickness, 0, 81 NULL); 82 83 /* Add Tree to left of Form */ 84 tree = XtVaCreateManagedWidget("tree", 85 xmlTreeWidgetClass, form, 86 XmNhorizontalSizePolicy, XmCONSTANT, 87 XmNautoSelect, False, 88 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 89 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 90 XtVaTypedArg, XmNblankBackground, XmRString, "white", 6, 91 XtVaTypedArg, XmNselectBackground, XmRString, "#000080", 8, 92 XtVaTypedArg, XmNselectForeground, XmRString, "white", 6, 93 XtVaTypedArg, XmNconnectingLineColor, XmRString, "#808080", 8, 94 XmNleftAttachment, XmATTACH_FORM, 95 XmNtopAttachment, XmATTACH_FORM, 96 XmNbottomAttachment, XmATTACH_FORM, 97 XmNrightAttachment, XmATTACH_POSITION, 98 XmNrightPosition, 45, 99 NULL); 100 XtVaSetValues(tree, 101 XmNcellDefaults, True, 102 XtVaTypedArg, XmNcellBackground, XmRString, "white", 6, 103 NULL); 104 105 /* Add a single row containing the root path to the Tree */ 106 str = XmStringCreateSimple("/"); 107 XmLTreeAddRow(tree, 1, True, False, 0, 108 XmUNSPECIFIED_PIXMAP, XmUNSPECIFIED_PIXMAP, str); 109 XmStringFree(str); 110 XtVaSetValues(tree, 111 XmNrow, 0, 112 XmNrowUserData, strdup("/"), 113 NULL); 114 115 XtAddCallback(tree, XmNexpandCallback, rowExpand, NULL); 116 XtAddCallback(tree, XmNcollapseCallback, rowCollapse, NULL); 117 XtAddCallback(tree, XmNdeleteCallback, rowDelete, NULL); 118 XtAddCallback(tree, XmNselectCallback, cellSelect, NULL); 119 120 /* Add a Grid to the right of the Form and set cell defaults */ 121 grid = XtVaCreateManagedWidget("grid", 122 xmlGridWidgetClass, form, 123 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 124 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 125 XtVaTypedArg, XmNblankBackground, XmRString, "white", 6, 126 XtVaTypedArg, XmNselectBackground, XmRString, "#000080", 8, 127 XtVaTypedArg, XmNselectForeground, XmRString, "white", 6, 128 XmNcolumns, 3, 129 XmNsimpleWidths, "24c 12c 10c", 130 XmNsimpleHeadings, "Name|Type|Size", 131 XmNvisibleColumns, 6, 132 XmNallowColumnResize, True, 133 XmNheadingRows, 1, 134 XmNvisibleRows, 16, 135 XmNhighlightRowMode, True, 136 XmNleftAttachment, XmATTACH_POSITION, 137 XmNleftPosition, 46, 138 XmNtopAttachment, XmATTACH_FORM, 139 XmNbottomAttachment, XmATTACH_FORM, 140 XmNrightAttachment, XmATTACH_FORM, 141 NULL); 142 XtVaSetValues(grid, 143 XmNcellDefaults, True, 144 XtVaTypedArg, XmNcellBackground, XmRString, "white", 6, 145 XmNcellTopBorderType, XmBORDER_NONE, 146 XmNcellBottomBorderType, XmBORDER_NONE, 147 XmNcellRightBorderType, XmBORDER_NONE, 148 XmNcellLeftBorderType, XmBORDER_NONE, 149 XmNcellAlignment, XmALIGNMENT_LEFT, 150 NULL); 151 XtVaSetValues(grid, 152 XmNcellDefaults, True, 153 XmNcolumn, 2, 154 XmNcellAlignment, XmALIGNMENT_RIGHT, 155 NULL); 156 157 /* Invoke the select callback for the first row in the Tree */ 158 /* to fill the Grid with the data for the root path */ 159 XmLGridSelectRow(tree, 0, True); 160 161 XtRealizeWidget(shell); 162 XtAppMainLoop(app); 163 } 164 165 void rowExpand(w, clientData, callData) 166 Widget w; 167 XtPointer clientData, callData; 168 { 169 XmLGridCallbackStruct *cbs; 170 XmLGridRow row; 171 int level, pos; 172 DIR *dir; 173 struct dirent *d; 174 struct stat s; 175 char *path, fullpath[1024]; 176 XmString str; 177 178 /* Retrieve the path of the directory expanded. This is kept */ 179 /* in the row's rowUserData */ 180 cbs = (XmLGridCallbackStruct *)callData; 181 row = XmLGridGetRow(w, XmCONTENT, cbs->row); 182 XtVaGetValues(w, 183 XmNrowPtr, row, 184 XmNrowUserData, &path, 185 XmNrowLevel, &level, 186 NULL); 187 pos = cbs->row + 1; 188 dir = opendir(path); 189 if (!dir) 190 return; 191 192 /* Add the subdirectories of the directory expanded to the Tree */ 193 XtVaSetValues(w, 194 XmNlayoutFrozen, True, 195 NULL); 196 while (d = readdir(dir)) 197 { 198 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) 199 continue; 200 sprintf(fullpath, "%s/%s", path, d->d_name); 201 if (lstat(fullpath, &s) == -1) 202 continue; 203 if (!S_ISDIR(s.st_mode)) 204 continue; 205 str = XmStringCreateSimple(d->d_name); 206 XmLTreeAddRow(w, level + 1, True, False, pos, 207 XmUNSPECIFIED_PIXMAP, XmUNSPECIFIED_PIXMAP, str); 208 XmStringFree(str); 209 XtVaSetValues(w, 210 XmNrow, pos, 211 XmNrowUserData, strdup(fullpath), 212 NULL); 213 pos++; 214 } 215 closedir(dir); 216 XtVaSetValues(w, 217 XmNlayoutFrozen, False, 218 NULL); 219 } 220 221 void rowCollapse(w, clientData, callData) 222 Widget w; 223 XtPointer clientData, callData; 224 { 225 XmLGridCallbackStruct *cbs; 226 XmLGridRow row; 227 char *path; 228 int i, j, level, rows; 229 230 /* Collapse the row by deleting the rows in the tree which */ 231 /* are children of the collapsed row. */ 232 cbs = (XmLGridCallbackStruct *)callData; 233 234 XmLTreeDeleteChildren(w, cbs->row); 235 } 236 237 void rowDelete(w, clientData, callData) 238 Widget w; 239 XtPointer clientData, callData; 240 { 241 /* Free the path contained in the rowUserData of the rows deleted */ 242 243 XmLGridCallbackStruct *cbs; 244 XmLGridRow row; 245 char *path; 246 247 cbs = (XmLGridCallbackStruct *)callData; 248 249 if (cbs->rowType != XmCONTENT || cbs->reason != XmCR_DELETE_ROW) 250 return; 251 252 row = XmLGridGetRow(w, XmCONTENT, cbs->row); 253 254 XtVaGetValues(w, 255 XmNrowPtr, row, 256 XmNrowUserData, &path, 257 NULL); 258 259 if (path) 260 free(path); 261 } 262 263 void cellSelect(w, clientData, callData) 264 Widget w; 265 XtPointer clientData, callData; 266 { 267 XmLGridCallbackStruct *cbs; 268 XmLGridRow row; 269 DIR *dir; 270 struct stat s; 271 struct dirent *d; 272 char *path, fullpath[1024], buf[256]; 273 int pos; 274 275 /* Retrieve the directory selected */ 276 cbs = (XmLGridCallbackStruct *)callData; 277 if (cbs->rowType != XmCONTENT) 278 return; 279 row = XmLGridGetRow(w, XmCONTENT, cbs->row); 280 XtVaGetValues(w, 281 XmNrowPtr, row, 282 XmNrowUserData, &path, 283 NULL); 284 dir = opendir(path); 285 if (!dir) 286 return; 287 288 /* Add a row for each file in the directory to the Grid */ 289 pos = 0; 290 XtVaSetValues(grid, 291 XmNlayoutFrozen, True, 292 NULL); 293 XmLGridDeleteAllRows(grid, XmCONTENT); 294 while (d = readdir(dir)) 295 { 296 sprintf(fullpath, "%s/%s", path, d->d_name); 297 if (lstat(fullpath, &s) == -1) 298 continue; 299 XmLGridAddRows(grid, XmCONTENT, pos, 1); 300 XmLGridSetStringsPos(grid, XmCONTENT, pos, XmCONTENT, 0, d->d_name); 301 if (S_ISDIR(s.st_mode)) 302 sprintf(buf, "Directory"); 303 else if (S_ISLNK(s.st_mode)) 304 sprintf(buf, "Link"); 305 else 306 sprintf(buf, "File"); 307 XmLGridSetStringsPos(grid, XmCONTENT, pos, XmCONTENT, 1, buf); 308 sprintf(buf, "%d", (int)s.st_size); 309 XmLGridSetStringsPos(grid, XmCONTENT, pos, XmCONTENT, 2, buf); 310 pos++; 311 } 312 closedir(dir); 313 XtVaSetValues(grid, 314 XmNlayoutFrozen, False, 315 NULL); 316 } 317 318