Don't use -import argument as fprintf format
[nedit.git] / Microline / XmL / Grid.c
blob9dbe3e43d3a2a04662c7ff641bcc24037f03f5eb
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is the Microline Widget Library, originally made available under the NPL by Neuron Data <http://www.neurondata.com>.
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.
23 * Contributor(s):
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.
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.
47 * ***** END LICENSE BLOCK ***** */
49 #include "GridP.h"
51 #include <Xm/ScrollBar.h>
52 #include <Xm/Text.h>
53 #include <Xm/DrawnB.h>
54 #include <Xm/CutPaste.h>
55 #ifndef MOTIF11
56 #include <Xm/DropSMgr.h>
57 #endif
58 #include <X11/StringDefs.h>
59 #include <X11/cursorfont.h>
60 #include <stdio.h>
61 #include <stdlib.h>
63 #ifdef SUNOS4
64 int fprintf(FILE *, char *, ...);
65 int fseek(FILE *, long, int);
66 int fread(char *, int, int, FILE *);
67 #endif
69 /* Create and Destroy */
70 static void ClassInitialize(void);
71 static void ClassPartInitialize(WidgetClass wc);
72 static void Initialize(Widget req, Widget newW, ArgList args, Cardinal *nargs);
73 static void Destroy(Widget w);
75 /* Geometry, Drawing, Entry and Picking */
76 static void Realize(Widget w, XtValueMask *valueMask,
77 XSetWindowAttributes *attr);
78 static void Redisplay(Widget w, XExposeEvent *event, Region region);
79 static void DrawResizeLine(XmLGridWidget g, int xy, int erase);
80 static void DrawXORRect(XmLGridWidget g, int xy, int size,
81 int isVert, int erase);
82 static void DefineCursor(XmLGridWidget g, char defineCursor);
83 static void DrawArea(XmLGridWidget g, int type, int row, int col);
84 static void ExtendSelectRange(XmLGridWidget g, int *type,
85 int *fr, int *lr, int *fc, int *lc);
86 static void ExtendSelect(XmLGridWidget g, XEvent *event, Boolean set,
87 int row, int col);
88 static void SelectTypeArea(XmLGridWidget g, int type, XEvent *event,
89 int row, int col, Boolean select, Boolean notify);
90 static int GetSelectedArea(XmLGridWidget g, int type, int *rowPos,
91 int *colPos, int count);
92 static void ChangeManaged(Widget w);
93 static void Resize(Widget w);
94 static void PlaceScrollbars(XmLGridWidget w);
95 static void VertLayout(XmLGridWidget g, int resizeIfNeeded);
96 static void HorizLayout(XmLGridWidget g, int resizeIfNeeded);
97 static void ApplyVisibleRows(XmLGridWidget g);
98 static void ApplyVisibleCols(XmLGridWidget g);
99 static void VisPosChanged(XmLGridWidget g, int isVert);
100 static void RecalcVisPos(XmLGridWidget g, int isVert);
101 static int PosToVisPos(XmLGridWidget g, int pos, int isVert);
102 static int VisPosToPos(XmLGridWidget g, int visPos, int isVert);
103 static unsigned char ColPosToType(XmLGridWidget g, int pos);
104 static int ColPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
105 static unsigned char RowPosToType(XmLGridWidget g, int pos);
106 static int RowPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
107 static int ColTypePosToPos(XmLGridWidget g, unsigned char type,
108 int pos, int allowNeg);
109 static int RowTypePosToPos(XmLGridWidget g, unsigned char type,
110 int pos, int allowNeg);
111 static int ScrollRowBottomPos(XmLGridWidget g, int row);
112 static int ScrollColRightPos(XmLGridWidget g, int col);
113 static int PosIsResize(XmLGridWidget g, int x, int y,
114 int *row, int *col, int *isVert);
115 static int XYToRowCol(XmLGridWidget g, int x, int y, int *row, int *col);
116 static int RowColToXY(XmLGridWidget g, int row, int col,
117 Boolean clipped, XRectangle *rect);
118 static int RowColFirstSpan(XmLGridWidget g, int row, int col,
119 int *spanRow, int *spanCol, XRectangle *rect, Boolean lookLeft,
120 Boolean lookUp);
121 static void RowColSpanRect(XmLGridWidget g, int row, int col, XRectangle *rect);
122 static XmLGridCell GetCell(XmLGridWidget g, int row, int col);
123 static int GetColWidth(XmLGridWidget g, int col);
124 static int GetRowHeight(XmLGridWidget g, int row);
125 static int ColIsVisible(XmLGridWidget g, int col);
126 static int RowIsVisible(XmLGridWidget g, int row);
127 static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
128 XtWidgetGeometry *);
129 static void ScrollCB(Widget w, XtPointer, XtPointer);
130 static int FindNextFocus(XmLGridWidget g, int row, int col,
131 int rowDir, int colDir, int *nextRow, int *nextCol);
132 static int SetFocus(XmLGridWidget g, int row, int col, int rowDir, int colDir);
133 static void ChangeFocus(XmLGridWidget g, int row, int col);
134 static void MakeColVisible(XmLGridWidget g, int col);
135 static void MakeRowVisible(XmLGridWidget g, int row);
136 static void TextAction(XmLGridWidget g, int action);
138 /* Getting and Setting Values */
139 static void GetSubValues(Widget w, ArgList args, Cardinal *nargs);
140 static void SetSubValues(Widget w, ArgList args, Cardinal *nargs);
141 static Boolean SetValues(Widget curW, Widget, Widget newW,
142 ArgList args, Cardinal *nargs);
143 static void CopyFontList(XmLGridWidget g);
144 static Boolean CvtStringToSizePolicy(Display *dpy, XrmValuePtr args,
145 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
146 XtPointer *data);
147 static Boolean CvtStringToSelectionPolicy(Display *dpy, XrmValuePtr args,
148 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
149 XtPointer *data);
150 static Boolean CvtStringToRowColType(Display *dpy, XrmValuePtr args,
151 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
152 XtPointer *data);
153 static Boolean CvtStringToCellAlignment(Display *dpy, XrmValuePtr args,
154 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
155 XtPointer *data);
156 static Boolean CvtStringToCellType(Display *dpy, XrmValuePtr args,
157 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
158 XtPointer *data);
159 static Boolean CvtStringToCellBorderType(Display *dpy, XrmValuePtr args,
160 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
161 XtPointer *data);
162 static void SetSimpleHeadings(XmLGridWidget g, char *data);
163 static void SetSimpleWidths(XmLGridWidget g, char *data);
165 /* Getting and Setting Row Values */
166 static void GetRowValueMask(XmLGridWidget g, char *s, long *mask);
167 static void _GetRowValueMask(XmLGridWidget g, char *s, long *mask);
168 static void GetRowValue(XmLGridWidget g, XmLGridRow row,
169 XtArgVal value, long mask);
170 static void _GetRowValue(XmLGridWidget g, XmLGridRow row,
171 XtArgVal value, long mask);
172 static int SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
173 static int _SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
175 /* Getting and Setting Column Values */
176 static void GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
177 static void _GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
178 static void GetColumnValue(XmLGridWidget g, XmLGridColumn col,
179 XtArgVal value, long mask);
180 static void _GetColumnValue(XmLGridWidget g, XmLGridColumn col,
181 XtArgVal value, long mask);
182 static int SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
183 static int _SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
185 /* Getting and Setting Cell Values */
186 static void CellValueGetMask(char *s, long *mask);
187 static void GetCellValue(XmLGridCell cell, XtArgVal value, long mask);
188 static XmLGridCellRefValues *CellRefValuesCreate(XmLGridWidget g,
189 XmLGridCellRefValues *copy);
190 static void SetCellValuesPreprocess(XmLGridWidget g, long mask);
191 static int SetCellHasRefValues(long mask);
192 static int SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
193 XmLGridColumn col, XmLGridCell cell, long mask);
194 static int _SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
195 XmLGridColumn col, XmLGridCell cell, long mask);
196 static void SetCellValues(XmLGridWidget g, XmLGridCell cell, long mask);
197 static void SetCellRefValues(XmLGridWidget g, XmLGridCellRefValues *values,
198 long mask);
199 static int SetCellRefValuesCompare(void *, void **, void **);
200 static void SetCellRefValuesPreprocess(XmLGridWidget g, int row, int col,
201 XmLGridCell cell, long mask);
203 /* Read, Write, Copy, Paste */
204 static int Read(XmLGridWidget g, int format, char delimiter,
205 int row, int col, char *data);
206 static void Write(XmLGridWidget g, FILE *file, int format, char delimiter,
207 Boolean skipHidden, int row, int col, int nrow, int ncol);
208 static char *CopyDataCreate(XmLGridWidget g, int selected, int row, int col,
209 int nrow, int ncol);
210 static Boolean Copy(XmLGridWidget g, Time time, int selected,
211 int row, int col, int nrow, int ncol);
212 static Boolean Paste(XmLGridWidget g, int row, int col);
214 /* Utility */
215 static void GetCoreBackground(Widget w, int, XrmValue *value);
216 static void GetManagerForeground(Widget w, int, XrmValue *value);
217 static void ClipRectToReg(XmLGridWidget g, XRectangle *rect, GridReg *reg);
218 static char *FileToString(FILE *file);
219 static char *CvtXmStringToStr(XmString str);
220 static XmLGridWidget WidgetToGrid(Widget w, char *funcname);
222 /* Actions, Callbacks and Handlers */
223 static void ButtonMotion(Widget w, XEvent *event, String *, Cardinal *);
224 static void DragTimer(XtPointer, XtIntervalId *);
225 static void CursorMotion(Widget w, XEvent *event, String *, Cardinal *);
226 static void Edit(Widget w, XEvent *event, String *, Cardinal *);
227 static void EditCancel(Widget w, XEvent *event, String *, Cardinal *);
228 static void EditComplete(Widget w, XEvent *event, String *, Cardinal *);
229 static void DragStart(Widget w, XEvent *event, String *, Cardinal *);
230 static Boolean DragConvert(Widget w, Atom *selection, Atom *target,
231 Atom *type, XtPointer *value, unsigned long *length, int *format);
232 static void DragFinish(Widget w, XtPointer clientData, XtPointer callData);
233 static void DropRegister(XmLGridWidget g, Boolean set);
234 static void DropStart(Widget w, XtPointer clientData, XtPointer callData);
235 static void DropTransfer(Widget w, XtPointer clientData, Atom *selType,
236 Atom *type, XtPointer value, unsigned long *length, int *format);
237 static void Select(Widget w, XEvent *event, String *, Cardinal *);
238 static void PopupSelect(Widget w, XEvent *event, String *, Cardinal *);
239 static void TextActivate(Widget w, XtPointer clientData, XtPointer callData);
240 static void TextFocus(Widget w, XtPointer clientData, XtPointer callData);
241 static void TextMapped(Widget w, XtPointer closure, XEvent *event,
242 Boolean *ctd);
243 static void TextModifyVerify(Widget w, XtPointer clientData,
244 XtPointer callData);
245 static void Traverse(Widget w, XEvent *event, String *, Cardinal *);
247 /* XFE Additions */
248 static void EditTimer(XtPointer, XtIntervalId *);
249 static void CreateHideUnhideButtons(XmLGridWidget g);
250 static void HideAction(Widget w, XEvent *event, String *, Cardinal *);
251 static void UnhideAction(Widget w, XEvent *event, String *, Cardinal *);
252 static void setHideUnhideSensitivity(Widget w);
253 static void MenuArm(Widget w, XEvent *event, String *, Cardinal *);
254 static void MenuDisarm(Widget w, XEvent *event, String *, Cardinal *);
255 static void ResizeColumnToFit(XmLGridWidget g, int x);
256 static int SizeColumnsToFit(XmLGridWidget g, int start_at);
257 static void GridCrossingEH(Widget w, XtPointer closure, XEvent *event,
258 Boolean *ctd);
259 static void GridInvokeCellCrossingCallbacks(Widget w,XtCallbackList list,
260 int reason,XEvent * event,
261 int row,int col);
262 static void GridCrossingEH(Widget w,XtPointer closure,XEvent * event,
263 Boolean * ctd);
265 /* XmLGridRow */
267 static XmLGridRow XmLGridRowNew(Widget grid);
268 static void XmLGridRowFree(Widget grid, XmLGridRow row);
269 static XmLGridRow _GridRowNew(Widget grid);
270 static void _GridRowFree(XmLGridRow row);
271 static XmLArray XmLGridRowCells(XmLGridRow row);
272 static int XmLGridRowGetPos(XmLGridRow row);
273 static int XmLGridRowGetVisPos(XmLGridRow row);
274 static Boolean XmLGridRowIsHidden(XmLGridRow row);
275 static Boolean XmLGridRowIsSelected(XmLGridRow row);
276 static void XmLGridRowSetSelected(XmLGridRow row, Boolean selected);
277 static void XmLGridRowSetVisPos(XmLGridRow row, int visPos);
278 static int XmLGridRowHeightInPixels(XmLGridRow row);
279 static void XmLGridRowHeightChanged(XmLGridRow row);
281 /* XmLGridColumn */
283 static XmLGridColumn XmLGridColumnNew(Widget grid);
284 static void XmLGridColumnFree(Widget grid, XmLGridColumn column);
285 static XmLGridColumn _GridColumnNew(Widget grid);
286 static void _GridColumnFree(XmLGridColumn column);
287 static int XmLGridColumnGetPos(XmLGridColumn column);
288 static int XmLGridColumnGetVisPos(XmLGridColumn column);
289 static Boolean XmLGridColumnIsHidden(XmLGridColumn column);
290 static Boolean XmLGridColumnIsSelected(XmLGridColumn column);
291 static void XmLGridColumnSetSelected(XmLGridColumn column, Boolean selected);
292 static void XmLGridColumnSetVisPos(XmLGridColumn column, int visPos);
293 static int XmLGridColumnWidthInPixels(XmLGridColumn column);
294 static void XmLGridColumnWidthChanged(XmLGridColumn column);
296 /* XmLGridCell */
298 static XmLGridCell XmLGridCellNew();
299 static void XmLGridCellFree(Widget grid, XmLGridCell cell);
300 static int XmLGridCellAction(XmLGridCell cell, Widget w,
301 XmLGridCallbackStruct *cbs);
302 static int _GridCellAction(XmLGridCell cell, Widget w,
303 XmLGridCallbackStruct *cbs);
304 static XmLGridCellRefValues *XmLGridCellGetRefValues(XmLGridCell cell);
305 static void XmLGridCellSetRefValues(XmLGridCell cell,
306 XmLGridCellRefValues *values);
307 static void XmLGridCellDerefValues(XmLGridCellRefValues *values);
308 static Boolean XmLGridCellInRowSpan(XmLGridCell cell);
309 static Boolean XmLGridCellInColumnSpan(XmLGridCell cell);
310 static Boolean XmLGridCellIsSelected(XmLGridCell cell);
311 static Boolean XmLGridCellIsValueSet(XmLGridCell cell);
312 static void XmLGridCellSetValueSet(XmLGridCell cell, Boolean set);
313 static void XmLGridCellSetInRowSpan(XmLGridCell cell, Boolean set);
314 static void XmLGridCellSetInColumnSpan(XmLGridCell cell, Boolean set);
315 static void XmLGridCellSetSelected(XmLGridCell cell, Boolean selected);
316 static void XmLGridCellAllocIcon(XmLGridCell cell);
317 static void XmLGridCellAllocPixmap(XmLGridCell cell);
318 static void XmLGridCellSetString(XmLGridCell cell, XmString string,
319 Boolean copy);
320 static XmString XmLGridCellGetString(XmLGridCell cell);
321 static void XmLGridCellSetToggle(XmLGridCell cell, Boolean state);
322 static Boolean XmLGridCellGetToggle(XmLGridCell cell);
323 static void XmLGridCellSetPixmap(XmLGridCell cell, Pixmap pixmap,
324 Dimension width, Dimension height);
325 static void XmLGridCellSetPixmask(XmLGridCell cell, Pixmap pixmask);
326 static XmLGridCellPixmap *XmLGridCellGetPixmap(XmLGridCell cell);
327 /* static void XmLGridCellClearTextString(XmLGridCell cell, Widget w); */
328 static int _XmLGridCellConfigureText(XmLGridCell cell, Widget w,
329 XRectangle *rect);
330 static int _XmLGridCellBeginTextEdit(XmLGridCell cell, Widget w,
331 XRectangle *clipRect);
332 static void _XmLGridCellCompleteTextEdit(XmLGridCell cell, Widget w);
333 static void _XmLGridCellInsertText(XmLGridCell cell, Widget w);
334 static int _XmLGridCellGetHeight(XmLGridCell cell, Widget w,XmLGridRow row);
335 static int _XmLGridCellGetWidth(XmLGridCell cell, Widget w,XmLGridColumn col);
336 static void _XmLGridCellFreeValue(XmLGridCell cell);
338 /*Xfe Additions*/
339 static Boolean XmLGridCellDrawSort(XmLGridCell cell);
340 static Boolean XmLGridCellSortAscending(XmLGridCell cell);
341 static void XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort);
342 static void XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending);
344 static XtActionsRec actions[] =
346 { "XmLGridEditComplete", EditComplete },
347 { "XmLGridButtonMotion", ButtonMotion },
348 { "XmLGridCursorMotion", CursorMotion },
349 { "XmLGridEditCancel", EditCancel },
350 { "XmLGridEdit", Edit },
351 { "XmLGridSelect", Select },
352 { "XmLGridPopupSelect", PopupSelect },
353 { "XmLGridDragStart", DragStart },
354 { "XmLGridTraverse", Traverse },
355 /* XFE Additions */
356 { "XmLGridHideColumn", HideAction },
357 { "XmLGridUnhideColumn", UnhideAction },
358 { "MenuArm", MenuArm },
359 { "MenuDisarm", MenuDisarm },
362 #define TEXT_HIDE 1
363 #define TEXT_SHOW 2
364 #define TEXT_EDIT 3
365 #define TEXT_EDIT_CANCEL 4
366 #define TEXT_EDIT_COMPLETE 5
367 #define TEXT_EDIT_INSERT 6
369 /* future defines */
370 #define XmTOGGLE_CELL 240
372 /* backwards compatibility defines */
373 #define XmTEXT_CELL 250
374 #define XmLABEL_CELL 251
376 /* Cursors */
378 #define horizp_width 19
379 #define horizp_height 13
380 static unsigned char horizp_bits[] = {
381 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x00,
382 0x00, 0x06, 0x00, 0x20, 0x46, 0x00, 0x30, 0xc6, 0x00, 0x38, 0xc6, 0x01,
383 0xfc, 0xff, 0x03, 0x38, 0xc6, 0x01, 0x30, 0xc6, 0x00, 0x20, 0x46, 0x00,
384 0x00, 0x06, 0x00 };
386 #define horizm_width 19
387 #define horizm_height 13
388 static unsigned char horizm_bits[] = {
389 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00,
390 0x60, 0x6f, 0x00, 0x70, 0xef, 0x00, 0x78, 0xef, 0x01, 0xfc, 0xff, 0x03,
391 0xfe, 0xff, 0x07, 0xfc, 0xff, 0x03, 0x78, 0xef, 0x01, 0x70, 0xef, 0x00,
392 0x60, 0x6f, 0x00 };
394 #define vertp_width 13
395 #define vertp_height 19
396 static unsigned char vertp_bits[] = {
397 0x06, 0x00, 0x06, 0x00, 0x06, 0x01, 0x86, 0x03, 0xc6, 0x07, 0xe6, 0x0f,
398 0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0xfe, 0x1f, 0xfe, 0x1f, 0x00, 0x01,
399 0x00, 0x01, 0x00, 0x01, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03, 0x00, 0x01,
400 0x00, 0x00};
402 #define vertm_width 13
403 #define vertm_height 19
404 static unsigned char vertm_bits[] = {
405 0x0f, 0x00, 0x0f, 0x01, 0x8f, 0x03, 0xcf, 0x07, 0xef, 0x0f, 0xff, 0x1f,
406 0xff, 0x1f, 0x8f, 0x03, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
407 0x80, 0x03, 0xf0, 0x1f, 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03,
408 0x00, 0x01};
410 /* Grid Translations */
412 static char translations[] =
413 "<Btn1Motion>: XmLGridButtonMotion()\n\
414 <MotionNotify>: XmLGridCursorMotion()\n\
415 ~Ctrl ~Shift <Btn1Down>: XmLGridSelect(BEGIN)\n\
416 ~Ctrl Shift <Btn1Down>: XmLGridSelect(EXTEND)\n\
417 Ctrl ~Shift <Btn1Down>: XmLGridSelect(TOGGLE)\n\
418 <Btn1Up>: XmLGridSelect(END)\n\
419 <Btn2Down>: XmLGridDragStart()\n\
420 ~Ctrl ~Shift <Btn3Down>: XmLGridPopupSelect(BEGIN)\n\
421 ~Ctrl Shift <Btn3Down>: XmLGridPopupSelect(EXTEND)\n\
422 Ctrl ~Shift <Btn3Down>: XmLGridPopupSelect(TOGGLE)\n\
423 <EnterWindow>: ManagerEnter()\n\
424 <LeaveWindow>: ManagerLeave()\n\
425 <FocusOut>: ManagerFocusOut()\n\
426 <FocusIn>: ManagerFocusIn()";
428 /* Text Translations */
430 static char traverseTranslations[] =
431 "~Ctrl ~Shift <Key>osfUp: XmLGridTraverse(UP)\n\
432 ~Ctrl Shift <Key>osfUp: XmLGridTraverse(EXTEND_UP)\n\
433 Ctrl ~Shift <Key>osfUp: XmLGridTraverse(PAGE_UP)\n\
434 ~Ctrl ~Shift <Key>osfDown: XmLGridTraverse(DOWN)\n\
435 ~Ctrl Shift <Key>osfDown: XmLGridTraverse(EXTEND_DOWN)\n\
436 Ctrl ~Shift <Key>osfDown: XmLGridTraverse(PAGE_DOWN)\n\
437 ~Ctrl ~Shift <Key>osfLeft: XmLGridTraverse(LEFT)\n\
438 ~Ctrl Shift <Key>osfLeft: XmLGridTraverse(EXTEND_LEFT)\n\
439 Ctrl ~Shift <Key>osfLeft: XmLGridTraverse(PAGE_LEFT)\n\
440 ~Ctrl ~Shift <Key>osfRight: XmLGridTraverse(RIGHT)\n\
441 ~Ctrl Shift <Key>osfRight: XmLGridTraverse(EXTEND_RIGHT)\n\
442 Ctrl ~Shift <Key>osfRight: XmLGridTraverse(PAGE_RIGHT)\n\
443 ~Ctrl ~Shift <Key>osfPageUp: XmLGridTraverse(PAGE_UP)\n\
444 ~Ctrl Shift <Key>osfPageUp: XmLGridTraverse(EXTEND_PAGE_UP)\n\
445 Ctrl ~Shift <Key>osfPageUp: XmLGridTraverse(PAGE_LEFT)\n\
446 Ctrl Shift <Key>osfPageUp: XmLGridTraverse(EXTEND_PAGE_LEFT)\n\
447 ~Ctrl Shift <Key>osfPageDown: XmLGridTraverse(EXTEND_PAGE_DOWN)\n\
448 Ctrl ~Shift <Key>osfPageDown: XmLGridTraverse(PAGE_RIGHT)\n\
449 ~Ctrl ~Shift <Key>osfPageDown: XmLGridTraverse(PAGE_DOWN)\n\
450 Ctrl Shift <Key>osfPageDown: XmLGridTraverse(EXTEND_PAGE_RIGHT)\n\
451 ~Ctrl ~Shift <Key>Tab: XmLGridTraverse(RIGHT)\n\
452 ~Ctrl Shift <Key>Tab: XmLGridTraverse(LEFT)\n\
453 ~Ctrl ~Shift <Key>Home: XmLGridTraverse(TO_TOP)\n\
454 ~Ctrl ~Shift <Key>osfBeginLine: XmLGridTraverse(TO_TOP)\n\
455 Ctrl ~Shift <Key>Home: XmLGridTraverse(TO_TOP_LEFT)\n\
456 ~Ctrl ~Shift <Key>End: XmLGridTraverse(TO_BOTTOM)\n\
457 ~Ctrl ~Shift <Key>osfEndLine: XmLGridTraverse(TO_BOTTOM)\n\
458 Ctrl ~Shift <Key>End: XmLGridTraverse(TO_BOTTOM_RIGHT)\n\
459 <Key>osfInsert: XmLGridEdit()\n\
460 <Key>F2: XmLGridEdit()\n\
461 ~Ctrl ~Shift <KeyDown>space: XmLGridSelect(BEGIN)\n\
462 ~Ctrl Shift <KeyDown>space: XmLGridSelect(EXTEND)\n\
463 Ctrl ~Shift <KeyDown>space: XmLGridSelect(TOGGLE)\n\
464 <KeyUp>space: XmLGridSelect(END)";
466 /* You can't put multiple actions for any translation
467 where one translation changes the translation table
468 XmLGridComplete() and XmLGridCancel() do this and these
469 actions can't be combined with others */
470 static char editTranslations[] =
471 "~Ctrl ~Shift <Key>osfDown: XmLGridEditComplete(DOWN)\n\
472 ~Ctrl Shift <Key>Tab: XmLGridEditComplete(LEFT)\n\
473 ~Ctrl ~Shift <Key>Tab: XmLGridEditComplete(RIGHT)\n\
474 ~Ctrl ~Shift <Key>osfUp: XmLGridEditComplete(UP)\n\
475 <Key>osfCancel: XmLGridEditCancel()\n\
476 <Key>Escape: XmLGridEditCancel()";
478 #if 0
479 static char hideButtonTranslations[] =
480 "<BtnDown>,<BtnUp>: XmLGridHideColumn()";
482 static char unhideButtonTranslations[] =
483 "<BtnDown>,<BtnUp>: XmLGridUnhideColumn()";
484 #endif /*0*/
486 static XtResource resources[] =
488 /* Grid Resources */
490 XmNactivateCallback, XmCCallback,
491 XmRCallback, sizeof(XtCallbackList),
492 XtOffset(XmLGridWidget, grid.activateCallback),
493 XmRImmediate, (XtPointer)0,
496 XmNaddCallback, XmCCallback,
497 XmRCallback, sizeof(XtCallbackList),
498 XtOffset(XmLGridWidget, grid.addCallback),
499 XmRImmediate, (XtPointer)0,
502 XmNallowColumnHide, XmCAllowColumnHide,
503 XmRBoolean, sizeof(Boolean),
504 XtOffset(XmLGridWidget, grid.allowColHide),
505 XmRImmediate, (XtPointer)False,
508 XmNallowColumnResize, XmCAllowColumnResize,
509 XmRBoolean, sizeof(Boolean),
510 XtOffset(XmLGridWidget, grid.allowColResize),
511 XmRImmediate, (XtPointer)False,
514 XmNallowDragSelected, XmCAllowDragSelected,
515 XmRBoolean, sizeof(Boolean),
516 XtOffset(XmLGridWidget, grid.allowDrag),
517 XmRImmediate, (XtPointer)False,
520 XmNallowDrop, XmCAllowDrop,
521 XmRBoolean, sizeof(Boolean),
522 XtOffset(XmLGridWidget, grid.allowDrop),
523 XmRImmediate, (XtPointer)False,
526 XmNallowRowHide, XmCAllowRowHide,
527 XmRBoolean, sizeof(Boolean),
528 XtOffset(XmLGridWidget, grid.allowRowHide),
529 XmRImmediate, (XtPointer)False,
532 XmNallowRowResize, XmCAllowRowResize,
533 XmRBoolean, sizeof(Boolean),
534 XtOffset(XmLGridWidget, grid.allowRowResize),
535 XmRImmediate, (XtPointer)False,
538 XmNautoSelect, XmCAutoSelect,
539 XmRBoolean, sizeof(Boolean),
540 XtOffset(XmLGridWidget, grid.autoSelect),
541 XmRImmediate, (XtPointer)True,
544 XmNblankBackground, XmCBlankBackground,
545 XmRPixel, sizeof(Pixel),
546 XtOffset(XmLGridWidget, grid.blankBg),
547 XmRCallProc, (XtPointer)GetCoreBackground,
550 XmNbottomFixedCount, XmCBottomFixedCount,
551 XmRInt, sizeof(int),
552 XtOffset(XmLGridWidget, grid.bottomFixedCount),
553 XmRImmediate, (XtPointer)0,
556 XmNbottomFixedMargin, XmCBottomFixedMargin,
557 XmRDimension, sizeof(Dimension),
558 XtOffset(XmLGridWidget, grid.bottomFixedMargin),
559 XmRImmediate, (XtPointer)0,
562 XmNcellDefaults, XmCCellDefaults,
563 XmRBoolean, sizeof(Boolean),
564 XtOffset(XmLGridWidget, grid.cellDefaults),
565 XmRImmediate, (XtPointer)False,
568 XmNcellDrawCallback, XmCCallback,
569 XmRCallback, sizeof(XtCallbackList),
570 XtOffset(XmLGridWidget, grid.cellDrawCallback),
571 XmRImmediate, (XtPointer)0,
574 XmNcellDropCallback, XmCCallback,
575 XmRCallback, sizeof(XtCallbackList),
576 XtOffset(XmLGridWidget, grid.cellDropCallback),
577 XmRImmediate, (XtPointer)0,
580 XmNcellFocusCallback, XmCCallback,
581 XmRCallback, sizeof(XtCallbackList),
582 XtOffset(XmLGridWidget, grid.cellFocusCallback),
583 XmRImmediate, (XtPointer)0,
586 XmNcellPasteCallback, XmCCallback,
587 XmRCallback, sizeof(XtCallbackList),
588 XtOffset(XmLGridWidget, grid.cellPasteCallback),
589 XmRImmediate, (XtPointer)0,
592 XmNcolumns, XmCColumns,
593 XmRInt, sizeof(int),
594 XtOffset(XmLGridWidget, grid.colCount),
595 XmRImmediate, (XtPointer)0,
598 XmNdeleteCallback, XmCCallback,
599 XmRCallback, sizeof(XtCallbackList),
600 XtOffset(XmLGridWidget, grid.deleteCallback),
601 XmRImmediate, (XtPointer)0,
604 XmNdeselectCallback, XmCCallback,
605 XmRCallback, sizeof(XtCallbackList),
606 XtOffset(XmLGridWidget, grid.deselectCallback),
607 XmRImmediate, (XtPointer)0,
610 XmNdebugLevel, XmCDebugLevel,
611 XmRInt, sizeof(int),
612 XtOffset(XmLGridWidget, grid.debugLevel),
613 XmRImmediate, (XtPointer)0,
616 XmNeditCallback, XmCCallback,
617 XmRCallback, sizeof(XtCallbackList),
618 XtOffset(XmLGridWidget, grid.editCallback),
619 XmRImmediate, (XtPointer)0,
622 XmNeditTranslations, XmCTranslations,
623 XmRTranslationTable, sizeof(XtTranslations),
624 XtOffset(XmLGridWidget, grid.editTrans),
625 XmRString, (XtPointer)editTranslations,
628 XmNfontList, XmCFontList,
629 XmRFontList, sizeof(XmFontList),
630 XtOffset(XmLGridWidget, grid.fontList),
631 XmRImmediate, (XtPointer)0
634 XmNfooterColumns, XmCFooterColumns,
635 XmRInt, sizeof(int),
636 XtOffset(XmLGridWidget, grid.footerColCount),
637 XmRImmediate, (XtPointer)0,
640 XmNfooterRows, XmCFooterRows,
641 XmRInt, sizeof(int),
642 XtOffset(XmLGridWidget, grid.footerRowCount),
643 XmRImmediate, (XtPointer)0,
646 XmNglobalPixmapHeight, XmCGlobalPixmapHeight,
647 XmRDimension, sizeof(Dimension),
648 XtOffset(XmLGridWidget, grid.globalPixmapHeight),
649 XmRImmediate, (XtPointer)0,
652 XmNglobalPixmapWidth, XmCGlobalPixmapWidth,
653 XmRDimension, sizeof(Dimension),
654 XtOffset(XmLGridWidget, grid.globalPixmapWidth),
655 XmRImmediate, (XtPointer)0,
658 XmNheadingColumns, XmCHeadingColumns,
659 XmRInt, sizeof(int),
660 XtOffset(XmLGridWidget, grid.headingColCount),
661 XmRImmediate, (XtPointer)0,
664 XmNheadingRows, XmCHeadingRows,
665 XmRInt, sizeof(int),
666 XtOffset(XmLGridWidget, grid.headingRowCount),
667 XmRImmediate, (XtPointer)0,
670 XmNhiddenColumns, XmCHiddenColumns,
671 XmRInt, sizeof(int),
672 XtOffset(XmLGridWidget, grid.hiddenColCount),
673 XmRImmediate, (XtPointer)0,
676 XmNhiddenRows, XmCHiddenRows,
677 XmRInt, sizeof(int),
678 XtOffset(XmLGridWidget, grid.hiddenRowCount),
679 XmRImmediate, (XtPointer)0,
682 XmNhighlightRowMode, XmCHighlightRowMode,
683 XmRBoolean, sizeof(Boolean),
684 XtOffset(XmLGridWidget, grid.highlightRowMode),
685 XmRImmediate, (XtPointer)False,
688 XmNhighlightThickness, XmCHighlightThickness,
689 XmRDimension, sizeof(Dimension),
690 XtOffset(XmLGridWidget, grid.highlightThickness),
691 XmRImmediate, (XtPointer)2,
694 XmNhorizontalScrollBar, XmCHorizontalScrollBar,
695 XmRWidget, sizeof(Widget),
696 XtOffset(XmLGridWidget, grid.hsb),
697 XmRImmediate, (XtPointer)0,
700 XmNhorizontalSizePolicy, XmCHorizontalSizePolicy,
701 XmRGridSizePolicy, sizeof(unsigned char),
702 XtOffset(XmLGridWidget, grid.hsPolicy),
703 XmRImmediate, (XtPointer)XmCONSTANT,
706 XmNhsbDisplayPolicy, XmCHsbDisplayPolicy,
707 XmRScrollBarDisplayPolicy, sizeof(unsigned char),
708 XtOffset(XmLGridWidget, grid.hsbDisplayPolicy),
709 XmRImmediate, (XtPointer)XmAS_NEEDED,
712 XmNimmediateDraw, XmCImmediateDraw,
713 XmRBoolean, sizeof(Boolean),
714 XtOffset(XmLGridWidget, grid.immediateDraw),
715 XmRImmediate, (XtPointer)False,
718 XmNlayoutFrozen, XmCLayoutFrozen,
719 XmRBoolean, sizeof(Boolean),
720 XtOffset(XmLGridWidget, grid.layoutFrozen),
721 XmRImmediate, (XtPointer)False,
724 XmNleftFixedCount, XmCLeftFixedCount,
725 XmRInt, sizeof(int),
726 XtOffset(XmLGridWidget, grid.leftFixedCount),
727 XmRImmediate, (XtPointer)0,
730 XmNleftFixedMargin, XmCLeftFixedMargin,
731 XmRDimension, sizeof(Dimension),
732 XtOffset(XmLGridWidget, grid.leftFixedMargin),
733 XmRImmediate, (XtPointer)0,
736 XmNminColumnWidth, XmCMinColumnWidth,
737 XmRDimension, sizeof(Dimension),
738 XtOffset(XmLGridWidget, grid.minColWidth),
739 XmRImmediate, (XtPointer)0,
742 XmNrightFixedCount, XmCRightFixedCount,
743 XmRInt, sizeof(int),
744 XtOffset(XmLGridWidget, grid.rightFixedCount),
745 XmRImmediate, (XtPointer)0,
748 XmNrightFixedMargin, XmCRightFixedMargin,
749 XmRDimension, sizeof(Dimension),
750 XtOffset(XmLGridWidget, grid.rightFixedMargin),
751 XmRImmediate, (XtPointer)0,
754 XmNresizeCallback, XmCCallback,
755 XmRCallback, sizeof(XtCallbackList),
756 XtOffset(XmLGridWidget, grid.resizeCallback),
757 XmRImmediate, (XtPointer)0,
760 XmNrows, XmCRows,
761 XmRInt, sizeof(int),
762 XtOffset(XmLGridWidget, grid.rowCount),
763 XmRImmediate, (XtPointer)0,
766 XmNscrollBarMargin, XmCScrollBarMargin,
767 XmRDimension, sizeof(Dimension),
768 XtOffset(XmLGridWidget, grid.scrollBarMargin),
769 XmRImmediate, (XtPointer)2,
772 XmNscrollCallback, XmCCallback,
773 XmRCallback, sizeof(XtCallbackList),
774 XtOffset(XmLGridWidget, grid.scrollCallback),
775 XmRImmediate, (XtPointer)0,
778 XmNscrollColumn, XmCScrollColumn,
779 XmRInt, sizeof(int),
780 XtOffset(XmLGridWidget, grid.cScrollCol),
781 XmRImmediate, (XtPointer)0,
784 XmNscrollRow, XmCScrollRow,
785 XmRInt, sizeof(int),
786 XtOffset(XmLGridWidget, grid.cScrollRow),
787 XmRImmediate, (XtPointer)0,
790 XmNselectCallback, XmCCallback,
791 XmRCallback, sizeof(XtCallbackList),
792 XtOffset(XmLGridWidget, grid.selectCallback),
793 XmRImmediate, (XtPointer)0,
796 XmNselectionPolicy, XmCGridSelectionPolicy,
797 XmRGridSelectionPolicy, sizeof(unsigned char),
798 XtOffset(XmLGridWidget, grid.selectionPolicy),
799 XmRImmediate, (XtPointer)XmSELECT_BROWSE_ROW,
802 XmNselectBackground, XmCSelectBackground,
803 XmRPixel, sizeof(Pixel),
804 XtOffset(XmLGridWidget, grid.selectBg),
805 XmRCallProc, (XtPointer)GetManagerForeground,
808 XmNselectForeground, XmCSelectForeground,
809 XmRPixel, sizeof(Pixel),
810 XtOffset(XmLGridWidget, grid.selectFg),
811 XmRCallProc, (XtPointer)GetCoreBackground,
814 XmNshadowRegions, XmCShadowRegions,
815 XmRInt, sizeof(int),
816 XtOffset(XmLGridWidget, grid.shadowRegions),
817 XmRImmediate, (XtPointer)511,
820 XmNshadowType, XmCShadowType,
821 XmRShadowType, sizeof(unsigned char),
822 XtOffset(XmLGridWidget, grid.shadowType),
823 XmRImmediate, (XtPointer)XmSHADOW_IN,
826 XmNsimpleHeadings, XmCSimpleHeadings,
827 XmRString, sizeof(char *),
828 XtOffset(XmLGridWidget, grid.simpleHeadings),
829 XmRImmediate, (XtPointer)0,
832 XmNsimpleWidths, XmCSimpleWidths,
833 XmRString, sizeof(char *),
834 XtOffset(XmLGridWidget, grid.simpleWidths),
835 XmRImmediate, (XtPointer)0,
838 XmNtextWidget, XmCTextWidget,
839 XmRWidget, sizeof(Widget),
840 XtOffset(XmLGridWidget, grid.text),
841 XmRImmediate, (XtPointer)0,
844 XmNtoggleBottomColor, XmCToggleBottomColor,
845 XmRPixel, sizeof(Pixel),
846 XtOffset(XmLGridWidget, grid.toggleBotColor),
847 XmRCallProc, (XtPointer)GetManagerForeground,
850 XmNtoggleTopColor, XmCToggleTopColor,
851 XmRPixel, sizeof(Pixel),
852 XtOffset(XmLGridWidget, grid.toggleTopColor),
853 XmRCallProc, (XtPointer)GetManagerForeground,
856 XmNtoggleSize, XmCToggleSize,
857 XmRDimension, sizeof(Dimension),
858 XtOffset(XmLGridWidget, grid.toggleSize),
859 XmRImmediate, (XtPointer)16,
862 XmNtraverseTranslations, XmCTranslations,
863 XmRTranslationTable, sizeof(XtTranslations),
864 XtOffset(XmLGridWidget, grid.traverseTrans),
865 XmRString, (XtPointer)traverseTranslations,
868 XmNtopFixedCount, XmCTopFixedCount,
869 XmRInt, sizeof(int),
870 XtOffset(XmLGridWidget, grid.topFixedCount),
871 XmRImmediate, (XtPointer)0,
874 XmNtopFixedMargin, XmCTopFixedMargin,
875 XmRDimension, sizeof(Dimension),
876 XtOffset(XmLGridWidget, grid.topFixedMargin),
877 XmRImmediate, (XtPointer)0,
880 XmNuseAverageFontWidth, XmCUseAverageFontWidth,
881 XmRBoolean, sizeof(Boolean),
882 XtOffset(XmLGridWidget, grid.useAvgWidth),
883 XmRImmediate, (XtPointer)True,
886 XmNverticalScrollBar, XmCVerticalScrollBar,
887 XmRWidget, sizeof(Widget),
888 XtOffset(XmLGridWidget, grid.vsb),
889 XmRImmediate, (XtPointer)0,
892 XmNverticalSizePolicy, XmCVerticalSizePolicy,
893 XmRGridSizePolicy, sizeof(unsigned char),
894 XtOffset(XmLGridWidget, grid.vsPolicy),
895 XmRImmediate, (XtPointer)XmCONSTANT,
898 XmNvisibleColumns, XmCVisibleColumns,
899 XmRInt, sizeof(int),
900 XtOffset(XmLGridWidget, grid.visibleCols),
901 XmRImmediate, (XtPointer)0,
904 XmNvisibleRows, XmCVisibleRows,
905 XmRInt, sizeof(int),
906 XtOffset(XmLGridWidget, grid.visibleRows),
907 XmRImmediate, (XtPointer)0,
910 XmNvsbDisplayPolicy, XmCVsbDisplayPolicy,
911 XmRScrollBarDisplayPolicy, sizeof(unsigned char),
912 XtOffset(XmLGridWidget, grid.vsbDisplayPolicy),
913 XmRImmediate, (XtPointer)XmAS_NEEDED,
915 /* Xfe Additions*/
917 XmNpopupCallback, XmCCallback,
918 XmRCallback, sizeof(XtCallbackList),
919 XtOffset(XmLGridWidget, grid.popupCallback),
920 XmRImmediate, (XtPointer)0,
923 XmNenterCellCallback,
924 XmCCallback,
925 XmRCallback,
926 sizeof(XtCallbackList),
927 XtOffset(XmLGridWidget, grid . enterCellCallback),
928 XmRImmediate,
929 (XtPointer) NULL
932 XmNleaveCellCallback,
933 XmCCallback,
934 XmRCallback,
935 sizeof(XtCallbackList),
936 XtOffset(XmLGridWidget, grid . leaveCellCallback),
937 XmRImmediate,
938 (XtPointer) NULL
941 XmNenterGridCallback,
942 XmCCallback,
943 XmRCallback,
944 sizeof(XtCallbackList),
945 XtOffset(XmLGridWidget, grid . enterGridCallback),
946 XmRImmediate,
947 (XtPointer) NULL
950 XmNleaveGridCallback,
951 XmCCallback,
952 XmRCallback,
953 sizeof(XtCallbackList),
954 XtOffset(XmLGridWidget, grid . leaveGridCallback),
955 XmRImmediate,
956 (XtPointer) NULL
959 /* Row Resources */
961 XmNrow, XmCGridRow,
962 XmRInt, sizeof(int),
963 XtOffset(XmLGridWidget, grid.cellRow),
964 XmRImmediate, (XtPointer)-1,
967 XmNrowUserData, XmCUserData,
968 XmRPointer, sizeof(XtPointer),
969 XtOffset(XmLGridWidget, grid.rowUserData),
970 XmRImmediate, (XtPointer)0,
973 XmNrowHeight, XmCRowHeight,
974 XmRDimension, sizeof(Dimension),
975 XtOffset(XmLGridWidget, grid.rowHeight),
976 XmRImmediate, (XtPointer)0,
979 XmNrowRangeEnd, XmCRowRangeEnd,
980 XmRInt, sizeof(int),
981 XtOffset(XmLGridWidget, grid.cellRowRangeEnd),
982 XmRImmediate, (XtPointer)-1,
985 XmNrowRangeStart, XmCRowRangeStart,
986 XmRInt, sizeof(int),
987 XtOffset(XmLGridWidget, grid.cellRowRangeStart),
988 XmRImmediate, (XtPointer)-1,
991 XmNrowSizePolicy, XmCRowSizePolicy,
992 XmRGridSizePolicy, sizeof(unsigned char),
993 XtOffset(XmLGridWidget, grid.rowSizePolicy),
994 XmRImmediate, (XtPointer)0,
997 XmNrowStep, XmCRowStep,
998 XmRInt, sizeof(int),
999 XtOffset(XmLGridWidget, grid.rowStep),
1000 XmRImmediate, (XtPointer)1,
1003 XmNrowType, XmCRowType,
1004 XmRRowType, sizeof(unsigned char),
1005 XtOffset(XmLGridWidget, grid.rowType),
1006 XmRImmediate, (XtPointer)XmINVALID_TYPE,
1008 /* Column Resources */
1010 XmNcolumn, XmCGridColumn,
1011 XmRInt, sizeof(int),
1012 XtOffset(XmLGridWidget, grid.cellCol),
1013 XmRImmediate, (XtPointer)-1,
1016 XmNcolumnUserData, XmCUserData,
1017 XmRPointer, sizeof(XtPointer),
1018 XtOffset(XmLGridWidget, grid.colUserData),
1019 XmRImmediate, (XtPointer)0,
1022 XmNcolumnResizable, XmCColumnResizable,
1023 XmRBoolean, sizeof(Boolean),
1024 XtOffset(XmLGridWidget, grid.colResizable),
1025 XmRImmediate, (XtPointer)TRUE,
1028 XmNcolumnWidth, XmCColumnWidth,
1029 XmRDimension, sizeof(Dimension),
1030 XtOffset(XmLGridWidget, grid.colWidth),
1031 XmRImmediate, (XtPointer)0,
1034 XmNcolumnRangeEnd, XmCColumnRangeEnd,
1035 XmRInt, sizeof(int),
1036 XtOffset(XmLGridWidget, grid.cellColRangeEnd),
1037 XmRImmediate, (XtPointer)-1,
1040 XmNcolumnRangeStart, XmCColumnRangeStart,
1041 XmRInt, sizeof(int),
1042 XtOffset(XmLGridWidget, grid.cellColRangeStart),
1043 XmRImmediate, (XtPointer)-1,
1046 XmNcolumnSizePolicy, XmCColumnSizePolicy,
1047 XmRGridSizePolicy, sizeof(unsigned char),
1048 XtOffset(XmLGridWidget, grid.colSizePolicy),
1049 XmRImmediate, (XtPointer)0,
1052 XmNcolumnStep, XmCColumnStep,
1053 XmRInt, sizeof(int),
1054 XtOffset(XmLGridWidget, grid.colStep),
1055 XmRImmediate, (XtPointer)1,
1058 XmNcolumnType, XmCColumnType,
1059 XmRColumnType, sizeof(unsigned char),
1060 XtOffset(XmLGridWidget, grid.colType),
1061 XmRImmediate, (XtPointer)XmINVALID_TYPE,
1063 /* xfe Column Resource additions */
1065 XmNcolumnHidden, XmCColumnHidden,
1066 XmRBoolean, sizeof(Boolean),
1067 XtOffset(XmLGridWidget, grid.colHidden),
1068 XmRImmediate, (XtPointer)FALSE,
1071 XmNcolumnSortType, XmCColumnSortType,
1072 XmRColumnSortType, sizeof(unsigned char),
1073 XtOffset(XmLGridWidget, grid.colSortType),
1074 XmRImmediate, (XtPointer)XmSORT_NONE,
1076 /* Cell Resources */
1078 XmNcellAlignment, XmCCellAlignment,
1079 XmRCellAlignment, sizeof(unsigned char),
1080 XtOffset(XmLGridWidget, grid.cellValues.alignment),
1081 XmRImmediate, (XtPointer)0,
1084 XmNcellBackground, XmCCellBackground,
1085 XmRPixel, sizeof(Pixel),
1086 XtOffset(XmLGridWidget, grid.cellValues.background),
1087 XmRImmediate, (XtPointer)0,
1090 XmNcellBottomBorderColor, XmCCellBottomBorderColor,
1091 XmRPixel, sizeof(Pixel),
1092 XtOffset(XmLGridWidget, grid.cellValues.bottomBorderColor),
1093 XmRImmediate, (XtPointer)0,
1096 XmNcellBottomBorderType, XmCCellBottomBorderType,
1097 XmRCellBorderType, sizeof(unsigned char),
1098 XtOffset(XmLGridWidget, grid.cellValues.bottomBorderType),
1099 XmRImmediate, (XtPointer)0,
1102 XmNcellColumnSpan, XmCCellColumnSpan,
1103 XmRInt, sizeof(int),
1104 XtOffset(XmLGridWidget, grid.cellValues.columnSpan),
1105 XmRImmediate, (XtPointer)0,
1108 XmNcellEditable, XmCCellEditable,
1109 XmRBoolean, sizeof(Boolean),
1110 XtOffset(XmLGridWidget, grid.cellValues.editable),
1111 XmRImmediate, (XtPointer)False,
1114 XmNcellFontList, XmCCellFontList,
1115 XmRFontList, sizeof(XmFontList),
1116 XtOffset(XmLGridWidget, grid.cellValues.fontList),
1117 XmRImmediate, (XtPointer)0,
1120 XmNcellForeground, XmCCellForeground,
1121 XmRPixel, sizeof(Pixel),
1122 XtOffset(XmLGridWidget, grid.cellValues.foreground),
1123 XmRImmediate, (XtPointer)0,
1126 XmNcellLeftBorderColor, XmCCellLeftBorderColor,
1127 XmRPixel, sizeof(Pixel),
1128 XtOffset(XmLGridWidget, grid.cellValues.leftBorderColor),
1129 XmRImmediate, (XtPointer)0,
1132 XmNcellLeftBorderType, XmCCellLeftBorderType,
1133 XmRCellBorderType, sizeof(unsigned char),
1134 XtOffset(XmLGridWidget, grid.cellValues.leftBorderType),
1135 XmRImmediate, (XtPointer)0,
1138 XmNcellMarginBottom, XmCCellMarginBottom,
1139 XmRDimension, sizeof(Dimension),
1140 XtOffset(XmLGridWidget, grid.cellValues.bottomMargin),
1141 XmRImmediate, (XtPointer)0,
1144 XmNcellMarginLeft, XmCCellMarginLeft,
1145 XmRDimension, sizeof(Dimension),
1146 XtOffset(XmLGridWidget, grid.cellValues.leftMargin),
1147 XmRImmediate, (XtPointer)0,
1150 XmNcellMarginRight, XmCCellMarginRight,
1151 XmRDimension, sizeof(Dimension),
1152 XtOffset(XmLGridWidget, grid.cellValues.rightMargin),
1153 XmRImmediate, (XtPointer)0,
1156 XmNcellMarginTop, XmCCellMarginTop,
1157 XmRDimension, sizeof(Dimension),
1158 XtOffset(XmLGridWidget, grid.cellValues.topMargin),
1159 XmRImmediate, (XtPointer)0,
1162 XmNcellPixmap, XmCCellPixmap,
1163 XmRManForegroundPixmap, sizeof(Pixmap),
1164 XtOffset(XmLGridWidget, grid.cellPixmap),
1165 XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
1168 XmNcellPixmapMask, XmCCellPixmapMask,
1169 XtRBitmap, sizeof(Pixmap),
1170 XtOffset(XmLGridWidget, grid.cellPixmapMask),
1171 XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
1174 XmNcellRightBorderColor, XmCCellRightBorderColor,
1175 XmRPixel, sizeof(Pixel),
1176 XtOffset(XmLGridWidget, grid.cellValues.rightBorderColor),
1177 XmRImmediate, (XtPointer)0,
1180 XmNcellRightBorderType, XmCCellRightBorderType,
1181 XmRCellBorderType, sizeof(unsigned char),
1182 XtOffset(XmLGridWidget, grid.cellValues.rightBorderType),
1183 XmRImmediate, (XtPointer)0,
1186 XmNcellRowSpan, XmCCellRowSpan,
1187 XmRInt, sizeof(int),
1188 XtOffset(XmLGridWidget, grid.cellValues.rowSpan),
1189 XmRImmediate, (XtPointer)0,
1192 XmNcellString, XmCXmString,
1193 XmRXmString, sizeof(XmString),
1194 XtOffset(XmLGridWidget, grid.cellString),
1195 XmRImmediate, (XtPointer)0,
1198 XmNcellToggleSet, XmCCellToggleSet,
1199 XmRBoolean, sizeof(Boolean),
1200 XtOffset(XmLGridWidget, grid.cellToggleSet),
1201 XmRImmediate, (XtPointer)False,
1204 XmNcellTopBorderColor, XmCCellTopBorderColor,
1205 XmRPixel, sizeof(Pixel),
1206 XtOffset(XmLGridWidget, grid.cellValues.topBorderColor),
1207 XmRImmediate, (XtPointer)0,
1210 XmNcellTopBorderType, XmCCellTopBorderType,
1211 XmRCellBorderType, sizeof(unsigned char),
1212 XtOffset(XmLGridWidget, grid.cellValues.topBorderType),
1213 XmRImmediate, (XtPointer)0,
1216 XmNcellType, XmCCellType,
1217 XmRCellType, sizeof(unsigned char),
1218 XtOffset(XmLGridWidget, grid.cellValues.type),
1219 XmRImmediate, (XtPointer)XmSTRING_CELL,
1222 XmNcellUserData, XmCUserData,
1223 XmRPointer, sizeof(XtPointer),
1224 XtOffset(XmLGridWidget, grid.cellValues.userData),
1225 XmRImmediate, (XtPointer)0,
1227 /* Overridden inherited resources */
1229 XmNshadowThickness, XmCShadowThickness,
1230 XmRHorizontalDimension, sizeof(Dimension),
1231 XtOffset(XmLGridWidget, manager.shadow_thickness),
1232 XmRImmediate, (XtPointer)2,
1234 /* XFE Addition*/
1236 XmNhideUnhideButtons, XmCHideUnhideButtons,
1237 XmRBoolean, sizeof(Boolean),
1238 XtOffset(XmLGridWidget, grid.hideUnhideButtons),
1239 XmRImmediate, (XtPointer)False,
1242 XmNsingleClickActivation, XmCSingleClickActivation,
1243 XmRBoolean, sizeof(Boolean),
1244 XtOffset(XmLGridWidget, grid.singleClickActivation),
1245 XmRImmediate, (XtPointer)False,
1247 #if 0
1249 XmNhideButtonTranslations, XmCTranslations,
1250 XmRTranslationTable, sizeof(XtTranslations),
1251 XtOffset(XmLGridWidget, grid.hideButtonTrans),
1252 XmRString, (XtPointer)hideButtonTranslations,
1255 XmNunhideButtonTranslations, XmCTranslations,
1256 XmRTranslationTable, sizeof(XtTranslations),
1257 XtOffset(XmLGridWidget, grid.unhideButtonTrans),
1258 XmRString, (XtPointer)unhideButtonTranslations,
1260 #endif /*0*/
1262 XmNuseTextWidget, XmCUseTextWidget,
1263 XmRBoolean, sizeof(Boolean),
1264 XtOffset(XmLGridWidget, grid.useTextWidget),
1265 XmRImmediate, (XtPointer)True,
1268 XmNiconSpacing, XmCIconSpacing,
1269 XmRHorizontalDimension, sizeof(Dimension),
1270 XtOffset(XmLGridWidget, grid.iconSpacing),
1271 XmRImmediate, (XtPointer) 4,
1275 XmLGridClassRec xmlGridClassRec =
1277 { /* core_class */
1278 (WidgetClass)&xmManagerClassRec, /* superclass */
1279 "XmLGrid", /* class_name */
1280 sizeof(XmLGridRec), /* widget_size */
1281 ClassInitialize, /* class_init */
1282 ClassPartInitialize, /* class_part_init */
1283 FALSE, /* class_inited */
1284 (XtInitProc)Initialize, /* initialize */
1285 0, /* initialize_hook */
1286 (XtRealizeProc)Realize, /* realize */
1287 (XtActionList)actions, /* actions */
1288 (Cardinal)XtNumber(actions), /* num_actions */
1289 (XtResource *)resources, /* resources */
1290 XtNumber(resources), /* num_resources */
1291 NULLQUARK, /* xrm_class */
1292 TRUE, /* compress_motion */
1293 XtExposeCompressMaximal, /* compress_exposure */
1294 TRUE, /* compress_enterleav */
1295 TRUE, /* visible_interest */
1296 (XtWidgetProc)Destroy, /* destroy */
1297 (XtWidgetProc)Resize, /* resize */
1298 (XtExposeProc)Redisplay, /* expose */
1299 (XtSetValuesFunc)SetValues, /* set_values */
1300 0, /* set_values_hook */
1301 XtInheritSetValuesAlmost, /* set_values_almost */
1302 (XtArgsProc)GetSubValues, /* get_values_hook */
1303 0, /* accept_focus */
1304 XtVersion, /* version */
1305 0, /* callback_private */
1306 translations, /* tm_table */
1307 0, /* query_geometry */
1308 0, /* display_accelerato */
1309 0, /* extension */
1311 { /* composite_class */
1312 (XtGeometryHandler)GeometryManager, /* geometry_manager */
1313 (XtWidgetProc)ChangeManaged, /* change_managed */
1314 XtInheritInsertChild, /* insert_child */
1315 XtInheritDeleteChild, /* delete_child */
1316 0, /* extension */
1318 { /* constraint_class */
1319 0, /* subresources */
1320 0, /* subresource_count */
1321 sizeof(XmLGridConstraintRec), /* constraint_size */
1322 0, /* initialize */
1323 0, /* destroy */
1324 0, /* set_values */
1325 0, /* extension */
1327 { /* manager_class */
1328 XtInheritTranslations, /* translations */
1329 0, /* syn resources */
1330 0, /* num syn_resources */
1331 0, /* get_cont_resources */
1332 0, /* num_get_cont_res */
1333 XmInheritParentProcess, /* parent_process */
1334 0, /* extension */
1336 { /* grid_class */
1337 0, /* initial rows */
1338 0, /* initial columns */
1339 XmInheritGridPreLayout, /* pre layout */
1340 sizeof(struct _XmLGridRowRec), /* row rec size */
1341 _GridRowNew, /* row new */
1342 _GridRowFree, /* row free */
1343 _GetRowValueMask, /* get row value mask */
1344 _GetRowValue, /* get row value */
1345 _SetRowValues, /* set row values */
1346 sizeof(struct _XmLGridColumnRec), /* column rec size */
1347 _GridColumnNew, /* column new */
1348 _GridColumnFree, /* column free */
1349 _GetColumnValueMask, /* get col value mask */
1350 _GetColumnValue, /* get column value */
1351 _SetColumnValues, /* set column values */
1352 _SetCellValuesResize, /* set cell vl resize */
1353 _GridCellAction, /* cell action */
1357 WidgetClass xmlGridWidgetClass = (WidgetClass)&xmlGridClassRec;
1360 Create and Destroy
1363 static void
1364 ClassInitialize(void)
1366 int off1, off2;
1368 XmLInitialize();
1370 XtSetTypeConverter(XmRString, XmRGridSizePolicy,
1371 CvtStringToSizePolicy, 0, 0, XtCacheNone, 0);
1372 XtSetTypeConverter(XmRString, XmRColumnType,
1373 CvtStringToRowColType, 0, 0, XtCacheNone, 0);
1374 XtSetTypeConverter(XmRString, XmRRowType,
1375 CvtStringToRowColType, 0, 0, XtCacheNone, 0);
1376 XtSetTypeConverter(XmRString, XmRGridSelectionPolicy,
1377 CvtStringToSelectionPolicy, 0, 0, XtCacheNone, 0);
1378 XtSetTypeConverter(XmRString, XmRCellAlignment,
1379 CvtStringToCellAlignment, 0, 0, XtCacheNone, 0);
1380 XtSetTypeConverter(XmRString, XmRCellType,
1381 CvtStringToCellType, 0, 0, XtCacheNone, 0);
1382 XtSetTypeConverter(XmRString, XmRCellBorderType,
1383 CvtStringToCellBorderType, 0, 0, XtCacheNone, 0);
1384 /* long must be > 2 bytes for cell mask to work */
1385 if (sizeof(long) < 3)
1386 fprintf(stderr, "xmlGridClass: fatal error: long < 3 bytes\n");
1387 /* compiler sanity check - make sure array pos lines up */
1388 off1 = XtOffset(XmLArrayItem *, pos);
1389 off2 = XtOffset(XmLGridColumn, grid.pos);
1390 if (off1 != off2)
1391 fprintf(stderr, "xmlGridClass: fatal error: column pos offset bad\n");
1392 off2 = XtOffset(XmLGridRow, grid.pos);
1393 if (off1 != off2)
1394 fprintf(stderr, "xmlGridClass: fatal error: row pos offset bad\n");
1397 static void
1398 ClassPartInitialize(WidgetClass wc)
1400 XmLGridWidgetClass c, sc;
1402 c = (XmLGridWidgetClass)wc;
1403 sc = (XmLGridWidgetClass)c->core_class.superclass;
1405 #define INHERIT_PROC(proc, inherit) \
1406 if (c->grid_class.proc == inherit) \
1407 c->grid_class.proc = sc->grid_class.proc;
1409 INHERIT_PROC(rowNewProc, XmInheritGridRowNew)
1410 INHERIT_PROC(rowFreeProc, XmInheritGridRowFree)
1411 INHERIT_PROC(getRowValueMaskProc, XmInheritGridGetRowValueMask)
1412 INHERIT_PROC(getRowValueProc, XmInheritGridGetRowValue)
1413 INHERIT_PROC(setRowValuesProc, XmInheritGridSetRowValues)
1415 INHERIT_PROC(columnNewProc, XmInheritGridColumnNew)
1416 INHERIT_PROC(columnFreeProc, XmInheritGridColumnFree)
1417 INHERIT_PROC(getColumnValueMaskProc, XmInheritGridGetColumnValueMask)
1418 INHERIT_PROC(getColumnValueProc, XmInheritGridGetColumnValue)
1419 INHERIT_PROC(setColumnValuesProc, XmInheritGridSetColumnValues)
1421 INHERIT_PROC(setCellValuesResizeProc, XmInheritGridSetCellValuesResize)
1422 INHERIT_PROC(cellActionProc, XmInheritGridCellAction)
1424 #undef INHERIT_PROC
1427 static void
1428 Initialize(Widget reqW,
1429 Widget newW,
1430 ArgList args,
1431 Cardinal *narg)
1433 XmLGridWidget g, request;
1434 Display *dpy;
1435 Pixmap pix, pixMask;
1436 Pixel white, black;
1437 XColor fg, bg;
1438 GridReg *reg;
1439 int i, valid, hc, c, fc, hr, r, fr;
1440 Boolean layoutFrozen;
1441 #ifdef POINTER_FOCUS_CHECK
1442 unsigned char kfp;
1443 Widget shell;
1444 #endif
1446 g = (XmLGridWidget)newW;
1447 dpy = XtDisplay((Widget)g);
1448 request = (XmLGridWidget)reqW;
1450 #ifdef POINTER_FOCUS_CHECK
1451 shell = XmLShellOfWidget(newW);
1452 if (shell && XmIsVendorShell(shell))
1454 XtVaGetValues(shell,
1455 XmNkeyboardFocusPolicy, &kfp,
1456 NULL);
1457 if (kfp == XmPOINTER)
1458 XmLWarning(newW, "keyboardFocusPolicy of XmPOINTER not supported");
1460 #endif
1462 black = BlackPixelOfScreen(XtScreen((Widget)g));
1463 white = WhitePixelOfScreen(XtScreen((Widget)g));
1465 g->grid.rowArray = XmLArrayNew(1, 1);
1466 g->grid.colArray = XmLArrayNew(1, 1);
1468 if (g->core.width <= 0)
1469 g->core.width = 100;
1470 if (g->core.height <= 0)
1471 g->core.height = 100;
1473 CopyFontList(g);
1475 if (g->grid.useTextWidget) {
1476 g->grid.text = XtVaCreateManagedWidget("text", xmTextWidgetClass, (Widget)g,
1477 XmNmarginHeight, 0,
1478 XmNmarginWidth, 3,
1479 XmNshadowThickness, 0,
1480 XmNhighlightThickness, 0,
1481 XmNx, 0,
1482 XmNy, 0,
1483 XmNwidth, 40,
1484 XmNheight, 40,
1485 XmNbackground, g->core.background_pixel,
1486 XmNforeground, g->manager.foreground,
1487 NULL);
1488 XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
1489 XtAddEventHandler(g->grid.text, StructureNotifyMask,
1490 True, (XtEventHandler)TextMapped, (XtPointer)0);
1491 XtAddCallback(g->grid.text, XmNactivateCallback, TextActivate, 0);
1492 XtAddCallback(g->grid.text, XmNfocusCallback, TextFocus, 0);
1493 XtAddCallback(g->grid.text, XmNlosingFocusCallback, TextFocus, 0);
1494 XtAddCallback(g->grid.text, XmNmodifyVerifyCallback, TextModifyVerify, 0);
1497 g->grid.hsb = XtVaCreateWidget(
1498 "hsb", xmScrollBarWidgetClass, (Widget)g,
1499 XmNincrement, 1,
1500 XmNorientation, XmHORIZONTAL,
1501 XmNtraversalOn, False,
1502 XmNbackground, g->core.background_pixel,
1503 /* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
1504 #ifndef IRIX
1505 XmNforeground, g->manager.foreground,
1506 #endif
1507 XmNtopShadowColor, g->manager.top_shadow_color,
1508 XmNbottomShadowColor, g->manager.bottom_shadow_color,
1509 NULL);
1510 XtAddCallback(g->grid.hsb, XmNdragCallback, ScrollCB, 0);
1511 XtAddCallback(g->grid.hsb, XmNvalueChangedCallback, ScrollCB, 0);
1512 g->grid.vsb = XtVaCreateWidget(
1513 "vsb", xmScrollBarWidgetClass, (Widget)g,
1514 XmNorientation, XmVERTICAL,
1515 XmNincrement, 1,
1516 XmNtraversalOn, False,
1517 XmNbackground, g->core.background_pixel,
1518 /* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
1519 #ifndef IRIX
1520 XmNforeground, g->manager.foreground,
1521 #endif
1522 XmNtopShadowColor, g->manager.top_shadow_color,
1523 XmNbottomShadowColor, g->manager.bottom_shadow_color,
1524 NULL);
1525 XtAddCallback(g->grid.vsb, XmNdragCallback, ScrollCB, 0);
1526 XtAddCallback(g->grid.vsb, XmNvalueChangedCallback, ScrollCB, 0);
1528 if (g->grid.hideUnhideButtons)
1530 CreateHideUnhideButtons(g);
1532 else
1534 g->grid.hideButton = 0;
1535 g->grid.unhideButton = 0;
1538 g->grid.inResize = False;
1540 /* Cursors */
1541 fg.red = ~0;
1542 fg.green = ~0;
1543 fg.blue = ~0;
1544 fg.pixel = white;
1545 fg.flags = DoRed | DoGreen | DoBlue;
1546 bg.red = 0;
1547 bg.green = 0;
1548 bg.blue = 0;
1549 bg.pixel = black;
1550 bg.flags = DoRed | DoGreen | DoBlue;
1551 pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1552 (char *)horizp_bits, horizp_width, horizp_height, 0, 1, 1);
1553 pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1554 (char *)horizm_bits, horizm_width, horizm_height, 1, 0, 1);
1555 g->grid.hResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
1556 &fg, &bg, 9, 9);
1557 XFreePixmap(dpy, pix);
1558 XFreePixmap(dpy, pixMask);
1559 pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1560 (char *)vertp_bits, vertp_width, vertp_height, 0, 1, 1);
1561 pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
1562 (char *)vertm_bits, vertm_width, vertm_height, 1, 0, 1);
1563 g->grid.vResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
1564 &fg, &bg, 9, 9);
1565 XFreePixmap(dpy, pix);
1566 XFreePixmap(dpy, pixMask);
1568 g->grid.cursorDefined = CursorNormal;
1569 g->grid.focusIn = 0;
1570 g->grid.focusRow = -1;
1571 g->grid.focusCol = -1;
1572 g->grid.mayHaveRowSpans = 0;
1573 g->grid.scrollCol = 0;
1574 g->grid.scrollRow = 0;
1575 g->grid.textHidden = 1;
1576 g->grid.inMode = InNormal;
1577 g->grid.inEdit = 0;
1578 g->grid.singleColScrollMode = 0;
1579 g->grid.layoutStack = 0;
1580 g->grid.needsHorizLayout = 0;
1581 g->grid.needsVertLayout = 0;
1582 g->grid.recalcHorizVisPos = 0;
1583 g->grid.recalcVertVisPos = 0;
1584 g->grid.vertVisChangedHint = 0;
1585 g->grid.defCellValues = CellRefValuesCreate(g, 0);
1586 g->grid.defCellValues->refCount = 1;
1587 g->grid.ignoreModifyVerify = 0;
1588 g->grid.extendRow = -1;
1589 g->grid.extendCol = -1;
1590 g->grid.extendToRow = -1;
1591 g->grid.extendToCol = -1;
1592 g->grid.extendSelect = True;
1593 g->grid.lastSelectRow = -1;
1594 g->grid.lastSelectCol = -1;
1595 g->grid.lastSelectTime = 0;
1596 g->grid.dragTimerSet = 0;
1597 g->grid.editTimerSet = 0;
1598 g->grid.gc = 0;
1601 * Support for:
1603 * XmNenterCellCallback
1604 * XmNenterCellCallback
1605 * XmNenterCallback
1606 * XmNleaveCallback
1608 g->grid.lastCursorMotionRow = -1;
1609 g->grid.lastCursorMotionCol = -1;
1611 XtAddEventHandler(newW,
1612 EnterWindowMask | LeaveWindowMask,
1613 True,
1614 (XtEventHandler) GridCrossingEH,
1615 (XtPointer) NULL);
1617 reg = g->grid.reg;
1618 for (i = 0; i < 9; i++)
1620 reg[i].x = 0;
1621 reg[i].y = 0;
1622 reg[i].width = 0;
1623 reg[i].height = 0;
1624 reg[i].row = 0;
1625 reg[i].col = 0;
1626 reg[i].nrow = 0;
1627 reg[i].ncol = 0;
1630 layoutFrozen = g->grid.layoutFrozen;
1631 g->grid.layoutFrozen = True;
1633 if (g->grid.hiddenColCount || g->grid.hiddenRowCount)
1635 XmLWarning(newW, "Initialize() - can't set hidden rows or columns");
1636 g->grid.hiddenColCount = 0;
1637 g->grid.hiddenRowCount = 0;
1639 hc = g->grid.headingColCount;
1640 c = XmLGridClassPartOfWidget(g).initialCols;
1641 if (c < g->grid.colCount)
1642 c = g->grid.colCount;
1643 fc = g->grid.footerColCount;
1644 hr = g->grid.headingRowCount;
1645 r = XmLGridClassPartOfWidget(g).initialRows;
1646 if (r < g->grid.rowCount)
1647 r = g->grid.rowCount ;
1648 fr = g->grid.footerRowCount;
1649 g->grid.headingColCount = 0;
1650 g->grid.colCount = 0;
1651 g->grid.footerColCount = 0;
1652 g->grid.headingRowCount = 0;
1653 g->grid.rowCount = 0;
1654 g->grid.footerRowCount = 0;
1655 XmLGridAddColumns(newW, XmHEADING, -1, hc);
1656 XmLGridAddColumns(newW, XmCONTENT, -1, c);
1657 XmLGridAddColumns(newW, XmFOOTER, -1, fc);
1658 XmLGridAddRows(newW, XmHEADING, -1, hr);
1659 XmLGridAddRows(newW, XmCONTENT, -1, r);
1660 XmLGridAddRows(newW, XmFOOTER, -1, fr);
1661 if (g->grid.simpleHeadings)
1663 g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
1664 SetSimpleHeadings(g, g->grid.simpleHeadings);
1666 if (g->grid.simpleWidths)
1668 g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
1669 SetSimpleWidths(g, g->grid.simpleWidths);
1671 if (g->grid.visibleRows)
1672 ApplyVisibleRows(g);
1673 if (g->grid.visibleCols && g->grid.hsPolicy == XmCONSTANT)
1674 ApplyVisibleCols(g);
1676 g->grid.layoutFrozen = layoutFrozen;
1677 VertLayout(g, 1);
1678 HorizLayout(g, 1);
1679 PlaceScrollbars(g);
1681 valid = 1;
1682 for (i = 0; i < *narg; i++)
1684 if (!args[i].name)
1685 continue;
1686 if (!strcmp(args[i].name, XmNrows) ||
1687 !strcmp(args[i].name, XmNcolumns))
1688 continue;
1689 if (!strncmp(args[i].name, "row", 3) ||
1690 !strncmp(args[i].name, "column", 6) ||
1691 !strncmp(args[i].name, "cell", 4))
1692 valid = 0;
1694 if (!valid)
1695 XmLWarning(newW,
1696 "Initialize() - can't set row,column or cell values in init");
1698 DropRegister(g, g->grid.allowDrop);
1701 static void
1702 Destroy(Widget w)
1704 XmLGridWidget g;
1705 Display *dpy;
1706 int i, count;
1708 g = (XmLGridWidget)w;
1709 dpy = XtDisplay(w);
1710 if (g->grid.dragTimerSet)
1711 XtRemoveTimeOut(g->grid.dragTimerId);
1712 if (g->grid.editTimerSet)
1713 XtRemoveTimeOut(g->grid.editTimerId);
1714 DefineCursor(g, CursorNormal);
1715 XFreeCursor(dpy, g->grid.hResizeCursor);
1716 XFreeCursor(dpy, g->grid.vResizeCursor);
1717 if (g->grid.gc)
1719 XFreeGC(dpy, g->grid.gc);
1720 XFreeFont(dpy, g->grid.fallbackFont);
1722 XmFontListFree(g->grid.fontList);
1723 XmLGridCellDerefValues(g->grid.defCellValues);
1724 ExtendSelect(g, (XEvent *)0, False, -1, -1);
1725 count = XmLArrayGetCount(g->grid.rowArray);
1726 for (i = 0; i < count; i++)
1727 XmLGridRowFree(w, (XmLGridRow)XmLArrayGet(g->grid.rowArray, i));
1728 XmLArrayFree(g->grid.rowArray);
1729 count = XmLArrayGetCount(g->grid.colArray);
1730 for (i = 0; i < count; i++)
1731 XmLGridColumnFree(w, (XmLGridColumn)XmLArrayGet(g->grid.colArray, i));
1732 XmLArrayFree(g->grid.colArray);
1733 if (g->grid.simpleHeadings)
1734 free((char *)g->grid.simpleHeadings);
1735 if (g->grid.simpleWidths)
1736 free((char *)g->grid.simpleWidths);
1740 Geometry, Drawing, Entry and Picking
1743 static void
1744 Realize(Widget w,
1745 XtValueMask *valueMask,
1746 XSetWindowAttributes *attr)
1748 XmLGridWidget g;
1749 Display *dpy;
1750 WidgetClass superClass;
1751 XtRealizeProc realize;
1752 XGCValues values;
1753 XtGCMask mask;
1754 static char dashes[2] = { 1, 1 };
1756 g = (XmLGridWidget)w;
1757 dpy = XtDisplay(g);
1758 superClass = xmlGridWidgetClass->core_class.superclass;
1759 realize = superClass->core_class.realize;
1760 (*realize)(w, valueMask, attr);
1762 if (!g->grid.gc)
1764 g->grid.fallbackFont = XLoadQueryFont(dpy, "fixed");
1765 values.foreground = g->manager.foreground;
1766 values.font = g->grid.fallbackFont->fid;
1767 mask = GCForeground | GCFont;
1768 g->grid.gc = XCreateGC(dpy, XtWindow(g), mask, &values);
1769 XSetDashes(dpy, g->grid.gc, 0, dashes, 2);
1770 if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
1771 g->grid.autoSelect == True &&
1772 g->grid.rowCount)
1773 XmLGridSelectRow(w, 0, False);
1777 static void
1778 Redisplay(Widget w,
1779 XExposeEvent *event,
1780 Region region)
1782 XmLGridWidget g;
1783 Display *dpy;
1784 Window win;
1785 XmLGridCell cell;
1786 XmLGridRow row;
1787 XmLGridColumn col;
1788 XmLGridCellRefValues *cellValues;
1789 XmLGridDrawStruct ds;
1790 XmLGridCallbackStruct cbs;
1791 GridReg *reg;
1792 XRectangle eRect, rRect, clipRect, rect[6];
1793 int i, n, st, c, r, sc, sr, width, height, rowHeight;
1794 int lastVisPos, visPos, hasDrawCB;
1795 Boolean spanUp, spanLeft;
1797 g = (XmLGridWidget)w;
1798 if (!XtIsRealized((Widget)g))
1799 return;
1800 if (!g->core.visible)
1801 return;
1802 if (g->grid.layoutFrozen == True)
1803 XmLWarning(w, "Redisplay() - layout frozen is True during redraw");
1804 dpy = XtDisplay(g);
1805 win = XtWindow(g);
1806 st = g->manager.shadow_thickness;
1807 reg = g->grid.reg;
1808 if (event)
1810 eRect.x = event->x;
1811 eRect.y = event->y;
1812 eRect.width = event->width;
1813 eRect.height = event->height;
1814 if (g->grid.debugLevel > 1)
1815 fprintf(stderr, "XmLGrid: Redisplay x %d y %d w %d h %d\n",
1816 event->x, event->y, event->width, event->height);
1818 else
1820 eRect.x = 0;
1821 eRect.y = 0;
1822 eRect.width = g->core.width;
1823 eRect.height = g->core.height;
1825 if (!eRect.width || !eRect.height)
1826 return;
1827 /* Hide any XORed graphics */
1828 DrawResizeLine(g, 0, 1);
1829 hasDrawCB = 0;
1830 if (XtHasCallbacks(w, XmNcellDrawCallback) == XtCallbackHasSome)
1831 hasDrawCB = 1;
1833 /* Add extra shadow around the whole widget
1834 * if 512 is set for shadow regions
1836 if (g->grid.shadowRegions == 512
1837 && g->manager.shadow_thickness
1838 && XmLRectIntersect(&eRect, &rRect) != XmLRectInside)
1840 #ifdef MOTIF11
1841 _XmDrawShadow(dpy, win,
1842 g->manager.bottom_shadow_GC,
1843 g->manager.top_shadow_GC,
1844 g->manager.shadow_thickness,
1845 0,0,
1846 g->core.width, g->core.height);
1847 #else
1848 _XmDrawShadows(dpy, win,
1849 g->manager.top_shadow_GC,
1850 g->manager.bottom_shadow_GC,
1851 0,0,
1852 g->core.width, g->core.height,
1853 g->manager.shadow_thickness,
1854 g->grid.shadowType);
1855 #endif
1857 /* end of extra shadow */
1858 for (i = 0; i < 9; i++)
1860 if (!reg[i].width || !reg[i].height)
1861 continue;
1862 rRect.x = reg[i].x;
1863 rRect.y = reg[i].y;
1864 rRect.width = reg[i].width;
1865 rRect.height = reg[i].height;
1866 if (XmLRectIntersect(&eRect, &rRect) == XmLRectOutside)
1867 continue;
1868 if (g->grid.debugLevel > 2)
1869 fprintf(stderr, "XmLGrid: Redisplay region %d shadows\n", i);
1870 rRect.x += st;
1871 rRect.width -= st * 2;
1872 rRect.y += st;
1873 rRect.height -= st * 2;
1874 if (XmLRectIntersect(&eRect, &rRect) != XmLRectInside
1875 && g->manager.shadow_thickness
1876 && g->grid.shadowRegions != 512)
1878 if (g->grid.shadowRegions & (1 << i))
1879 #ifdef MOTIF11
1880 _XmDrawShadow(dpy, win,
1881 g->manager.bottom_shadow_GC,
1882 g->manager.top_shadow_GC,
1883 g->manager.shadow_thickness,
1884 reg[i].x, reg[i].y,
1885 reg[i].width, reg[i].height);
1886 #else
1887 _XmDrawShadows(dpy, win,
1888 g->manager.top_shadow_GC,
1889 g->manager.bottom_shadow_GC,
1890 reg[i].x, reg[i].y,
1891 reg[i].width, reg[i].height,
1892 g->manager.shadow_thickness,
1893 g->grid.shadowType);
1894 #endif
1895 else
1896 #ifdef MOTIF11
1897 _XmEraseShadow(dpy, win,
1898 g->manager.shadow_thickness,
1899 reg[i].x, reg[i].y,
1900 reg[i].width, reg[i].height);
1901 #else
1902 _XmClearBorder(dpy, win,
1903 reg[i].x, reg[i].y,
1904 reg[i].width, reg[i].height,
1905 g->manager.shadow_thickness);
1906 #endif
1908 rRect.x += st;
1909 height = 0;
1910 if (g->grid.debugLevel > 2)
1911 fprintf(stderr, "XmLGrid: Redisplay region %d content\n", i);
1912 for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
1914 rowHeight = GetRowHeight(g, r);
1915 if (!rowHeight && !g->grid.mayHaveRowSpans)
1916 continue;
1917 width = 0;
1918 for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
1920 rRect.x = reg[i].x + st + width;
1921 rRect.y = reg[i].y + st + height;
1922 if (g->grid.singleColScrollMode)
1923 rRect.x -= g->grid.singleColScrollPos;
1924 rRect.width = GetColWidth(g, c);
1925 #if 0
1926 if (i == 1 && r == reg[1].row && c == reg[1].col - 1)
1928 rRect.width -= 10;
1930 #endif /*0 slamm */
1931 rRect.height = rowHeight;
1932 width += rRect.width;
1933 cell = GetCell(g, r, c);
1934 if (!cell)
1935 continue;
1936 cellValues = XmLGridCellGetRefValues(cell);
1938 spanUp = False;
1939 spanLeft = False;
1940 if (XmLGridCellInRowSpan(cell))
1942 if (r == reg[i].row)
1944 spanUp = True;
1945 if (c == reg[i].col)
1946 spanLeft = True;
1948 else
1949 continue;
1951 if (XmLGridCellInColumnSpan(cell))
1953 if (c == reg[i].col)
1954 spanLeft = True;
1955 else
1956 continue;
1958 sr = r;
1959 sc = c;
1960 if (spanUp == True || spanLeft == True ||
1961 cellValues->rowSpan || cellValues->columnSpan)
1963 if (RowColFirstSpan(g, r, c, &sr, &sc, &rRect,
1964 spanLeft, spanUp) == -1)
1965 continue;
1966 RowColSpanRect(g, sr, sc, &rRect);
1968 if (!rRect.width || !rRect.height)
1969 continue;
1970 clipRect = rRect;
1971 ClipRectToReg(g, &clipRect, &reg[i]);
1972 if (!clipRect.width || !clipRect.height)
1973 continue;
1974 if (event && XRectInRegion(region, clipRect.x, clipRect.y,
1975 clipRect.width, clipRect.height) == RectangleOut)
1976 continue;
1977 cell = GetCell(g, sr, sc);
1978 if (!cell)
1979 continue;
1980 cellValues = XmLGridCellGetRefValues(cell);
1981 cbs.reason = XmCR_CELL_DRAW;
1982 cbs.event = (XEvent *)event;
1983 cbs.rowType = RowPosToType(g, sr);
1984 cbs.row = RowPosToTypePos(g, cbs.rowType, sr);
1985 cbs.columnType = ColPosToType(g, sc);
1986 cbs.column = ColPosToTypePos(g, cbs.columnType, sc);
1987 cbs.clipRect = &clipRect;
1988 cbs.drawInfo = &ds;
1989 ds.gc = g->grid.gc;
1990 ds.cellRect = &rRect;
1991 ds.topMargin = cellValues->topMargin;
1992 ds.bottomMargin = cellValues->bottomMargin;
1993 ds.leftMargin = cellValues->leftMargin;
1994 ds.rightMargin = cellValues->rightMargin;
1995 ds.background = cellValues->background;
1996 ds.foreground = cellValues->foreground;
1997 ds.fontList = cellValues->fontList;
1998 ds.alignment = cellValues->alignment;
1999 ds.selectBackground = g->grid.selectBg;
2000 ds.selectForeground = g->grid.selectFg;
2001 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, sr);
2002 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, sc);
2003 ds.drawFocusType = XmDRAW_FOCUS_NONE;
2004 if (g->grid.focusRow == sr &&
2005 g->grid.highlightRowMode == True &&
2006 g->grid.focusIn)
2008 RecalcVisPos(g, 0);
2009 visPos = XmLGridColumnGetVisPos(col);
2010 lastVisPos = XmLArrayGetCount(g->grid.colArray) -
2011 g->grid.hiddenColCount - 1;
2012 if (visPos == 0 && visPos == lastVisPos)
2013 ds.drawFocusType = XmDRAW_FOCUS_CELL;
2014 else if (visPos == 0)
2015 ds.drawFocusType = XmDRAW_FOCUS_LEFT;
2016 else if (visPos == lastVisPos)
2017 ds.drawFocusType = XmDRAW_FOCUS_RIGHT;
2018 else
2019 ds.drawFocusType = XmDRAW_FOCUS_MID;
2021 if (g->grid.focusRow == sr &&
2022 g->grid.focusCol == sc &&
2023 g->grid.highlightRowMode == False &&
2024 g->grid.focusIn)
2025 ds.drawFocusType = XmDRAW_FOCUS_CELL;
2026 if (XmLGridRowIsSelected(row) == True ||
2027 XmLGridColumnIsSelected(col) == True ||
2028 XmLGridCellIsSelected(cell) == True)
2029 ds.drawSelected = True;
2030 else
2031 ds.drawSelected = False;
2032 if (g->grid.selectionPolicy == XmSELECT_CELL &&
2033 g->grid.focusIn && g->grid.focusRow == sr &&
2034 g->grid.focusCol == sc)
2035 ds.drawSelected = False;
2036 ds.stringDirection = g->manager.string_direction;
2037 XmLGridCellAction(cell, (Widget)g, &cbs);
2038 if (hasDrawCB)
2039 XtCallCallbackList(w, g->grid.cellDrawCallback,
2040 (XtPointer)&cbs);
2042 height += rowHeight;
2045 if (g->grid.debugLevel > 1)
2046 fprintf(stderr, "XmLGrid: Redisplay non-cell areas\n");
2047 n = 0;
2048 if (reg[0].width && g->grid.leftFixedMargin)
2050 rect[n].x = reg[0].width;
2051 rect[n].y = 0;
2052 rect[n].width = g->grid.leftFixedMargin;
2053 rect[n].height = g->core.height;
2054 n++;
2056 if (reg[2].width && g->grid.rightFixedMargin)
2058 width = 0;
2059 if (reg[0].ncol)
2060 width += reg[0].width + g->grid.leftFixedMargin;
2061 if (reg[1].ncol)
2062 width += reg[1].width;
2063 rect[n].x = width;
2064 rect[n].y = 0;
2065 rect[n].width = g->grid.rightFixedMargin;
2066 rect[n].height = g->core.height;
2067 n++;
2069 if (reg[0].height && g->grid.topFixedMargin)
2071 rect[n].x = 0;
2072 rect[n].y = reg[0].height;
2073 rect[n].width = g->core.width;
2074 rect[n].height = g->grid.topFixedMargin;
2075 n++;
2077 if (reg[6].height && g->grid.bottomFixedMargin)
2079 rect[n].x = 0;
2080 height = 0;
2081 if (reg[0].nrow)
2082 height += reg[0].height + g->grid.topFixedMargin;
2083 if (reg[3].nrow)
2084 height += reg[3].height;
2085 rect[n].y = height;
2086 rect[n].width = g->core.width;
2087 rect[n].height = g->grid.bottomFixedMargin;
2088 n++;
2090 width = reg[1].width;
2091 if (reg[0].ncol)
2092 width += reg[0].width + g->grid.leftFixedMargin;
2093 if (reg[2].ncol)
2094 width += g->grid.rightFixedMargin + reg[2].width;
2095 if (width < (int)g->core.width)
2097 rect[n].x = width;
2098 rect[n].y = 0;
2099 rect[n].width = g->core.width - width;
2100 rect[n].height = g->core.height;
2101 n++;
2103 height = reg[3].height;
2104 if (reg[0].nrow)
2105 height += reg[0].height + g->grid.topFixedMargin;
2106 if (reg[6].nrow)
2107 height += g->grid.bottomFixedMargin + reg[6].height;
2108 if (height < (int)g->core.height)
2110 rect[n].x = 0;
2111 rect[n].y = height;
2112 rect[n].width = g->core.width;
2113 rect[n].height = g->core.height - height;
2114 n++;
2116 for (i = 0; i < n; i++)
2118 if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
2119 continue;
2120 XClearArea(dpy, win, rect[i].x, rect[i].y, rect[i].width,
2121 rect[i].height, False);
2123 n = 0;
2124 if (reg[1].width)
2126 width = 0;
2127 for (c = reg[1].col; c < reg[1].col + reg[1].ncol; c++)
2128 width += GetColWidth(g, c);
2129 for (i = 1; i < 9; i += 3)
2130 if (reg[i].height && width < reg[i].width - st * 2)
2132 rect[n].x = reg[i].x + st + width;
2133 rect[n].y = reg[i].y + st;
2134 rect[n].width = reg[i].x + reg[i].width -
2135 rect[n].x - st;
2136 rect[n].height = reg[i].height - st * 2;
2137 n++;
2140 if (reg[3].height)
2142 height = 0;
2143 for (r = reg[3].row; r < reg[3].row + reg[3].nrow; r++)
2144 height += GetRowHeight(g, r);
2145 for (i = 3; i < 6; i++)
2146 if (reg[i].width && height < reg[i].height - st * 2)
2148 rect[n].x = reg[i].x + st;
2149 rect[n].y = reg[i].y + st + height;
2150 rect[n].width = reg[i].width - st * 2;
2151 rect[n].height = reg[i].y + reg[i].height -
2152 rect[n].y - st;
2153 n++;
2156 XSetForeground(dpy, g->grid.gc, g->grid.blankBg);
2157 for (i = 0; i < n; i++)
2159 if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
2160 continue;
2161 XFillRectangle(dpy, win, g->grid.gc, rect[i].x, rect[i].y,
2162 rect[i].width, rect[i].height);
2164 /* Show any XORed graphics */
2165 DrawResizeLine(g, 0, 1);
2168 static void
2169 DrawResizeLine(XmLGridWidget g,
2170 int xy,
2171 int erase)
2173 if (g->grid.inMode != InResize)
2174 return;
2175 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && !g->grid.resizeIsVert)
2176 return;
2177 DrawXORRect(g, xy, 2, g->grid.resizeIsVert, erase);
2180 static void
2181 DrawXORRect(XmLGridWidget g,
2182 int xy,
2183 int size,
2184 int isVert,
2185 int erase)
2187 Display *dpy;
2188 Window win;
2189 GC gc;
2190 Pixel black, white;
2191 int oldXY, maxX, maxY;
2193 if (!XtIsRealized((Widget)g))
2194 return;
2195 /* erase is (0 == none) (1 == hide/show) (2 == permenent erase) */
2196 dpy = XtDisplay(g);
2197 win = XtWindow(g);
2198 gc = g->grid.gc;
2199 XSetFunction(dpy, gc, GXinvert);
2200 black = BlackPixelOfScreen(XtScreen((Widget)g));
2201 white = WhitePixelOfScreen(XtScreen((Widget)g));
2202 XSetForeground(dpy, gc, black ^ white);
2203 maxX = g->core.width;
2204 if (XtIsManaged(g->grid.vsb))
2205 maxX -= g->grid.vsb->core.width + g->grid.scrollBarMargin;
2206 maxY = g->core.height;
2207 if (XtIsManaged(g->grid.hsb))
2208 maxY -= g->grid.hsb->core.height + g->grid.scrollBarMargin;
2209 oldXY = g->grid.resizeLineXY;
2210 if (isVert)
2212 if (oldXY != -1)
2213 XFillRectangle(dpy, win, gc, 0, oldXY, maxX, size);
2215 else
2217 if (oldXY != -1)
2218 XFillRectangle(dpy, win, gc, oldXY, 0, size, maxY);
2220 if (!erase)
2222 if (isVert)
2224 if (xy > maxY)
2225 xy = maxY - 2;
2226 if (xy < 0)
2227 xy = 0;
2228 XFillRectangle(dpy, win, gc, 0, xy, maxX, size);
2230 else
2232 if (xy > maxX)
2233 xy = maxX - 2;
2234 if (xy < 0)
2235 xy = 0;
2236 XFillRectangle(dpy, win, gc, xy, 0, size, maxY);
2238 g->grid.resizeLineXY = xy;
2240 else if (erase == 2)
2241 g->grid.resizeLineXY = -1;
2242 XSetFunction(dpy, gc, GXcopy);
2245 static void
2246 DefineCursor(XmLGridWidget g,
2247 char defineCursor)
2249 Display *dpy;
2250 Window win;
2252 if (!XtIsRealized((Widget)g))
2253 return;
2254 dpy = XtDisplay(g);
2255 win = XtWindow(g);
2256 if (defineCursor != g->grid.cursorDefined)
2257 XUndefineCursor(dpy, win);
2258 if (defineCursor == CursorVResize)
2259 XDefineCursor(dpy, win, g->grid.vResizeCursor);
2260 else if (defineCursor == CursorHResize)
2261 XDefineCursor(dpy, win, g->grid.hResizeCursor);
2262 g->grid.cursorDefined = defineCursor;
2265 static void
2266 DrawArea(XmLGridWidget g,
2267 int type,
2268 int row,
2269 int col)
2271 GridReg *reg;
2272 Display *dpy;
2273 Window win;
2274 XExposeEvent event;
2275 XRectangle rect[3];
2276 Region region;
2277 int i, j, n;
2278 Dimension width, height, st;
2280 if (g->grid.layoutFrozen == True)
2281 return;
2282 if (!XtIsRealized((Widget)g))
2283 return;
2284 if (!g->core.visible)
2285 return;
2286 dpy = XtDisplay(g);
2287 win = XtWindow(g);
2288 reg = g->grid.reg;
2289 st = g->manager.shadow_thickness;
2290 if (g->grid.debugLevel > 1)
2291 fprintf(stderr, "XmLGrid: DrawArea %d %d %d\n", type, row, col);
2293 n = 0;
2294 switch (type)
2296 case DrawAll:
2298 rect[n].x = 0;
2299 rect[n].y = 0;
2300 rect[n].width = g->core.width;
2301 rect[n].height = g->core.height;
2302 n++;
2303 break;
2305 case DrawHScroll:
2307 for (i = 1; i < 9; i += 3)
2309 if (!reg[i].width || !reg[i].height)
2310 continue;
2311 rect[n].x = reg[i].x + st;
2312 rect[n].y = reg[i].y + st;
2313 rect[n].width = reg[i].width - st * 2;
2314 rect[n].height = reg[i].height - st * 2;
2315 n++;
2317 break;
2319 case DrawVScroll:
2321 for (i = 3; i < 6; i++)
2324 if (!reg[i].width || !reg[i].height)
2325 continue;
2326 rect[n].x = reg[i].x + st;
2327 rect[n].y = reg[i].y + st;
2328 rect[n].width = reg[i].width - st * 2;
2329 rect[n].height = reg[i].height - st * 2;
2330 n++;
2332 break;
2334 case DrawRow:
2336 for (i = 0; i < 9; i++)
2338 if (!reg[i].width || !reg[i].height)
2339 continue;
2340 if (!(row >= reg[i].row &&
2341 row < reg[i].row + reg[i].nrow))
2342 continue;
2343 height = 0;
2344 for (j = reg[i].row; j < row; j++)
2345 height += GetRowHeight(g, j);
2346 rect[n].x = reg[i].x + st;
2347 rect[n].y = reg[i].y + st + height;
2348 rect[n].width = reg[i].width - st * 2;
2349 rect[n].height = GetRowHeight(g, row);
2350 ClipRectToReg(g, &rect[n], &reg[i]);
2351 n++;
2353 break;
2355 case DrawCol:
2357 for (i = 0; i < 9; i++)
2359 if (!reg[i].width || !reg[i].height)
2360 continue;
2361 if (!(col >= reg[i].col &&
2362 col < reg[i].col + reg[i].ncol))
2363 continue;
2364 width = 0;
2365 for (j = reg[i].col; j < col; j++)
2366 width += GetColWidth(g, j);
2367 rect[n].x = reg[i].x + st + width;
2368 rect[n].y = reg[i].y + st;
2369 rect[n].width = GetColWidth(g, col);
2370 rect[n].height = reg[i].height - st * 2;
2371 ClipRectToReg(g, &rect[n], &reg[i]);
2372 n++;
2374 break;
2376 case DrawCell:
2378 if (!RowColToXY(g, row, col, True, &rect[n]))
2379 n++;
2380 break;
2383 for (i = 0; i < n; i++)
2385 if (!rect[i].width || !rect[i].height)
2386 continue;
2387 event.type = Expose;
2388 event.window = win;
2389 event.display = dpy;
2390 event.x = rect[i].x;
2391 event.y = rect[i].y;
2392 event.width = rect[i].width;
2393 event.height = rect[i].height;
2394 event.send_event = True;
2395 event.count = 0;
2396 if (g->grid.immediateDraw)
2398 region = XCreateRegion();
2399 XUnionRectWithRegion(&rect[i], region, region);
2400 Redisplay((Widget)g, &event, region);
2401 XDestroyRegion(region);
2403 else
2404 XSendEvent(dpy, win, False, ExposureMask, (XEvent *)&event);
2405 if (g->grid.debugLevel > 1)
2406 fprintf(stderr, "XmLGrid: DrawArea expose x %d y %d w %d h %d\n",
2407 event.x, event.y, event.width, event.height);
2411 static void
2412 ExtendSelectRange(XmLGridWidget g,
2413 int *type,
2414 int *fr,
2415 int *lr,
2416 int *fc,
2417 int *lc)
2419 int r, c;
2421 if ((g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW) ||
2422 (ColPosToType(g, g->grid.extendCol) != XmCONTENT))
2423 *type = SelectRow;
2424 else if (RowPosToType(g, g->grid.extendRow) != XmCONTENT)
2425 *type = SelectCol;
2426 else
2427 *type = SelectCell;
2429 r = g->grid.extendToRow;
2430 if (r < g->grid.headingRowCount)
2431 r = g->grid.headingRowCount;
2432 if (r >= g->grid.headingRowCount + g->grid.rowCount)
2433 r = g->grid.headingRowCount + g->grid.rowCount - 1;
2434 if (*type == SelectCol)
2436 *fr = 0;
2437 *lr = 1;
2439 else if (g->grid.extendRow < r)
2441 *fr = g->grid.extendRow;
2442 *lr = r;
2444 else
2446 *fr = r;
2447 *lr = g->grid.extendRow;
2449 c = g->grid.extendToCol;
2450 if (c < g->grid.headingColCount)
2451 c = g->grid.headingColCount;
2452 if (c >= g->grid.headingColCount + g->grid.colCount)
2453 c = g->grid.headingColCount + g->grid.colCount - 1;
2454 if (*type == SelectRow)
2456 *fc = 0;
2457 *lc = 1;
2459 else if (g->grid.extendCol < c)
2461 *fc = g->grid.extendCol;
2462 *lc = c;
2464 else
2466 *fc = c;
2467 *lc = g->grid.extendCol;
2471 static void
2472 ExtendSelect(XmLGridWidget g,
2473 XEvent *event,
2474 Boolean set,
2475 int row,
2476 int col)
2478 int type;
2479 int r, fr, lr;
2480 int c, fc, lc;
2482 if (row == -1 || col == -1)
2484 g->grid.extendRow = -1;
2485 g->grid.extendCol = -1;
2486 g->grid.extendToRow = -1;
2487 g->grid.extendToCol = -1;
2488 g->grid.extendSelect = True;
2489 return;
2491 if (RowPosToType(g, row) == XmFOOTER || ColPosToType(g, col) == XmFOOTER)
2492 return;
2493 if ((g->grid.extendToRow == row && g->grid.extendToCol == col) ||
2494 (g->grid.extendRow == -1 && row == g->grid.focusRow &&
2495 g->grid.extendCol == -1 && col == g->grid.focusCol))
2496 return;
2497 if (g->grid.extendRow != -1 && g->grid.extendCol != -1)
2499 /* clear previous extend */
2500 ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
2501 for (r = fr; r <= lr; r += 1)
2502 for (c = fc; c <= lc; c += 1)
2503 SelectTypeArea(g, type, event,
2504 RowPosToTypePos(g, XmCONTENT, r),
2505 ColPosToTypePos(g, XmCONTENT, c), False, True);
2507 else
2509 g->grid.extendRow = g->grid.focusRow;
2510 g->grid.extendCol = g->grid.focusCol;
2512 if (set == True)
2514 g->grid.extendRow = row;
2515 g->grid.extendCol = col;
2517 if (g->grid.extendRow < 0 || g->grid.extendCol < 0)
2518 return;
2519 g->grid.extendToRow = row;
2520 g->grid.extendToCol = col;
2522 /* set new extend */
2523 ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
2524 for (r = fr; r <= lr; r += 1)
2525 for (c = fc; c <= lc; c += 1)
2526 SelectTypeArea(g, type, event,
2527 RowPosToTypePos(g, XmCONTENT, r),
2528 ColPosToTypePos(g, XmCONTENT, c),
2529 g->grid.extendSelect, True);
2532 static void
2533 SelectTypeArea(XmLGridWidget g,
2534 int type,
2535 XEvent *event,
2536 int row,
2537 int col,
2538 Boolean select,
2539 Boolean notify)
2541 Widget w;
2542 XmLGridRow rowp;
2543 XmLGridColumn colp;
2544 XmLGridCell cellp;
2545 int r, fr, lr, hrc;
2546 int c, fc, lc, hcc;
2547 int badPos, hasCB;
2548 XmLGridCallbackStruct cbs;
2550 w = (Widget)g;
2551 hrc = g->grid.headingRowCount;
2552 hcc = g->grid.headingColCount;
2553 cbs.event = event;
2554 cbs.rowType = XmCONTENT;
2555 cbs.columnType = XmCONTENT;
2556 hasCB = 0;
2557 if (select == True)
2559 if (type == SelectRow)
2560 cbs.reason = XmCR_SELECT_ROW;
2561 else if (type == SelectCol)
2562 cbs.reason = XmCR_SELECT_COLUMN;
2563 else if (type == SelectCell)
2564 cbs.reason = XmCR_SELECT_CELL;
2565 if (XtHasCallbacks(w, XmNselectCallback) == XtCallbackHasSome)
2566 hasCB = 1;
2568 else
2570 if (type == SelectRow)
2571 cbs.reason = XmCR_DESELECT_ROW;
2572 else if (type == SelectCol)
2573 cbs.reason = XmCR_DESELECT_COLUMN;
2574 else if (type == SelectCell)
2575 cbs.reason = XmCR_DESELECT_CELL;
2576 if (XtHasCallbacks(w, XmNdeselectCallback) == XtCallbackHasSome)
2577 hasCB = 1;
2579 if (row != -1)
2581 fr = hrc + row;
2582 lr = fr + 1;
2584 else
2586 fr = hrc;
2587 lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
2589 if (col != -1)
2591 fc = hcc + col;
2592 lc = fc + 1;
2594 else
2596 fc = hcc;
2597 lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
2599 badPos = 0;
2600 for (r = fr; r < lr; r++)
2601 for (c = fc; c < lc; c++)
2603 if (type == SelectRow)
2605 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
2606 if (!rowp)
2608 badPos = 1;
2609 continue;
2611 if (XmLGridRowIsSelected(rowp) == select)
2612 continue;
2613 if (select == True &&
2614 (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW ||
2615 g->grid.selectionPolicy == XmSELECT_SINGLE_ROW))
2616 SelectTypeArea(g, SelectRow, event, -1, 0, False, notify);
2617 XmLGridRowSetSelected(rowp, select);
2618 if (RowIsVisible(g, r))
2619 DrawArea(g, DrawRow, r, 0);
2620 if (notify && hasCB)
2622 cbs.row = r - hrc;
2623 if (select == True)
2624 XtCallCallbackList(w, g->grid.selectCallback,
2625 (XtPointer)&cbs);
2626 else
2627 XtCallCallbackList(w, g->grid.deselectCallback,
2628 (XtPointer)&cbs);
2631 else if (type == SelectCol)
2633 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
2634 if (!colp)
2636 badPos = 1;
2637 continue;
2639 if (XmLGridColumnIsSelected(colp) == select)
2640 continue;
2641 XmLGridColumnSetSelected(colp, select);
2642 if (ColIsVisible(g, c))
2643 DrawArea(g, DrawCol, 0, c);
2644 if (notify && hasCB)
2646 cbs.column = c - hcc;
2647 if (select == True)
2648 XtCallCallbackList(w, g->grid.selectCallback,
2649 (XtPointer)&cbs);
2650 else
2651 XtCallCallbackList(w, g->grid.deselectCallback,
2652 (XtPointer)&cbs);
2655 else if (type == SelectCell)
2657 cellp = GetCell(g, r, c);
2658 if (!cellp)
2660 badPos = 1;
2661 continue;
2663 if (XmLGridCellIsSelected(cellp) == select)
2664 continue;
2665 XmLGridCellSetSelected(cellp, select);
2666 DrawArea(g, DrawCell, r, c);
2667 if (notify && hasCB)
2669 cbs.column = c - hcc;
2670 cbs.row = r - hrc;
2671 if (select == True)
2672 XtCallCallbackList(w, g->grid.selectCallback,
2673 (XtPointer)&cbs);
2674 else
2675 XtCallCallbackList(w, g->grid.deselectCallback,
2676 (XtPointer)&cbs);
2680 if (badPos)
2681 XmLWarning((Widget)g, "SelectTypeArea() - bad position");
2684 static int
2685 GetSelectedArea(XmLGridWidget g,
2686 int type,
2687 int *rowPos,
2688 int *colPos,
2689 int count)
2691 XmLGridRow row;
2692 XmLGridColumn col;
2693 XmLGridCell cell;
2694 int r, fr, lr;
2695 int c, fc, lc;
2696 int n;
2698 if (type == SelectCol)
2700 fr = 0;
2701 lr = 1;
2703 else
2705 fr = g->grid.headingRowCount;
2706 lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
2708 if (type == SelectRow)
2710 fc = 0;
2711 lc = 1;
2713 else
2715 fc = g->grid.headingColCount;
2716 lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
2718 n = 0;
2719 for (r = fr; r < lr; r++)
2720 for (c = fc; c < lc; c++)
2722 if (type == SelectRow)
2724 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
2725 if (row && XmLGridRowIsSelected(row) == True)
2727 if (rowPos && n < count)
2728 rowPos[n] = r - fr;
2729 n++;
2732 else if (type == SelectCol)
2734 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
2735 if (col && XmLGridColumnIsSelected(col) == True)
2737 if (colPos && n < count)
2738 colPos[n] = c - fc;
2739 n++;
2742 else if (type == SelectCell)
2744 cell = GetCell(g, r, c);
2745 if (cell && XmLGridCellIsSelected(cell) == True)
2747 if (rowPos && colPos && n < count)
2749 rowPos[n] = r - fr;
2750 colPos[n] = c - fc;
2752 n++;
2756 return n;
2759 static void
2760 ChangeManaged(Widget w)
2762 _XmNavigChangeManaged(w);
2765 static void
2766 Resize(Widget w)
2768 XmLGridWidget g;
2769 XmLGridCallbackStruct cbs;
2771 g = (XmLGridWidget)w;
2773 if (!g->grid.inResize)
2775 cbs.reason = XmCR_RESIZE_GRID;
2777 g->grid.inResize = True;
2778 XtCallCallbackList((Widget)g, g->grid.resizeCallback,
2779 (XtPointer)&cbs);
2780 g->grid.inResize = False;
2783 VertLayout(g, 0);
2784 HorizLayout(g, 0);
2785 PlaceScrollbars(g);
2786 DrawArea(g, DrawAll, 0, 0);
2789 static void
2790 PlaceScrollbars(XmLGridWidget g)
2792 int x, y;
2793 int width, height;
2794 Widget vsb, hsb;
2795 Dimension st, headingRowHeight = 0;
2797 st = g->manager.shadow_thickness;
2798 vsb = g->grid.vsb;
2799 hsb = g->grid.hsb;
2800 width = g->core.width;
2801 if (XtIsManaged(vsb))
2802 width -= vsb->core.width;
2803 if (width <= 0)
2804 width = 1;
2805 y = g->core.height - hsb->core.height;
2806 XtConfigureWidget(hsb, 0, y, width, hsb->core.height, 0);
2808 height = g->core.height;
2809 if (XtIsManaged(hsb))
2810 height -= hsb->core.height;
2812 y = 0;
2814 if (g->grid.headingRowCount > 0)
2816 XmLGridRow rowp;
2818 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
2820 headingRowHeight = XmLGridRowHeightInPixels(rowp) + st;
2823 if (g->grid.hideUnhideButtons
2824 && g->grid.hideButton && g->grid.unhideButton)
2826 int buttonWidth = vsb->core.width - 4;
2828 if (headingRowHeight == 0)
2829 headingRowHeight = 20;
2831 /* if there is at least heading row, we make the
2832 height of the button the height of the first
2833 heading row.
2835 This is pretty braindead... */
2837 XtConfigureWidget(g->grid.unhideButton,
2838 g->core.width - buttonWidth*2 - st,
2839 y + st,
2840 buttonWidth,
2841 headingRowHeight - st, 0);
2842 XtConfigureWidget(g->grid.hideButton,
2843 g->core.width - buttonWidth - st,
2844 y + st,
2845 buttonWidth,
2846 headingRowHeight - st, 0);
2848 setHideUnhideSensitivity((Widget)g);
2850 /* once we've positioned it, make sure it's managed.
2851 Doing it in this order (position, then manage) reduces
2852 screen flickering -- the button doesn't flash on in the
2853 upper left corner for an instant. */
2854 if (!XtIsManaged(g->grid.hideButton))
2855 XtManageChild(g->grid.hideButton);
2856 if (!XtIsManaged(g->grid.unhideButton))
2857 XtManageChild(g->grid.unhideButton);
2860 if (height <= 0)
2861 width = 1;
2862 x = g->core.width - vsb->core.width;
2863 XtConfigureWidget(vsb,
2864 x, y + headingRowHeight + g->manager.shadow_thickness,
2865 vsb->core.width, height - headingRowHeight - g->manager.shadow_thickness,
2869 void
2870 _XmLGridLayout(XmLGridWidget g)
2872 VertLayout(g, 1);
2873 HorizLayout(g, 1);
2876 static void
2877 VertLayout(XmLGridWidget g,
2878 int resizeIfNeeded)
2880 GridReg *reg;
2881 int i, j, st2, height, rowCount;
2882 int topNRow, topHeight;
2883 int midRow, midY, midNRow, midHeight;
2884 int botRow, botY, botNRow, botHeight;
2885 int scrollChanged, needsSB, needsResize, cRow;
2886 int maxRow, maxPos, maxHeight, newHeight, sliderSize;
2887 int horizSizeChanged;
2888 XtWidgetGeometry req;
2889 XmLGridCallbackStruct cbs;
2890 XmLGridPreLayoutProc preLayoutProc;
2892 if (g->grid.layoutFrozen == True)
2894 g->grid.needsVertLayout = 1;
2895 return;
2898 maxRow = maxPos = maxHeight = newHeight = horizSizeChanged = 0;
2899 preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
2900 if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
2901 horizSizeChanged = preLayoutProc(g, 1);
2903 scrollChanged = 0;
2904 needsResize = 0;
2905 needsSB = 0;
2906 rowCount = XmLArrayGetCount(g->grid.rowArray);
2907 reg = g->grid.reg;
2908 st2 = g->manager.shadow_thickness * 2;
2909 TextAction(g, TEXT_HIDE);
2911 topHeight = 0;
2912 topNRow = g->grid.topFixedCount;
2913 if (topNRow > g->grid.rowCount + g->grid.headingRowCount)
2914 topNRow = g->grid.rowCount + g->grid.headingRowCount;
2915 if (topNRow)
2917 topHeight += st2;
2918 for (i = 0; i < topNRow; i++)
2919 topHeight += GetRowHeight(g, i);
2921 botHeight = 0;
2922 botNRow = g->grid.bottomFixedCount;
2923 if (topNRow + botNRow > rowCount)
2924 botNRow = rowCount - topNRow;
2925 botRow = rowCount - botNRow;
2926 if (botNRow)
2928 botHeight += st2;
2929 for (i = botRow; i < rowCount; i++)
2930 botHeight += GetRowHeight(g, i);
2932 height = 0;
2933 if (topNRow)
2934 height += topHeight + g->grid.topFixedMargin;
2935 midY = height;
2936 if (botNRow)
2937 height += botHeight + g->grid.bottomFixedMargin;
2938 if (XtIsManaged(g->grid.hsb))
2940 height += g->grid.hsb->core.height;
2941 height += g->grid.scrollBarMargin;
2943 maxHeight = g->core.height - height;
2944 if (g->grid.vsPolicy != XmCONSTANT)
2946 if (rowCount == topNRow + botNRow)
2947 midHeight = 0;
2948 else
2949 midHeight = st2;
2950 for (i = topNRow; i < rowCount - botNRow; i++)
2951 midHeight += GetRowHeight(g, i);
2952 midRow = topNRow;
2953 midNRow = rowCount - topNRow - botNRow;
2954 needsResize = 1;
2955 newHeight = midHeight + height;
2956 if (g->grid.debugLevel)
2957 fprintf(stderr, "XmLGrid: VertLayout VARIABLE height\n");
2959 else
2961 if (maxHeight < st2)
2962 maxHeight = 0;
2963 height = st2;
2964 j = rowCount - botNRow - 1;
2965 for (i = j; i >= topNRow; i--)
2967 height += GetRowHeight(g, i);
2968 if (height > maxHeight)
2969 break;
2971 i++;
2972 if (i > j)
2973 i = j;
2974 maxRow = i;
2975 if (maxRow < topNRow)
2976 maxRow = topNRow;
2977 if (g->grid.debugLevel)
2978 fprintf(stderr, "XmLGrid: VertLayout max scroll row %d\n", i);
2979 if (maxRow == topNRow)
2981 if (g->grid.scrollRow != topNRow)
2983 scrollChanged = 1;
2984 g->grid.scrollRow = topNRow;
2986 midRow = topNRow;
2987 midHeight = maxHeight;
2988 midNRow = rowCount - topNRow - botNRow;
2989 if (g->grid.debugLevel)
2990 fprintf(stderr, "XmLGrid: VertLayout everything fits\n");
2992 else
2994 if (g->grid.scrollRow < topNRow)
2996 scrollChanged = 1;
2997 g->grid.scrollRow = topNRow;
2998 if (g->grid.debugLevel)
2999 fprintf(stderr, "XmLGrid: VertLayout scrolled < topRow\n");
3001 if (g->grid.scrollRow > maxRow)
3003 if (g->grid.debugLevel)
3004 fprintf(stderr, "XmLGrid: VertLayout scrolled > maxRow\n");
3005 scrollChanged = 1;
3006 g->grid.scrollRow = maxRow;
3008 height = st2;
3009 midNRow = 0;
3010 for (i = g->grid.scrollRow; i < rowCount - botNRow; i++)
3012 midNRow++;
3013 height += GetRowHeight(g, i);
3014 if (height >= maxHeight)
3015 break;
3017 needsSB = 1;
3018 midRow = g->grid.scrollRow;
3019 midHeight = maxHeight;
3022 botY = midY + midHeight;
3023 if (botNRow)
3024 botY += g->grid.bottomFixedMargin;
3025 for (i = 0; i < 3; i++)
3027 reg[i].y = 0;
3028 reg[i].height = topHeight;
3029 reg[i].row = 0;
3030 reg[i].nrow = topNRow;
3032 for (i = 3; i < 6; i++)
3034 reg[i].y = midY;
3035 reg[i].height = midHeight;
3036 reg[i].row = midRow;
3037 reg[i].nrow = midNRow;
3039 for (i = 6; i < 9; i++)
3041 reg[i].y = botY;
3042 reg[i].height = botHeight;
3043 reg[i].row = botRow;
3044 reg[i].nrow = botNRow;
3046 if (g->grid.debugLevel)
3048 fprintf(stderr, "XmLGrid: VertLayout TOP %3dy %3dh %3dr %3dnr\n",
3049 reg[0].y, reg[0].height, reg[0].row, reg[0].nrow);
3050 fprintf(stderr, "XmLGrid: VertLayout MID %3dy %3dh %3dr %3dnr\n",
3051 reg[3].y, reg[3].height, reg[3].row, reg[3].nrow);
3052 fprintf(stderr, "XmLGrid: VertLayout BOT %3dy %3dh %3dr %3dnr\n",
3053 reg[6].y, reg[6].height, reg[6].row, reg[6].nrow);
3055 if (needsSB)
3057 if (!XtIsManaged(g->grid.vsb))
3059 XtManageChild(g->grid.vsb);
3060 horizSizeChanged = 1;
3062 if (g->grid.debugLevel)
3063 fprintf(stderr, "XmLGrid: VertLayout set sb values\n");
3064 maxPos = PosToVisPos(g, maxRow, 1);
3065 sliderSize = PosToVisPos(g, rowCount - botNRow - 1, 1) - maxPos + 1;
3066 XtVaSetValues(g->grid.vsb,
3067 XmNminimum, PosToVisPos(g, topNRow, 1),
3068 XmNmaximum, maxPos + sliderSize,
3069 XmNsliderSize, sliderSize,
3070 XmNpageIncrement, sliderSize,
3071 XmNvalue, PosToVisPos(g, g->grid.scrollRow, 1),
3072 NULL);
3074 else if (g->grid.vsPolicy == XmCONSTANT &&
3075 g->grid.vsbDisplayPolicy == XmSTATIC)
3077 if (!XtIsManaged(g->grid.vsb))
3079 XtManageChild(g->grid.vsb);
3080 horizSizeChanged = 1;
3082 if (g->grid.debugLevel)
3083 fprintf(stderr, "XmLGrid: VertLayout vsb not needed but static\n");
3084 XtVaSetValues(g->grid.vsb,
3085 XmNminimum, 0,
3086 XmNmaximum, 1,
3087 XmNsliderSize, 1,
3088 XmNpageIncrement, 1,
3089 XmNvalue, 0,
3090 NULL);
3092 else
3094 if (XtIsManaged(g->grid.vsb))
3096 XtUnmanageChild(g->grid.vsb);
3097 horizSizeChanged = 1;
3100 if (needsResize && resizeIfNeeded)
3102 if (newHeight < 1)
3103 newHeight = 1;
3104 req.request_mode = CWHeight;
3105 req.height = newHeight;
3106 if (g->grid.debugLevel)
3107 fprintf(stderr, "XmLGrid: VertLayout Req h %d\n", (int)newHeight);
3108 XtMakeGeometryRequest((Widget)g, &req, NULL);
3109 PlaceScrollbars(g);
3111 if (scrollChanged)
3112 DrawArea(g, DrawVScroll, 0, 0);
3113 TextAction(g, TEXT_SHOW);
3114 cRow = g->grid.scrollRow - g->grid.headingRowCount;
3115 if (cRow != g->grid.cScrollRow)
3117 g->grid.cScrollRow = cRow;
3118 cbs.reason = XmCR_SCROLL_ROW;
3119 cbs.rowType = XmCONTENT;
3120 cbs.row = cRow;
3121 XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
3123 if (horizSizeChanged)
3125 if (g->grid.layoutStack > 2)
3126 XmLWarning((Widget)g, "VertLayout() - recursion error");
3127 else
3129 g->grid.layoutStack++;
3130 HorizLayout(g, resizeIfNeeded);
3131 g->grid.layoutStack--;
3133 PlaceScrollbars(g);
3137 static void
3138 HorizLayout(XmLGridWidget g,
3139 int resizeIfNeeded)
3141 GridReg *reg;
3142 int i, j, st2, width, colCount;
3143 int leftNCol, leftWidth;
3144 int midCol, midX, midNCol, midWidth;
3145 int rightCol, rightX, rightNCol, rightWidth;
3146 int scrollChanged, needsSB, needsResize, cCol;
3147 int maxCol, maxPos, maxWidth, newWidth, sliderSize;
3148 int vertSizeChanged;
3149 XtWidgetGeometry req;
3150 XmLGridCallbackStruct cbs;
3151 XmLGridPreLayoutProc preLayoutProc;
3153 if (g->grid.layoutFrozen == True)
3155 g->grid.needsHorizLayout = 1;
3156 return;
3159 maxCol = maxPos = newWidth = vertSizeChanged = 0;
3160 preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
3161 if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
3162 vertSizeChanged = preLayoutProc(g, 0);
3164 scrollChanged = 0;
3165 needsResize = 0;
3166 needsSB = 0;
3168 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && g->grid.visibleCols)
3169 colCount = g->grid.visibleCols;
3170 else
3171 colCount = g->grid.colCount + g->grid.headingColCount
3172 + g->grid.footerColCount;
3174 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3176 SizeColumnsToFit(g, 0);
3179 reg = g->grid.reg;
3180 st2 = g->manager.shadow_thickness * 2;
3181 TextAction(g, TEXT_HIDE);
3183 leftWidth = 0;
3184 leftNCol = g->grid.leftFixedCount;
3185 if (leftNCol > g->grid.colCount + g->grid.headingColCount)
3186 leftNCol = g->grid.colCount + g->grid.headingColCount;
3187 if (leftNCol)
3189 leftWidth += st2;
3190 for (i = 0; i < leftNCol; i++)
3191 leftWidth += GetColWidth(g, i);
3193 rightWidth = 0;
3194 rightNCol = g->grid.rightFixedCount;
3195 if (rightNCol + leftNCol > colCount)
3196 rightNCol = colCount - leftNCol;
3197 rightCol = colCount - rightNCol;
3198 if (rightNCol)
3200 rightWidth += st2;
3201 for (i = rightCol; i < colCount; i++)
3202 rightWidth += GetColWidth(g, i);
3204 width = 0;
3205 if (leftNCol)
3206 width += leftWidth + g->grid.leftFixedMargin;
3207 midX = width;
3208 if (rightNCol)
3209 width += rightWidth + g->grid.rightFixedMargin;
3210 if (XtIsManaged(g->grid.vsb))
3212 width += g->grid.vsb->core.width;
3213 width += g->grid.scrollBarMargin;
3215 maxWidth = g->core.width - width;
3216 if (g->grid.hsPolicy == XmVARIABLE ||
3217 g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3219 if (colCount == leftNCol + rightNCol)
3220 midWidth = 0;
3221 else
3222 midWidth = st2;
3224 /* This assumes the show/hide buttons will be wider
3225 than the vertical scrollbar
3227 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
3229 if (g->grid.hideUnhideButtons)
3230 midWidth += XtWidth(g->grid.hideButton) * 2;
3231 else if (XtIsManaged(g->grid.vsb))
3232 midWidth += XtWidth(g->grid.vsb);
3236 for (i = leftNCol; i < colCount - rightNCol; i++)
3237 midWidth += GetColWidth(g, i);
3238 midCol = leftNCol;
3239 midNCol = colCount - leftNCol - rightNCol;
3240 needsResize = 1;
3241 newWidth = midWidth + width;
3242 if (g->grid.debugLevel)
3244 if (g->grid.hsPolicy == XmVARIABLE)
3245 fprintf(stderr, "XmLGrid: HorizLayout VARIABLE width\n");
3246 else
3247 fprintf(stderr, "XmLGrid: HorizLayout REZISE_IF_POSSIBLE\n");
3250 else
3252 if (maxWidth < st2)
3253 maxWidth = 0;
3254 width = st2;
3255 j = colCount - rightNCol - 1;
3256 for (i = j; i >= leftNCol; i--)
3258 width += GetColWidth(g, i);
3259 if (width > maxWidth)
3260 break;
3262 i++;
3263 if (i > j)
3264 i = j;
3265 maxCol = i;
3266 if (maxCol < leftNCol)
3267 maxCol = leftNCol;
3268 if (g->grid.debugLevel)
3269 fprintf(stderr, "XmLGrid: HorizLayout max scroll col %d\n", i);
3270 if (maxCol == leftNCol)
3272 if (g->grid.scrollCol != leftNCol)
3274 scrollChanged = 1;
3275 g->grid.scrollCol = leftNCol;
3277 midCol = leftNCol;
3278 midWidth = maxWidth;
3279 midNCol = colCount - leftNCol - rightNCol;
3280 if (g->grid.debugLevel)
3281 fprintf(stderr, "XmLGrid: HorizLayout everything fits\n");
3283 else
3285 if (g->grid.scrollCol < leftNCol)
3287 scrollChanged = 1;
3288 g->grid.scrollCol = leftNCol;
3289 if (g->grid.debugLevel)
3290 fprintf(stderr, "XmLGrid: HorizLayout scroll < leftCol\n");
3292 if (g->grid.scrollCol > maxCol)
3294 if (g->grid.debugLevel)
3295 fprintf(stderr, "XmLGrid: HorizLayout scroll > maxCol\n");
3296 scrollChanged = 1;
3297 g->grid.scrollCol = maxCol;
3299 width = st2;
3300 midNCol = 0;
3301 for (i = g->grid.scrollCol; i < colCount - rightNCol; i++)
3303 midNCol++;
3304 width += GetColWidth(g, i);
3305 if (width >= maxWidth)
3306 break;
3308 needsSB = 1;
3309 midCol = g->grid.scrollCol;
3310 midWidth = maxWidth;
3313 rightX = midX + midWidth;
3314 if (rightNCol)
3315 rightX += g->grid.rightFixedMargin;
3316 for (i = 0; i < 9; i += 3)
3318 reg[i].x = 0;
3319 reg[i].width = leftWidth;
3320 reg[i].col = 0;
3321 reg[i].ncol = leftNCol;
3323 for (i = 1; i < 9; i += 3)
3325 reg[i].x = midX;
3326 reg[i].width = midWidth;
3327 reg[i].col = midCol;
3328 reg[i].ncol = midNCol;
3330 for (i = 2; i < 9; i += 3)
3332 reg[i].x = rightX;
3333 reg[i].width = rightWidth;
3334 reg[i].col = rightCol;
3335 reg[i].ncol = rightNCol;
3338 if (g->grid.debugLevel)
3340 fprintf(stderr, "XmLGrid: HorizLayout LFT %3dx %3dw %3dc %3dnc\n",
3341 reg[0].x, reg[0].width, reg[0].col, reg[0].ncol);
3342 fprintf(stderr, "XmLGrid: HorizLayout MID %3dx %3dw %3dc %3dnc\n",
3343 reg[1].x, reg[1].width, reg[1].col, reg[1].ncol);
3344 fprintf(stderr, "XmLGrid: HorizLayout RHT %3dx %3dw %3dc %3dnc\n",
3345 reg[2].x, reg[2].width, reg[2].col, reg[2].ncol);
3347 if (g->grid.hsPolicy == XmCONSTANT && colCount == 1 &&
3348 g->grid.colCount == 1 && width > maxWidth)
3350 /* Single Column Pixel Scroll Mode */
3351 if (g->grid.singleColScrollMode)
3353 i = g->grid.singleColScrollPos;
3354 if (i < 0)
3355 i = 0;
3356 else if (i > width - maxWidth)
3357 i = width - maxWidth;
3359 else
3360 i = 0;
3361 XtVaSetValues(g->grid.hsb,
3362 XmNminimum, 0,
3363 XmNmaximum, width - maxWidth + 1,
3364 XmNsliderSize, 1,
3365 XmNpageIncrement, ((width - maxWidth) / 4) + 1,
3366 XmNvalue, i,
3367 NULL);
3368 if (!XtIsManaged(g->grid.hsb))
3370 XtManageChild(g->grid.hsb);
3371 vertSizeChanged = 1;
3373 g->grid.singleColScrollMode = 1;
3374 g->grid.singleColScrollPos = i;
3376 else
3377 g->grid.singleColScrollMode = 0;
3378 if (g->grid.singleColScrollMode)
3380 else if (needsSB)
3382 if (g->grid.debugLevel)
3383 fprintf(stderr, "XmLGrid: HorizLayout set sb values\n");
3384 if (!XtIsManaged(g->grid.hsb))
3386 XtManageChild(g->grid.hsb);
3387 vertSizeChanged = 1;
3389 maxPos = PosToVisPos(g, maxCol, 0);
3390 sliderSize = PosToVisPos(g, colCount - rightNCol - 1, 0) - maxPos + 1;
3391 XtVaSetValues(g->grid.hsb,
3392 XmNminimum, PosToVisPos(g, leftNCol, 0),
3393 XmNmaximum, maxPos + sliderSize,
3394 XmNsliderSize, sliderSize,
3395 XmNpageIncrement, sliderSize,
3396 XmNvalue, PosToVisPos(g, g->grid.scrollCol, 0),
3397 NULL);
3399 else if (g->grid.hsPolicy == XmCONSTANT &&
3400 g->grid.hsbDisplayPolicy == XmSTATIC)
3402 if (!XtIsManaged(g->grid.hsb))
3404 XtManageChild(g->grid.hsb);
3405 vertSizeChanged = 1;
3407 if (g->grid.debugLevel)
3408 fprintf(stderr, "XmLGrid: HorizLayout hsb not needed - static\n");
3409 XtVaSetValues(g->grid.hsb,
3410 XmNminimum, 0,
3411 XmNmaximum, 1,
3412 XmNsliderSize, 1,
3413 XmNpageIncrement, 1,
3414 XmNvalue, 0,
3415 NULL);
3417 else
3419 if (XtIsManaged(g->grid.hsb))
3421 XtUnmanageChild(g->grid.hsb);
3422 vertSizeChanged = 1;
3425 if (needsResize && resizeIfNeeded)
3427 if (newWidth < 1)
3428 newWidth = 1;
3429 req.request_mode = CWWidth;
3430 req.width = newWidth;
3431 if (g->grid.debugLevel)
3432 fprintf(stderr, "XmLGrid: HorizLayout Req w %d\n", (int)newWidth);
3433 XtMakeGeometryRequest((Widget)g, &req, NULL);
3434 PlaceScrollbars(g);
3436 if (scrollChanged)
3437 DrawArea(g, DrawHScroll, 0, 0);
3438 TextAction(g, TEXT_SHOW);
3439 cCol = g->grid.scrollCol - g->grid.headingColCount;
3440 if (cCol != g->grid.cScrollCol)
3442 g->grid.cScrollCol = cCol;
3443 cbs.reason = XmCR_SCROLL_COLUMN;
3444 cbs.columnType = XmCONTENT;
3445 cbs.column = cCol;
3446 XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
3448 if (vertSizeChanged)
3450 if (g->grid.layoutStack > 2)
3451 XmLWarning((Widget)g, "HorizLayout() - recursion error");
3452 else
3454 g->grid.layoutStack++;
3455 VertLayout(g, resizeIfNeeded);
3456 g->grid.layoutStack--;
3458 PlaceScrollbars(g);
3462 static void
3463 ApplyVisibleRows(XmLGridWidget g)
3465 XtWidgetGeometry req;
3466 XmLGridCellRefValues *cellValues;
3468 if (g->grid.vsPolicy != XmCONSTANT)
3470 XmLWarning((Widget)g,
3471 "verticalSizePolicy must be XmCONSTANT to set visibleRows");
3472 return;
3474 cellValues = g->grid.defCellValues;
3475 req.request_mode = CWHeight;
3476 req.height = g->manager.shadow_thickness * 2 + g->grid.visibleRows *
3477 (4 + cellValues->fontHeight + cellValues->topMargin +
3478 cellValues->bottomMargin);
3479 if (g->grid.hsPolicy == XmCONSTANT &&
3480 g->grid.hsbDisplayPolicy == XmSTATIC)
3481 req.height += g->grid.scrollBarMargin + XtHeight(g->grid.hsb);
3482 XtMakeGeometryRequest((Widget)g, &req, NULL);
3485 static void
3486 ApplyVisibleCols(XmLGridWidget g)
3488 XtWidgetGeometry req;
3489 XmLGridCellRefValues *cellValues;
3491 if (g->grid.hsPolicy != XmCONSTANT)
3493 XmLWarning((Widget)g,
3494 "horizontalSizePolicy must be XmCONSTANT to set visibleColumns");
3495 return;
3497 cellValues = g->grid.defCellValues;
3498 req.request_mode = CWWidth;
3499 req.width = g->manager.shadow_thickness * 2 + g->grid.visibleCols *
3500 (4 + 8 * cellValues->fontWidth + cellValues->leftMargin +
3501 cellValues->rightMargin);
3502 if (g->grid.vsPolicy == XmCONSTANT &&
3503 g->grid.vsbDisplayPolicy == XmSTATIC)
3504 req.width += g->grid.scrollBarMargin + XtWidth(g->grid.vsb);
3505 XtMakeGeometryRequest((Widget)g, &req, NULL);
3508 static void
3509 VisPosChanged(XmLGridWidget g,
3510 int isVert)
3512 if (isVert)
3514 g->grid.recalcVertVisPos = 1;
3515 g->grid.vertVisChangedHint = 1;
3517 else
3518 g->grid.recalcHorizVisPos = 1;
3521 static void
3522 RecalcVisPos(XmLGridWidget g,
3523 int isVert)
3525 XmLGridRow row;
3526 XmLGridColumn col;
3527 int i, count, visPos;
3529 if (g->grid.layoutFrozen == True)
3530 XmLWarning((Widget)g, "RecalcVisPos() - layout is frozen");
3531 visPos = 0;
3532 if (isVert)
3534 if (!g->grid.recalcVertVisPos)
3535 return;
3536 count = XmLArrayGetCount(g->grid.rowArray);
3537 for (i = 0; i < count; i++)
3539 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
3540 XmLGridRowSetVisPos(row, visPos);
3541 if (!XmLGridRowIsHidden(row))
3542 visPos++;
3544 g->grid.recalcVertVisPos = 0;
3546 else
3548 if (!g->grid.recalcHorizVisPos)
3549 return;
3550 count = XmLArrayGetCount(g->grid.colArray);
3551 for (i = 0; i < count; i++)
3553 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
3554 XmLGridColumnSetVisPos(col, visPos);
3555 if (!XmLGridColumnIsHidden(col))
3556 visPos++;
3558 g->grid.recalcHorizVisPos = 0;
3562 static int
3563 PosToVisPos(XmLGridWidget g,
3564 int pos,
3565 int isVert)
3567 int visPos;
3568 XmLGridRow row;
3569 XmLGridColumn col;
3571 if (isVert)
3573 if (!g->grid.hiddenRowCount)
3574 visPos = pos;
3575 else
3577 RecalcVisPos(g, isVert);
3578 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
3579 if (row)
3580 visPos = XmLGridRowGetVisPos(row);
3581 else
3582 visPos = -1;
3585 else
3587 if (!g->grid.hiddenColCount)
3588 visPos = pos;
3589 else
3591 RecalcVisPos(g, isVert);
3592 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
3593 if (col)
3594 visPos = XmLGridColumnGetVisPos(col);
3595 else
3596 visPos = -1;
3599 if (visPos == -1)
3600 XmLWarning((Widget)g, "PosToVisPos() - invalid pos");
3601 return visPos;
3604 static int
3605 VisPosToPos(XmLGridWidget g,
3606 int visPos,
3607 int isVert)
3609 XmLGridRow row;
3610 XmLGridColumn col;
3611 int i1, i2, vp1, vp2, ic, mid, val, count;
3613 if (isVert)
3615 if (!g->grid.hiddenRowCount)
3616 return visPos;
3617 count = XmLArrayGetCount(g->grid.rowArray);
3618 if (!count)
3620 XmLWarning((Widget)g, "VisPosToPos() - called when no rows exist");
3621 return -1;
3623 RecalcVisPos(g, isVert);
3624 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
3625 vp1 = XmLGridRowGetVisPos(row);
3626 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, count - 1);
3627 vp2 = XmLGridRowGetVisPos(row);
3628 if (visPos < vp1 || visPos > vp2)
3630 XmLWarning((Widget)g, "VisPosToPos() - invalid Vert visPos");
3631 return -1;
3634 else
3636 if (!g->grid.hiddenColCount)
3637 return visPos;
3638 count = XmLArrayGetCount(g->grid.colArray);
3639 if (!count)
3641 XmLWarning((Widget)g, "VisPosToPos() - called when no cols exist");
3642 return -1;
3644 RecalcVisPos(g, isVert);
3645 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, 0);
3646 vp1 = XmLGridColumnGetVisPos(col);
3647 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, count - 1);
3648 vp2 = XmLGridColumnGetVisPos(col);
3649 if (visPos < vp1 || visPos > vp2)
3651 XmLWarning((Widget)g, "VisPosToPos() - invalid Horiz visPos");
3652 return -1;
3655 i1 = 0;
3656 i2 = count;
3657 ic = 0;
3658 while (1)
3660 mid = i1 + (i2 - i1) / 2;
3661 if (isVert)
3663 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, mid);
3664 val = XmLGridRowGetVisPos(row);
3666 else
3668 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, mid);
3669 val = XmLGridColumnGetVisPos(col);
3671 if (visPos > val)
3672 i1 = mid;
3673 else if (visPos < val)
3674 i2 = mid;
3675 else
3676 break;
3677 if (++ic > 1000)
3678 return -1; /* inf loop */
3680 return mid;
3683 static unsigned char
3684 ColPosToType(XmLGridWidget g,
3685 int pos)
3687 unsigned char type;
3689 if (pos < g->grid.headingColCount)
3690 type = XmHEADING;
3691 else if (pos < g->grid.headingColCount + g->grid.colCount)
3692 type = XmCONTENT;
3693 else
3694 type = XmFOOTER;
3695 return type;
3698 static int
3699 ColPosToTypePos(XmLGridWidget g,
3700 unsigned char type,
3701 int pos)
3703 int c;
3705 if (type == XmHEADING)
3706 c = pos;
3707 else if (type == XmCONTENT)
3708 c = pos - g->grid.headingColCount;
3709 else
3710 c = pos - g->grid.headingColCount - g->grid.colCount;
3711 return c;
3714 static unsigned char
3715 RowPosToType(XmLGridWidget g,
3716 int pos)
3718 unsigned char type;
3720 if (pos < g->grid.headingRowCount)
3721 type = XmHEADING;
3722 else if (pos < g->grid.headingRowCount + g->grid.rowCount)
3723 type = XmCONTENT;
3724 else
3725 type = XmFOOTER;
3726 return type;
3729 static int
3730 RowPosToTypePos(XmLGridWidget g,
3731 unsigned char type,
3732 int pos)
3734 int r;
3736 if (type == XmHEADING)
3737 r = pos;
3738 else if (type == XmCONTENT)
3739 r = pos - g->grid.headingRowCount;
3740 else
3741 r = pos - g->grid.headingRowCount - g->grid.rowCount;
3742 return r;
3745 static int
3746 ColTypePosToPos(XmLGridWidget g,
3747 unsigned char type,
3748 int pos,
3749 int allowNeg)
3751 if (pos < 0)
3753 if (!allowNeg)
3754 return -1;
3755 if (type == XmHEADING)
3756 pos = g->grid.headingColCount;
3757 else if (type == XmFOOTER || type == XmALL_TYPES)
3758 pos = g->grid.headingColCount + g->grid.colCount +
3759 g->grid.footerColCount;
3760 else /* XmCONTENT */
3761 pos = g->grid.headingColCount + g->grid.colCount;
3763 else
3765 if (type == XmALL_TYPES)
3767 else if (type == XmHEADING)
3769 if (pos >= g->grid.headingColCount)
3770 return -1;
3772 else if (type == XmFOOTER)
3774 if (pos >= g->grid.footerColCount)
3775 return -1;
3776 pos += g->grid.headingColCount + g->grid.colCount;
3778 else /* XmCONTENT */
3780 if (pos >= g->grid.colCount)
3781 return -1;
3782 pos += g->grid.headingColCount;
3785 return pos;
3788 static int
3789 RowTypePosToPos(XmLGridWidget g,
3790 unsigned char type,
3791 int pos,
3792 int allowNeg)
3794 if (pos < 0)
3796 if (!allowNeg)
3797 return -1;
3798 if (type == XmHEADING)
3799 pos = g->grid.headingRowCount;
3800 else if (type == XmFOOTER || type == XmALL_TYPES)
3801 pos = g->grid.headingRowCount + g->grid.rowCount +
3802 g->grid.footerRowCount;
3803 else /* XmCONTENT */
3804 pos = g->grid.headingRowCount + g->grid.rowCount;
3806 else
3808 if (type == XmALL_TYPES)
3810 else if (type == XmHEADING)
3812 if (pos >= g->grid.headingRowCount)
3813 return -1;
3815 else if (type == XmFOOTER)
3817 if (pos >= g->grid.footerRowCount)
3818 return -1;
3819 pos += g->grid.headingRowCount + g->grid.rowCount;
3821 else /* XmCONTENT */
3823 if (pos >= g->grid.rowCount)
3824 return -1;
3825 pos += g->grid.headingRowCount;
3828 return pos;
3831 static int
3832 ScrollRowBottomPos(XmLGridWidget g,
3833 int row)
3835 int r, h, height;
3837 if (g->grid.vsPolicy == XmVARIABLE)
3838 return -1;
3839 height = g->grid.reg[4].height;
3840 h = 0;
3841 r = row;
3842 while (r >= 0)
3844 h += GetRowHeight(g, r);
3845 if (h > height)
3846 break;
3847 r--;
3849 if (r != row)
3850 r++;
3851 return r;
3854 static int
3855 ScrollColRightPos(XmLGridWidget g,
3856 int col)
3858 int c, w, width;
3860 if (g->grid.hsPolicy == XmVARIABLE)
3861 return -1;
3862 width = g->grid.reg[4].width;
3863 w = 0;
3864 c = col;
3865 while (c >= 0)
3867 w += GetColWidth(g, c);
3868 if (w >= width)
3869 break;
3870 c--;
3872 if (c != col)
3873 c++;
3874 return c;
3877 static int
3878 PosIsResize(XmLGridWidget g,
3879 int x,
3880 int y,
3881 int *row,
3882 int *col,
3883 int *isVert)
3885 XRectangle rect;
3886 int i, nx, ny, margin;
3888 /* check for bottom resize */
3889 if (g->grid.allowRowResize == True)
3890 for (i = 0; i < 2; i++)
3892 nx = x;
3893 ny = y - (4 * i);
3895 if (XYToRowCol(g, nx, ny, row, col) != -1
3896 && RowColToXY(g, *row, *col, False, &rect) != -1
3897 && ColPosToType(g, *col) == XmHEADING)
3899 margin = ny - (rect.y + rect.height);
3900 if (margin > -5 && margin < 5)
3902 *isVert = 1;
3903 return 1;
3907 /* check for right resize */
3908 if (g->grid.allowColResize == True)
3909 for (i = 0; i < 2; i++)
3911 XmLGridColumn colp;
3912 int c;
3914 nx = x - (4 * i);
3915 ny = y;
3917 if (XYToRowCol(g, nx, ny, row, col) != -1
3918 && RowColToXY(g, *row, *col, False, &rect) != -1
3919 && RowPosToType(g, *row) == XmHEADING
3920 && *col != XmLArrayGetCount(g->grid.colArray) - 1)
3922 Boolean foundResizable = 0;
3924 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, *col);
3926 if (!colp->grid.resizable)
3927 continue;
3929 for (c = *col + 1;
3930 c < XmLArrayGetCount(g->grid.colArray);
3931 c ++)
3933 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
3935 if (colp->grid.resizable
3936 && (g->grid.hsPolicy != XmRESIZE_IF_POSSIBLE
3937 || (g->grid.visibleCols == 0
3938 || c < g->grid.visibleCols))
3941 foundResizable = True;
3942 break;
3945 if (!foundResizable) return 0;
3947 margin = nx - (rect.x + rect.width);
3948 if (margin > -5 && margin < 5)
3950 *isVert = 0;
3951 return 1;
3955 return 0;
3958 int
3959 XmLGridPosIsResize(Widget g,
3960 int x,
3961 int y)
3963 int row, col;
3964 int isVert;
3965 return PosIsResize((XmLGridWidget) g, x, y, &row, &col, &isVert);
3968 static int
3969 XYToRowCol(XmLGridWidget g,
3970 int x,
3971 int y,
3972 int *row,
3973 int *col)
3975 XRectangle xyRect, rect;
3976 GridReg *reg;
3977 int i, r, c;
3978 int width, height;
3979 int st;
3981 reg = g->grid.reg;
3982 st = g->manager.shadow_thickness;
3983 xyRect.x = x;
3984 xyRect.y = y;
3985 xyRect.width = 1;
3986 xyRect.height = 1;
3987 for (i = 0; i < 9; i++)
3989 if (!reg[i].width || !reg[i].height)
3990 continue;
3991 rect.x = reg[i].x + st;
3992 rect.y = reg[i].y + st;
3993 rect.width = reg[i].width - st * 2;
3994 rect.height = reg[i].height - st * 2;
3995 if (XmLRectIntersect(&xyRect, &rect) == XmLRectOutside)
3996 continue;
3997 height = 0;
3998 for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
4000 width = 0;
4001 for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
4003 rect.x = reg[i].x + st + width;
4004 rect.y = reg[i].y + st + height;
4005 rect.width = GetColWidth(g, c);
4006 rect.height = GetRowHeight(g, r);
4007 if (g->grid.singleColScrollMode)
4008 rect.x -= g->grid.singleColScrollPos;
4009 ClipRectToReg(g, &rect, &reg[i]);
4010 if (XmLRectIntersect(&xyRect, &rect) != XmLRectOutside)
4012 if (!RowColFirstSpan(g, r, c, row, col, 0, True, True))
4013 return 0; /* SUCCESS */
4014 else
4015 return -1;
4017 width += GetColWidth(g, c);
4019 height += GetRowHeight(g, r);
4022 return -1;
4025 static int
4026 RowColToXY(XmLGridWidget g,
4027 int row,
4028 int col,
4029 Boolean clipped,
4030 XRectangle *rect)
4032 XmLGridCell cell;
4033 XmLGridCellRefValues *cellValues;
4034 GridReg *reg;
4035 Dimension st;
4036 int i, r, c, off;
4038 reg = g->grid.reg;
4039 st = g->manager.shadow_thickness;
4040 cell = GetCell(g, row, col);
4041 if (!cell)
4042 return -1;
4043 cellValues = XmLGridCellGetRefValues(cell);
4045 if (!cellValues) return -1;
4047 for (i = 0; i < 9; i++)
4049 if (!reg[i].width || !reg[i].height)
4050 continue;
4051 if (!(col >= reg[i].col &&
4052 col < reg[i].col + reg[i].ncol &&
4053 row >= reg[i].row &&
4054 row < reg[i].row + reg[i].nrow))
4055 continue;
4056 off = 0;
4057 for (r = reg[i].row; r < row; r++)
4058 off += GetRowHeight(g, r);
4059 rect->y = reg[i].y + st + off;
4060 rect->height = GetRowHeight(g, row);
4061 if (cellValues->rowSpan)
4062 for (r = row + 1; r <= row + cellValues->rowSpan; r++)
4063 rect->height += GetRowHeight(g, r);
4064 off = 0;
4065 for (c = reg[i].col; c < col; c++)
4066 off += GetColWidth(g, c);
4067 rect->x = reg[i].x + st + off;
4068 rect->width = GetColWidth(g, col);
4069 if (cellValues->columnSpan)
4070 for (c = col + 1; c <= col + cellValues->columnSpan; c++)
4071 rect->width += GetColWidth(g, c);
4072 if (g->grid.singleColScrollMode)
4073 rect->x -= g->grid.singleColScrollPos;
4074 if (clipped == True)
4075 ClipRectToReg(g, rect, &reg[i]);
4076 return 0;
4078 return -1;
4081 static int
4082 RowColFirstSpan(XmLGridWidget g,
4083 int row,
4084 int col,
4085 int *firstRow,
4086 int *firstCol,
4087 XRectangle *rect,
4088 Boolean lookLeft,
4089 Boolean lookUp)
4091 XmLGridCell cell;
4092 int done;
4094 done = 0;
4095 while (!done)
4097 cell = GetCell(g, row, col);
4098 if (!cell)
4099 return -1;
4100 if (XmLGridCellInRowSpan(cell) == True)
4102 if (lookUp == True)
4104 row--;
4105 if (rect)
4106 rect->y -= GetRowHeight(g, row);
4108 else
4109 row = -1;
4110 if (row < 0)
4111 done = 1;
4113 else if (XmLGridCellInColumnSpan(cell) == True)
4115 if (lookLeft == True)
4117 col--;
4118 if (rect)
4119 rect->x -= GetColWidth(g, col);
4121 else
4122 col = -1;
4123 if (col < 0)
4124 done = 1;
4126 else
4127 done = 1;
4129 if (row < 0 || col < 0)
4130 return -1;
4131 *firstRow = row;
4132 *firstCol = col;
4133 return 0;
4136 static void
4137 RowColSpanRect(XmLGridWidget g,
4138 int row,
4139 int col,
4140 XRectangle *rect)
4142 XmLGridCell cell;
4143 XmLGridCellRefValues *cellValues;
4144 int r, c;
4146 cell = GetCell(g, row, col);
4147 cellValues = XmLGridCellGetRefValues(cell);
4148 rect->width = 0;
4149 rect->height = 0;
4150 for (r = row; r <= row + cellValues->rowSpan; r++)
4151 rect->height += GetRowHeight(g, r);
4152 for (c = col; c <= col + cellValues->columnSpan; c++)
4153 rect->width += GetColWidth(g, c);
4156 static XmLGridCell
4157 GetCell(XmLGridWidget g,
4158 int row,
4159 int col)
4161 XmLGridRow rowp;
4163 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4164 if (!rowp)
4165 return 0;
4166 return (XmLGridCell)XmLArrayGet(XmLGridRowCells(rowp), col);
4169 static int
4170 GetColWidth(XmLGridWidget g,
4171 int col)
4173 XmLGridColumn colp;
4175 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4176 if (!colp)
4177 return 0;
4178 return XmLGridColumnWidthInPixels(colp);
4181 static int
4182 GetRowHeight(XmLGridWidget g,
4183 int row)
4185 XmLGridRow rowp;
4187 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4188 if (!rowp)
4189 return 0;
4190 return XmLGridRowHeightInPixels(rowp);
4193 static int
4194 ColIsVisible(XmLGridWidget g,
4195 int col)
4197 XmLGridColumn c;
4198 int i, c1, c2;
4200 c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4201 if (!c)
4203 XmLWarning((Widget)g, "ColumnIsVisible() - invalid column");
4204 return -1;
4206 if (XmLGridColumnIsHidden(c) == True)
4207 return 0;
4208 if (g->grid.hsPolicy != XmCONSTANT)
4209 return 1;
4210 for (i = 0; i < 3; i ++)
4212 c1 = g->grid.reg[i].col;
4213 c2 = c1 + g->grid.reg[i].ncol;
4214 if (col >= c1 && col < c2)
4215 return 1;
4217 return 0;
4220 static int
4221 RowIsVisible(XmLGridWidget g,
4222 int row)
4224 XmLGridRow r;
4225 int i, r1, r2;
4227 r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4228 if (!r)
4230 XmLWarning((Widget)g, "RowIsVisible() - invalid row");
4231 return -1;
4233 if (XmLGridRowIsHidden(r) == True)
4234 return 0;
4235 if (g->grid.vsPolicy != XmCONSTANT)
4236 return 1;
4237 for (i = 0; i < 9; i += 3)
4239 r1 = g->grid.reg[i].row;
4240 r2 = r1 + g->grid.reg[i].nrow;
4241 if (row >= r1 && row < r2)
4242 return 1;
4244 return 0;
4247 static XtGeometryResult
4248 GeometryManager(Widget w,
4249 XtWidgetGeometry *request,
4250 XtWidgetGeometry *allow)
4252 if (request->request_mode & CWWidth)
4253 w->core.width = request->width;
4254 if (request->request_mode & CWHeight)
4255 w->core.height = request->height;
4256 if (request->request_mode & CWX)
4257 w->core.x = request->x;
4258 if (request->request_mode & CWY)
4259 w->core.y = request->y;
4260 if (request->request_mode & CWBorderWidth)
4261 w->core.border_width = request->border_width;
4262 return XtGeometryYes;
4265 static void
4266 ScrollCB(Widget w,
4267 XtPointer clientData,
4268 XtPointer callData)
4270 XmLGridWidget g;
4271 XmScrollBarCallbackStruct *cbs;
4272 unsigned char orientation;
4273 int visPos;
4275 g = (XmLGridWidget)(XtParent(w));
4276 cbs = (XmScrollBarCallbackStruct *)callData;
4277 visPos = cbs->value;
4278 XtVaGetValues(w, XmNorientation, &orientation, NULL);
4279 if (orientation == XmHORIZONTAL && g->grid.singleColScrollMode)
4281 g->grid.singleColScrollPos = visPos;
4282 DrawArea(g, DrawHScroll, 0, 0);
4284 else if (orientation == XmVERTICAL)
4286 if (visPos == PosToVisPos(g, g->grid.scrollRow, 1))
4287 return;
4288 g->grid.scrollRow = VisPosToPos(g, visPos, 1);
4289 VertLayout(g, 0);
4290 DrawArea(g, DrawVScroll, 0, 0);
4292 else
4294 if (visPos == PosToVisPos(g, g->grid.scrollCol, 0))
4295 return;
4296 g->grid.scrollCol = VisPosToPos(g, visPos, 0);
4297 HorizLayout(g, 0);
4298 DrawArea(g, DrawHScroll, 0, 0);
4302 static int
4303 FindNextFocus(XmLGridWidget g,
4304 int row,
4305 int col,
4306 int rowDir,
4307 int colDir,
4308 int *nextRow,
4309 int *nextCol)
4311 int traverse;
4312 int hrc, hcc, rc, cc;
4313 XmLGridColumn colp;
4314 XmLGridRow rowp;
4315 XmLGridCell cell;
4317 hcc = g->grid.headingColCount;
4318 cc = g->grid.colCount;
4319 hrc = g->grid.headingRowCount;
4320 rc = g->grid.rowCount;
4321 if (!rc || !cc)
4322 return -1;
4323 if (col < hcc)
4324 col = hcc;
4325 else if (col >= hcc + cc)
4326 col = hcc + cc - 1;
4327 if (row < hrc)
4328 row = hrc;
4329 else if (row >= hrc + rc)
4330 row = hrc + rc - 1;
4331 traverse = 0;
4332 while (1)
4334 if (row < hrc || row >= hrc + rc)
4335 break;
4336 if (col < hcc || col >= hcc + cc)
4337 break;
4338 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
4339 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
4340 cell = GetCell(g, row, col);
4341 if (cell &&
4342 RowPosToType(g, row) == XmCONTENT &&
4343 ColPosToType(g, col) == XmCONTENT &&
4344 XmLGridCellInRowSpan(cell) == False &&
4345 XmLGridCellInColumnSpan(cell) == False &&
4346 XmLGridRowIsHidden(rowp) == False &&
4347 XmLGridColumnIsHidden(colp) == False)
4349 traverse = 1;
4350 break;
4352 if (!rowDir && !colDir)
4353 break;
4354 row += rowDir;
4355 col += colDir;
4357 if (!traverse)
4358 return -1;
4359 *nextRow = row;
4360 *nextCol = col;
4361 return 0;
4364 static int
4365 SetFocus(XmLGridWidget g,
4366 int row,
4367 int col,
4368 int rowDir,
4369 int colDir)
4371 if (FindNextFocus(g, row, col, rowDir, colDir, &row, &col) == -1)
4372 return -1;
4373 ChangeFocus(g, row, col);
4374 return 0;
4377 static void
4378 ChangeFocus(XmLGridWidget g,
4379 int row,
4380 int col)
4382 XmLGridCell cell;
4383 XmLGridCallbackStruct cbs;
4384 int focusRow, focusCol;
4386 focusRow = g->grid.focusRow;
4387 focusCol = g->grid.focusCol;
4388 g->grid.focusRow = row;
4389 g->grid.focusCol = col;
4390 if (focusRow != -1 && focusCol != -1)
4392 cell = GetCell(g, focusRow, focusCol);
4393 if (cell)
4395 if (g->grid.highlightRowMode == True)
4396 DrawArea(g, DrawRow, focusRow, 0);
4397 else
4398 DrawArea(g, DrawCell, focusRow, focusCol);
4399 cbs.reason = XmCR_CELL_FOCUS_OUT;
4400 cbs.columnType = ColPosToType(g, focusCol);
4401 cbs.column = ColPosToTypePos(g, cbs.columnType, focusCol);
4402 cbs.rowType = RowPosToType(g, focusRow);
4403 cbs.row = RowPosToTypePos(g, cbs.rowType, focusRow);
4404 XmLGridCellAction(cell, (Widget)g, &cbs);
4405 XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
4406 (XtPointer)&cbs);
4409 if (row != -1 && col != -1)
4411 cell = GetCell(g, row, col);
4412 if (cell)
4414 if (g->grid.highlightRowMode == True)
4415 DrawArea(g, DrawRow, row, 0);
4416 else
4417 DrawArea(g, DrawCell, row, col);
4418 cbs.reason = XmCR_CELL_FOCUS_IN;
4419 cbs.columnType = ColPosToType(g, col);
4420 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
4421 cbs.rowType = RowPosToType(g, row);
4422 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
4423 XmLGridCellAction(cell, (Widget)g, &cbs);
4424 XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
4425 (XtPointer)&cbs);
4427 else
4429 if (!XmLArrayGet(g->grid.rowArray, row))
4430 g->grid.focusRow = -1;
4431 if (!XmLArrayGet(g->grid.colArray, col))
4432 g->grid.focusCol = -1;
4437 static void
4438 MakeColVisible(XmLGridWidget g,
4439 int col)
4441 int st, width, scrollWidth, scrollCol, prevScrollCol;
4443 if (g->grid.hsPolicy != XmCONSTANT)
4444 return;
4445 if (col < g->grid.leftFixedCount ||
4446 col >= XmLArrayGetCount(g->grid.colArray) - g->grid.rightFixedCount)
4447 return;
4448 st = g->manager.shadow_thickness;
4449 scrollCol = col;
4450 if (col > g->grid.scrollCol)
4452 scrollWidth = g->grid.reg[4].width - st * 2;
4453 width = 0;
4454 while (1)
4456 width += GetColWidth(g, scrollCol);
4457 if (width > scrollWidth)
4458 break;
4459 if (scrollCol < g->grid.leftFixedCount)
4460 break;
4461 scrollCol--;
4463 scrollCol++;
4464 if (scrollCol > col)
4465 scrollCol = col;
4466 /* only scroll if needed */
4467 if (scrollCol < g->grid.scrollCol)
4468 scrollCol = g->grid.scrollCol;
4470 if (scrollCol == g->grid.scrollCol)
4471 return;
4472 prevScrollCol = g->grid.scrollCol;
4473 g->grid.scrollCol = scrollCol;
4474 HorizLayout(g, 0);
4475 if (g->grid.scrollCol != prevScrollCol)
4476 DrawArea(g, DrawHScroll, 0, 0);
4479 static void
4480 MakeRowVisible(XmLGridWidget g,
4481 int row)
4483 int st, height, scrollHeight, scrollRow, prevScrollRow;
4485 if (g->grid.vsPolicy != XmCONSTANT)
4486 return;
4487 if (row < g->grid.topFixedCount ||
4488 row >= XmLArrayGetCount(g->grid.rowArray) - g->grid.bottomFixedCount)
4489 return;
4490 st = g->manager.shadow_thickness;
4491 scrollRow = row;
4492 if (row > g->grid.scrollRow)
4494 scrollHeight = g->grid.reg[4].height - st * 2;
4495 height = 0;
4496 while (1)
4498 height += GetRowHeight(g, scrollRow);
4499 if (height > scrollHeight)
4500 break;
4501 if (scrollRow < g->grid.topFixedCount)
4502 break;
4503 scrollRow--;
4505 scrollRow++;
4506 if (scrollRow > row)
4507 scrollRow = row;
4508 /* only scroll if needed */
4509 if (scrollRow < g->grid.scrollRow)
4510 scrollRow = g->grid.scrollRow;
4512 if (scrollRow == g->grid.scrollRow)
4513 return;
4514 prevScrollRow = g->grid.scrollRow;
4515 g->grid.scrollRow = scrollRow;
4516 VertLayout(g, 0);
4517 if (g->grid.scrollRow != prevScrollRow)
4518 DrawArea(g, DrawVScroll, 0, 0);
4521 static void
4522 TextAction(XmLGridWidget g,
4523 int action)
4525 int row, col, reason, ret, isVisible;
4526 XRectangle rect;
4527 XtTranslations trans;
4528 WidgetClass wc;
4529 XmLGridCell cellp;
4530 XmLGridCallbackStruct cbs;
4532 if (!g->grid.text || !XtIsRealized(g->grid.text))
4533 return;
4534 row = g->grid.focusRow;
4535 col = g->grid.focusCol;
4536 if (row == -1 || col == -1)
4537 return;
4538 isVisible = 0;
4539 if (RowColToXY(g, row, col, True, &rect) != -1)
4540 isVisible = 1;
4541 cellp = GetCell(g, row, col);
4542 if (!cellp)
4543 return;
4544 cbs.rowType = XmCONTENT;
4545 cbs.row = RowPosToTypePos(g, XmCONTENT, row);
4546 cbs.columnType = XmCONTENT;
4547 cbs.column = ColPosToTypePos(g, XmCONTENT, col);
4548 cbs.clipRect = &rect;
4549 switch (action)
4551 case TEXT_EDIT:
4552 case TEXT_EDIT_INSERT:
4554 if (g->grid.inEdit || !isVisible)
4555 return;
4556 g->grid.inEdit = 1;
4557 if (action == TEXT_EDIT)
4558 cbs.reason = XmCR_EDIT_BEGIN;
4559 else
4560 cbs.reason = XmCR_EDIT_INSERT;
4561 ret = XmLGridCellAction(cellp, (Widget)g, &cbs);
4562 if (ret)
4564 reason = cbs.reason;
4565 cbs.reason = XmCR_CONF_TEXT;
4566 XmLGridCellAction(cellp, (Widget)g, &cbs);
4567 cbs.reason = reason;
4568 wc = g->grid.text->core.widget_class;
4569 trans = (XtTranslations)wc->core_class.tm_table;
4570 XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
4571 XtOverrideTranslations(g->grid.text, g->grid.editTrans);
4572 XtMapWidget(g->grid.text);
4573 g->grid.textHidden = 0;
4574 XtCallCallbackList((Widget)g, g->grid.editCallback,
4575 (XtPointer)&cbs);
4577 else
4578 g->grid.inEdit = 0;
4579 break;
4581 case TEXT_EDIT_CANCEL:
4582 case TEXT_EDIT_COMPLETE:
4584 if (!g->grid.inEdit)
4585 return;
4586 if (action == TEXT_EDIT_COMPLETE)
4587 cbs.reason = XmCR_EDIT_COMPLETE;
4588 else
4589 cbs.reason = XmCR_EDIT_CANCEL;
4590 XmLGridCellAction(cellp, (Widget)g, &cbs);
4591 wc = g->grid.text->core.widget_class;
4592 trans = (XtTranslations)wc->core_class.tm_table;
4593 XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
4594 XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
4595 XtCallCallbackList((Widget)g, g->grid.editCallback,
4596 (XtPointer)&cbs);
4597 XmTextSetString(g->grid.text, "");
4598 XmTextSetInsertionPosition(g->grid.text, 0);
4599 g->grid.inEdit = 0;
4600 XtUnmapWidget(g->grid.text);
4601 g->grid.textHidden = 1;
4602 XtConfigureWidget(g->grid.text, 0, 0, 30, 10, 0);
4603 break;
4605 case TEXT_HIDE:
4607 if (g->grid.textHidden || !isVisible)
4608 return;
4609 XtUnmapWidget(g->grid.text);
4610 g->grid.textHidden = 1;
4611 break;
4613 case TEXT_SHOW:
4615 if (!g->grid.textHidden || !g->grid.inEdit || !isVisible)
4616 return;
4617 if (rect.width == 0 || rect.height == 0)
4618 TextAction(g, TEXT_EDIT_CANCEL);
4619 else
4621 cbs.reason = XmCR_CONF_TEXT;
4622 XmLGridCellAction(cellp, (Widget)g, &cbs);
4623 XtMapWidget(g->grid.text);
4624 g->grid.textHidden = 0;
4626 break;
4632 Getting and Setting Values
4635 static void
4636 GetSubValues(Widget w,
4637 ArgList args,
4638 Cardinal *nargs)
4640 XmLGridWidget g;
4641 int i, c;
4642 long mask;
4643 XmLGridRow row;
4644 XmLGridColumn col;
4645 XmLGridCell cell;
4647 g = (XmLGridWidget)w;
4648 row = 0;
4649 col = 0;
4650 for (i = 0; i < *nargs; i++)
4652 if (!args[i].name)
4653 continue;
4654 if (!strncmp(args[i].name, "row", 3))
4656 if (!strcmp(args[i].name, XmNrowPtr))
4658 row = (XmLGridRow)args[i].value;
4659 continue;
4661 mask = 0;
4662 GetRowValueMask(g, args[i].name, &mask);
4663 if (!mask)
4664 continue;
4665 if (!row)
4667 XmLWarning(w, "GetValues() - invalid row");
4668 continue;
4670 GetRowValue(g, row, args[i].value, mask);
4672 else if (!strncmp(args[i].name, "column", 6))
4674 if (!strcmp(args[i].name, XmNcolumnPtr))
4676 col = (XmLGridColumn)args[i].value;
4677 continue;
4679 mask = 0;
4680 GetColumnValueMask(g, args[i].name, &mask);
4681 if (!mask)
4682 continue;
4683 if (!col)
4685 XmLWarning(w, "GetValues() - invalid column");
4686 continue;
4688 GetColumnValue(g, col, args[i].value, mask);
4690 else if (!strncmp(args[i].name, "cell", 4))
4692 mask = 0;
4693 CellValueGetMask(args[i].name, &mask);
4694 if (!mask)
4695 continue;
4696 if (!row || !col)
4698 XmLWarning(w, "GetValues() - invalid cell");
4699 continue;
4701 c = XmLGridColumnGetPos(col);
4702 cell = (XmLGridCell)XmLArrayGet(XmLGridRowCells(row), c);
4703 GetCellValue(cell, args[i].value, mask);
4708 static void
4709 SetSubValues(Widget w,
4710 ArgList args,
4711 Cardinal *nargs)
4713 XmLGridWidget g;
4714 XmLGridRow row;
4715 XmLGridColumn col;
4716 XmLGridCell cell;
4717 XmLGridCellRefValues *values, *newValues, *prevValues;
4718 XmLArray cellArray;
4719 int r, r1, r2, rowsValid;
4720 int c, c1, c2, cd1, cd2, colsValid;
4721 unsigned char rowType, colType;
4722 long rowMask, colMask, cellMask;
4723 int i, nRefValues, allCols;
4724 int needsHorizResize, needsVertResize;
4725 char buf[256];
4727 newValues = (XmLGridCellRefValues *)NULL;
4728 g = (XmLGridWidget)w;
4729 needsHorizResize = 0;
4730 needsVertResize = 0;
4731 rowMask = 0;
4732 colMask = 0;
4733 cellMask = 0;
4734 for (i = 0; i < *nargs; i++)
4736 if (!args[i].name)
4737 continue;
4738 if (!strncmp(args[i].name, "row", 3))
4740 if (!strcmp(args[i].name, XmNrowPtr))
4741 XmLWarning(w, "SetValues() - can't use XmNrowPtr");
4742 GetRowValueMask(g, args[i].name, &rowMask);
4744 else if (!strncmp(args[i].name, "column", 6))
4746 if (!strcmp(args[i].name, XmNcolumnPtr))
4747 XmLWarning(w, "SetValues() - can't use XmNcolumnPtr");
4748 GetColumnValueMask(g, args[i].name, &colMask);
4750 else if (!strncmp(args[i].name, "cell", 4))
4751 CellValueGetMask(args[i].name, &cellMask);
4752 else if (rowMask || colMask || cellMask)
4754 sprintf(buf, "SetValues() - %s is not a row/column/cell resource",
4755 args[i].name);
4756 XmLWarning(w, buf);
4759 if (rowMask || colMask || cellMask)
4761 if (g->grid.rowType == XmINVALID_TYPE)
4762 rowType = XmCONTENT;
4763 else
4764 rowType = g->grid.rowType;
4765 rowsValid = 1;
4766 if (g->grid.cellRowRangeStart != -1 && g->grid.cellRowRangeEnd != -1)
4768 r1 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeStart, 0);
4769 r2 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeEnd, 0);
4770 if (r1 < 0 || r2 < 0 || r1 > r2)
4771 rowsValid = 0;
4772 r2++;
4774 else if (g->grid.cellRow != -1)
4776 r1 = RowTypePosToPos(g, rowType, g->grid.cellRow, 0);
4777 if (r1 == -1)
4778 rowsValid = 0;
4779 r2 = r1 + 1;
4781 else
4783 r1 = RowTypePosToPos(g, rowType, 0, 0);
4784 if (r1 == -1)
4785 r1 = 0;
4786 r2 = RowTypePosToPos(g, rowType, -1, 1);
4788 if (!rowsValid)
4790 XmLWarning(w, "SetValues() - invalid row(s) specified");
4791 r1 = 0;
4792 r2 = 0;
4794 if (g->grid.colType == XmINVALID_TYPE)
4795 colType = XmCONTENT;
4796 else
4797 colType = g->grid.colType;
4798 colsValid = 1;
4799 if (g->grid.cellColRangeStart != -1 && g->grid.cellColRangeEnd != -1)
4801 c1 = ColTypePosToPos(g, colType, g->grid.cellColRangeStart, 0);
4802 c2 = ColTypePosToPos(g, colType, g->grid.cellColRangeEnd, 0);
4803 if (c1 < 0 || c2 < 0 || c1 > c2)
4804 colsValid = 0;
4805 c2++;
4807 else if (g->grid.cellCol != -1)
4809 c1 = ColTypePosToPos(g, colType, g->grid.cellCol, 0);
4810 if (c1 == -1)
4811 colsValid = 0;
4812 c2 = c1 + 1;
4814 else
4816 c1 = ColTypePosToPos(g, colType, 0, 0);
4817 if (c1 == -1)
4818 c1 = 0;
4819 c2 = ColTypePosToPos(g, colType, -1, 1);
4821 if (!colsValid)
4823 XmLWarning(w, "SetValues() - invalid column(s) specified");
4824 c1 = 0;
4825 c2 = 0;
4827 if (g->grid.debugLevel)
4829 fprintf(stderr, "XmLGrid: SetValues for rows %d to %d\n", r1, r2);
4830 fprintf(stderr, "XmLGrid: & columns %d to %d\n", c1, c2);
4832 if (rowMask)
4833 for (r = r1; r < r2; r += g->grid.rowStep)
4835 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
4836 if (!row)
4837 continue;
4838 if (SetRowValues(g, row, rowMask))
4839 needsVertResize = 1;
4840 DrawArea(g, DrawRow, r, 0);
4842 if (colMask)
4843 for (c = c1; c < c2; c += g->grid.colStep)
4845 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4846 if (!col)
4847 continue;
4848 if (SetColumnValues(g, col, colMask))
4849 needsHorizResize = 1;
4850 DrawArea(g, DrawCol, 0, c);
4852 if (cellMask)
4853 SetCellValuesPreprocess(g, cellMask);
4854 if (cellMask && g->grid.cellDefaults == True)
4856 allCols = 0;
4857 if (g->grid.colType == XmINVALID_TYPE &&
4858 g->grid.cellCol == -1 &&
4859 g->grid.cellColRangeStart == -1 &&
4860 g->grid.cellColRangeEnd == -1 &&
4861 g->grid.colStep == 1)
4862 allCols = 1;
4864 if (allCols)
4866 /* set cell default values */
4867 newValues = CellRefValuesCreate(g, g->grid.defCellValues);
4868 newValues->refCount = 1;
4869 SetCellRefValues(g, newValues, cellMask);
4870 if (newValues->rowSpan || newValues->columnSpan)
4872 newValues->rowSpan = 0;
4873 newValues->columnSpan = 0;
4874 XmLWarning((Widget)g,
4875 "SetValues() - can't set default cell spans");
4877 XmLGridCellDerefValues(g->grid.defCellValues);
4878 g->grid.defCellValues = newValues;
4879 cd1 = 0;
4880 cd2 = XmLArrayGetCount(g->grid.colArray);
4882 else
4884 cd1 = c1;
4885 cd2 = c2;
4887 /* set column cell default values */
4888 for (c = cd1; c < cd2; c += g->grid.colStep)
4890 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4891 if (!col)
4892 continue;
4893 if (allCols && !col->grid.defCellValues)
4894 continue;
4895 if (col->grid.defCellValues)
4896 newValues = CellRefValuesCreate(g, col->grid.defCellValues);
4897 else
4898 newValues = CellRefValuesCreate(g, g->grid.defCellValues);
4899 newValues->refCount = 1;
4900 SetCellRefValues(g, newValues, cellMask);
4901 if (newValues->rowSpan || newValues->columnSpan)
4903 newValues->rowSpan = 0;
4904 newValues->columnSpan = 0;
4905 XmLWarning((Widget)g,
4906 "SetValues() - can't set default cell spans");
4908 if (col->grid.defCellValues)
4909 XmLGridCellDerefValues(col->grid.defCellValues);
4910 col->grid.defCellValues = newValues;
4913 else if (cellMask)
4915 /* set cell values */
4916 if (SetCellHasRefValues(cellMask))
4918 cellArray = XmLArrayNew(0, 0);
4919 XmLArrayAdd(cellArray, -1, (r2 - r1) * (c2 - c1));
4920 nRefValues = 0;
4921 for (r = r1; r < r2; r += g->grid.rowStep)
4922 for (c = c1; c < c2; c += g->grid.colStep)
4924 cell = GetCell(g, r, c);
4925 if (!cell)
4926 continue;
4927 SetCellRefValuesPreprocess(g, r, c, cell, cellMask);
4928 XmLArraySet(cellArray, nRefValues, cell);
4929 nRefValues++;
4931 XmLArraySort(cellArray, SetCellRefValuesCompare,
4932 (void *)&cellMask, 0, nRefValues);
4933 prevValues = 0;
4934 for (i = 0; i < nRefValues; i++)
4936 cell = (XmLGridCell)XmLArrayGet(cellArray, i);
4937 values = XmLGridCellGetRefValues(cell);
4938 if (values != prevValues)
4940 newValues = CellRefValuesCreate(g, values);
4941 SetCellRefValues(g, newValues, cellMask);
4943 XmLGridCellSetRefValues(cell, newValues);
4944 prevValues = values;
4946 XmLArrayFree(cellArray);
4948 for (r = r1; r < r2; r += g->grid.rowStep)
4949 for (c = c1; c < c2; c += g->grid.colStep)
4951 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
4952 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
4953 cell = GetCell(g, r, c);
4954 if (!row || !col || !cell)
4955 continue;
4956 if (SetCellValuesResize(g, row, col, cell, cellMask))
4958 needsHorizResize = 1;
4959 needsVertResize = 1;
4961 SetCellValues(g, cell, cellMask);
4962 if (!needsHorizResize && !needsVertResize)
4963 DrawArea(g, DrawCell, r, c);
4967 if (needsHorizResize)
4968 HorizLayout(g, 1);
4969 if (needsVertResize)
4970 VertLayout(g, 1);
4971 if (needsHorizResize || needsVertResize)
4972 DrawArea(g, DrawAll, 0, 0);
4973 g->grid.rowType = XmINVALID_TYPE;
4974 g->grid.colType = XmINVALID_TYPE;
4975 g->grid.rowStep = 1;
4976 g->grid.colStep = 1;
4977 g->grid.cellRow = -1;
4978 g->grid.cellRowRangeStart = -1;
4979 g->grid.cellRowRangeEnd = -1;
4980 g->grid.cellCol = -1;
4981 g->grid.cellColRangeStart = -1;
4982 g->grid.cellColRangeEnd = -1;
4983 g->grid.cellDefaults = False;
4986 static Boolean
4987 SetValues(Widget curW,
4988 Widget reqW,
4989 Widget newW,
4990 ArgList args,
4991 Cardinal *nargs)
4993 XmLGridWidget g, cur;
4994 int hc, c, fc, hr, r, fr;
4995 int tfc, bfc, lfc, rfc;
4996 int needsVertLayout, needsHorizLayout, needsRedraw;
4997 XmLGridCellRefValues *cellValues;
4999 g = (XmLGridWidget)newW;
5000 cur = (XmLGridWidget)curW;
5001 needsRedraw = 0;
5002 needsVertLayout = 0;
5003 needsHorizLayout = 0;
5005 #define NE(value) (g->value != cur->value)
5006 if (NE(grid.cScrollCol))
5008 g->grid.scrollCol = g->grid.cScrollCol + g->grid.headingColCount;
5009 needsHorizLayout = 1;
5010 needsRedraw = 1;
5012 if (NE(grid.cScrollRow))
5014 g->grid.scrollRow = g->grid.cScrollRow + g->grid.headingRowCount;
5015 needsVertLayout = 1;
5016 needsRedraw = 1;
5018 if (NE(grid.bottomFixedCount) ||
5019 NE(grid.bottomFixedMargin) ||
5020 NE(grid.topFixedCount) ||
5021 NE(grid.topFixedMargin) ||
5022 NE(grid.vsbDisplayPolicy))
5024 needsVertLayout = 1;
5025 needsRedraw = 1;
5027 if (NE(grid.leftFixedCount) ||
5028 NE(grid.leftFixedMargin) ||
5029 NE(grid.rightFixedCount) ||
5030 NE(grid.rightFixedMargin) ||
5031 NE(grid.hsbDisplayPolicy))
5033 needsHorizLayout = 1;
5034 needsRedraw = 1;
5036 if (NE(grid.layoutFrozen))
5038 if (g->grid.layoutFrozen == False)
5040 if (g->grid.needsVertLayout == True)
5042 needsVertLayout = 1;
5043 g->grid.needsVertLayout = False;
5045 if (g->grid.needsHorizLayout == True)
5047 needsHorizLayout = 1;
5048 g->grid.needsHorizLayout = False;
5050 needsRedraw = 1;
5053 if (NE(grid.scrollBarMargin) ||
5054 NE(manager.shadow_thickness) ||
5055 NE(core.border_width) ||
5056 NE(grid.vsPolicy) ||
5057 NE(grid.hsPolicy))
5059 needsVertLayout = 1;
5060 needsHorizLayout = 1;
5061 needsRedraw = 1;
5063 if (NE(grid.blankBg) ||
5064 NE(grid.highlightThickness) ||
5065 NE(grid.selectBg) ||
5066 NE(grid.selectFg) ||
5067 NE(grid.toggleTopColor) ||
5068 NE(grid.toggleBotColor) ||
5069 NE(grid.shadowRegions) ||
5070 NE(grid.shadowType))
5071 needsRedraw = 1;
5072 if (NE(grid.fontList))
5074 XmFontListFree(cur->grid.fontList);
5075 CopyFontList(g);
5076 cellValues = CellRefValuesCreate(g, g->grid.defCellValues);
5077 cellValues->refCount = 1;
5078 XmFontListFree(cellValues->fontList);
5079 cellValues->fontList = XmFontListCopy(g->grid.fontList);
5080 XmLFontListGetDimensions(cellValues->fontList,
5081 &cellValues->fontWidth, &cellValues->fontHeight,
5082 g->grid.useAvgWidth);
5083 XmLGridCellDerefValues(g->grid.defCellValues);
5084 g->grid.defCellValues = cellValues;
5086 if (NE(grid.allowDrop))
5087 DropRegister(g, g->grid.allowDrop);
5088 if (g->grid.rowStep < 1)
5090 XmLWarning(newW, "SetValues() - rowStep can't be < 1");
5091 g->grid.rowStep = 1;
5093 if (g->grid.colStep < 1)
5095 XmLWarning(newW, "SetValues() - colStep can't be < 1");
5096 g->grid.colStep = 1;
5098 if (NE(grid.hsb) ||
5099 NE(grid.vsb) ||
5100 NE(grid.text))
5102 XmLWarning(newW, "SetValues() - child Widgets are read-only");
5103 g->grid.hsb = cur->grid.hsb;
5104 g->grid.vsb = cur->grid.vsb;
5105 g->grid.text = cur->grid.text;
5107 if (NE(grid.useTextWidget))
5109 XmLWarning(newW, "SetValues() - can't set use of text widget");
5110 g->grid.useTextWidget = cur->grid.useTextWidget;
5112 if (NE(grid.hiddenColCount) ||
5113 NE(grid.hiddenRowCount))
5115 XmLWarning(newW, "SetValues() - can't set hidden rows or columns");
5116 g->grid.hiddenColCount = cur->grid.hiddenColCount;
5117 g->grid.hiddenRowCount = cur->grid.hiddenRowCount;
5120 /* store fixed counts, add/removing rows/columns can change these */
5121 tfc = -1;
5122 bfc = -1;
5123 lfc = -1;
5124 rfc = -1;
5125 if (NE(grid.topFixedCount))
5126 tfc = g->grid.topFixedCount;
5127 if (NE(grid.bottomFixedCount))
5128 bfc = g->grid.bottomFixedCount;
5129 if (NE(grid.leftFixedCount))
5130 lfc = g->grid.leftFixedCount;
5131 if (NE(grid.rightFixedCount))
5132 rfc = g->grid.rightFixedCount;
5133 g->grid.topFixedCount = cur->grid.topFixedCount;
5134 g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
5135 g->grid.leftFixedCount = cur->grid.leftFixedCount;
5136 g->grid.rightFixedCount = cur->grid.rightFixedCount;
5138 hc = g->grid.headingColCount - cur->grid.headingColCount;
5139 c = g->grid.colCount - cur->grid.colCount;
5140 fc = g->grid.footerColCount - cur->grid.footerColCount;
5141 hr = g->grid.headingRowCount - cur->grid.headingRowCount;
5142 r = g->grid.rowCount - cur->grid.rowCount;
5143 fr = g->grid.footerRowCount - cur->grid.footerRowCount;
5144 g->grid.headingColCount = cur->grid.headingColCount;
5145 g->grid.colCount = cur->grid.colCount;
5146 g->grid.footerColCount = cur->grid.footerColCount;
5147 g->grid.headingRowCount = cur->grid.headingRowCount;
5148 g->grid.rowCount = cur->grid.rowCount;
5149 g->grid.footerRowCount = cur->grid.footerRowCount;
5150 if (hc > 0)
5151 XmLGridAddColumns((Widget)g, XmHEADING, -1, hc);
5152 if (hc < 0)
5153 XmLGridDeleteColumns((Widget)g, XmHEADING,
5154 g->grid.headingColCount + hc, -(hc));
5155 if (c > 0)
5156 XmLGridAddColumns((Widget)g, XmCONTENT, -1, c);
5157 if (c < 0)
5158 XmLGridDeleteColumns((Widget)g, XmCONTENT,
5159 g->grid.colCount + c, -(c));
5160 if (fc > 0)
5161 XmLGridAddColumns((Widget)g, XmFOOTER, -1, fc);
5162 if (fc < 0)
5163 XmLGridDeleteColumns((Widget)g, XmFOOTER,
5164 g->grid.footerColCount + fc, -(fc));
5165 if (hr > 0)
5166 XmLGridAddRows((Widget)g, XmHEADING, -1, hr);
5167 if (hr < 0)
5168 XmLGridDeleteRows((Widget)g, XmHEADING,
5169 g->grid.headingRowCount + hr, -(hr));
5170 if (r > 0)
5171 XmLGridAddRows((Widget)g, XmCONTENT, -1, r);
5172 if (r < 0)
5173 XmLGridDeleteRows((Widget)g, XmCONTENT,
5174 g->grid.rowCount + r, -(r));
5175 if (fr > 0)
5176 XmLGridAddRows((Widget)g, XmFOOTER, -1, fr);
5177 if (fr < 0)
5178 XmLGridDeleteRows((Widget)g, XmFOOTER,
5179 g->grid.footerRowCount + fr, -(fr));
5181 /* restore fixed counts if user specified */
5182 if (tfc != -1)
5183 g->grid.topFixedCount = tfc;
5184 if (bfc != -1)
5185 g->grid.bottomFixedCount = bfc;
5186 if (lfc != -1)
5187 g->grid.leftFixedCount = lfc;
5188 if (rfc != -1)
5189 g->grid.rightFixedCount = rfc;
5191 if (g->grid.topFixedCount < g->grid.headingRowCount)
5193 XmLWarning(newW,
5194 "SetValues() - can't set topFixedCount < headingRowCount");
5195 g->grid.topFixedCount = cur->grid.topFixedCount;
5197 if (g->grid.bottomFixedCount < g->grid.footerRowCount)
5199 XmLWarning(newW,
5200 "SetValues() - can't set bottomFixedCount < footerRowCount");
5201 g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
5203 if (g->grid.leftFixedCount < g->grid.headingColCount)
5205 XmLWarning(newW,
5206 "SetValues() - can't set leftFixedCount < headingColumnCount");
5207 g->grid.leftFixedCount = cur->grid.leftFixedCount;
5209 if (g->grid.rightFixedCount < g->grid.footerColCount)
5211 XmLWarning(newW,
5212 "SetValues() - can't set rightFixedCount < footerColumnCount");
5213 g->grid.rightFixedCount = cur->grid.rightFixedCount;
5216 if (NE(grid.simpleHeadings))
5218 if (cur->grid.simpleHeadings)
5219 free((char *)cur->grid.simpleHeadings);
5220 if (g->grid.simpleHeadings)
5222 g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
5223 SetSimpleHeadings(g, g->grid.simpleHeadings);
5226 if (NE(grid.simpleWidths))
5228 if (cur->grid.simpleWidths)
5229 free((char *)cur->grid.simpleWidths);
5230 if (g->grid.simpleWidths)
5232 g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
5233 SetSimpleWidths(g, g->grid.simpleWidths);
5236 if (NE(grid.visibleRows))
5238 ApplyVisibleRows(g);
5239 needsVertLayout = 1;
5240 needsRedraw = 1;
5242 if (NE(grid.visibleCols))
5244 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
5245 XmLGridSetVisibleColumnCount((Widget)g, g->grid.visibleCols);
5246 else
5247 ApplyVisibleCols(g);
5248 needsHorizLayout = 1;
5249 needsRedraw = 1;
5252 /* for the hidden columns stuff */
5253 if (NE(grid.hideUnhideButtons))
5255 if (g->grid.hideUnhideButtons)
5257 CreateHideUnhideButtons(g);
5259 else
5261 XtDestroyWidget(g->grid.hideButton);
5262 XtDestroyWidget(g->grid.unhideButton);
5263 g->grid.hideButton = 0;
5264 g->grid.unhideButton = 0;
5267 needsVertLayout = 1;
5268 needsHorizLayout = 1;
5269 needsRedraw = 1;
5271 #undef NE
5273 SetSubValues(newW, args, nargs);
5275 if (needsVertLayout)
5276 VertLayout(g, 1);
5277 if (needsHorizLayout)
5278 HorizLayout(g, 1);
5279 if (needsRedraw)
5280 DrawArea(g, DrawAll, 0, 0);
5281 return (False);
5284 static void
5285 CopyFontList(XmLGridWidget g)
5287 if (!g->grid.fontList)
5288 g->grid.fontList = XmLFontListCopyDefault((Widget)g);
5289 else
5290 g->grid.fontList = XmFontListCopy(g->grid.fontList);
5291 if (!g->grid.fontList)
5292 XmLWarning((Widget)g, "- fatal error - font list NULL");
5295 static Boolean
5296 CvtStringToSizePolicy(Display *dpy,
5297 XrmValuePtr args,
5298 Cardinal *narg,
5299 XrmValuePtr fromVal,
5300 XrmValuePtr toVal,
5301 XtPointer *data)
5303 static XmLStringToUCharMap map[] =
5305 { "CONSTANT", XmCONSTANT },
5306 { "VARIABLE", XmVARIABLE },
5307 { "RESIZE_IF_POSSIBLE", XmRESIZE_IF_POSSIBLE },
5308 { 0, 0 },
5311 return XmLCvtStringToUChar(dpy, "XmRGridSizePolicy", map, fromVal, toVal);
5314 static Boolean
5315 CvtStringToRowColType(Display *dpy,
5316 XrmValuePtr args,
5317 Cardinal *narg,
5318 XrmValuePtr fromVal,
5319 XrmValuePtr toVal,
5320 XtPointer *data)
5322 static XmLStringToUCharMap map[] =
5324 { "HEADING", XmHEADING },
5325 { "CONTENT", XmCONTENT },
5326 { "FOOTER", XmFOOTER },
5327 { "ALL_TYPES", XmALL_TYPES },
5328 { 0, 0 },
5331 return XmLCvtStringToUChar(dpy, "XmRRowColType", map, fromVal, toVal);
5334 static Boolean
5335 CvtStringToSelectionPolicy(Display *dpy,
5336 XrmValuePtr args,
5337 Cardinal *narg,
5338 XrmValuePtr fromVal,
5339 XrmValuePtr toVal,
5340 XtPointer *data)
5342 static XmLStringToUCharMap map[] =
5344 { "SELECT_NONE", XmSELECT_NONE },
5345 { "SELECT_SINGLE_ROW", XmSELECT_SINGLE_ROW },
5346 { "SELECT_BROWSE_ROW", XmSELECT_BROWSE_ROW },
5347 { "SELECT_MULTIPLE_ROW", XmSELECT_MULTIPLE_ROW },
5348 { "SELECT_CELL", XmSELECT_CELL },
5349 { 0, 0 },
5352 return XmLCvtStringToUChar(dpy, "XmRGridSelectionPolicy", map,
5353 fromVal, toVal);
5356 static Boolean
5357 CvtStringToCellAlignment(Display *dpy,
5358 XrmValuePtr args,
5359 Cardinal *narg,
5360 XrmValuePtr fromVal,
5361 XrmValuePtr toVal,
5362 XtPointer *data)
5364 static XmLStringToUCharMap map[] =
5366 { "ALIGNMENT_LEFT", XmALIGNMENT_LEFT },
5367 { "ALIGNMENT_CENTER", XmALIGNMENT_CENTER },
5368 { "ALIGNMENT_RIGHT", XmALIGNMENT_RIGHT },
5369 { "ALIGNMENT_TOP_LEFT", XmALIGNMENT_TOP_LEFT },
5370 { "ALIGNMENT_TOP", XmALIGNMENT_TOP },
5371 { "ALIGNMENT_TOP_RIGHT", XmALIGNMENT_TOP_RIGHT },
5372 { "ALIGNMENT_BOTTOM_LEFT", XmALIGNMENT_BOTTOM_LEFT },
5373 { "ALIGNMENT_BOTTOM", XmALIGNMENT_BOTTOM },
5374 { "ALIGNMENT_BOTTOM_RIGHT", XmALIGNMENT_BOTTOM_RIGHT },
5375 { 0, 0 },
5378 return XmLCvtStringToUChar(dpy, "XmRGridCellAlignment", map,
5379 fromVal, toVal);
5382 static Boolean
5383 CvtStringToCellBorderType(Display *dpy,
5384 XrmValuePtr args,
5385 Cardinal *narg,
5386 XrmValuePtr fromVal,
5387 XrmValuePtr toVal,
5388 XtPointer *data)
5390 static XmLStringToUCharMap map[] =
5392 { "BORDER_NONE", XmBORDER_NONE },
5393 { "BORDER_LINE", XmBORDER_LINE },
5394 { "BORDER_DASH", XmBORDER_DASH },
5395 { 0, 0 },
5398 return XmLCvtStringToUChar(dpy, "XmRGridCellBorderType", map,
5399 fromVal, toVal);
5402 static Boolean
5403 CvtStringToCellType(Display *dpy,
5404 XrmValuePtr args,
5405 Cardinal *narg,
5406 XrmValuePtr fromVal,
5407 XrmValuePtr toVal,
5408 XtPointer *data)
5410 static XmLStringToUCharMap map[] =
5412 { "ICON_CELL", XmICON_CELL },
5413 { "STRING_CELL", XmSTRING_CELL },
5414 { "PIXMAP_CELL", XmPIXMAP_CELL },
5415 { "TOGGLE_CELL", XmTOGGLE_CELL },
5416 { 0, 0 },
5419 return XmLCvtStringToUChar(dpy, "XmRGridCellType", map, fromVal, toVal);
5422 static void
5423 SetSimpleHeadings(XmLGridWidget g,
5424 char *data)
5426 char *c;
5427 int n, count;
5429 if (!data || !*data)
5430 return;
5431 c = data;
5432 n = 1;
5433 while (*c)
5435 if (*c == '|')
5436 n++;
5437 c++;
5439 count = XmLArrayGetCount(g->grid.colArray);
5440 if (n > count)
5442 XmLWarning((Widget)g,
5443 "SetSimpleHeadings() - headings given for non-existing columns");
5444 return;
5446 if (g->grid.headingRowCount < 1)
5448 XmLWarning((Widget)g, "SetSimpleHeadings() - no heading row exists");
5449 return;
5451 XmLGridSetStrings((Widget)g, data);
5454 static void
5455 SetSimpleWidths(XmLGridWidget g,
5456 char *data)
5458 XmLGridColumn colp;
5459 int i, n, colCount, valid;
5460 Dimension prevWidth;
5461 unsigned char prevSizePolicy;
5462 long mask;
5463 struct WidthRec
5465 Dimension width;
5466 unsigned char sizePolicy;
5467 } *widths;
5469 if (!data)
5470 return;
5471 i = ((int)strlen(data) / 2) + 1;
5472 widths = (struct WidthRec *)malloc(i * sizeof(struct WidthRec));
5473 valid = 1;
5474 n = 0;
5475 while (*data)
5477 if (*data >= '0' && *data <= '9')
5479 widths[n].width = atoi(data);
5480 while (*data >= '0' && *data <= '9')
5481 data++;
5483 else
5485 valid = 0;
5486 break;
5488 if (*data == 'c' || *data == 'C')
5490 widths[n].sizePolicy = XmVARIABLE;
5491 data++;
5493 else if (*data == 'p' || *data == 'P')
5495 widths[n].sizePolicy = XmCONSTANT;
5496 data++;
5498 else
5500 valid = 0;
5501 break;
5503 while (*data == ' ')
5504 data++;
5505 n++;
5507 if (!valid)
5509 free((char *)widths);
5510 XmLWarning((Widget)g, "SetSimpleWidths() - invalid widths string");
5511 return;
5513 colCount = XmLArrayGetCount(g->grid.colArray);
5514 if (n > colCount)
5516 free((char *)widths);
5517 XmLWarning((Widget)g,
5518 "SetSimpleWidths() - widths given for non-existing columns");
5519 return;
5521 prevWidth = g->grid.colWidth;
5522 prevSizePolicy = g->grid.colSizePolicy;
5523 for (i = 0; i < n; i++)
5525 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
5526 if (!colp)
5527 continue;
5528 GetColumnValueMask(g, XmNcolumnWidth, &mask);
5529 GetColumnValueMask(g, XmNcolumnSizePolicy, &mask);
5530 g->grid.colWidth = widths[i].width;
5531 g->grid.colSizePolicy = widths[i].sizePolicy;
5532 SetColumnValues(g, colp, mask);
5534 free((char *)widths);
5535 g->grid.colWidth = prevWidth;
5536 g->grid.colSizePolicy = prevSizePolicy;
5537 HorizLayout(g, 1);
5538 DrawArea(g, DrawAll, 0, 0);
5542 Getting and Setting Row Values
5545 static void
5546 GetRowValueMask(XmLGridWidget g,
5547 char *s,
5548 long *mask)
5550 XmLGridClassPartOfWidget(g).getRowValueMaskProc(g, s, mask);
5553 /* Only to be called through Grid class */
5554 static void
5555 _GetRowValueMask(XmLGridWidget g,
5556 char *s,
5557 long *mask)
5559 static XrmQuark qHeight, qSizePolicy, qUserData;
5560 static int quarksValid = 0;
5561 XrmQuark q;
5563 if (!quarksValid)
5565 qHeight = XrmStringToQuark(XmNrowHeight);
5566 qSizePolicy = XrmStringToQuark(XmNrowSizePolicy);
5567 qUserData = XrmStringToQuark(XmNrowUserData);
5568 quarksValid = 1;
5570 q = XrmStringToQuark(s);
5571 if (q == qHeight)
5572 *mask |= XmLGridRowHeight;
5573 else if (q == qSizePolicy)
5574 *mask |= XmLGridRowSizePolicy;
5575 else if (q == qUserData)
5576 *mask |= XmLGridRowUserData;
5579 static void
5580 GetRowValue(XmLGridWidget g,
5581 XmLGridRow row,
5582 XtArgVal value,
5583 long mask)
5585 XmLGridClassPartOfWidget(g).getRowValueProc(g, row, value, mask);
5588 /* Only to be called through Grid class */
5589 static void
5590 _GetRowValue(XmLGridWidget g,
5591 XmLGridRow row,
5592 XtArgVal value,
5593 long mask)
5595 switch (mask)
5597 case XmLGridRowHeight:
5598 *((Dimension *)value) = row->grid.height;
5599 break;
5600 case XmLGridRowSizePolicy:
5601 *((unsigned char *)value) = row->grid.sizePolicy;
5602 break;
5603 case XmLGridRowUserData:
5604 *((XtPointer *)value) = (XtPointer)row->grid.userData;
5605 break;
5609 static int
5610 SetRowValues(XmLGridWidget g,
5611 XmLGridRow row,
5612 long mask)
5614 return XmLGridClassPartOfWidget(g).setRowValuesProc(g, row, mask);
5617 /* Only to be called through Grid class */
5618 static int
5619 _SetRowValues(XmLGridWidget g, XmLGridRow row, long mask)
5621 int needsResize = 0, visible = 0;
5622 Boolean newIsHidden;
5624 if (mask & XmLGridRowHeight || mask & XmLGridRowSizePolicy)
5626 visible = RowIsVisible(g, XmLGridRowGetPos(row));
5627 XmLGridRowHeightChanged(row);
5629 if (mask & XmLGridRowHeight)
5631 if (g->grid.rowHeight > 0)
5632 newIsHidden = False;
5633 else
5634 newIsHidden = True;
5635 if (XmLGridRowIsHidden(row) != newIsHidden)
5637 if (newIsHidden == True)
5638 g->grid.hiddenRowCount++;
5639 else
5640 g->grid.hiddenRowCount--;
5641 VisPosChanged(g, 1);
5642 needsResize = 1;
5644 if (visible && !g->grid.inResize)
5645 needsResize = 1;
5646 row->grid.height = g->grid.rowHeight;
5648 if (mask & XmLGridRowSizePolicy)
5650 row->grid.sizePolicy = g->grid.rowSizePolicy;
5651 if (visible && !g->grid.inResize)
5652 needsResize = 1;
5654 if (mask & XmLGridRowUserData)
5655 row->grid.userData = g->grid.rowUserData;
5656 return needsResize;
5660 Getting and Setting Column Values
5663 static void
5664 GetColumnValueMask(XmLGridWidget g,
5665 char *s,
5666 long *mask)
5668 XmLGridClassPartOfWidget(g).getColumnValueMaskProc(g, s, mask);
5671 /* Only to be called through Grid class */
5672 static void
5673 _GetColumnValueMask(XmLGridWidget g,
5674 char *s,
5675 long *mask)
5677 static XrmQuark qWidth, qSizePolicy, qUserData, qResizable;
5678 static XrmQuark qHidden, qSortType;
5679 static int quarksValid = 0;
5680 XrmQuark q;
5682 if (!quarksValid)
5684 qWidth = XrmStringToQuark(XmNcolumnWidth);
5685 qSizePolicy = XrmStringToQuark(XmNcolumnSizePolicy);
5686 qUserData = XrmStringToQuark(XmNcolumnUserData);
5687 qResizable = XrmStringToQuark(XmNcolumnResizable);
5688 qHidden = XrmStringToQuark(XmNcolumnHidden);
5689 qSortType = XrmStringToQuark(XmNcolumnSortType);
5690 quarksValid = 1;
5692 q = XrmStringToQuark(s);
5693 if (q == qWidth)
5694 *mask |= XmLGridColumnWidth;
5695 else if (q == qSizePolicy)
5696 *mask |= XmLGridColumnSizePolicy;
5697 else if (q == qUserData)
5698 *mask |= XmLGridColumnUserData;
5699 else if (q == qResizable)
5700 *mask |= XmLGridColumnResizable;
5701 else if (q == qHidden)
5702 *mask |= XmLGridColumnHidden;
5703 else if (q == qSortType)
5704 *mask |= XmLGridColumnSortType;
5707 static void
5708 GetColumnValue(XmLGridWidget g,
5709 XmLGridColumn col,
5710 XtArgVal value,
5711 long mask)
5713 XmLGridClassPartOfWidget(g).getColumnValueProc(g, col, value, mask);
5716 /* Only to be called through Grid class */
5717 static void
5718 _GetColumnValue(XmLGridWidget g,
5719 XmLGridColumn col,
5720 XtArgVal value,
5721 long mask)
5723 switch (mask)
5725 case XmLGridColumnWidth:
5726 *((Dimension *)value) = col->grid.width;
5727 break;
5728 case XmLGridColumnSizePolicy:
5729 *((unsigned char *)value) = col->grid.sizePolicy;
5730 break;
5731 case XmLGridColumnUserData:
5732 *((XtPointer *)value) = col->grid.userData;
5733 break;
5734 case XmLGridColumnResizable:
5735 *((Boolean *)value) = col->grid.resizable;
5736 break;
5737 case XmLGridColumnHidden:
5738 *((Boolean *)value) = col->grid.hidden;
5739 break;
5740 case XmLGridColumnSortType:
5741 *((unsigned char *)value) = col->grid.sort;
5742 break;
5747 static int
5748 SetColumnValues(XmLGridWidget g,
5749 XmLGridColumn col,
5750 long mask)
5752 return XmLGridClassPartOfWidget(g).setColumnValuesProc(g, col, mask);
5755 /* Only to be called through Grid class */
5756 static int
5757 _SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask)
5759 int needsResize = 0, visible = 0;
5760 Boolean newIsHidden;
5762 if (mask & XmLGridColumnWidth || mask & XmLGridColumnSizePolicy)
5764 visible = ColIsVisible(g, XmLGridColumnGetPos(col));
5765 XmLGridColumnWidthChanged(col);
5767 if (mask & XmLGridColumnWidth)
5769 if (g->grid.colWidth > 0)
5770 newIsHidden = False;
5771 else
5772 newIsHidden = True;
5773 if (XmLGridColumnIsHidden(col) != newIsHidden)
5775 if (newIsHidden == True)
5776 g->grid.hiddenColCount++;
5777 else
5778 g->grid.hiddenRowCount--;
5779 VisPosChanged(g, 0);
5780 needsResize = 1;
5782 if (visible && !g->grid.inResize)
5783 needsResize = 1;
5784 col->grid.width = g->grid.colWidth;
5786 if (mask & XmLGridColumnSizePolicy)
5788 col->grid.sizePolicy = g->grid.colSizePolicy;
5789 if (visible && !g->grid.inResize)
5790 needsResize = 1;
5791 if (col->grid.sizePolicy != XmCONSTANT
5792 && g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
5794 XmLWarning((Widget)g, "XmNcolumnSizePolicy must equal XmCONSTANT");
5797 if (mask & XmLGridColumnUserData)
5798 col->grid.userData = g->grid.colUserData;
5799 if (mask & XmLGridColumnResizable)
5800 col->grid.resizable = g->grid.colResizable;
5801 if (mask & XmLGridColumnHidden)
5802 col->grid.hidden = g->grid.colHidden;
5803 if (mask & XmLGridColumnSortType)
5804 XmLGridSetSort((Widget)g, XmLGridColumnGetPos(col), g->grid.colSortType);
5805 return needsResize;
5809 Getting and Setting Cell Values
5812 static void
5813 CellValueGetMask(char *s,
5814 long *mask)
5816 static XrmQuark qAlignment, qBackground, qBottomBorderColor;
5817 static XrmQuark qBottomBorderType, qColumnSpan;
5818 static XrmQuark qEditable, qFontList, qForeground;
5819 static XrmQuark qLeftBorderColor, qLeftBorderType;
5820 static XrmQuark qMarginBottom, qMarginLeft, qMarginRight;
5821 static XrmQuark qMarginTop, qPixmap, qPixmapMask;
5822 static XrmQuark qRightBorderColor, qRightBorderType;
5823 static XrmQuark qRowSpan, qString, qToggleSet;
5824 static XrmQuark qTopBorderColor, qTopBorderType, qType;
5825 static XrmQuark qUserData;
5826 static int quarksValid = 0;
5827 XrmQuark q;
5829 if (!quarksValid)
5831 qAlignment = XrmStringToQuark(XmNcellAlignment);
5832 qBackground = XrmStringToQuark(XmNcellBackground);
5833 qBottomBorderColor = XrmStringToQuark(XmNcellBottomBorderColor);
5834 qBottomBorderType = XrmStringToQuark(XmNcellBottomBorderType);
5835 qColumnSpan = XrmStringToQuark(XmNcellColumnSpan);
5836 qEditable = XrmStringToQuark(XmNcellEditable);
5837 qFontList = XrmStringToQuark(XmNcellFontList);
5838 qForeground = XrmStringToQuark(XmNcellForeground);
5839 qLeftBorderColor = XrmStringToQuark(XmNcellLeftBorderColor);
5840 qLeftBorderType = XrmStringToQuark(XmNcellLeftBorderType);
5841 qMarginBottom = XrmStringToQuark(XmNcellMarginBottom);
5842 qMarginLeft = XrmStringToQuark(XmNcellMarginLeft);
5843 qMarginRight = XrmStringToQuark(XmNcellMarginRight);
5844 qMarginTop= XrmStringToQuark(XmNcellMarginTop);
5845 qPixmap = XrmStringToQuark(XmNcellPixmap);
5846 qPixmapMask = XrmStringToQuark(XmNcellPixmapMask);
5847 qRightBorderColor = XrmStringToQuark(XmNcellRightBorderColor);
5848 qRightBorderType = XrmStringToQuark(XmNcellRightBorderType);
5849 qRowSpan = XrmStringToQuark(XmNcellRowSpan);
5850 qString = XrmStringToQuark(XmNcellString);
5851 qToggleSet = XrmStringToQuark(XmNcellToggleSet);
5852 qTopBorderColor = XrmStringToQuark(XmNcellTopBorderColor);
5853 qTopBorderType = XrmStringToQuark(XmNcellTopBorderType);
5854 qType = XrmStringToQuark(XmNcellType);
5855 qUserData = XrmStringToQuark(XmNcellUserData);
5856 quarksValid = 1;
5858 q = XrmStringToQuark(s);
5859 if (q == qAlignment)
5860 *mask |= XmLGridCellAlignment;
5861 else if (q == qBackground)
5862 *mask |= XmLGridCellBackground;
5863 else if (q == qBottomBorderColor)
5864 *mask |= XmLGridCellBottomBorderColor;
5865 else if (q == qBottomBorderType)
5866 *mask |= XmLGridCellBottomBorderType;
5867 else if (q == qColumnSpan)
5868 *mask |= XmLGridCellColumnSpan;
5869 else if (q == qEditable)
5870 *mask |= XmLGridCellEditable;
5871 else if (q == qFontList)
5872 *mask |= XmLGridCellFontList;
5873 else if (q == qForeground)
5874 *mask |= XmLGridCellForeground;
5875 else if (q == qLeftBorderColor)
5876 *mask |= XmLGridCellLeftBorderColor;
5877 else if (q == qLeftBorderType)
5878 *mask |= XmLGridCellLeftBorderType;
5879 else if (q == qMarginBottom)
5880 *mask |= XmLGridCellMarginBottom;
5881 else if (q == qMarginLeft)
5882 *mask |= XmLGridCellMarginLeft;
5883 else if (q == qMarginRight)
5884 *mask |= XmLGridCellMarginRight;
5885 else if (q == qMarginTop)
5886 *mask |= XmLGridCellMarginTop;
5887 else if (q == qPixmap)
5888 *mask |= XmLGridCellPixmapF;
5889 else if (q == qPixmapMask)
5890 *mask |= XmLGridCellPixmapMask;
5891 else if (q == qRightBorderColor)
5892 *mask |= XmLGridCellRightBorderColor;
5893 else if (q == qRightBorderType)
5894 *mask |= XmLGridCellRightBorderType;
5895 else if (q == qRowSpan)
5896 *mask |= XmLGridCellRowSpan;
5897 else if (q == qString)
5898 *mask |= XmLGridCellString;
5899 else if (q == qToggleSet)
5900 *mask |= XmLGridCellToggleSet;
5901 else if (q == qTopBorderColor)
5902 *mask |= XmLGridCellTopBorderColor;
5903 else if (q == qTopBorderType)
5904 *mask |= XmLGridCellTopBorderType;
5905 else if (q == qType)
5906 *mask |= XmLGridCellType;
5907 else if (q == qUserData)
5908 *mask |= XmLGridCellUserData;
5911 static void
5912 GetCellValue(XmLGridCell cell,
5913 XtArgVal value,
5914 long mask)
5916 XmLGridCellRefValues *values;
5917 XmLGridCellPixmap *pix;
5918 XmString str;
5920 values = XmLGridCellGetRefValues(cell);
5921 switch (mask)
5923 case XmLGridCellAlignment:
5924 *((unsigned char *)value) = values->alignment;
5925 break;
5926 case XmLGridCellBackground:
5927 *((Pixel *)value) = values->background;
5928 break;
5929 case XmLGridCellBottomBorderColor:
5930 *((Pixel *)value) = values->bottomBorderColor;
5931 break;
5932 case XmLGridCellBottomBorderType:
5933 *((unsigned char *)value) = values->bottomBorderType;
5934 break;
5935 case XmLGridCellColumnSpan:
5936 *((int *)value) = values->columnSpan;
5937 break;
5938 case XmLGridCellEditable:
5939 *((Boolean *)value) = values->editable;
5940 break;
5941 case XmLGridCellFontList:
5942 *((XmFontList *)value) = values->fontList;
5943 break;
5944 case XmLGridCellForeground:
5945 *((Pixel *)value) = values->foreground;
5946 break;
5947 case XmLGridCellLeftBorderColor:
5948 *((Pixel *)value) = values->leftBorderColor;
5949 break;
5950 case XmLGridCellLeftBorderType:
5951 *((unsigned char *)value) = values->leftBorderType;
5952 break;
5953 case XmLGridCellMarginBottom:
5954 *((Dimension *)value) = values->bottomMargin;
5955 break;
5956 case XmLGridCellMarginLeft:
5957 *((Dimension *)value) = values->leftMargin;
5958 break;
5959 case XmLGridCellMarginRight:
5960 *((Dimension *)value) = values->rightMargin;
5961 break;
5962 case XmLGridCellMarginTop:
5963 *((Dimension *)value) = values->topMargin;
5964 break;
5965 case XmLGridCellPixmapF:
5966 pix = XmLGridCellGetPixmap(cell);
5967 if (pix)
5968 *((Pixmap *)value) = pix->pixmap;
5969 else
5970 *((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
5971 break;
5972 case XmLGridCellPixmapMask:
5973 pix = XmLGridCellGetPixmap(cell);
5974 if (pix)
5975 *((Pixmap *)value) = pix->pixmask;
5976 else
5977 *((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
5978 break;
5979 case XmLGridCellRightBorderColor:
5980 *((Pixel *)value) = values->rightBorderColor;
5981 break;
5982 case XmLGridCellRightBorderType:
5983 *((unsigned char *)value) = values->rightBorderType;
5984 break;
5985 case XmLGridCellRowSpan:
5986 *((int *)value) = values->rowSpan;
5987 break;
5988 case XmLGridCellString:
5989 str = XmLGridCellGetString(cell);
5990 if (str)
5991 *((XmString *)value) = XmStringCopy(str);
5992 else
5993 *((XmString *)value) = 0;
5994 break;
5995 case XmLGridCellToggleSet:
5996 *((Boolean *)value) = XmLGridCellGetToggle(cell);
5997 break;
5998 case XmLGridCellTopBorderColor:
5999 *((Pixel *)value) = values->topBorderColor;
6000 break;
6001 case XmLGridCellTopBorderType:
6002 *((unsigned char *)value) = values->topBorderType;
6003 break;
6004 case XmLGridCellType:
6005 *((unsigned char *)value) = values->type;
6006 break;
6007 case XmLGridCellUserData:
6008 *((XtPointer *)value) = (XtPointer)values->userData;
6009 break;
6013 static XmLGridCellRefValues *
6014 CellRefValuesCreate(XmLGridWidget g,
6015 XmLGridCellRefValues *copy)
6017 short width, height;
6018 XmLGridCellRefValues *values;
6020 values = (XmLGridCellRefValues *)malloc(sizeof(XmLGridCellRefValues));
6021 if (!copy)
6023 /* default values */
6024 values->bottomBorderType = XmBORDER_LINE;
6025 values->leftBorderType = XmBORDER_LINE;
6026 values->rightBorderType = XmBORDER_LINE;
6027 values->topBorderType = XmBORDER_LINE;
6028 XmLFontListGetDimensions(g->grid.fontList, &width, &height,
6029 g->grid.useAvgWidth);
6030 values->alignment = XmALIGNMENT_CENTER;
6031 values->background = g->core.background_pixel;
6032 values->bottomBorderColor = g->manager.bottom_shadow_color;
6033 values->bottomMargin = 0;
6034 values->columnSpan = 0;
6035 values->editable = False;
6036 values->fontHeight = height;
6037 values->fontList = XmFontListCopy(g->grid.fontList);
6038 values->fontWidth = width;
6039 values->foreground = g->manager.foreground;
6040 values->leftBorderColor = g->manager.top_shadow_color;
6041 values->leftMargin = 0;
6042 values->refCount = 0;
6043 values->rightBorderColor = g->manager.bottom_shadow_color;
6044 values->rightMargin = 0;
6045 values->rowSpan = 0;
6046 values->topBorderColor = g->manager.top_shadow_color;
6047 values->topMargin = 0;
6048 values->type = XmSTRING_CELL;
6049 values->userData = 0;
6051 else
6053 /* copy values */
6054 *values = *copy;
6055 values->fontList = XmFontListCopy(copy->fontList);
6056 values->refCount = 0;
6058 return values;
6061 static void
6062 SetCellValuesPreprocess(XmLGridWidget g,
6063 long mask)
6065 XmLGridCellRefValues *newValues;
6066 int x, y;
6067 short width, height;
6068 Display *dpy;
6069 Window pixRoot;
6070 unsigned int pixWidth, pixHeight;
6071 unsigned int pixBW, pixDepth;
6073 /* calculate font width and height if set */
6074 newValues = &g->grid.cellValues;
6075 if (mask & XmLGridCellFontList)
6077 XmLFontListGetDimensions(newValues->fontList, &width, &height,
6078 g->grid.useAvgWidth);
6079 newValues->fontWidth = width;
6080 newValues->fontHeight = height;
6082 if (mask & XmLGridCellPixmapF)
6084 if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP &&
6085 g->grid.globalPixmapWidth &&
6086 g->grid.globalPixmapHeight)
6088 g->grid.cellPixmapWidth = g->grid.globalPixmapWidth;
6089 g->grid.cellPixmapHeight = g->grid.globalPixmapHeight;
6091 else if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
6093 dpy = XtDisplay(g);
6094 XGetGeometry(dpy, g->grid.cellPixmap, &pixRoot,
6095 &x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
6096 g->grid.cellPixmapWidth = (Dimension)pixWidth;
6097 g->grid.cellPixmapHeight = (Dimension)pixHeight;
6099 else
6101 g->grid.cellPixmapWidth = 0;
6102 g->grid.cellPixmapHeight = 0;
6107 static int
6108 SetCellHasRefValues(long mask)
6110 long unrefMask;
6112 /* return 1 if mask contains any reference counted values */
6113 unrefMask = XmLGridCellPixmapF | XmLGridCellPixmapMask |
6114 XmLGridCellString | XmLGridCellToggleSet;
6115 mask = mask | unrefMask;
6116 mask = mask ^ unrefMask;
6117 if (!mask)
6118 return 0;
6119 return 1;
6122 static int
6123 SetCellValuesResize(XmLGridWidget g,
6124 XmLGridRow row,
6125 XmLGridColumn col,
6126 XmLGridCell cell,
6127 long mask)
6129 return XmLGridClassPartOfWidget(g).setCellValuesResizeProc(g, row, col,
6130 cell, mask);
6133 static int
6134 _SetCellValuesResize(XmLGridWidget g,
6135 XmLGridRow row,
6136 XmLGridColumn col,
6137 XmLGridCell cell,
6138 long mask)
6140 XmLGridCellPixmap *cellPix;
6141 int pixResize, needsResize, rowVisible, colVisible;
6143 needsResize = 0;
6144 pixResize = 0;
6145 if (mask & XmLGridCellPixmapF)
6147 pixResize = 1;
6148 if (!(mask & XmLGridCellType))
6150 /* no resize needed if we replace with an equal size pixmap */
6151 cellPix = XmLGridCellGetPixmap(cell);
6152 if (cellPix && cellPix->pixmap != XmUNSPECIFIED_PIXMAP &&
6153 g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
6155 if (cellPix->width == g->grid.cellPixmapWidth &&
6156 cellPix->height == g->grid.cellPixmapHeight)
6157 pixResize = 0;
6161 if (mask & XmLGridCellType || mask & XmLGridCellFontList || pixResize ||
6162 mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan ||
6163 mask & XmLGridCellMarginLeft || mask & XmLGridCellMarginRight ||
6164 mask & XmLGridCellMarginTop || mask & XmLGridCellMarginBottom)
6166 XmLGridRowHeightChanged(row);
6167 XmLGridColumnWidthChanged(col);
6168 rowVisible = RowIsVisible(g, XmLGridRowGetPos(row));
6169 colVisible = ColIsVisible(g, XmLGridColumnGetPos(col));
6170 if (rowVisible | colVisible)
6171 needsResize = 1;
6173 return needsResize;
6176 static void
6177 SetCellValues(XmLGridWidget g,
6178 XmLGridCell cell,
6179 long mask)
6181 /* set non-reference counted cell values */
6182 if (mask & XmLGridCellPixmapF)
6183 XmLGridCellSetPixmap(cell, g->grid.cellPixmap,
6184 g->grid.cellPixmapWidth, g->grid.cellPixmapHeight);
6185 if (mask & XmLGridCellPixmapMask)
6186 XmLGridCellSetPixmask(cell, g->grid.cellPixmapMask);
6187 if (mask & XmLGridCellString)
6188 XmLGridCellSetString(cell, g->grid.cellString, True);
6189 if (mask & XmLGridCellToggleSet)
6190 XmLGridCellSetToggle(cell, g->grid.cellToggleSet);
6193 static void
6194 SetCellRefValues(XmLGridWidget g,
6195 XmLGridCellRefValues *values,
6196 long mask)
6198 XmLGridCellRefValues *newValues;
6200 /* set reference counted cell values */
6201 newValues = &g->grid.cellValues;
6202 if (mask & XmLGridCellAlignment)
6203 values->alignment = newValues->alignment;
6204 if (mask & XmLGridCellBackground)
6205 values->background = newValues->background;
6206 if (mask & XmLGridCellBottomBorderColor)
6207 values->bottomBorderColor = newValues->bottomBorderColor;
6208 if (mask & XmLGridCellBottomBorderType)
6209 values->bottomBorderType = newValues->bottomBorderType;
6210 if (mask & XmLGridCellColumnSpan)
6211 values->columnSpan = newValues->columnSpan;
6212 if (mask & XmLGridCellEditable)
6213 values->editable = newValues->editable;
6214 if (mask & XmLGridCellFontList)
6216 XmFontListFree(values->fontList);
6217 values->fontList = XmFontListCopy(newValues->fontList);
6218 values->fontWidth = newValues->fontWidth;
6219 values->fontHeight = newValues->fontHeight;
6221 if (mask & XmLGridCellForeground)
6222 values->foreground = newValues->foreground;
6223 if (mask & XmLGridCellLeftBorderColor)
6224 values->leftBorderColor = newValues->leftBorderColor;
6225 if (mask & XmLGridCellLeftBorderType)
6226 values->leftBorderType = newValues->leftBorderType;
6227 if (mask & XmLGridCellRightBorderColor)
6228 values->rightBorderColor = newValues->rightBorderColor;
6229 if (mask & XmLGridCellRightBorderType)
6230 values->rightBorderType = newValues->rightBorderType;
6231 if (mask & XmLGridCellMarginBottom)
6232 values->bottomMargin = newValues->bottomMargin;
6233 if (mask & XmLGridCellMarginLeft)
6234 values->leftMargin = newValues->leftMargin;
6235 if (mask & XmLGridCellMarginRight)
6236 values->rightMargin = newValues->rightMargin;
6237 if (mask & XmLGridCellMarginTop)
6238 values->topMargin = newValues->topMargin;
6239 if (mask & XmLGridCellRowSpan)
6240 values->rowSpan = newValues->rowSpan;
6241 if (mask & XmLGridCellTopBorderColor)
6242 values->topBorderColor = newValues->topBorderColor;
6243 if (mask & XmLGridCellTopBorderType)
6244 values->topBorderType = newValues->topBorderType;
6245 if (mask & XmLGridCellType)
6247 values->type = newValues->type;
6248 /* backwards compatibility cell types */
6249 if (values->type == XmLABEL_CELL)
6251 values->type = XmSTRING_CELL;
6252 values->editable = False;
6254 else if (values->type == XmTEXT_CELL)
6256 values->type = XmSTRING_CELL;
6257 values->editable = True;
6260 if (mask & XmLGridCellUserData)
6261 values->userData = newValues->userData;
6264 static int
6265 SetCellRefValuesCompare(void *userData,
6266 void **item1,
6267 void **item2)
6269 XmLGridCell cell1, cell2;
6270 XmLGridCellRefValues *values1, *values2;
6271 long mask;
6273 mask = *((long *)userData);
6274 cell1 = (XmLGridCell)*item1;
6275 cell2 = (XmLGridCell)*item2;
6276 values1 = XmLGridCellGetRefValues(cell1);
6277 values2 = XmLGridCellGetRefValues(cell2);
6278 if (values1 == values2)
6279 return 0;
6281 #define RVCOMPARE(res, var) \
6282 if (!(mask & res)) \
6284 if (values1->var < values2->var) \
6285 return -1; \
6286 if (values1->var > values2->var) \
6287 return 1; \
6289 RVCOMPARE(XmLGridCellAlignment, alignment)
6290 RVCOMPARE(XmLGridCellBackground, background)
6291 RVCOMPARE(XmLGridCellBottomBorderColor, bottomBorderColor)
6292 RVCOMPARE(XmLGridCellBottomBorderType, bottomBorderType)
6293 RVCOMPARE(XmLGridCellColumnSpan, columnSpan)
6294 RVCOMPARE(XmLGridCellEditable, editable)
6295 RVCOMPARE(XmLGridCellFontList, fontList)
6296 RVCOMPARE(XmLGridCellForeground, foreground)
6297 RVCOMPARE(XmLGridCellLeftBorderColor, leftBorderColor)
6298 RVCOMPARE(XmLGridCellLeftBorderType, leftBorderType)
6299 RVCOMPARE(XmLGridCellMarginBottom, bottomMargin)
6300 RVCOMPARE(XmLGridCellMarginLeft, leftMargin)
6301 RVCOMPARE(XmLGridCellMarginRight, rightMargin)
6302 RVCOMPARE(XmLGridCellMarginTop, topMargin)
6303 RVCOMPARE(XmLGridCellRightBorderColor, rightBorderColor)
6304 RVCOMPARE(XmLGridCellRightBorderType, rightBorderType)
6305 RVCOMPARE(XmLGridCellRowSpan, rowSpan)
6306 RVCOMPARE(XmLGridCellTopBorderColor, topBorderColor)
6307 RVCOMPARE(XmLGridCellTopBorderType, topBorderType)
6308 RVCOMPARE(XmLGridCellType, type)
6309 RVCOMPARE(XmLGridCellUserData, userData)
6310 #undef RVCOMPARE
6312 /* If the two cell values are equal, we merge them
6313 into one record here. This speeds up the sort
6314 and will allow the merge to compare just the values
6315 pointers to test equality. Note that this will not
6316 merge every possible item that could be merged, we
6317 don't want to do that because of the performance impact */
6318 if (values1 < values2)
6319 XmLGridCellSetRefValues(cell1, values2);
6320 else
6321 XmLGridCellSetRefValues(cell2, values1);
6322 return 0;
6325 static void
6326 SetCellRefValuesPreprocess(XmLGridWidget g,
6327 int row,
6328 int col,
6329 XmLGridCell cell,
6330 long mask)
6332 int r, c, rowSpan, colSpan;
6333 XmLGridCell spanCell;
6334 XmLGridCellRefValues *oldValues, *newValues;
6335 unsigned char oldType, newType;
6336 XmLGridCallbackStruct cbs;
6338 if (mask & XmLGridCellType)
6340 oldType = XmLGridCellGetRefValues(cell)->type;
6341 newType = g->grid.cellValues.type;
6342 if (oldType != newType)
6344 cbs.reason = XmCR_FREE_VALUE;
6345 XmLGridCellAction(cell, (Widget)g, &cbs);
6348 if (mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan)
6350 /* expose old cell area in case the span area shrinks */
6351 DrawArea(g, DrawCell, row, col);
6352 oldValues = XmLGridCellGetRefValues(cell);
6353 newValues = &g->grid.cellValues;
6354 if (mask & XmLGridCellRowSpan)
6356 g->grid.mayHaveRowSpans = 1;
6357 if (newValues->rowSpan < 0)
6359 XmLWarning((Widget)g,
6360 "SetValues() - row span can't be < 0");
6361 newValues->rowSpan = 0;
6363 rowSpan = newValues->rowSpan;
6365 else
6366 rowSpan = oldValues->rowSpan;
6367 if (mask & XmLGridCellColumnSpan)
6369 if (newValues->columnSpan < 0)
6371 XmLWarning((Widget)g,
6372 "SetValues() - column span can't be < 0");
6373 newValues->columnSpan = 0;
6375 colSpan = newValues->columnSpan;
6377 else
6378 colSpan = oldValues->columnSpan;
6379 /* clear old span */
6380 for (c = col; c <= col + oldValues->columnSpan; c++)
6381 for (r = row; r <= row + oldValues->rowSpan; r++)
6383 /* skip the cell itself */
6384 if (c == col && r == row)
6385 continue;
6386 spanCell = GetCell(g, r, c);
6387 if (!spanCell)
6388 continue;
6389 XmLGridCellSetInRowSpan(spanCell, False);
6390 XmLGridCellSetInColumnSpan(spanCell, False);
6392 /* set new span */
6393 for (c = col; c <= col + colSpan; c++)
6394 for (r = row; r <= row + rowSpan; r++)
6396 /* skip the cell itself */
6397 if (c == col && r == row)
6398 continue;
6399 spanCell = GetCell(g, r, c);
6400 if (!spanCell)
6401 continue;
6402 if (r == row)
6403 XmLGridCellSetInColumnSpan(spanCell, True);
6404 else
6405 XmLGridCellSetInRowSpan(spanCell, True);
6411 Read, Write, Copy, Paste
6414 static int
6415 Read(XmLGridWidget g,
6416 int format,
6417 char delimiter,
6418 int row,
6419 int col,
6420 char *data)
6422 char *c1, *c2, buf[256], *bufp;
6423 int r, c, i, j, len, n, needsResize, allowSet, done;
6424 XmString str;
6425 XmLGridCell cell;
6426 XmLGridRow rowp;
6427 XmLGridColumn colp;
6428 XmLGridCellRefValues *cellValues;
6429 XmLGridCallbackStruct cbs;
6431 if (format == XmFORMAT_PAD)
6433 XmLWarning((Widget)g, "Read() - FORMAT_PAD not supported");
6434 return 0;
6436 if (format == XmFORMAT_XL ||
6437 format == XmFORMAT_DROP ||
6438 format == XmFORMAT_PASTE)
6439 delimiter = '\t';
6440 c1 = data;
6441 c2 = data;
6442 r = row;
6443 c = col;
6444 needsResize = 0;
6445 done = 0;
6446 n = 0;
6447 while (!done)
6449 if (!(*c2) || *c2 == delimiter || *c2 == '\n')
6451 len = c2 - c1;
6452 if (len < 256)
6453 bufp = buf;
6454 else
6455 bufp = (char *)malloc(len + 1);
6456 if (format == XmFORMAT_XL)
6458 /* strip leading and trailing double-quotes */
6459 if (len && c1[0] == '"')
6461 c1++;
6462 len--;
6464 if (len && c1[len - 1] == '"')
6465 len--;
6467 j = 0;
6468 for (i = 0; i < len; i++)
6470 if (c1[0] == '\\' && c1[1] == 'n')
6472 bufp[j++] = '\n';
6473 c1 += 2;
6474 i++;
6476 else
6477 bufp[j++] = *c1++;
6479 bufp[j] = 0;
6480 j = 0;
6481 str = XmStringCreateLtoR(bufp, XmSTRING_DEFAULT_CHARSET);
6482 if (bufp != buf)
6483 free((char *)bufp);
6484 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6485 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6486 cell = GetCell(g, r, c);
6487 allowSet = 1;
6488 if (cell && (format == XmFORMAT_PASTE || format == XmFORMAT_DROP))
6490 cellValues = XmLGridCellGetRefValues(cell);
6491 if (cellValues->type != XmSTRING_CELL ||
6492 cellValues->editable != True ||
6493 RowPosToType(g, r) != XmCONTENT ||
6494 ColPosToType(g, c) != XmCONTENT)
6495 allowSet = 0;
6497 if (cell && allowSet)
6499 XmLGridCellSetString(cell, str, False);
6500 if (SetCellValuesResize(g, rowp, colp, cell, XmLGridCellString))
6501 needsResize = 1;
6502 if (!needsResize)
6503 DrawArea(g, DrawCell, r, c);
6504 cbs.columnType = ColPosToType(g, c);
6505 cbs.column = ColPosToTypePos(g, cbs.columnType, c);
6506 cbs.rowType = RowPosToType(g, r);
6507 cbs.row = RowPosToTypePos(g, cbs.rowType, r);
6508 if (format == XmFORMAT_PASTE)
6510 cbs.reason = XmCR_CELL_PASTE;
6511 XtCallCallbackList((Widget)g, g->grid.cellPasteCallback,
6512 (XtPointer)&cbs);
6514 else if (format == XmFORMAT_DROP)
6516 cbs.reason = XmCR_CELL_DROP;
6517 XtCallCallbackList((Widget)g, g->grid.cellDropCallback,
6518 (XtPointer)&cbs);
6520 n++;
6522 else
6523 XmStringFree(str);
6525 if (!(*c2))
6526 done = 1;
6527 else if (*c2 == delimiter)
6529 c++;
6530 c1 = c2 + 1;
6532 else if (*c2 == '\n')
6534 r++;
6535 c = col;
6536 c1 = c2 + 1;
6538 c2++;
6540 if (needsResize)
6542 VertLayout(g, 1);
6543 HorizLayout(g, 1);
6544 DrawArea(g, DrawAll, 0, 0);
6546 return n;
6549 static void
6550 Write(XmLGridWidget g,
6551 FILE *file,
6552 int format,
6553 char delimiter,
6554 Boolean skipHidden,
6555 int row,
6556 int col,
6557 int nrow,
6558 int ncol)
6560 int r, c, i, first, last;
6561 char *cs = NULL;
6562 Boolean set;
6563 XmString str;
6564 XmLGridColumn colp;
6565 XmLGridRow rowp;
6566 XmLGridCell cell;
6568 first = 1;
6569 for (r = row; r < row + nrow; r++)
6571 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6572 if (!rowp)
6573 continue;
6574 if (skipHidden == True && XmLGridRowIsHidden(rowp) == True)
6575 continue;
6576 if (first)
6577 first = 0;
6578 else
6579 fprintf(file, "\n");
6580 for (c = col; c < col + ncol; c++)
6582 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6583 if (!colp)
6584 continue;
6585 if (skipHidden == True && XmLGridColumnIsHidden(colp) == True)
6586 continue;
6587 cell = GetCell(g, r, c);
6588 if (!cell)
6589 continue;
6590 str = XmLGridCellGetString(cell);
6591 set = False;
6592 if (str)
6594 cs = CvtXmStringToStr(str);
6595 if (cs)
6596 set = True;
6598 if (set == False)
6599 cs = "";
6600 fprintf(file, "%s", cs);
6602 last = 0;
6603 if (c == col + ncol - 1)
6604 last = 1;
6605 if (!last && format == XmFORMAT_DELIMITED)
6606 fprintf(file, "%c", delimiter);
6607 else if (!last && format == XmFORMAT_XL)
6608 fprintf(file, "\t");
6609 else if (format == XmFORMAT_PAD)
6611 if (colp->grid.sizePolicy == XmVARIABLE)
6612 for (i = 0; i < (int)(colp->grid.width - strlen(cs)); i++)
6613 fprintf(file, " ");
6616 if (set == True)
6617 free(cs);
6622 static char *
6623 CopyDataCreate(XmLGridWidget g, int selected, int row, int col, int nrow, int ncol)
6625 XmLGridColumn colp;
6626 XmLGridRow rowp;
6627 XmLGridCell cell;
6628 char *buf, *cs = NULL;
6629 XmString str;
6630 Boolean set;
6631 int r, c, wroteStr, bufsize, buflen, len;
6633 if (selected)
6635 row = 0;
6636 nrow = XmLArrayGetCount(g->grid.rowArray);
6637 col = 0;
6638 ncol = XmLArrayGetCount(g->grid.colArray);
6640 bufsize = 1024;
6641 buflen = 0;
6642 buf = (char *)malloc(bufsize);
6644 for (r = row; r < row + nrow; r++)
6646 wroteStr = 0;
6647 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
6648 if (!rowp)
6649 continue;
6650 for (c = col; c < col + ncol; c++)
6652 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
6653 if (!colp)
6654 continue;
6655 cell = GetCell(g, r, c);
6656 if (!cell)
6657 continue;
6658 if (selected &&
6659 XmLGridRowIsSelected(rowp) == False &&
6660 XmLGridColumnIsSelected(colp) == False &&
6661 XmLGridCellIsSelected(cell) == False)
6662 continue;
6663 str = XmLGridCellGetString(cell);
6664 set = False;
6665 if (str)
6667 cs = CvtXmStringToStr(str);
6668 if (cs)
6669 set = True;
6671 if (set == False)
6672 cs = "";
6673 if (wroteStr)
6674 buf[buflen++] = '\t';
6676 len = strlen(cs);
6677 /* allocate if string plus tab plus new-line plus 0 if too large */
6678 while (len + buflen + 3 > bufsize)
6679 bufsize *= 2;
6680 buf = (char *)realloc(buf, bufsize);
6681 strcpy(&buf[buflen], cs);
6682 buflen += len;
6683 if (set == True)
6684 free(cs);
6685 wroteStr = 1;
6687 if (wroteStr)
6688 buf[buflen++] = '\n';
6690 if (!buflen)
6692 free((char *)buf);
6693 return 0;
6695 buf[buflen - 1] = 0;
6696 return buf;
6699 static Boolean
6700 Copy(XmLGridWidget g,
6701 Time time,
6702 int selected,
6703 int row,
6704 int col,
6705 int nrow,
6706 int ncol)
6708 int i;
6709 long itemID;
6710 Display *dpy;
6711 Window win;
6712 XmString clipStr;
6713 char *buf;
6714 #ifdef MOTIF11
6715 int dataID;
6716 #else
6717 long ldataID;
6718 #endif
6720 if (!XtIsRealized((Widget)g))
6722 XmLWarning((Widget)g, "Copy() - widget not realized");
6723 return False;
6725 dpy = XtDisplay((Widget)g);
6726 win = XtWindow((Widget)g);
6727 buf = CopyDataCreate(g, selected, row, col, nrow, ncol);
6728 if (!buf)
6729 return False;
6730 clipStr = XmStringCreateSimple("Grid Copy");
6731 for (i = 0; i < 10000; i++)
6732 if (XmClipboardStartCopy(dpy, win, clipStr, time, NULL,
6733 NULL, &itemID) == ClipboardSuccess)
6734 break;
6735 XmStringFree(clipStr);
6736 if (i == 10000)
6738 XmLWarning((Widget)g, "Copy() - start clipboard copy failed");
6739 return False;
6741 for (i = 0; i < 10000; i++)
6742 #ifdef MOTIF11
6743 if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
6744 (long)strlen(buf) + 1, 0, &dataID) == ClipboardSuccess)
6745 #else
6746 if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
6747 (long)strlen(buf) + 1, 0, &ldataID) == ClipboardSuccess)
6748 #endif
6749 break;
6750 free((char *)buf);
6751 if (i == 10000)
6753 XmLWarning((Widget)g, "Copy() - clipboard copy transfer failed");
6754 return False;
6756 for (i = 0; i < 10000; i++)
6757 if (XmClipboardEndCopy(dpy, win, itemID) == ClipboardSuccess)
6758 break;
6759 if (i == 10000)
6761 XmLWarning((Widget)g, "Copy() - end clipboard copy failed");
6762 return False;
6764 return True;
6767 static Boolean
6768 Paste(XmLGridWidget g,
6769 int row,
6770 int col)
6772 Display *dpy;
6773 Window win;
6774 int i, res, done;
6775 unsigned long len, reclen;
6776 char *buf;
6778 if (!XtIsRealized((Widget)g))
6780 XmLWarning((Widget)g, "Paste() - widget not realized");
6781 return False;
6783 dpy = XtDisplay((Widget)g);
6784 win = XtWindow((Widget)g);
6785 for (i = 0; i < 10000; i++)
6786 if (XmClipboardInquireLength(dpy, win, "STRING", &len) ==
6787 ClipboardSuccess)
6788 break;
6789 if (i == 10000)
6791 XmLWarning((Widget)g, "Paste() - can't retrieve clipboard length");
6792 return False;
6794 if (!len)
6795 return False;
6796 buf = (char *)malloc((int)len);
6797 done = 0;
6798 while (!done)
6800 res = XmClipboardRetrieve(dpy, win, "STRING", buf, len,
6801 &reclen, NULL);
6802 switch (res)
6804 case ClipboardSuccess:
6805 done = 2;
6806 break;
6807 case ClipboardTruncate:
6808 case ClipboardNoData:
6809 done = 1;
6810 break;
6811 case ClipboardLocked:
6812 break;
6815 if (done != 2 || reclen != len)
6817 free((char *)buf);
6818 XmLWarning((Widget)g, "Paste() - retrieve from clipboard failed");
6819 return False;
6821 Read(g, XmFORMAT_PASTE, 0, row, col, buf);
6822 free((char *)buf);
6823 return True;
6827 Utility
6830 static void
6831 GetCoreBackground(Widget w,
6832 int offset,
6833 XrmValue *value)
6835 value->addr = (caddr_t)&w->core.background_pixel;
6838 static void
6839 GetManagerForeground(Widget w,
6840 int offset,
6841 XrmValue *value)
6843 XmLGridWidget g;
6845 g = (XmLGridWidget)w;
6846 value->addr = (caddr_t)&g->manager.foreground;
6849 static void
6850 ClipRectToReg(XmLGridWidget g,
6851 XRectangle *rect,
6852 GridReg *reg)
6854 int i, st;
6855 XRectangle regRect;
6857 st = g->manager.shadow_thickness;
6858 if (!reg->width || !reg->height)
6859 i = XmLRectOutside;
6860 else
6862 regRect.x = reg->x + st;
6863 regRect.y = reg->y + st;
6864 regRect.width = reg->width - st * 2;
6865 regRect.height = reg->height - st * 2;
6866 i = XmLRectIntersect(rect, &regRect);
6868 if (i == XmLRectInside)
6869 return;
6870 if (i == XmLRectOutside)
6872 rect->width = 0;
6873 rect->height = 0;
6874 return;
6876 if (rect->y + (int)rect->height - 1 >= reg->y + (int)reg->height - st)
6877 rect->height = reg->y + reg->height - rect->y - st;
6878 if (rect->x + (int)rect->width - 1 >= reg->x + (int)reg->width - st)
6879 rect->width = reg->x + reg->width - rect->x - st;
6880 if (rect->y < reg->y + st)
6882 rect->height -= (reg->y + st) - rect->y;
6883 rect->y = reg->y + st;
6885 if (rect->x < reg->x + st)
6887 rect->width -= (reg->x + st) - rect->x;
6888 rect->x = reg->x + st;
6892 static char *
6893 FileToString(FILE *file)
6895 long len, n;
6896 char *s;
6898 if (!file)
6899 return 0;
6900 fseek(file, 0L, 2);
6901 len = ftell(file);
6902 s = (char *)malloc((int)len + 1);
6903 if (!s)
6904 return 0;
6905 s[len] = 0;
6906 fseek(file, 0L, 0);
6907 n = fread(s, 1, (int)len, file);
6908 if (n != len)
6910 free((char *)s);
6911 return 0;
6913 return s;
6916 static char *
6917 CvtXmStringToStr(XmString str)
6919 XmStringContext context;
6920 XmStringCharSet charset;
6921 XmStringDirection dir;
6922 Boolean sep;
6923 char *text, *c;
6924 int len, size;
6926 if (!XmStringInitContext(&context, str))
6927 return 0;
6928 size = 0;
6929 c = 0;
6930 while (XmStringGetNextSegment(context, &text, &charset, &dir, &sep))
6932 len = strlen(text);
6933 size += len + 3;
6934 if (!c)
6936 c = (char *)malloc(size);
6937 *c = 0;
6939 else
6940 c = (char *)realloc(c, size);
6941 strcat(c, text);
6942 if (sep == True)
6944 len = strlen(c);
6945 c[len] = '\\';
6946 c[len + 1] = 'n';
6947 c[len + 2] = 0;
6949 XtFree(text);
6950 XtFree(charset);
6952 XmStringFreeContext(context);
6953 return c;
6956 static XmLGridWidget
6957 WidgetToGrid(Widget w,
6958 char *funcname)
6960 char buf[256];
6962 if (!XmLIsGrid(w))
6964 sprintf(buf, "%s - widget not an XmLGrid", funcname);
6965 XmLWarning(w, buf);
6966 return 0;
6968 return (XmLGridWidget)w;
6972 Actions, Callbacks and Handlers
6975 static void
6976 ButtonMotion(Widget w,
6977 XEvent *event,
6978 String *params,
6979 Cardinal *nparam)
6981 XmLGridWidget g;
6982 XMotionEvent *me;
6983 char dragTimerSet;
6984 int row, col, x, y;
6986 if (event->type != MotionNotify)
6987 return;
6988 g = (XmLGridWidget)w;
6989 me = (XMotionEvent *)event;
6990 if (g->grid.inMode == InResize)
6992 if (g->grid.resizeIsVert)
6993 DrawResizeLine(g, me->y, 0);
6994 else
6996 DrawResizeLine(g, me->x, 0);
6997 if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
6998 ResizeColumnToFit(g, me->x);
7002 /* drag scrolling */
7003 dragTimerSet = 0;
7004 if (g->grid.inMode == InSelect)
7006 if (g->grid.vsPolicy == XmCONSTANT)
7008 y = g->grid.reg[4].y;
7009 if (g->grid.selectionPolicy == XmSELECT_CELL &&
7010 g->grid.extendRow != -1 &&
7011 g->grid.extendCol != -1 &&
7012 RowPosToType(g, g->grid.extendRow) == XmHEADING)
7014 else if (me->y < y)
7015 dragTimerSet |= DragUp;
7016 y += g->grid.reg[4].height;
7017 if (me->y > y)
7018 dragTimerSet |= DragDown;
7020 if (g->grid.hsPolicy == XmCONSTANT)
7022 x = g->grid.reg[4].x;
7023 if (g->grid.selectionPolicy == XmSELECT_CELL &&
7024 g->grid.extendCol != -1 &&
7025 g->grid.extendRow != -1 &&
7026 ColPosToType(g, g->grid.extendCol) == XmHEADING)
7028 else if (me->x < x)
7029 dragTimerSet |= DragLeft;
7030 x += g->grid.reg[4].width;
7031 if (me->x > x)
7032 dragTimerSet |= DragRight;
7035 if (!g->grid.dragTimerSet && dragTimerSet)
7036 g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7037 80, DragTimer, (caddr_t)g);
7038 else if (g->grid.dragTimerSet && !dragTimerSet)
7039 XtRemoveTimeOut(g->grid.dragTimerId);
7040 g->grid.dragTimerSet = dragTimerSet;
7042 /* Extend Selection */
7043 if (g->grid.inMode == InSelect && XYToRowCol(g, me->x, me->y,
7044 &row, &col) != -1)
7046 TextAction(g, TEXT_EDIT_CANCEL);
7047 if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7048 RowPosToType(g, row) == XmCONTENT)
7049 ExtendSelect(g, event, False, row, col);
7050 else if (g->grid.selectionPolicy == XmSELECT_CELL)
7051 ExtendSelect(g, event, False, row, col);
7054 if (g->grid.inMode == InSelect &&
7055 g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7056 XYToRowCol(g, me->x, me->y, &row, &col) != -1)
7058 if (RowPosToType(g, row) == XmCONTENT)
7060 if (!SetFocus(g, row, col, 0, 1))
7061 SelectTypeArea(g, SelectRow, event,
7062 RowPosToTypePos(g, XmCONTENT,
7063 g->grid.focusRow), 0, True, True);
7068 static void
7069 DragTimer(XtPointer clientData,
7070 XtIntervalId *intervalId)
7072 Widget w;
7073 XmLGridWidget g;
7074 XRectangle rect;
7075 XmLGridRow rowp;
7076 XmLGridColumn colp;
7077 int r, c, min, max, inc, pi, ss, value, newValue;
7078 int extRow, extCol;
7080 g = (XmLGridWidget)clientData;
7081 w = (Widget)g;
7082 extRow = -1;
7083 extCol = -1;
7084 if (g->grid.vsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragUp) ||
7085 (g->grid.dragTimerSet & DragDown)))
7087 XtVaGetValues(g->grid.vsb,
7088 XmNminimum, &min,
7089 XmNmaximum, &max,
7090 XmNvalue, &value,
7091 XmNsliderSize, &ss,
7092 XmNincrement, &inc,
7093 XmNpageIncrement, &pi,
7094 NULL);
7095 newValue = value;
7096 if (g->grid.dragTimerSet & DragUp)
7097 newValue--;
7098 else
7099 newValue++;
7100 if (newValue != value && newValue >= min && newValue <= (max - ss))
7102 XmScrollBarSetValues(g->grid.vsb, newValue, ss, inc, pi, True);
7103 r = g->grid.reg[4].row;
7104 if (g->grid.dragTimerSet & DragDown)
7105 r += g->grid.reg[4].nrow - 1;
7106 /* simple check to make sure row selected is totally visible */
7107 if (g->grid.reg[4].nrow)
7109 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
7110 if (rowp && !RowColToXY(g, r, 0, True, &rect))
7112 if (GetRowHeight(g, r) != rect.height)
7113 r--;
7116 if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
7118 if (!SetFocus(g, r, g->grid.focusCol, -1, 1))
7119 SelectTypeArea(g, SelectRow, (XEvent *)0,
7120 RowPosToTypePos(g, XmCONTENT, g->grid.focusRow),
7121 0, True, True);
7123 else if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW)
7124 ExtendSelect(g, (XEvent *)0, False, r, g->grid.focusCol);
7125 else if (g->grid.selectionPolicy == XmSELECT_CELL)
7127 extRow = r;
7128 extCol = g->grid.extendToCol;
7132 if (g->grid.hsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragLeft) ||
7133 (g->grid.dragTimerSet & DragRight)))
7135 XtVaGetValues(g->grid.hsb,
7136 XmNminimum, &min,
7137 XmNmaximum, &max,
7138 XmNvalue, &value,
7139 XmNsliderSize, &ss,
7140 XmNincrement, &inc,
7141 XmNpageIncrement, &pi,
7142 NULL);
7143 newValue = value;
7144 if (g->grid.dragTimerSet & DragLeft)
7145 newValue--;
7146 else
7147 newValue++;
7148 if (newValue != value && newValue >= min && newValue <= (max - ss))
7150 XmScrollBarSetValues(g->grid.hsb, newValue, ss, inc, pi, True);
7151 c = g->grid.reg[4].col;
7152 if (g->grid.dragTimerSet & DragRight)
7153 c += g->grid.reg[4].ncol - 1;
7154 if (g->grid.selectionPolicy == XmSELECT_CELL)
7156 /* simple check to make sure col selected is totally visible */
7157 if (g->grid.reg[4].ncol)
7159 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
7160 if (colp && !RowColToXY(g, c, 0, True, &rect))
7162 if (GetColWidth(g, c) != rect.width)
7163 c--;
7166 if (extRow == -1)
7167 extRow = g->grid.extendToRow;
7168 extCol = c;
7172 if (extRow != -1 && extCol != -1)
7173 ExtendSelect(g, (XEvent *)0, False, extRow, extCol);
7174 g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7175 80, DragTimer, (caddr_t)g);
7178 /*----------------------------------------------------------------------*/
7179 static void
7180 CursorMotion(Widget w,
7181 XEvent *event,
7182 String *params,
7183 Cardinal *nparam)
7185 XmLGridWidget g;
7186 XMotionEvent *me;
7187 int isVert, row, col;
7188 char defineCursor;
7190 if (event->type != MotionNotify)
7191 return;
7192 g = (XmLGridWidget)w;
7193 me = (XMotionEvent *)event;
7194 defineCursor = CursorNormal;
7197 int motionRow;
7198 int motionCol;
7199 int newMotionRow = -1;
7200 int newMotionCol = -1;
7201 Boolean invokeEnterCellCallback = False;
7203 if (XYToRowCol(g,me->x,me->y,&motionRow,&motionCol) != -1)
7205 if (motionRow != g->grid.lastCursorMotionRow ||
7206 motionCol != g->grid.lastCursorMotionCol)
7208 newMotionRow = motionRow;
7209 newMotionCol = motionCol;
7211 invokeEnterCellCallback = True;
7215 if (g->grid.lastCursorMotionRow != -1 &&
7216 g->grid.lastCursorMotionCol != -1)
7218 /* Invoke XmNleaveCellCallback */
7219 GridInvokeCellCrossingCallbacks(w,
7220 g->grid.leaveCellCallback,
7221 XmCR_LEAVE_CELL,
7222 event,
7223 g->grid.lastCursorMotionRow,
7224 g->grid.lastCursorMotionCol);
7227 if (invokeEnterCellCallback)
7229 /* Invoke XmNenterCellCallback */
7230 GridInvokeCellCrossingCallbacks(w,
7231 g->grid.enterCellCallback,
7232 XmCR_ENTER_CELL,
7233 event,
7234 newMotionRow,
7235 newMotionCol);
7238 g->grid.lastCursorMotionRow = newMotionRow;
7239 g->grid.lastCursorMotionCol = newMotionCol;
7242 if (PosIsResize(g, me->x, me->y, &row, &col, &isVert))
7244 if (isVert)
7245 defineCursor = CursorVResize;
7246 else
7247 defineCursor = CursorHResize;
7250 DefineCursor(g, defineCursor);
7252 /*----------------------------------------------------------------------*/
7253 static void
7254 Edit(Widget w,
7255 XEvent *event,
7256 String *params,
7257 Cardinal *nparam)
7259 XmLGridWidget g;
7261 g = (XmLGridWidget)XtParent(w);
7262 TextAction(g, TEXT_EDIT_INSERT);
7265 static void
7266 EditCancel(Widget w,
7267 XEvent *event,
7268 String *params,
7269 Cardinal *nparam)
7271 XmLGridWidget g;
7273 g = (XmLGridWidget)XtParent(w);
7274 TextAction(g, TEXT_EDIT_CANCEL);
7277 static void
7278 EditComplete(Widget w,
7279 XEvent *event,
7280 String *params,
7281 Cardinal *nparam)
7283 XmLGridWidget g;
7285 g = (XmLGridWidget)XtParent(w);
7286 TextAction(g, TEXT_EDIT_COMPLETE);
7287 if (*nparam == 1)
7288 Traverse(w, event, params, nparam);
7291 #ifndef MOTIF11
7292 extern Widget _XmGetTextualDragIcon(Widget);
7293 #endif
7295 static void
7296 DragStart(Widget w,
7297 XEvent *event,
7298 String *params,
7299 Cardinal *nparam)
7301 #ifndef MOTIF11
7302 XmLGridWidget g;
7303 Widget dragIcon;
7304 Atom exportTargets[1];
7305 Arg args[10];
7306 char *data;
7307 XButtonEvent *be;
7308 int row, col;
7309 XmLGridColumn colp;
7310 XmLGridRow rowp;
7311 XmLGridCell cell;
7312 static XtCallbackRec dragFinish[2] =
7313 { { DragFinish, NULL }, { NULL, NULL } };
7315 g = (XmLGridWidget)w;
7316 be = (XButtonEvent *)event;
7317 if (!g->grid.allowDrag || !be)
7318 return;
7319 if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7320 return;
7321 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7322 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
7323 cell = GetCell(g, row, col);
7324 if (!rowp || !colp || !cell)
7325 return;
7326 if (XmLGridRowIsSelected(rowp) == False &&
7327 XmLGridColumnIsSelected(colp) == False &&
7328 XmLGridCellIsSelected(cell) == False)
7329 return;
7330 data = CopyDataCreate(g, 1, 0, 0, 0, 0);
7331 if (!data)
7332 return;
7333 dragIcon = _XmGetTextualDragIcon((Widget)w);
7334 exportTargets[0] = XA_STRING;
7335 dragFinish[0].closure = (XtPointer)data;
7336 XtSetArg(args[0], XmNconvertProc, DragConvert);
7337 XtSetArg(args[1], XmNexportTargets, exportTargets);
7338 XtSetArg(args[2], XmNnumExportTargets, 1);
7339 XtSetArg(args[3], XmNdragOperations, XmDROP_COPY);
7340 XtSetArg(args[4], XmNsourceCursorIcon, dragIcon);
7341 XtSetArg(args[4], XmNclientData, (XtPointer)data);
7342 XtSetArg(args[5], XmNdragDropFinishCallback, dragFinish);
7343 XmDragStart(w, event, args, 6);
7344 #endif
7347 static Boolean
7348 DragConvert(Widget w,
7349 Atom *selection,
7350 Atom *target,
7351 Atom *type,
7352 XtPointer *value,
7353 unsigned long *length,
7354 int *format)
7356 #ifdef MOTIF11
7357 return FALSE;
7358 #else
7359 Atom targetsA, timestampA, multipleA, *exportTargets;
7360 int n;
7361 char *data, *dataCopy;
7363 if (!XmIsDragContext(w))
7364 return FALSE;
7365 targetsA = XInternAtom(XtDisplay(w), "TARGETS", FALSE);
7366 timestampA = XInternAtom(XtDisplay(w), "TIMESTAMP", FALSE);
7367 multipleA = XInternAtom(XtDisplay(w), "MULTIPLE", FALSE);
7368 if (*target == targetsA)
7370 n = 4;
7371 exportTargets = (Atom *)XtMalloc(sizeof(Atom) * n);
7372 exportTargets[0] = XA_STRING;
7373 exportTargets[1] = targetsA;
7374 exportTargets[2] = multipleA;
7375 exportTargets[3] = timestampA;
7376 *type = XA_ATOM;
7377 *value = (XtPointer)exportTargets;
7378 *format = 32;
7379 *length = (n * sizeof(Atom)) >> 2;
7380 return TRUE;
7382 else if (*target == XA_STRING)
7384 XtVaGetValues(w, XmNclientData, &data, NULL);
7385 *type = XA_STRING;
7386 dataCopy = XtMalloc(strlen(data));
7387 strncpy(dataCopy, data, strlen(data));
7388 *value = (XtPointer)dataCopy;
7389 *length = strlen(data);
7390 *format = 8;
7391 return TRUE;
7393 return FALSE;
7394 #endif
7397 static void
7398 DragFinish(Widget w,
7399 XtPointer clientData,
7400 XtPointer callData)
7402 free ((char *)clientData);
7405 static void
7406 DropRegister(XmLGridWidget g, Boolean set)
7408 #ifndef MOTIF11
7409 Atom importTargets[1];
7410 Arg args[4];
7412 if (set == True)
7414 importTargets[0] = XA_STRING;
7415 XtSetArg(args[0], XmNdropSiteOperations, XmDROP_COPY);
7416 XtSetArg(args[1], XmNimportTargets, importTargets);
7417 XtSetArg(args[2], XmNnumImportTargets, 1);
7418 XtSetArg(args[3], XmNdropProc, DropStart);
7419 XmDropSiteRegister((Widget)g, args, 4);
7421 else
7422 XmDropSiteUnregister((Widget)g);
7423 #endif
7426 static void
7427 DropStart(Widget w,
7428 XtPointer clientData,
7429 XtPointer callData)
7431 #ifndef MOTIF11
7432 XmLGridWidget g;
7433 XmDropProcCallbackStruct *cbs;
7434 XmDropTransferEntryRec te[2];
7435 Atom *exportTargets;
7436 Arg args[10];
7437 int row, col, i, n, valid;
7439 g = (XmLGridWidget)w;
7440 cbs = (XmDropProcCallbackStruct *)callData;
7441 if (g->grid.allowDrop == False || cbs->dropAction == XmDROP_HELP)
7443 cbs->dropSiteStatus = XmINVALID_DROP_SITE;
7444 return;
7446 valid = 0;
7447 if (XYToRowCol(g, cbs->x, cbs->y, &row, &col) != -1 &&
7448 cbs->dropAction == XmDROP && cbs->operation == XmDROP_COPY)
7450 XtVaGetValues(cbs->dragContext,
7451 XmNexportTargets, &exportTargets,
7452 XmNnumExportTargets, &n,
7453 NULL);
7454 for (i = 0; i < n; i++)
7455 if (exportTargets[i] == XA_STRING)
7456 valid = 1;
7458 if (!valid)
7460 cbs->operation = (long)XmDROP_NOOP;
7461 cbs->dropSiteStatus = XmINVALID_DROP_SITE;
7462 XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
7463 XtSetArg(args[1], XmNnumDropTransfers, 0);
7464 XmDropTransferStart(cbs->dragContext, args, 2);
7465 return;
7467 g->grid.dropLoc.row = row;
7468 g->grid.dropLoc.col = col;
7469 cbs->operation = (long)XmDROP_COPY;
7470 te[0].target = XA_STRING;
7471 te[0].client_data = (XtPointer)g;
7472 XtSetArg(args[0], XmNdropTransfers, te);
7473 XtSetArg(args[1], XmNnumDropTransfers, 1);
7474 XtSetArg(args[2], XmNtransferProc, DropTransfer);
7475 XmDropTransferStart(cbs->dragContext, args, 3);
7476 #endif
7479 static void
7480 DropTransfer(Widget w,
7481 XtPointer clientData,
7482 Atom *selType,
7483 Atom *type,
7484 XtPointer value,
7485 unsigned long *length,
7486 int *format)
7488 #ifndef MOTIF11
7489 XmLGridWidget g;
7490 char *buf;
7491 int len;
7493 if (!value)
7494 return;
7495 g = (XmLGridWidget)clientData;
7496 len = (int)*length;
7497 if (len < 0)
7498 return;
7499 buf = (char *)malloc(len + 1);
7500 strncpy(buf, (char *)value, len);
7501 XtFree((char *)value);
7502 buf[len] = 0;
7503 Read(g, XmFORMAT_DROP, 0, g->grid.dropLoc.row, g->grid.dropLoc.col, buf);
7504 free((char *)buf);
7505 #endif
7508 static void
7509 Select(Widget w,
7510 XEvent *event,
7511 String *params,
7512 Cardinal *nparam)
7514 XmLGridWidget g;
7515 Display *dpy;
7516 Window win;
7517 static XrmQuark qACTIVATE, qBEGIN, qEXTEND, qEND;
7518 static XrmQuark qTOGGLE;
7519 static int quarksValid = 0;
7520 XrmQuark q;
7521 int isVert;
7522 int row, col, resizeRow, resizeCol;
7523 XButtonEvent *be;
7524 XRectangle rect;
7525 XmLGridRow rowp;
7526 XmLGridCell cellp;
7527 XmLGridColumn colp;
7528 XmLGridCallbackStruct cbs;
7529 Boolean flag;
7531 if (*nparam != 1)
7532 return;
7534 if (XmLIsGrid(w))
7535 g = (XmLGridWidget)w;
7536 else
7537 g = (XmLGridWidget)XtParent(w);
7538 dpy = XtDisplay(g);
7539 win = XtWindow(g);
7540 if (!quarksValid)
7542 qACTIVATE = XrmStringToQuark("ACTIVATE");
7543 qBEGIN = XrmStringToQuark("BEGIN");
7544 qEXTEND = XrmStringToQuark("EXTEND");
7545 qEND = XrmStringToQuark("END");
7546 qTOGGLE = XrmStringToQuark("TOGGLE");
7548 q = XrmStringToQuark(params[0]);
7549 be = 0;
7550 if (event->type == KeyPress || event->type == KeyRelease)
7552 row = g->grid.focusRow;
7553 col = g->grid.focusCol;
7555 else /* Button */
7557 be = (XButtonEvent *)event;
7558 if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7560 row = -1;
7561 col = -1;
7565 /* double click activate check */
7566 if (q == qBEGIN && be)
7568 if (row != -1 && col != -1
7569 && row == g->grid.focusRow && col == g->grid.focusCol
7572 int doubleClickTime = XtGetMultiClickTime(dpy);
7573 Time timeSinceLastClick = be->time - g->grid.lastSelectTime;
7574 if (timeSinceLastClick < doubleClickTime)
7576 /* Clear inplace editing if some other event happens */
7577 if (g->grid.editTimerSet)
7579 XtRemoveTimeOut(g->grid.editTimerId);
7580 g->grid.editTimerSet = 0;
7583 /* Second click came within double click time */
7584 q = qACTIVATE;
7586 else if (!g->grid.editTimerSet && g->grid.lastSelectTime != 0)
7588 /* Only begin an edit when we are sure we don't
7589 * have a double click
7591 if (!g->grid.singleClickActivation) {
7592 g->grid.editTimerId =
7593 XtAppAddTimeOut(XtWidgetToApplicationContext(w),
7594 doubleClickTime*2, EditTimer, (caddr_t)g);
7595 g->grid.editTimerSet = 1;
7599 g->grid.lastSelectRow = row;
7600 g->grid.lastSelectCol = col;
7601 g->grid.lastSelectTime = be->time;
7603 else if (q == qBEGIN)
7604 g->grid.lastSelectTime = 0;
7606 if (q == qBEGIN && be && PosIsResize(g, be->x, be->y,
7607 &resizeRow, &resizeCol, &isVert))
7609 g->grid.resizeIsVert = isVert;
7610 g->grid.inMode = InResize;
7611 g->grid.resizeLineXY = -1;
7612 g->grid.resizeRow = resizeRow;
7613 g->grid.resizeCol = resizeCol;
7614 if (isVert)
7616 DrawResizeLine(g, be->y, 0);
7617 DefineCursor(g, CursorVResize);
7619 else
7621 DrawResizeLine(g, be->x, 0);
7622 DefineCursor(g, CursorHResize);
7625 else if (q == qBEGIN || q == qEXTEND || q == qTOGGLE)
7627 if (g->grid.inMode != InNormal)
7628 return;
7629 if (row == -1 || col == -1)
7630 return;
7631 if (RowPosToType(g, row) == XmCONTENT &&
7632 ColPosToType(g, col) == XmCONTENT)
7634 TextAction(g, TEXT_EDIT_COMPLETE);
7635 if (q != qEXTEND)
7637 SetFocus(g, row, col, 0, 1);
7638 ExtendSelect(g, event, False, -1, -1);
7640 XmProcessTraversal(g->grid.text, XmTRAVERSE_CURRENT);
7642 if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7643 RowPosToType(g, row) == XmCONTENT)
7645 flag = True;
7646 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7647 #if 0
7648 /* Don't want single click to unselect something. -slamm */
7649 if (q == qBEGIN && rowp && XmLGridRowIsSelected(rowp) == True)
7650 flag = False;
7651 #endif /* 0 -slamm */
7652 if (q == qTOGGLE && rowp && XmLGridRowIsSelected(rowp) == True)
7653 flag = False;
7654 if (q == qBEGIN)
7655 SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
7656 if (be && q == qEXTEND)
7657 ExtendSelect(g, event, False, row, col);
7658 else
7659 SelectTypeArea(g, SelectRow, event,
7660 RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
7662 if (g->grid.selectionPolicy == XmSELECT_CELL)
7664 if (q == qBEGIN)
7666 SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
7667 SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
7668 SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
7670 else if (q == qTOGGLE)
7671 ExtendSelect(g, event, False, -1, -1);
7672 if (RowPosToType(g, row) == XmFOOTER ||
7673 ColPosToType(g, col) == XmFOOTER)
7674 ExtendSelect(g, event, False, -1, -1);
7675 if (be && q == qEXTEND)
7676 ExtendSelect(g, event, False, row, col);
7677 else if (RowPosToType(g, row) == XmCONTENT &&
7678 ColPosToType(g, col) == XmCONTENT)
7680 flag = True;
7681 cellp = GetCell(g, row, col);
7682 if (q == qTOGGLE && cellp &&
7683 XmLGridCellIsSelected(cellp) == True)
7684 flag = False;
7685 SelectTypeArea(g, SelectCell, event,
7686 RowPosToTypePos(g, XmCONTENT, row),
7687 ColPosToTypePos(g, XmCONTENT, col), flag, True);
7689 else if (RowPosToType(g, row) == XmHEADING &&
7690 ColPosToType(g, col) == XmCONTENT)
7692 if (q == qTOGGLE)
7694 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
7695 if (colp && XmLGridColumnIsSelected(colp) == True)
7696 g->grid.extendSelect = False;
7698 ExtendSelect(g, event, True, row, col);
7700 else if (ColPosToType(g, col) == XmHEADING &&
7701 RowPosToType(g, row) == XmCONTENT)
7703 if (q == qTOGGLE)
7705 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7706 if (rowp && XmLGridRowIsSelected(rowp) == True)
7707 g->grid.extendSelect = False;
7709 ExtendSelect(g, event, True, row, col);
7712 if (g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
7713 RowPosToType(g, row) == XmCONTENT)
7715 flag = True;
7716 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7717 if (rowp && XmLGridRowIsSelected(rowp) == True)
7718 flag = False;
7719 SelectTypeArea(g, SelectRow, event,
7720 RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
7722 if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7723 RowPosToType(g, row) == XmCONTENT)
7724 SelectTypeArea(g, SelectRow, event,
7725 RowPosToTypePos(g, XmCONTENT, row), 0, True, True);
7726 if (g->grid.selectionPolicy == XmSELECT_NONE ||
7727 (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
7728 RowPosToType(g, row) != XmCONTENT) ||
7729 (g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
7730 RowPosToType(g, row) != XmCONTENT) ||
7731 (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
7732 RowPosToType(g, row) != XmCONTENT) )
7734 cbs.reason = XmCR_SELECT_CELL;
7735 cbs.event = event;
7736 cbs.columnType = ColPosToType(g, col);
7737 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7738 cbs.rowType = RowPosToType(g, row);
7739 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7740 XtCallCallbackList((Widget)g, g->grid.selectCallback,
7741 (XtPointer)&cbs);
7743 g->grid.inMode = InSelect;
7745 else if (q == qEND && g->grid.inMode == InResize)
7747 int r, c, width, height;
7748 r = g->grid.resizeRow;
7749 c = g->grid.resizeCol;
7750 g->grid.resizeRow = -1;
7751 g->grid.resizeCol = -1;
7752 if (!RowColToXY(g, r, c, False, &rect))
7754 if (g->grid.resizeIsVert)
7756 cbs.rowType = RowPosToType(g, r);
7757 cbs.row = RowPosToTypePos(g, cbs.rowType, r);
7758 height = 0;
7759 if (g->grid.resizeLineXY > rect.y)
7760 height = g->grid.resizeLineXY - rect.y -
7761 (rect.height - GetRowHeight(g, r));
7762 if (height < 6 && g->grid.allowRowHide == False)
7763 height = 6;
7764 XtVaSetValues((Widget)g,
7765 XmNrowType, cbs.rowType,
7766 XmNrow, cbs.row,
7767 XmNrowHeight, height,
7768 XmNrowSizePolicy, XmCONSTANT,
7769 NULL);
7770 cbs.reason = XmCR_RESIZE_ROW;
7772 else
7774 cbs.columnType = ColPosToType(g, c);
7775 cbs.column = ColPosToTypePos(g, cbs.columnType, c);
7776 width = 0;
7777 if (g->grid.resizeLineXY > rect.x)
7778 width = g->grid.resizeLineXY - rect.x -
7779 (rect.width - GetColWidth(g, c));
7780 if (width < 6 && g->grid.allowColHide == False)
7781 width = 6;
7782 XtVaSetValues((Widget)g,
7783 XmNcolumnType, cbs.columnType,
7784 XmNcolumn, cbs.column,
7785 XmNcolumnWidth, width,
7786 XmNcolumnSizePolicy, XmCONSTANT,
7787 NULL);
7788 cbs.reason = XmCR_RESIZE_COLUMN;
7791 XtCallCallbackList((Widget)g, g->grid.resizeCallback,
7792 (XtPointer)&cbs);
7794 DrawResizeLine(g, 0, 2);
7795 DefineCursor(g, CursorNormal);
7796 g->grid.inMode = InNormal;
7798 else if (q == qEND)
7800 g->grid.inMode = InNormal;
7801 if (g->grid.dragTimerSet)
7802 XtRemoveTimeOut(g->grid.dragTimerId);
7803 g->grid.dragTimerSet = 0;
7805 /* XFE Additions to handle button up events in menus - they generate activate events */
7807 if (XmIsMenuShell(XmLShellOfWidget((Widget)g)))
7809 cbs.reason = XmCR_ACTIVATE;
7810 cbs.event = event;
7811 cbs.columnType = ColPosToType(g, col);
7812 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7813 cbs.rowType = RowPosToType(g, row);
7814 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7815 XtCallCallbackList((Widget)g, g->grid.activateCallback,
7816 (XtPointer)&cbs);
7820 if (q == qBEGIN && g->grid.singleClickActivation) {
7821 cbs.reason = XmCR_ACTIVATE;
7822 cbs.event = event;
7823 cbs.columnType = ColPosToType(g, col);
7824 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7825 cbs.rowType = RowPosToType(g, row);
7826 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7827 XtCallCallbackList((Widget)g, g->grid.activateCallback,
7828 (XtPointer)&cbs);
7830 if (q == qACTIVATE)
7832 cbs.reason = XmCR_ACTIVATE;
7833 cbs.event = event;
7834 cbs.columnType = ColPosToType(g, col);
7835 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7836 cbs.rowType = RowPosToType(g, row);
7837 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7838 XtCallCallbackList((Widget)g, g->grid.activateCallback,
7839 (XtPointer)&cbs);
7844 * Selection policy when posting a context menu.
7845 * If over a current selection, leave the selection alone.
7846 * Otherwise, change the selection the same as Select(),
7847 * except do not allow dragging to extend the selection.
7849 static void
7850 PopupSelect(Widget w,
7851 XEvent *event,
7852 String *params,
7853 Cardinal *nparam)
7855 XmLGridWidget g;
7856 int row, col;
7857 XButtonEvent *be;
7858 XmLGridRow rowp;
7859 XmLGridCallbackStruct cbs;
7861 if (*nparam != 1)
7862 return;
7864 if (XmLIsGrid(w))
7865 g = (XmLGridWidget)w;
7866 else
7867 g = (XmLGridWidget)XtParent(w);
7869 be = 0;
7870 if (event->type == KeyPress || event->type == KeyRelease)
7872 row = g->grid.focusRow;
7873 col = g->grid.focusCol;
7875 else /* Button */
7877 be = (XButtonEvent *)event;
7878 if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
7880 row = -1;
7881 col = -1;
7884 if (RowPosToType(g, row) == XmCONTENT)
7886 XmLGridRow rowp;
7887 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
7888 if (rowp && !XmLGridRowIsSelected(rowp))
7890 String end_params[1];
7891 end_params[0] = "END";
7892 Select(w, event, params, nparam);
7893 Select(w, event, end_params, nparam);
7896 if (XtHasCallbacks(w, XmNpopupCallback) == XtCallbackHasSome)
7898 cbs.reason = XmCR_SHOW_POPUP;
7899 cbs.event = event;
7900 cbs.columnType = ColPosToType(g, col);
7901 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
7902 cbs.rowType = RowPosToType(g, row);
7903 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
7904 XtCallCallbackList((Widget)g, g->grid.popupCallback,
7905 (XtPointer)&cbs);
7909 static void
7910 Traverse(Widget w,
7911 XEvent *event,
7912 String *params,
7913 Cardinal *nparam)
7915 XmLGridWidget g;
7916 static XrmQuark qDOWN, qEXTEND_DOWN, qEXTEND_LEFT;
7917 static XrmQuark qEXTEND_PAGE_DOWN, qEXTEND_PAGE_LEFT;
7918 static XrmQuark qEXTEND_PAGE_RIGHT, qEXTEND_PAGE_UP;
7919 static XrmQuark qEXTEND_RIGHT, qEXTEND_UP, qLEFT, qPAGE_DOWN;
7920 static XrmQuark qPAGE_LEFT, qPAGE_RIGHT, qPAGE_UP, qRIGHT;
7921 static XrmQuark qTO_BOTTOM, qTO_BOTTOM_RIGHT, qTO_LEFT;
7922 static XrmQuark qTO_RIGHT, qTO_TOP, qTO_TOP_LEFT, qUP;
7923 static int quarksValid = 0;
7924 int extend, focusRow, focusCol, rowDir, colDir;
7925 int rowLoc, colLoc, prevRowLoc, prevColLoc;
7926 int scrollRow, scrollCol, prevScrollRow, prevScrollCol;
7927 XrmQuark q;
7929 g = (XmLGridWidget)XtParent(w);
7930 if (*nparam != 1)
7931 return;
7932 if (!quarksValid)
7934 qDOWN = XrmStringToQuark("DOWN");
7935 qEXTEND_DOWN = XrmStringToQuark("EXTEND_DOWN");
7936 qEXTEND_LEFT = XrmStringToQuark("EXTEND_LEFT");
7937 qEXTEND_PAGE_DOWN = XrmStringToQuark("EXTEND_PAGE_DOWN");
7938 qEXTEND_PAGE_LEFT = XrmStringToQuark("EXTEND_PAGE_LEFT");
7939 qEXTEND_PAGE_RIGHT = XrmStringToQuark("EXTEND_PAGE_RIGHT");
7940 qEXTEND_PAGE_UP = XrmStringToQuark("EXTEND_PAGE_UP");
7941 qEXTEND_RIGHT = XrmStringToQuark("EXTEND_RIGHT");
7942 qEXTEND_UP = XrmStringToQuark("EXTEND_UP");
7943 qLEFT = XrmStringToQuark("LEFT");
7944 qPAGE_DOWN = XrmStringToQuark("PAGE_DOWN");
7945 qPAGE_LEFT = XrmStringToQuark("PAGE_LEFT");
7946 qPAGE_RIGHT = XrmStringToQuark("PAGE_RIGHT");
7947 qPAGE_UP = XrmStringToQuark("PAGE_UP");
7948 qRIGHT = XrmStringToQuark("RIGHT");
7949 qTO_BOTTOM = XrmStringToQuark("TO_BOTTOM");
7950 qTO_BOTTOM_RIGHT = XrmStringToQuark("TO_BOTTOM_RIGHT");
7951 qTO_LEFT = XrmStringToQuark("TO_LEFT");
7952 qTO_RIGHT = XrmStringToQuark("TO_RIGHT");
7953 qTO_TOP = XrmStringToQuark("TO_TOP");
7954 qTO_TOP_LEFT = XrmStringToQuark("TO_TOP_LEFT");
7955 qUP = XrmStringToQuark("UP");
7956 quarksValid = 1;
7958 q = XrmStringToQuark(params[0]);
7959 extend = 0;
7960 /* map the extends to their counterparts and set extend flag */
7961 if (q == qEXTEND_DOWN)
7963 q = qDOWN;
7964 extend = 1;
7966 else if (q == qEXTEND_LEFT)
7968 q = qLEFT;
7969 extend = 1;
7971 else if (q == qEXTEND_PAGE_DOWN)
7973 q = qPAGE_DOWN;
7974 extend = 1;
7976 else if (q == qEXTEND_PAGE_LEFT)
7978 q = qPAGE_LEFT;
7979 extend = 1;
7981 else if (q == qEXTEND_PAGE_RIGHT)
7983 q = qPAGE_RIGHT;
7984 extend = 1;
7986 else if (q == qEXTEND_PAGE_UP)
7988 q = qPAGE_UP;
7989 extend = 1;
7991 else if (q == qEXTEND_RIGHT)
7993 q = qRIGHT;
7994 extend = 1;
7996 else if (q == qEXTEND_UP)
7998 q = qUP;
7999 extend = 1;
8001 if (extend && g->grid.selectionPolicy != XmSELECT_MULTIPLE_ROW &&
8002 g->grid.selectionPolicy != XmSELECT_CELL)
8003 return;
8004 if (extend && g->grid.extendRow != -1 && g->grid.extendCol != -1)
8006 focusRow = g->grid.extendToRow;
8007 focusCol = g->grid.extendToCol;
8009 else
8011 focusRow = g->grid.focusRow;
8012 focusCol = g->grid.focusCol;
8014 rowDir = 0;
8015 colDir = 0;
8016 if (focusRow < g->grid.topFixedCount)
8017 prevRowLoc = 0;
8018 else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
8019 g->grid.bottomFixedCount)
8020 prevRowLoc = 2;
8021 else
8022 prevRowLoc = 1;
8023 if (focusCol < g->grid.leftFixedCount)
8024 prevColLoc = 0;
8025 else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
8026 g->grid.rightFixedCount)
8027 prevColLoc = 2;
8028 else
8029 prevColLoc = 1;
8030 /* calculate new focus row, col and walk direction */
8031 if (q == qDOWN)
8033 focusRow++;
8034 rowDir = 1;
8036 else if (q == qLEFT)
8038 focusCol--;
8039 colDir = -1;
8041 else if (q == qPAGE_DOWN)
8043 if (prevRowLoc == 1)
8044 focusRow = g->grid.reg[4].row + g->grid.reg[4].nrow - 1;
8045 if (focusRow == g->grid.focusRow)
8046 focusRow += 4;
8047 rowDir = 1;
8049 else if (q == qPAGE_LEFT)
8051 if (prevColLoc == 1)
8052 focusCol = g->grid.reg[4].col - 1;
8053 if (focusCol == g->grid.focusCol)
8054 focusCol -= 4;
8055 colDir = -1;
8057 else if (q == qPAGE_RIGHT)
8059 if (prevColLoc == 1)
8060 focusCol = g->grid.reg[4].col + g->grid.reg[4].ncol - 1;
8061 if (focusCol == g->grid.focusCol)
8062 focusCol += 4;
8063 colDir = 1;
8065 else if (q == qPAGE_UP)
8067 if (prevRowLoc == 1)
8068 focusRow = g->grid.reg[4].row - 1;
8069 if (focusRow == g->grid.focusRow)
8070 focusRow -= 4;
8071 rowDir = -1;
8073 else if (q == qRIGHT)
8075 focusCol++;
8076 colDir = 1;
8078 else if (q == qTO_BOTTOM)
8080 focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
8081 rowDir = -1;
8083 else if (q == qTO_BOTTOM_RIGHT)
8085 focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
8086 focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
8087 rowDir = -1;
8088 colDir = -1;
8090 else if (q == qTO_LEFT)
8092 focusCol = 0;
8093 colDir = 1;
8095 else if (q == qTO_RIGHT)
8097 focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
8098 colDir = -1;
8100 else if (q == qTO_TOP)
8102 focusRow = 0;
8103 rowDir = 1;
8105 else if (q == qTO_TOP_LEFT)
8107 focusCol = 0;
8108 focusRow = 0;
8109 rowDir = 1;
8110 colDir = 1;
8112 else if (q == qUP)
8114 focusRow -= 1;
8115 rowDir = -1;
8117 if (!rowDir && !colDir)
8118 return;
8119 if (extend)
8121 if (FindNextFocus(g, focusRow, focusCol, rowDir, colDir,
8122 &focusRow, &focusCol) == -1)
8123 return;
8124 ExtendSelect(g, event, False, focusRow, focusCol);
8126 else
8128 if (SetFocus(g, focusRow, focusCol, rowDir, colDir) == -1)
8129 return;
8130 ExtendSelect(g, event, False, -1, -1);
8131 focusRow = g->grid.focusRow;
8132 focusCol = g->grid.focusCol;
8133 if (g->grid.selectionPolicy == XmSELECT_CELL)
8135 SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
8136 SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
8137 SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
8138 SelectTypeArea(g, SelectCell, event,
8139 RowPosToTypePos(g, XmCONTENT, focusRow),
8140 ColPosToTypePos(g, XmCONTENT, focusCol),
8141 True, True);
8143 else if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
8144 SelectTypeArea(g, SelectRow, event,
8145 RowPosToTypePos(g, XmCONTENT, focusRow), 0, True, True);
8147 scrollRow = -1;
8148 scrollCol = -1;
8149 if (q == qPAGE_UP)
8150 scrollRow = ScrollRowBottomPos(g, focusRow);
8151 else if (q == qPAGE_DOWN)
8152 scrollRow = focusRow;
8153 else if (q == qPAGE_LEFT)
8154 scrollCol = ScrollColRightPos(g, focusCol);
8155 else if (q == qPAGE_RIGHT)
8156 scrollCol = focusCol;
8157 else
8159 if (focusRow < g->grid.topFixedCount)
8160 rowLoc = 0;
8161 else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
8162 g->grid.bottomFixedCount)
8163 rowLoc = 2;
8164 else
8165 rowLoc = 1;
8166 if (prevRowLoc != 0 && rowLoc == 0)
8167 scrollRow = g->grid.reg[0].nrow;
8168 else if (prevRowLoc != 2 && rowLoc == 2)
8169 scrollRow = g->grid.reg[6].row - 1;
8171 if (focusCol < g->grid.leftFixedCount)
8172 colLoc = 0;
8173 else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
8174 g->grid.rightFixedCount)
8175 colLoc = 2;
8176 else
8177 colLoc = 1;
8178 if (prevColLoc != 0 && colLoc == 0)
8179 scrollCol = g->grid.reg[0].ncol;
8180 else if (prevColLoc != 2 && colLoc == 2)
8181 scrollCol = g->grid.reg[2].col - 1;
8183 if (g->grid.vsPolicy == XmVARIABLE)
8185 else if (scrollRow != -1)
8187 prevScrollRow = g->grid.scrollRow;
8188 g->grid.scrollRow = scrollRow;
8189 VertLayout(g, 0);
8190 if (g->grid.scrollRow != prevScrollRow)
8191 DrawArea(g, DrawVScroll, 0, 0);
8193 else
8194 MakeRowVisible(g, focusRow);
8195 if (g->grid.hsPolicy == XmVARIABLE)
8197 else if (scrollCol != -1)
8199 prevScrollCol = g->grid.scrollCol;
8200 g->grid.scrollCol = scrollCol;
8201 HorizLayout(g, 0);
8202 if (g->grid.scrollCol != prevScrollCol)
8203 DrawArea(g, DrawHScroll, 0, 0);
8205 else
8206 MakeColVisible(g, focusCol);
8209 static void
8210 TextActivate(Widget w,
8211 XtPointer clientData,
8212 XtPointer callData)
8214 XmLGridWidget g;
8215 XmAnyCallbackStruct *cbs;
8216 String params[1];
8217 Cardinal nparam;
8219 cbs = (XmAnyCallbackStruct *)callData;
8220 g = (XmLGridWidget)XtParent(w);
8221 if (g->grid.inEdit)
8223 nparam = 0;
8224 EditComplete(w, cbs->event, params, &nparam);
8226 else
8228 params[0] = "ACTIVATE";
8229 nparam = 1;
8230 Select(XtParent(w), cbs->event, params, &nparam);
8234 static void
8235 TextFocus(Widget w,
8236 XtPointer clientData,
8237 XtPointer callData)
8239 XmLGridWidget g;
8240 XmAnyCallbackStruct *cbs;
8241 int focusRow, focusCol;
8243 cbs = (XmAnyCallbackStruct *)callData;
8244 g = (XmLGridWidget)XtParent(w);
8245 if (cbs->reason == XmCR_FOCUS)
8246 g->grid.focusIn = 1;
8247 else
8248 g->grid.focusIn = 0;
8249 focusRow = g->grid.focusRow;
8250 focusCol = g->grid.focusCol;
8251 if (focusRow != -1 && focusCol != -1)
8253 if (g->grid.highlightRowMode == True)
8254 DrawArea(g, DrawRow, focusRow, 0);
8255 else
8256 DrawArea(g, DrawCell, focusRow, focusCol);
8260 static void
8261 TextMapped(Widget w,
8262 XtPointer clientData,
8263 XEvent *event,
8264 Boolean *con)
8266 XmLGridWidget g;
8268 g = (XmLGridWidget)(XtParent(w));
8269 if (event->type != MapNotify)
8270 return;
8271 if (g->grid.textHidden)
8272 XtUnmapWidget(g->grid.text);
8275 static void
8276 TextModifyVerify(Widget w,
8277 XtPointer clientData,
8278 XtPointer callData)
8280 XmLGridWidget g;
8281 XmTextVerifyCallbackStruct *cbs;
8283 g = (XmLGridWidget)XtParent(w);
8284 cbs = (XmTextVerifyCallbackStruct *)callData;
8285 if (!cbs->event || g->grid.ignoreModifyVerify || g->grid.inEdit)
8286 return;
8287 TextAction(g, TEXT_EDIT);
8288 if (!g->grid.inEdit)
8289 cbs->doit = False;
8293 XmLGridRow
8296 static
8297 XmLGridRow XmLGridRowNew(Widget grid)
8299 return XmLGridClassPartOfWidget(grid).rowNewProc(grid);
8302 /* Only to be called through Grid class */
8303 static XmLGridRow
8304 _GridRowNew(Widget grid)
8306 XmLGridWidget g;
8307 XmLGridRow row;
8308 int size;
8310 g = (XmLGridWidget)grid;
8311 size = XmLGridClassPartOfWidget(grid).rowRecSize;
8312 row = (XmLGridRow)malloc(size);
8313 row->grid.grid = grid;
8314 row->grid.heightInPixels = 0;
8315 row->grid.heightInPixelsValid = 0;
8316 row->grid.height = 1;
8317 row->grid.selected = False;
8318 row->grid.sizePolicy = XmVARIABLE;
8319 row->grid.userData = 0;
8320 row->grid.cellArray = XmLArrayNew(0, 0);
8321 return row;
8324 static void
8325 XmLGridRowFree(Widget grid,
8326 XmLGridRow row)
8328 XmLGridClassPartOfWidget(grid).rowFreeProc(row);
8331 /* Only to be called through Grid class */
8332 static void
8333 _GridRowFree(XmLGridRow row)
8335 int i, count;
8337 count = XmLArrayGetCount(row->grid.cellArray);
8338 for (i = 0; i < count; i++)
8339 XmLGridCellFree(row->grid.grid,
8340 (XmLGridCell)XmLArrayGet(row->grid.cellArray, i));
8341 XmLArrayFree(row->grid.cellArray);
8342 free ((char *)row);
8345 static
8346 XmLArray XmLGridRowCells(XmLGridRow row)
8348 return row->grid.cellArray;
8351 static int
8352 XmLGridRowGetPos(XmLGridRow row)
8354 return row->grid.pos;
8357 static int
8358 XmLGridRowGetVisPos(XmLGridRow row)
8360 return row->grid.visPos;
8363 static Boolean
8364 XmLGridRowIsHidden(XmLGridRow row)
8366 if (!row->grid.height)
8367 return True;
8368 return False;
8371 static Boolean
8372 XmLGridRowIsSelected(XmLGridRow row)
8374 return row->grid.selected;
8377 static void
8378 XmLGridRowSetSelected(XmLGridRow row,
8379 Boolean selected)
8381 row->grid.selected = selected;
8384 static void
8385 XmLGridRowSetVisPos(XmLGridRow row,
8386 int visPos)
8388 row->grid.visPos = visPos;
8391 static int
8392 XmLGridRowHeightInPixels(XmLGridRow row)
8394 int i, count;
8395 Dimension height, maxHeight;
8396 XmLGridWidget g;
8397 XmLGridCell cell;
8398 XmLGridCallbackStruct cbs;
8399 XmLGridCellRefValues *cellValues;
8401 if (row->grid.sizePolicy == XmCONSTANT)
8402 return row->grid.height;
8403 if (!row->grid.height)
8404 return 0;
8405 if (!row->grid.heightInPixelsValid)
8407 g = (XmLGridWidget)row->grid.grid;
8408 count = XmLArrayGetCount(row->grid.cellArray);
8409 if (!count)
8411 cellValues = g->grid.defCellValues;
8412 maxHeight = 4 + row->grid.height * cellValues->fontHeight +
8413 cellValues->topMargin + cellValues->bottomMargin;
8415 else
8416 maxHeight = 0;
8417 for (i = 0; i < count; i++)
8419 cell = (XmLGridCell)XmLArrayGet(row->grid.cellArray, i);
8420 cbs.reason = XmCR_PREF_HEIGHT;
8421 cbs.rowType = RowPosToType(g, row->grid.pos);
8422 cbs.row = RowPosToTypePos(g, cbs.rowType, row->grid.pos);
8423 cbs.columnType = ColPosToType(g, i);
8424 cbs.column = ColPosToTypePos(g, cbs.columnType, i);
8425 cbs.object = (void *)row;
8426 height = XmLGridCellAction(cell, (Widget)g, &cbs);
8427 if (height > maxHeight)
8428 maxHeight = height;
8430 row->grid.heightInPixels = maxHeight;
8431 row->grid.heightInPixelsValid = 1;
8433 return row->grid.heightInPixels;
8436 static void
8437 XmLGridRowHeightChanged(XmLGridRow row)
8439 row->grid.heightInPixelsValid = 0;
8443 XmLGridColumn
8446 static XmLGridColumn
8447 XmLGridColumnNew(Widget grid)
8449 return XmLGridClassPartOfWidget(grid).columnNewProc(grid);
8452 /* Only to be called through Grid class */
8453 static XmLGridColumn
8454 _GridColumnNew(Widget grid)
8456 XmLGridWidget g;
8457 XmLGridColumn column;
8458 int size;
8460 g = (XmLGridWidget)grid;
8461 size = XmLGridClassPartOfWidget(grid).columnRecSize;
8462 column = (XmLGridColumn)malloc(size);
8463 column->grid.grid = grid;
8464 column->grid.widthInPixels = 0;
8465 column->grid.widthInPixelsValid = 0;
8466 column->grid.defCellValues = 0;
8467 column->grid.selected = False;
8468 column->grid.sizePolicy = XmVARIABLE;
8469 column->grid.width = 8;
8470 column->grid.userData = 0;
8471 column->grid.resizable = True;
8472 column->grid.hidden = 0;
8473 return column;
8476 static void
8477 XmLGridColumnFree(Widget grid,
8478 XmLGridColumn column)
8480 XmLGridClassPartOfWidget(grid).columnFreeProc(column);
8483 /* Only to be called through Grid class */
8484 static void
8485 _GridColumnFree(XmLGridColumn column)
8487 if (column->grid.defCellValues)
8488 XmLGridCellDerefValues(column->grid.defCellValues);
8489 free((char *)column);
8492 static int
8493 XmLGridColumnGetPos(XmLGridColumn column)
8495 return column->grid.pos;
8498 static int
8499 XmLGridColumnGetVisPos(XmLGridColumn column)
8501 return column->grid.visPos;
8504 static Boolean
8505 XmLGridColumnIsHidden(XmLGridColumn column)
8507 return column->grid.width == 0
8508 || column->grid.hidden;
8511 static Boolean
8512 XmLGridColumnIsSelected(XmLGridColumn column)
8514 return column->grid.selected;
8517 static void
8518 XmLGridColumnSetSelected(XmLGridColumn column,
8519 Boolean selected)
8521 column->grid.selected = selected;
8524 static void
8525 XmLGridColumnSetVisPos(XmLGridColumn column,
8526 int visPos)
8528 column->grid.visPos = visPos;
8531 static int
8532 XmLGridColumnWidthInPixels(XmLGridColumn column)
8534 int i, count;
8535 Dimension width, maxWidth;
8536 XmLGridCell cell;
8537 XmLGridWidget g;
8538 XmLGridCallbackStruct cbs;
8539 XmLGridCellRefValues *cellValues;
8541 if (column->grid.sizePolicy == XmCONSTANT)
8542 return column->grid.width;
8543 if (!column->grid.width)
8544 return 0;
8545 if (!column->grid.widthInPixelsValid)
8547 g = (XmLGridWidget)column->grid.grid;
8548 count = XmLArrayGetCount(g->grid.rowArray);
8549 if (!count)
8551 cellValues = g->grid.defCellValues;
8552 maxWidth = 4 + column->grid.width * cellValues->fontWidth +
8553 cellValues->leftMargin + cellValues->rightMargin;
8555 else
8556 maxWidth = 0;
8557 for (i = 0; i < count; i++)
8559 cell = GetCell(g, i, column->grid.pos);
8560 cbs.reason = XmCR_PREF_WIDTH;
8561 cbs.rowType = RowPosToType(g, i);
8562 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
8563 cbs.columnType = ColPosToType(g, column->grid.pos);
8564 cbs.column = ColPosToTypePos(g, cbs.columnType, column->grid.pos);
8565 cbs.object = (void *)column;
8566 width = XmLGridCellAction(cell, (Widget)g, &cbs);
8567 if (width > maxWidth)
8568 maxWidth = width;
8570 column->grid.widthInPixels = maxWidth;
8571 column->grid.widthInPixelsValid = 1;
8573 return column->grid.widthInPixels;
8576 static void
8577 XmLGridColumnWidthChanged(XmLGridColumn column)
8579 column->grid.widthInPixelsValid = 0;
8583 XmLGridCell
8586 static XmLGridCell
8587 XmLGridCellNew(void)
8589 XmLGridCell c;
8591 c = (XmLGridCell)malloc(sizeof(struct _XmLGridCellRec));
8592 c->cell.refValues = 0;
8593 c->cell.flags = 0;
8594 return c;
8597 static void
8598 XmLGridCellFree(Widget grid,
8599 XmLGridCell cell)
8601 XmLGridCallbackStruct cbs;
8603 cbs.reason = XmCR_FREE_VALUE;
8604 XmLGridCellAction(cell, grid, &cbs);
8605 XmLGridCellDerefValues(cell->cell.refValues);
8606 free((char *)cell);
8609 static int
8610 XmLGridCellAction(XmLGridCell cell,
8611 Widget w,
8612 XmLGridCallbackStruct *cbs)
8614 return XmLGridClassPartOfWidget(w).cellActionProc(cell, w, cbs);
8617 /* Only to be called through Grid class */
8618 static int
8619 _GridCellAction(XmLGridCell cell,
8620 Widget w,
8621 XmLGridCallbackStruct *cbs)
8623 int ret;
8625 ret = 0;
8626 switch (cbs->reason)
8628 case XmCR_CELL_DRAW:
8629 _XmLGridCellDrawBackground(cell, w, cbs->clipRect, cbs->drawInfo);
8630 _XmLGridCellDrawValue(cell, w, cbs->clipRect, cbs->drawInfo);
8631 _XmLGridCellDrawBorders(cell, w, cbs->clipRect, cbs->drawInfo);
8632 break;
8633 case XmCR_CELL_FOCUS_IN:
8634 break;
8635 case XmCR_CELL_FOCUS_OUT:
8636 break;
8637 case XmCR_CONF_TEXT:
8638 _XmLGridCellConfigureText(cell, w, cbs->clipRect);
8639 break;
8640 case XmCR_EDIT_BEGIN:
8641 ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
8642 break;
8643 case XmCR_EDIT_CANCEL:
8644 break;
8645 case XmCR_EDIT_COMPLETE:
8646 _XmLGridCellCompleteTextEdit(cell, w);
8647 break;
8648 case XmCR_EDIT_INSERT:
8649 ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
8650 if (ret)
8651 _XmLGridCellInsertText(cell, w);
8652 break;
8653 case XmCR_FREE_VALUE:
8654 _XmLGridCellFreeValue(cell);
8655 break;
8656 case XmCR_PREF_HEIGHT:
8657 ret = _XmLGridCellGetHeight(cell, w,(XmLGridRow)cbs->object);
8658 break;
8659 case XmCR_PREF_WIDTH:
8660 ret = _XmLGridCellGetWidth(cell, w,(XmLGridColumn)cbs->object);
8661 break;
8663 return ret;
8666 static XmLGridCellRefValues *
8667 XmLGridCellGetRefValues(XmLGridCell cell)
8669 return cell->cell.refValues;
8672 static void
8673 XmLGridCellSetRefValues(XmLGridCell cell,
8674 XmLGridCellRefValues *values)
8676 values->refCount++;
8677 XmLGridCellDerefValues(cell->cell.refValues);
8678 cell->cell.refValues = values;
8681 static void
8682 XmLGridCellDerefValues(XmLGridCellRefValues *values)
8684 if (!values)
8685 return;
8686 values->refCount--;
8687 if (!values->refCount)
8689 XmFontListFree(values->fontList);
8690 free((char *)values);
8694 static Boolean
8695 XmLGridCellInRowSpan(XmLGridCell cell)
8697 if (cell->cell.flags & XmLGridCellInRowSpanFlag)
8698 return True;
8699 return False;
8702 static Boolean
8703 XmLGridCellInColumnSpan(XmLGridCell cell)
8705 if (cell->cell.flags & XmLGridCellInColumnSpanFlag)
8706 return True;
8707 return False;
8710 static Boolean
8711 XmLGridCellIsSelected(XmLGridCell cell)
8713 if (cell->cell.flags & XmLGridCellSelectedFlag)
8714 return True;
8715 return False;
8718 static Boolean
8719 XmLGridCellIsValueSet(XmLGridCell cell)
8721 if (cell->cell.flags & XmLGridCellValueSetFlag)
8722 return True;
8723 return False;
8726 static void
8727 XmLGridCellSetValueSet(XmLGridCell cell,
8728 Boolean set)
8730 cell->cell.flags |= XmLGridCellValueSetFlag;
8731 if (set != True)
8732 cell->cell.flags ^= XmLGridCellValueSetFlag;
8735 static void
8736 XmLGridCellSetInRowSpan(XmLGridCell cell,
8737 Boolean set)
8739 cell->cell.flags |= XmLGridCellInRowSpanFlag;
8740 if (set != True)
8741 cell->cell.flags ^= XmLGridCellInRowSpanFlag;
8744 static void
8745 XmLGridCellSetInColumnSpan(XmLGridCell cell,
8746 Boolean set)
8748 cell->cell.flags |= XmLGridCellInColumnSpanFlag;
8749 if (set != True)
8750 cell->cell.flags ^= XmLGridCellInColumnSpanFlag;
8753 static void
8754 XmLGridCellSetSelected(XmLGridCell cell,
8755 Boolean selected)
8757 cell->cell.flags |= XmLGridCellSelectedFlag;
8758 if (selected != True)
8759 cell->cell.flags ^= XmLGridCellSelectedFlag;
8762 /*Xfe Additions*/
8763 static Boolean
8764 XmLGridCellDrawSort(XmLGridCell cell)
8766 if (cell->cell.flags & XmLGridCellDrawSortFlag)
8767 return True;
8768 return False;
8770 static Boolean
8771 XmLGridCellSortAscending(XmLGridCell cell)
8773 if (cell->cell.flags & XmLGridCellSortAscendingFlag)
8774 return True;
8775 return False;
8777 static void
8778 XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort)
8780 cell->cell.flags |= XmLGridCellDrawSortFlag;
8781 if (drawSort != True)
8782 cell->cell.flags ^= XmLGridCellDrawSortFlag;
8784 static void
8785 XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending)
8787 cell->cell.flags |= XmLGridCellSortAscendingFlag;
8788 if (ascending != True)
8789 cell->cell.flags ^= XmLGridCellSortAscendingFlag;
8793 static void
8794 XmLGridCellAllocIcon(XmLGridCell cell)
8796 XmLGridCellIcon *icon;
8798 icon = (XmLGridCellIcon *)malloc(sizeof(XmLGridCellIcon));
8799 icon->pix.pixmap = XmUNSPECIFIED_PIXMAP;
8800 icon->pix.pixmask = XmUNSPECIFIED_PIXMAP;
8801 icon->pix.width = 0;
8802 icon->pix.height = 0;
8803 icon->string = 0;
8804 cell->cell.value = (void *)icon;
8805 XmLGridCellSetValueSet(cell, True);
8808 static void
8809 XmLGridCellAllocPixmap(XmLGridCell cell)
8811 XmLGridCellPixmap *pix;
8813 pix = (XmLGridCellPixmap *)malloc(sizeof(XmLGridCellPixmap));
8814 pix->width = 0;
8815 pix->height = 0;
8816 pix->pixmap = XmUNSPECIFIED_PIXMAP;
8817 pix->pixmask = XmUNSPECIFIED_PIXMAP;
8818 cell->cell.value = (void *)pix;
8819 XmLGridCellSetValueSet(cell, True);
8822 static void
8823 XmLGridCellSetString(XmLGridCell cell,
8824 XmString string,
8825 Boolean copy)
8827 XmLGridCellIcon *icon;
8829 if (cell->cell.refValues->type == XmSTRING_CELL)
8831 _XmLGridCellFreeValue(cell);
8832 if (string)
8834 if (copy == True)
8835 cell->cell.value = (void *)XmStringCopy(string);
8836 else
8837 cell->cell.value = (void *)string;
8838 XmLGridCellSetValueSet(cell, True);
8840 else
8841 XmLGridCellSetValueSet(cell, False);
8843 else if (cell->cell.refValues->type == XmICON_CELL)
8845 if (XmLGridCellIsValueSet(cell) == False)
8846 XmLGridCellAllocIcon(cell);
8847 icon = (XmLGridCellIcon *)cell->cell.value;
8848 if (icon->string)
8849 XmStringFree(icon->string);
8850 if (string && copy == True)
8851 icon->string = XmStringCopy(string);
8852 else
8853 icon->string = string;
8855 else if (string && copy == False)
8856 XmStringFree(string);
8859 static XmString
8860 XmLGridCellGetString(XmLGridCell cell)
8862 XmString str;
8864 str = 0;
8865 if (cell->cell.refValues->type == XmSTRING_CELL)
8867 if (XmLGridCellIsValueSet(cell) == True)
8868 str = (XmString)cell->cell.value;
8870 else if (cell->cell.refValues->type == XmICON_CELL)
8872 if (XmLGridCellIsValueSet(cell) == True)
8873 str = ((XmLGridCellIcon *)cell->cell.value)->string;
8875 return str;
8878 static void
8879 XmLGridCellSetToggle(XmLGridCell cell,
8880 Boolean state)
8882 if (cell->cell.refValues->type == XmTOGGLE_CELL)
8884 if (state)
8885 cell->cell.value = (void *)1;
8886 else
8887 cell->cell.value = (void *)0;
8888 XmLGridCellSetValueSet(cell, True);
8892 static Boolean
8893 XmLGridCellGetToggle(XmLGridCell cell)
8895 Boolean toggled;
8897 toggled = False;
8898 if (cell->cell.refValues->type == XmTOGGLE_CELL)
8900 if (XmLGridCellIsValueSet(cell) == True &&
8901 cell->cell.value == (void *)1)
8902 toggled = True;
8904 return toggled;
8907 static void
8908 XmLGridCellSetPixmap(XmLGridCell cell,
8909 Pixmap pixmap,
8910 Dimension width,
8911 Dimension height)
8913 XmLGridCellPixmap *pix;
8915 pix = 0;
8916 if (cell->cell.refValues->type == XmPIXMAP_CELL)
8918 if (XmLGridCellIsValueSet(cell) == False)
8919 XmLGridCellAllocPixmap(cell);
8920 pix = (XmLGridCellPixmap *)cell->cell.value;
8922 else if (cell->cell.refValues->type == XmICON_CELL)
8924 if (XmLGridCellIsValueSet(cell) == False)
8925 XmLGridCellAllocIcon(cell);
8926 pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8928 if (!pix)
8929 return;
8930 pix->pixmap = pixmap;
8931 pix->height = height;
8932 pix->width = width;
8935 static void
8936 XmLGridCellSetPixmask(XmLGridCell cell,
8937 Pixmap pixmask)
8939 XmLGridCellPixmap *pix;
8941 if (XmLGridCellIsValueSet(cell) == False)
8943 fprintf(stderr, "XmLGridCellSetPixmask: pixmap must be set ");
8944 fprintf(stderr, "before pixmask\n");
8945 return;
8947 pix = 0;
8948 if (cell->cell.refValues->type == XmPIXMAP_CELL)
8949 pix = (XmLGridCellPixmap *)cell->cell.value;
8950 else if (cell->cell.refValues->type == XmICON_CELL)
8951 pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8952 if (!pix)
8953 return;
8954 pix->pixmask = pixmask;
8957 static XmLGridCellPixmap *
8958 XmLGridCellGetPixmap(XmLGridCell cell)
8960 XmLGridCellPixmap *pix;
8962 pix = 0;
8963 if (cell->cell.refValues->type == XmPIXMAP_CELL)
8965 if (XmLGridCellIsValueSet(cell) == True)
8966 pix = (XmLGridCellPixmap *)cell->cell.value;
8968 else if (cell->cell.refValues->type == XmICON_CELL)
8970 if (XmLGridCellIsValueSet(cell) == True)
8971 pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
8973 return pix;
8976 /* Only to be called by XmLGridCellAction() */
8977 void
8978 _XmLGridCellDrawBackground(XmLGridCell cell,
8979 Widget w,
8980 XRectangle *clipRect,
8981 XmLGridDrawStruct *ds)
8983 Display *dpy;
8984 Window win;
8986 dpy = XtDisplay(w);
8987 win = XtWindow(w);
8988 if (ds->drawSelected == True)
8989 XSetForeground(dpy, ds->gc, ds->selectBackground);
8990 else
8991 XSetForeground(dpy, ds->gc, ds->background);
8992 XFillRectangle(dpy, win, ds->gc, clipRect->x, clipRect->y,
8993 clipRect->width, clipRect->height);
8996 /* Only to be called by XmLGridCellAction() */
8997 void
8998 _XmLGridCellDrawBorders(XmLGridCell cell,
8999 Widget w,
9000 XRectangle *clipRect,
9001 XmLGridDrawStruct *ds)
9003 XmLGridWidget g;
9004 Display *dpy;
9005 Window win;
9006 GC gc;
9007 Pixel black, white;
9008 int x1, x2, y1, y2, loff, roff;
9009 int drawLeft, drawRight, drawBot, drawTop;
9010 XRectangle *cellRect;
9011 unsigned char borderType;
9013 g = (XmLGridWidget)w;
9014 dpy = XtDisplay(w);
9015 win = XtWindow(w);
9016 gc = ds->gc;
9017 cellRect = ds->cellRect;
9018 black = BlackPixelOfScreen(XtScreen(w));
9019 white = WhitePixelOfScreen(XtScreen(w));
9020 x1 = clipRect->x;
9021 x2 = clipRect->x + clipRect->width - 1;
9022 y1 = clipRect->y;
9023 y2 = clipRect->y + clipRect->height - 1;
9024 drawLeft = 1;
9025 drawRight = 1;
9026 drawBot = 1;
9027 drawTop = 1;
9028 if (cellRect->x != clipRect->x)
9029 drawLeft = 0;
9030 if (cellRect->x + cellRect->width != clipRect->x + clipRect->width)
9031 drawRight = 0;
9032 if (cellRect->y != clipRect->y)
9033 drawTop = 0;
9034 if (cellRect->y + cellRect->height != clipRect->y + clipRect->height)
9035 drawBot = 0;
9036 borderType = cell->cell.refValues->rightBorderType;
9037 if (borderType != XmBORDER_NONE && drawRight)
9039 if (borderType == XmBORDER_DASH)
9040 XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9041 XSetForeground(dpy, gc, cell->cell.refValues->rightBorderColor);
9042 XDrawLine(dpy, win, gc, x2, y1, x2, y2);
9043 if (borderType == XmBORDER_DASH)
9044 XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9046 borderType = cell->cell.refValues->bottomBorderType;
9047 if (borderType != XmBORDER_NONE && drawBot)
9049 if (borderType == XmBORDER_DASH)
9050 XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9051 XSetForeground(dpy, gc, cell->cell.refValues->bottomBorderColor);
9052 XDrawLine(dpy, win, gc, x1, y2, x2, y2);
9053 if (borderType == XmBORDER_DASH)
9054 XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9056 borderType = cell->cell.refValues->topBorderType;
9057 if (borderType != XmBORDER_NONE && drawTop)
9059 if (borderType == XmBORDER_DASH)
9060 XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9061 XSetForeground(dpy, gc, cell->cell.refValues->topBorderColor);
9062 XDrawLine(dpy, win, gc, x1, y1, x2, y1);
9063 if (borderType == XmBORDER_DASH)
9064 XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9066 borderType = cell->cell.refValues->leftBorderType;
9067 if (borderType != XmBORDER_NONE && drawLeft)
9069 if (borderType == XmBORDER_DASH)
9070 XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
9071 XSetForeground(dpy, gc, cell->cell.refValues->leftBorderColor);
9072 XDrawLine(dpy, win, gc, x1, y1, x1, y2);
9073 if (borderType == XmBORDER_DASH)
9074 XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
9076 if (ds->drawFocusType == XmDRAW_FOCUS_NONE)
9077 return;
9078 if (ds->drawFocusType == XmDRAW_FOCUS_LEFT)
9079 drawRight = 0;
9080 else if (ds->drawFocusType == XmDRAW_FOCUS_RIGHT)
9081 drawLeft = 0;
9082 else if (ds->drawFocusType == XmDRAW_FOCUS_MID)
9084 drawLeft = 0;
9085 drawRight = 0;
9087 if (!drawLeft)
9088 loff = 0;
9089 else
9090 loff = 2;
9091 if (!drawRight)
9092 roff = 0;
9093 else
9094 roff = 2;
9095 if (g->grid.highlightThickness < 2)
9096 return;
9097 XSetForeground(dpy, gc, g->manager.highlight_color);
9098 if (drawTop)
9099 XDrawLine(dpy, win, gc, x1, y1, x2, y1);
9100 if (drawLeft)
9101 XDrawLine(dpy, win, gc, x1, y1 + 2, x1, y2);
9102 if (drawRight)
9103 XDrawLine(dpy, win, gc, x2, y1 + 2, x2, y2);
9104 if (drawBot)
9105 XDrawLine(dpy, win, gc, x1 + loff, y2, x2 - roff, y2);
9106 if (drawTop && clipRect->height > 1)
9107 XDrawLine(dpy, win, gc, x1, y1 + 1, x2, y1 + 1);
9108 if (drawBot && (int)clipRect->height > 1 &&
9109 (int)clipRect->width > roff &&
9110 (int)clipRect->width > loff)
9111 XDrawLine(dpy, win, gc, x1 + loff, y2 - 1, x2 - roff, y2 - 1);
9112 if (clipRect->width > 1 && clipRect->height > 2)
9114 if (drawLeft)
9115 XDrawLine(dpy, win, gc, x1 + 1, y1 + 2, x1 + 1, y2);
9116 if (drawRight)
9117 XDrawLine(dpy, win, gc, x2 - 1, y1 + 2, x2 - 1, y2);
9121 /* Only to be called by XmLGridCellAction() */
9122 void
9123 _XmLGridCellDrawValue(XmLGridCell cell,
9124 Widget w,
9125 XRectangle *clipRect,
9126 XmLGridDrawStruct *ds)
9128 XmLGridWidget g;
9129 Display *dpy;
9130 XmLGridCellPixmap *pix;
9131 XmLGridCellIcon *icon;
9132 XRectangle cellRect;
9133 XmLGridCellRefValues *cellValues;
9134 int type, horizMargin, vertMargin, xoff;
9136 g = (XmLGridWidget)w;
9137 cellRect = *ds->cellRect;
9138 cellValues = cell->cell.refValues;
9139 horizMargin = ds->leftMargin + ds->rightMargin;
9140 vertMargin = ds->topMargin + ds->bottomMargin;
9141 if (horizMargin >= (int)cellRect.width ||
9142 vertMargin >= (int)cellRect.height)
9143 return;
9144 type = cellValues->type;
9145 cellRect.x += ds->leftMargin;
9146 cellRect.y += ds->topMargin;
9147 cellRect.width -= horizMargin;
9148 cellRect.height -= vertMargin;
9149 dpy = XtDisplay(w);
9150 if (type == XmSTRING_CELL && XmLGridCellIsValueSet(cell) == True)
9152 if (ds->drawSelected == True)
9153 XSetForeground(dpy, ds->gc, ds->selectForeground);
9154 else
9155 XSetForeground(dpy, ds->gc, ds->foreground);
9156 XmLStringDraw(w, (XmString)cell->cell.value, ds->stringDirection,
9157 ds->fontList, ds->alignment, ds->gc,
9158 &cellRect, clipRect);
9160 if (type == XmPIXMAP_CELL && XmLGridCellIsValueSet(cell) == True)
9162 pix = (XmLGridCellPixmap *)cell->cell.value;
9163 XmLPixmapDraw(w, pix->pixmap, pix->pixmask,
9164 pix->width, pix->height, ds->alignment,
9165 ds->gc, &cellRect, clipRect);
9167 if (type == XmICON_CELL && XmLGridCellIsValueSet(cell) == True)
9169 icon = (XmLGridCellIcon *)cell->cell.value;
9170 if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP)
9172 XmLPixmapDraw(w, icon->pix.pixmap, icon->pix.pixmask,
9173 icon->pix.width, icon->pix.height, ds->alignment,
9174 ds->gc, &cellRect, clipRect);
9175 xoff = icon->pix.width + g->grid.iconSpacing;
9176 cellRect.x += xoff;
9177 if (xoff < (int)cellRect.width)
9178 cellRect.width -= xoff;
9179 else
9180 cellRect.width = 0;
9182 if (cellRect.width && icon->string)
9184 if (ds->drawSelected == True)
9185 XSetForeground(dpy, ds->gc, ds->selectForeground);
9186 else
9187 XSetForeground(dpy, ds->gc, ds->foreground);
9188 XmLStringDraw(w, icon->string, ds->stringDirection,
9189 ds->fontList, ds->alignment, ds->gc,
9190 &cellRect, clipRect);
9193 if (type == XmTOGGLE_CELL)
9194 XmLDrawToggle(w, XmLGridCellGetToggle(cell),
9195 g->grid.toggleSize, ds->alignment, ds->gc,
9196 ds->background, g->grid.toggleTopColor,
9197 g->grid.toggleBotColor, ds->foreground,
9198 &cellRect, clipRect);
9200 if (cellRect.width > cellRect.height - 4 && XmLGridCellDrawSort(cell))
9202 int arrow_direction = XmLGridCellSortAscending(cell);
9203 int arrow_size = cellRect.height * 0.75;
9205 if (arrow_size > 0)
9207 XSetForeground(dpy, ds->gc, ds->background);
9209 _XmDrawArrow(dpy, XtWindow(w),
9210 ((XmManagerWidget)g)->manager.bottom_shadow_GC,
9211 ((XmManagerWidget)g)->manager.top_shadow_GC,
9212 ds->gc,
9213 cellRect.x + cellRect.width - arrow_size - 2,
9214 cellRect.y + (cellRect.height / 2 - arrow_size / 2),
9215 arrow_size,
9216 arrow_size,
9218 arrow_direction);
9224 /* Only to be called by XmLGridCellAction() */
9225 static int
9226 _XmLGridCellConfigureText(XmLGridCell cell, Widget w, XRectangle *rect)
9228 XmLGridWidget g;
9230 g = (XmLGridWidget)w;
9231 XtConfigureWidget(g->grid.text, rect->x, rect->y,
9232 rect->width, rect->height, 0);
9233 return(0);
9236 /* Only to be called by XmLGridCellAction() */
9237 static int
9238 _XmLGridCellBeginTextEdit(XmLGridCell cell,
9239 Widget w,
9240 XRectangle *clipRect)
9242 XmLGridWidget g = (XmLGridWidget)w;
9243 Widget text;
9245 if ((cell->cell.refValues->type != XmSTRING_CELL &&
9246 cell->cell.refValues->type != XmICON_CELL)
9247 || cell->cell.refValues->editable != True
9248 || g->grid.useTextWidget != True)
9249 return 0;
9250 XtVaGetValues(w,
9251 XmNtextWidget, &text,
9252 NULL);
9253 XtVaSetValues(text,
9254 XmNfontList, cell->cell.refValues->fontList,
9255 NULL);
9256 return 1;
9259 /* Only to be called by XmLGridCellAction() */
9260 static void
9261 _XmLGridCellCompleteTextEdit(XmLGridCell cell,
9262 Widget w)
9264 XmLGridWidget g = (XmLGridWidget)w;
9265 Widget text;
9266 char *s;
9267 int i, len;
9269 if ((cell->cell.refValues->type != XmSTRING_CELL &&
9270 cell->cell.refValues->type != XmICON_CELL)
9271 || cell->cell.refValues->editable != True
9272 || g->grid.useTextWidget != True)
9273 return;
9274 XtVaGetValues(w,
9275 XmNtextWidget, &text,
9276 NULL);
9277 s = XmTextGetString(text);
9278 len = strlen(s);
9279 for (i = 0; i < len - 1; i++)
9280 if (s[i] == '\\' && s[i + 1] == 'n')
9282 s[i] = '\n';
9283 strcpy(&s[i + 1], &s[i + 2]);
9285 XmLGridCellSetString(cell,
9286 XmStringCreateLtoR(s, XmSTRING_DEFAULT_CHARSET),
9287 False);
9288 #if 0
9289 if (XmLGridCellIsValueSet(cell) == True)
9290 XmStringFree((XmString)cell->cell.value);
9291 if (strlen(s))
9293 cell->cell.value = (void *)XmStringCreateLtoR(s,
9294 XmSTRING_DEFAULT_CHARSET);
9295 XmLGridCellSetValueSet(cell, True);
9297 else
9298 XmLGridCellSetValueSet(cell, False);
9299 #endif /*0*/
9300 XtFree(s);
9303 /* Only to be called by XmLGridCellAction() */
9304 static void
9305 _XmLGridCellInsertText(XmLGridCell cell,
9306 Widget w)
9308 XmLGridWidget g = (XmLGridWidget)w;
9309 char *s;
9310 Widget text = NULL;
9312 if ((cell->cell.refValues->type != XmSTRING_CELL &&
9313 cell->cell.refValues->type != XmICON_CELL)
9314 || cell->cell.refValues->editable != True
9315 || g->grid.useTextWidget != True)
9316 return;
9317 XtVaGetValues(w,
9318 XmNtextWidget, &text,
9319 NULL);
9320 s = 0;
9321 if (XmLGridCellIsValueSet(cell) == True)
9322 s = CvtXmStringToStr(XmLGridCellGetString(cell));
9323 if (s)
9325 XmTextSetString(text, s);
9326 free(s);
9328 else
9329 XmTextSetString(text, "");
9330 XmTextSetInsertionPosition(text, XmTextGetLastPosition(text));
9331 XmProcessTraversal(text, XmTRAVERSE_CURRENT);
9334 /* Only to be called by XmLGridCellAction() */
9335 static int
9336 _XmLGridCellGetHeight(XmLGridCell cell,
9337 Widget w,
9338 XmLGridRow row)
9340 XmLGridCellPixmap *pix;
9341 XmLGridCellIcon *icon;
9342 XmLGridCellRefValues *cellValues;
9343 int height, pixHeight;
9345 cellValues = cell->cell.refValues;
9346 height = -1;
9347 if (cellValues->type == XmPIXMAP_CELL)
9349 if (XmLGridCellIsValueSet(cell) == True)
9351 pix = (XmLGridCellPixmap *)cell->cell.value;
9352 if (pix->height)
9353 height = 4 + pix->height + cellValues->topMargin +
9354 cellValues->bottomMargin;
9357 else if (cellValues->type == XmICON_CELL)
9359 pixHeight = 0;
9360 if (XmLGridCellIsValueSet(cell) == True)
9362 icon = (XmLGridCellIcon *)cell->cell.value;
9363 if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.height)
9364 pixHeight = 4 + icon->pix.height +
9365 cellValues->topMargin + cellValues->bottomMargin;
9367 height = 4 + row->grid.height * cellValues->fontHeight +
9368 cellValues->topMargin + cellValues->bottomMargin;
9369 if (pixHeight > height)
9370 height = pixHeight;
9372 else if (cellValues->type == XmTOGGLE_CELL)
9373 height = 4 + 16 + cellValues->topMargin +
9374 cellValues->bottomMargin;
9375 else if (cellValues->type == XmSTRING_CELL)
9377 height = 4 + row->grid.height * cellValues->fontHeight +
9378 cellValues->topMargin + cellValues->bottomMargin;
9380 if (height < 0 || cellValues->rowSpan)
9381 height = 4;
9382 return height;
9385 /* Only to be called by XmLGridCellAction() */
9386 static int
9387 _XmLGridCellGetWidth(XmLGridCell cell,
9388 Widget w,
9389 XmLGridColumn col)
9391 XmLGridWidget g = (XmLGridWidget)w;
9392 XmLGridCellPixmap *pix;
9393 XmLGridCellIcon *icon;
9394 XmLGridCellRefValues *cellValues;
9395 int width;
9397 cellValues = cell->cell.refValues;
9398 width = -1;
9399 if (cellValues->type == XmPIXMAP_CELL)
9401 if (XmLGridCellIsValueSet(cell) == True)
9403 pix = (XmLGridCellPixmap *)cell->cell.value;
9404 if (pix->width)
9405 width = 4 + pix->width + cellValues->leftMargin +
9406 cellValues->rightMargin;
9409 else if (cellValues->type == XmICON_CELL)
9411 width = 4 + col->grid.width * cellValues->fontWidth +
9412 cellValues->leftMargin + cellValues->rightMargin;
9413 if (XmLGridCellIsValueSet(cell) == True)
9415 icon = (XmLGridCellIcon *)cell->cell.value;
9416 if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.width)
9417 width += icon->pix.width + g->grid.iconSpacing;
9420 else if (cellValues->type == XmTOGGLE_CELL)
9421 width = 4 + 16 + cellValues->leftMargin +
9422 cellValues->rightMargin;
9423 else if (cellValues->type == XmSTRING_CELL)
9424 width = 4 + col->grid.width * cellValues->fontWidth +
9425 cellValues->leftMargin + cellValues->rightMargin;
9426 if (width < 0 || cellValues->columnSpan)
9427 width = 4;
9428 return width;
9431 /* Only to be called by XmLGridCellAction() */
9432 static void
9433 _XmLGridCellFreeValue(XmLGridCell cell)
9435 int type;
9436 XmLGridCellIcon *icon;
9438 if (XmLGridCellIsValueSet(cell) == False)
9439 return;
9440 type = cell->cell.refValues->type;
9441 if (type == XmSTRING_CELL)
9442 XmStringFree((XmString)cell->cell.value);
9443 else if (type == XmPIXMAP_CELL)
9444 free((char *)cell->cell.value);
9445 else if (type == XmICON_CELL)
9447 icon = (XmLGridCellIcon *)cell->cell.value;
9448 if (icon->string)
9449 XmStringFree(icon->string);
9450 free((char *)icon);
9452 XmLGridCellSetValueSet(cell, False);
9456 Public Functions
9459 Widget
9460 XmLCreateGrid(Widget parent,
9461 char *name,
9462 ArgList arglist,
9463 Cardinal argcount)
9465 return XtCreateWidget(name, xmlGridWidgetClass, parent,
9466 arglist, argcount);
9469 void
9470 XmLGridAddColumns(Widget w,
9471 unsigned char type,
9472 int position,
9473 int count)
9475 XmLGridWidget g;
9476 XmLGridColumn col;
9477 XmLGridRow row;
9478 XmLGridCell cell;
9479 XmLGridCallbackStruct cbs;
9480 int i, j, rowCount, hasAddCB, redraw;
9482 g = WidgetToGrid(w, "AddColumns()");
9483 if (!g)
9484 return;
9485 if (count <= 0)
9486 return;
9487 redraw = 0;
9488 position = ColTypePosToPos(g, type, position, 1);
9489 if (position < 0)
9490 position = ColTypePosToPos(g, type, -1, 1);
9491 /* adjust count */
9492 if (type == XmHEADING)
9494 g->grid.headingColCount += count;
9495 g->grid.leftFixedCount += count;
9496 redraw = 1;
9498 else if (type == XmFOOTER)
9500 g->grid.footerColCount += count;
9501 g->grid.rightFixedCount += count;
9502 redraw = 1;
9504 else /* XmCONTENT */
9505 g->grid.colCount += count;
9507 hasAddCB = 0;
9508 if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
9509 hasAddCB = 1;
9510 /* add columns */
9511 XmLArrayAdd(g->grid.colArray, position, count);
9512 for (i = 0; i < count; i++)
9514 col = 0;
9515 if (hasAddCB)
9517 cbs.reason = XmCR_ADD_COLUMN;
9518 cbs.columnType = type;
9519 cbs.object = 0;
9520 XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9521 col = (XmLGridColumn)cbs.object;
9523 if (!col)
9524 col = XmLGridColumnNew(w);
9525 XmLArraySet(g->grid.colArray, position + i, col);
9527 /* add cells */
9528 rowCount = XmLArrayGetCount(g->grid.rowArray);
9529 for (j = 0; j < rowCount; j++)
9531 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
9532 XmLArrayAdd(XmLGridRowCells(row), position, count);
9533 for (i = position; i < position + count; i++)
9535 cell = 0;
9536 if (hasAddCB)
9538 cbs.reason = XmCR_ADD_CELL;
9539 cbs.rowType = RowPosToType(g, j);
9540 cbs.columnType = type;
9541 cbs.object = 0;
9542 XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9543 cell = (XmLGridCell)cbs.object;
9545 if (!cell)
9546 cell = XmLGridCellNew();
9547 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9548 if (col->grid.defCellValues)
9549 XmLGridCellSetRefValues(cell, col->grid.defCellValues);
9550 else
9551 XmLGridCellSetRefValues(cell, g->grid.defCellValues);
9552 XmLArraySet(XmLGridRowCells(row), i, cell);
9554 XmLGridRowHeightChanged(row);
9556 for (i = position; i < position + count; i++)
9558 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9559 XmLGridColumnWidthChanged(col);
9561 /* sanity check */
9562 if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
9563 g->grid.colCount + g->grid.footerColCount)
9564 XmLWarning(w, "AddColumns() - count sanity check failed");
9566 /* maintain scroll and focus position */
9567 if (g->grid.hsPolicy == XmCONSTANT)
9569 if (type == XmCONTENT && g->grid.colCount == count)
9570 g->grid.scrollCol = 0;
9571 else if (position <= g->grid.scrollCol)
9572 g->grid.scrollCol += count;
9574 if (position <= g->grid.focusCol)
9575 g->grid.focusCol += count;
9576 VisPosChanged(g, 0);
9577 HorizLayout(g, 1);
9578 VertLayout(g, 1);
9579 if (g->grid.focusCol == -1 && type == XmCONTENT)
9581 if (g->grid.focusRow != -1)
9582 SetFocus(g, g->grid.focusRow, position, 0, 0);
9583 else
9584 g->grid.focusCol = position;
9586 for (i = position; i < position + count; i++)
9587 redraw |= ColIsVisible(g, i);
9588 if (redraw)
9589 DrawArea(g, DrawAll, 0, 0);
9592 void
9593 XmLGridAddRows(Widget w,
9594 unsigned char type,
9595 int position,
9596 int count)
9598 XmLGridWidget g;
9599 XmLGridRow row;
9600 XmLGridColumn col;
9601 XmLGridCell cell;
9602 XmLGridCallbackStruct cbs;
9603 int i, j, hasAddCB, redraw, colCount;
9605 g = WidgetToGrid(w, "AddRows()");
9606 if (!g)
9607 return;
9608 if (count <= 0)
9609 return;
9610 redraw = 0;
9611 position = RowTypePosToPos(g, type, position, 1);
9612 if (position < 0)
9613 position = RowTypePosToPos(g, type, -1, 1);
9614 /* adjust count */
9615 if (type == XmHEADING)
9617 g->grid.headingRowCount += count;
9618 g->grid.topFixedCount += count;
9619 redraw = 1;
9621 else if (type == XmFOOTER)
9623 g->grid.footerRowCount += count;
9624 g->grid.bottomFixedCount += count;
9625 redraw = 1;
9627 else /* XmCONTENT */
9628 g->grid.rowCount += count;
9630 /* add rows and cells */
9631 XmLArrayAdd(g->grid.rowArray, position, count);
9632 colCount = XmLArrayGetCount(g->grid.colArray);
9633 hasAddCB = 0;
9634 if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
9635 hasAddCB = 1;
9636 for (i = 0; i < count; i++)
9638 row = 0;
9639 if (hasAddCB)
9641 cbs.reason = XmCR_ADD_ROW;
9642 cbs.rowType = type;
9643 cbs.object = 0;
9644 XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9645 row = (XmLGridRow)cbs.object;
9647 if (!row)
9648 row = XmLGridRowNew(w);
9649 XmLArraySet(g->grid.rowArray, position + i, row);
9650 XmLArrayAdd(XmLGridRowCells(row), 0, colCount);
9651 for (j = 0; j < colCount; j++)
9653 cell = 0;
9654 if (hasAddCB)
9656 cbs.reason = XmCR_ADD_CELL;
9657 cbs.rowType = type;
9658 cbs.columnType = ColPosToType(g, j);
9659 cbs.object = 0;
9660 XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
9661 cell = (XmLGridCell)cbs.object;
9663 if (!cell)
9664 cell = XmLGridCellNew();
9665 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
9666 if (col->grid.defCellValues)
9667 XmLGridCellSetRefValues(cell, col->grid.defCellValues);
9668 else
9669 XmLGridCellSetRefValues(cell, g->grid.defCellValues);
9670 XmLArraySet(XmLGridRowCells(row), j, cell);
9672 XmLGridRowHeightChanged(row);
9674 for (j = 0; j < colCount; j++)
9676 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
9677 XmLGridColumnWidthChanged(col);
9679 /* sanity check */
9680 if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
9681 g->grid.rowCount + g->grid.footerRowCount)
9682 XmLWarning(w, "AddRows() - count sanity check failed");
9684 /* maintain scroll and focus position */
9685 if (g->grid.vsPolicy == XmCONSTANT)
9687 if (type == XmCONTENT && g->grid.rowCount == count)
9688 g->grid.scrollRow = 0;
9689 else if (position <= g->grid.scrollRow)
9690 g->grid.scrollRow += count;
9692 if (position <= g->grid.focusRow)
9693 g->grid.focusRow += count;
9694 VisPosChanged(g, 1);
9695 HorizLayout(g, 1);
9696 VertLayout(g, 1);
9697 if (g->grid.focusRow == -1 && type == XmCONTENT)
9699 if (g->grid.focusCol != -1)
9700 SetFocus(g, position, g->grid.focusCol, 0, 0);
9701 else
9702 g->grid.focusRow = position;
9704 for (i = position; i < position + count; i++)
9705 redraw |= RowIsVisible(g, i);
9706 if (redraw)
9707 DrawArea(g, DrawAll, 0, 0);
9709 #ifdef XmLEVAL
9710 if (g->grid.rowCount > 100)
9712 fprintf(stderr, "XmL: evaluation version only supports <= 100 rows\n");
9713 exit(0);
9715 #endif
9718 void
9719 XmLGridDeleteAllColumns(Widget w,
9720 unsigned char type)
9722 XmLGridWidget g;
9723 int n;
9725 g = WidgetToGrid(w, "DeleteAllColumns()");
9726 if (!g)
9727 return;
9728 if (type == XmHEADING)
9729 n = g->grid.headingColCount;
9730 else if (type == XmCONTENT)
9731 n = g->grid.colCount;
9732 else if (type == XmFOOTER)
9733 n = g->grid.footerColCount;
9734 else
9736 XmLWarning(w, "DeleteAllColumns() - invalid type");
9737 return;
9739 if (!n)
9740 return;
9741 XmLGridDeleteColumns(w, type, 0, n);
9744 void
9745 XmLGridDeleteAllRows(Widget w,
9746 unsigned char type)
9748 XmLGridWidget g;
9749 int n;
9751 g = WidgetToGrid(w, "DeleteAllRows()");
9752 if (!g)
9753 return;
9754 if (type == XmHEADING)
9755 n = g->grid.headingRowCount;
9756 else if (type == XmCONTENT)
9757 n = g->grid.rowCount;
9758 else if (type == XmFOOTER)
9759 n = g->grid.footerRowCount;
9760 else
9762 XmLWarning(w, "DeleteAllRows() - invalid type");
9763 return;
9765 if (!n)
9766 return;
9767 XmLGridDeleteRows(w, type, 0, n);
9770 void
9771 XmLGridDeselectAllRows(Widget w,
9772 Boolean notify)
9774 XmLGridWidget g;
9776 g = WidgetToGrid(w, "DeselectAllRows()");
9777 if (!g)
9778 return;
9779 SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, False, notify);
9782 void
9783 XmLGridDeselectAllColumns(Widget w,
9784 Boolean notify)
9786 XmLGridWidget g;
9788 g = WidgetToGrid(w, "DeselectAllColumns()");
9789 if (!g)
9790 return;
9791 SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, False, notify);
9794 void
9795 XmLGridDeselectAllCells(Widget w,
9796 Boolean notify)
9798 XmLGridWidget g;
9800 g = WidgetToGrid(w, "DeselectAllCells()");
9801 if (!g)
9802 return;
9803 SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, False, notify);
9806 void
9807 XmLGridDeselectCell(Widget w,
9808 int row,
9809 int column,
9810 Boolean notify)
9812 XmLGridWidget g;
9814 g = WidgetToGrid(w, "DeselectCell()");
9815 if (!g)
9816 return;
9817 SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, False, notify);
9820 void
9821 XmLGridDeselectColumn(Widget w,
9822 int column,
9823 Boolean notify)
9825 XmLGridWidget g;
9827 g = WidgetToGrid(w, "DeselectColumn()");
9828 if (!g)
9829 return;
9830 SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, False, notify);
9833 void
9834 XmLGridDeselectRow(Widget w,
9835 int row,
9836 Boolean notify)
9838 XmLGridWidget g;
9840 g = WidgetToGrid(w, "DeselectRow()");
9841 if (!g)
9842 return;
9843 SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, False, notify);
9846 void
9847 XmLGridDeleteColumns(Widget w,
9848 unsigned char type,
9849 int position,
9850 int count)
9852 XmLGridWidget g;
9853 XmLGridRow row;
9854 XmLGridColumn col;
9855 XmLGridCallbackStruct cbs;
9856 int changeFocus, i, j, rowCount, lastPos, redraw;
9858 g = WidgetToGrid(w, "DeleteColumns()");
9859 if (!g)
9860 return;
9861 if (count <= 0)
9862 return;
9863 lastPos = ColTypePosToPos(g, type, position + count - 1, 0);
9864 position = ColTypePosToPos(g, type, position, 0);
9865 if (position < 0 || lastPos < 0)
9867 XmLWarning(w, "DeleteColumns() - invalid position");
9868 return;
9870 changeFocus = 0;
9871 if (position <= g->grid.focusCol && lastPos >= g->grid.focusCol)
9873 /* deleting focus col */
9874 TextAction(g, TEXT_EDIT_CANCEL);
9875 ChangeFocus(g, g->grid.focusRow, -1);
9876 changeFocus = 1;
9878 redraw = 0;
9880 if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
9881 for (i = position; i < position + count; i++)
9883 rowCount = XmLArrayGetCount(g->grid.rowArray);
9884 for (j = 0; j < rowCount; j++)
9886 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
9887 cbs.reason = XmCR_DELETE_CELL;
9888 cbs.rowType = RowPosToType(g, j);
9889 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
9890 cbs.columnType = type;
9891 cbs.column = RowPosToTypePos(g, cbs.columnType, j);
9892 cbs.object = XmLArrayGet(XmLGridRowCells(row), i);
9893 XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
9895 cbs.reason = XmCR_DELETE_COLUMN;
9896 cbs.columnType = type;
9897 cbs.column = RowPosToTypePos(g, cbs.columnType, i);
9898 cbs.object = XmLArrayGet(g->grid.colArray, i);
9899 XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
9902 /* adjust count */
9903 if (type == XmHEADING)
9905 g->grid.headingColCount -= count;
9906 g->grid.leftFixedCount -= count;
9907 redraw = 1;
9909 else if (type == XmFOOTER)
9911 g->grid.footerColCount -= count;
9912 g->grid.rightFixedCount -= count;
9913 redraw = 1;
9915 else /* XmCONTENT */
9916 g->grid.colCount -= count;
9918 for (i = position; i < position + count; i++)
9920 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9921 if (XmLGridColumnIsHidden(col) == True)
9922 g->grid.hiddenColCount--;
9923 redraw |= ColIsVisible(g, i);
9926 /* delete columns */
9927 for (i = position; i < position + count; i++)
9929 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
9930 XmLGridColumnFree(w, col);
9932 XmLArrayDel(g->grid.colArray, position, count);
9933 /* delete cells */
9934 rowCount = XmLArrayGetCount(g->grid.rowArray);
9935 for (i = 0; i < rowCount; i++)
9937 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
9938 for (j = position; j < position + count; j++)
9939 XmLGridCellFree(w,
9940 (XmLGridCell)XmLArrayGet(XmLGridRowCells(row), j));
9941 XmLArrayDel(XmLGridRowCells(row), position, count);
9942 XmLGridRowHeightChanged(row);
9944 /* sanity check */
9945 if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
9946 g->grid.colCount + g->grid.footerColCount)
9947 XmLWarning(w, "DeleteColumns() - count sanity check failed");
9949 /* maintain scroll and focus position */
9950 if (g->grid.hsPolicy == XmCONSTANT)
9952 if (lastPos < g->grid.scrollCol)
9953 g->grid.scrollCol -= count;
9954 else if (position <= g->grid.scrollCol)
9955 g->grid.scrollCol = position;
9957 if (lastPos < g->grid.focusCol)
9958 g->grid.focusCol -= count;
9959 VisPosChanged(g, 0);
9960 HorizLayout(g, 1);
9961 VertLayout(g, 1);
9962 if (changeFocus)
9964 SetFocus(g, g->grid.focusRow, position, 0, 1);
9965 if (g->grid.focusCol == -1)
9966 SetFocus(g, g->grid.focusRow, position, 0, -1);
9968 if (redraw)
9969 DrawArea(g, DrawAll, 0, 0);
9972 void
9973 XmLGridDeleteRows(Widget w,
9974 unsigned char type,
9975 int position,
9976 int count)
9978 XmLGridWidget g;
9979 XmLGridRow row;
9980 XmLGridColumn col;
9981 XmLGridCallbackStruct cbs;
9982 int changeFocus, i, j, colCount, lastPos, redraw;
9984 g = WidgetToGrid(w, "DeleteRows()");
9985 if (!g)
9986 return;
9987 if (count <= 0)
9988 return;
9989 lastPos = RowTypePosToPos(g, type, position + count - 1, 0);
9990 position = RowTypePosToPos(g, type, position, 0);
9991 if (position < 0 || lastPos < 0)
9993 XmLWarning(w, "DeleteRows() - invalid position");
9994 return;
9996 changeFocus = 0;
9997 if (position <= g->grid.focusRow && lastPos >= g->grid.focusRow)
9999 /* deleting focus row */
10000 TextAction(g, TEXT_EDIT_CANCEL);
10001 ChangeFocus(g, -1, g->grid.focusCol);
10002 changeFocus = 1;
10004 redraw = 0;
10006 if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
10007 for (i = position; i < position + count; i++)
10009 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10010 colCount = XmLArrayGetCount(g->grid.colArray);
10011 for (j = 0; j < colCount; j++)
10013 cbs.reason = XmCR_DELETE_CELL;
10014 cbs.rowType = type;
10015 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
10016 cbs.columnType = ColPosToType(g, j);
10017 cbs.column = ColPosToTypePos(g, cbs.columnType, j);
10018 cbs.object = XmLArrayGet(XmLGridRowCells(row), j);
10019 XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
10021 cbs.reason = XmCR_DELETE_ROW;
10022 cbs.rowType = type;
10023 cbs.row = RowPosToTypePos(g, cbs.rowType, i);
10024 cbs.object = (void *)row;
10025 XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
10028 /* adjust count */
10029 if (type == XmHEADING)
10031 g->grid.headingRowCount -= count;
10032 g->grid.topFixedCount -= count;
10033 redraw = 1;
10035 else if (type == XmFOOTER)
10037 g->grid.footerRowCount -= count;
10038 g->grid.bottomFixedCount -= count;
10039 redraw = 1;
10041 else /* XmCONTENT */
10042 g->grid.rowCount -= count;
10044 for (i = position; i < position + count; i++)
10046 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10047 if (XmLGridRowIsHidden(row) == True)
10048 g->grid.hiddenRowCount--;
10049 redraw |= RowIsVisible(g, i);
10052 /* delete rows and cells */
10053 for (i = position; i < position + count; i++)
10055 row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
10056 XmLGridRowFree(w, row);
10058 XmLArrayDel(g->grid.rowArray, position, count);
10059 colCount = XmLArrayGetCount(g->grid.colArray);
10060 for (i = 0; i < colCount; i++)
10062 col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
10063 XmLGridColumnWidthChanged(col);
10065 /* sanity check */
10066 if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
10067 g->grid.rowCount + g->grid.footerRowCount)
10068 XmLWarning(w, "DeleteRows() - count sanity check failed");
10070 /* maintain scroll and focus position */
10071 if (g->grid.vsPolicy == XmCONSTANT)
10073 if (lastPos < g->grid.scrollRow)
10074 g->grid.scrollRow -= count;
10075 else if (position <= g->grid.scrollRow)
10076 g->grid.scrollRow = position;
10078 if (lastPos < g->grid.focusRow)
10079 g->grid.focusRow -= count;
10080 VisPosChanged(g, 1);
10081 HorizLayout(g, 1);
10082 VertLayout(g, 1);
10083 if (changeFocus)
10085 SetFocus(g, position, g->grid.focusCol, 1, 0);
10086 if (g->grid.focusRow == -1)
10087 SetFocus(g, position, g->grid.focusCol, -1, 0);
10089 if (redraw)
10090 DrawArea(g, DrawAll, 0, 0);
10093 void
10094 XmLGridGetFocus(Widget w,
10095 int *row,
10096 int *column,
10097 Boolean *focusIn)
10099 XmLGridWidget g;
10100 unsigned char rowType, colType;
10102 g = WidgetToGrid(w, "GetFocus()");
10103 if (!g)
10104 return;
10105 if (g->grid.focusIn)
10106 *focusIn = True;
10107 else
10108 *focusIn = False;
10109 if (g->grid.focusRow < 0 || g->grid.focusCol < 0)
10111 *row = -1;
10112 *column = -1;
10113 return;
10115 rowType = RowPosToType(g, g->grid.focusRow);
10116 colType = ColPosToType(g, g->grid.focusCol);
10117 if (rowType != XmCONTENT || colType != XmCONTENT)
10119 *row = -1;
10120 *column = -1;
10121 XmLWarning(w, "GetFocus() - focus row/column invalid\n");
10122 return;
10124 *row = RowPosToTypePos(g, XmCONTENT, g->grid.focusRow);
10125 *column = ColPosToTypePos(g, XmCONTENT, g->grid.focusCol);
10128 XmLGridRow
10129 XmLGridGetRow(Widget w,
10130 unsigned char rowType,
10131 int row)
10134 XmLGridWidget g;
10135 XmLGridRow r;
10136 int pos;
10138 g = WidgetToGrid(w, "GetRow()");
10139 if (!g)
10140 return 0;
10141 pos = RowTypePosToPos(g, rowType, row, 0);
10142 r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
10143 if (!r)
10144 XmLWarning(w, "GetRow() - invalid row");
10145 return r;
10149 XmLGridEditBegin(Widget w,
10150 Boolean insert,
10151 int row,
10152 int column)
10154 XmLGridWidget g;
10155 int r, c;
10156 XRectangle rect;
10158 g = WidgetToGrid(w, "EditBegin()");
10159 if (!g)
10160 return -1;
10161 if (column < 0 || column >= g->grid.colCount)
10163 XmLWarning(w, "EditBegin() - invalid column");
10164 return -1;
10166 if (row < 0 || row >= g->grid.rowCount)
10168 XmLWarning(w, "EditBegin() - invalid row");
10169 return -1;
10171 r = RowTypePosToPos(g, XmCONTENT, row, 0);
10172 c = ColTypePosToPos(g, XmCONTENT, column, 0);
10173 if (RowColToXY(g, r, c, True, &rect) == -1)
10175 XmLWarning(w, "EditBegin() - cell must be visible to begin edit");
10176 return -1;
10178 if (SetFocus(g, r, c, 0, 0) == -1)
10180 XmLWarning(w, "EditBegin() - can't set focus to cell");
10181 return -1;
10183 if (insert == False)
10184 TextAction(g, TEXT_EDIT);
10185 else
10186 TextAction(g, TEXT_EDIT_INSERT);
10187 return 0;
10190 void
10191 XmLGridEditCancel(Widget w)
10193 XmLGridWidget g;
10195 g = WidgetToGrid(w, "EditCancel()");
10196 if (!g)
10197 return;
10198 TextAction(g, TEXT_EDIT_CANCEL);
10201 void
10202 XmLGridEditComplete(Widget w)
10204 XmLGridWidget g;
10206 g = WidgetToGrid(w, "EditComplete()");
10207 if (!g)
10208 return;
10209 TextAction(g, TEXT_EDIT_COMPLETE);
10212 XmLGridColumn
10213 XmLGridGetColumn(Widget w,
10214 unsigned char columnType,
10215 int column)
10217 XmLGridWidget g;
10218 XmLGridColumn c;
10219 int pos;
10221 g = WidgetToGrid(w, "GetColumn()");
10222 if (!g)
10223 return 0;
10224 pos = ColTypePosToPos(g, columnType, column, 0);
10225 c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
10226 if (!c)
10227 XmLWarning(w, "GetColumn() - invalid column");
10228 return c;
10232 XmLGridGetSelectedCellCount(Widget w)
10234 XmLGridWidget g;
10236 g = WidgetToGrid(w, "GetSelectedCellCount()");
10237 if (!g)
10238 return -1;
10239 return GetSelectedArea(g, SelectCell, 0, 0, 0);
10243 XmLGridGetSelectedCells(Widget w,
10244 int *rowPositions,
10245 int *columnPositions,
10246 int count)
10248 XmLGridWidget g;
10249 int n;
10251 g = WidgetToGrid(w, "GetSelectedCells()");
10252 if (!g)
10253 return -1;
10254 n = GetSelectedArea(g, SelectCell, rowPositions, columnPositions, count);
10255 if (count != n)
10257 XmLWarning(w, "GetSelectedCells() - count is incorrect");
10258 return -1;
10260 return 0;
10264 XmLGridGetSelectedColumnCount(Widget w)
10266 XmLGridWidget g;
10268 g = WidgetToGrid(w, "GetSelectedColumnCount()");
10269 if (!g)
10270 return -1;
10271 return GetSelectedArea(g, SelectCol, 0, 0, 0);
10275 XmLGridGetSelectedColumns(Widget w,
10276 int *positions,
10277 int count)
10279 XmLGridWidget g;
10280 int n;
10282 g = WidgetToGrid(w, "GetSelectedColumns()");
10283 if (!g)
10284 return -1;
10285 n = GetSelectedArea(g, SelectCol, 0, positions, count);
10286 if (count != n)
10288 XmLWarning(w, "GetSelectedColumns() - count is incorrect");
10289 return -1;
10291 return 0;
10295 XmLGridGetSelectedRow(Widget w)
10297 XmLGridWidget g;
10298 int n, pos;
10300 g = WidgetToGrid(w, "GetSelectedRow()");
10301 if (!g)
10302 return -1;
10303 n = GetSelectedArea(g, SelectRow, &pos, 0, 1);
10304 if (n != 1)
10305 return -1;
10306 return pos;
10310 XmLGridGetSelectedRowCount(Widget w)
10312 XmLGridWidget g;
10314 g = WidgetToGrid(w, "GetSelectedRowCount()");
10315 if (!g)
10316 return -1;
10317 return GetSelectedArea(g, SelectRow, 0, 0, 0);
10321 XmLGridGetSelectedRows(Widget w,
10322 int *positions,
10323 int count)
10325 XmLGridWidget g;
10326 int n;
10328 g = WidgetToGrid(w, "GetSelectedRows()");
10329 if (!g)
10330 return -1;
10331 n = GetSelectedArea(g, SelectRow, positions, 0, count);
10332 if (count != n)
10334 XmLWarning(w, "GetSelectedRows() - count is incorrect");
10335 return -1;
10337 return 0;
10340 Boolean
10341 XmLGridColumnIsVisible(Widget w,
10342 int col)
10344 XmLGridWidget g;
10346 g = WidgetToGrid(w, "ColumnIsVisible()");
10347 if (!g)
10348 return -1;
10349 if (!ColIsVisible(g, g->grid.headingColCount + col))
10350 return False;
10351 return True;
10354 void
10355 XmLGridMoveColumns(Widget w,
10356 int newPosition,
10357 int position,
10358 int count)
10360 XmLGridWidget g;
10361 XmLGridRow row;
10362 int i, np, p, rowCount;
10364 g = WidgetToGrid(w, "MoveColumns()");
10365 if (!g)
10366 return;
10367 np = ColTypePosToPos(g, XmCONTENT, newPosition, 0);
10368 p = ColTypePosToPos(g, XmCONTENT, position, 0);
10369 if (XmLArrayMove(g->grid.colArray, np, p, count) == -1)
10371 XmLWarning(w, "MoveColumns() - invalid position");
10372 return;
10374 rowCount = XmLArrayGetCount(g->grid.rowArray);
10375 for (i = 0; i < rowCount; i++)
10377 row = XmLArrayGet(g->grid.rowArray, i);
10378 XmLArrayMove(XmLGridRowCells(row), np, p, count);
10380 VisPosChanged(g, 0);
10381 HorizLayout(g, 1);
10382 DrawArea(g, DrawAll, 0, 0);
10385 void
10386 XmLGridMoveRows(Widget w,
10387 int newPosition,
10388 int position,
10389 int count)
10391 XmLGridWidget g;
10392 int np, p;
10394 g = WidgetToGrid(w, "MoveRows()");
10395 if (!g)
10396 return;
10397 np = RowTypePosToPos(g, XmCONTENT, newPosition, 0);
10398 p = RowTypePosToPos(g, XmCONTENT, position, 0);
10399 if (XmLArrayMove(g->grid.rowArray, np, p, count) == -1)
10401 XmLWarning(w, "MoveRows() - invalid position/count");
10402 return;
10404 VisPosChanged(g, 1);
10405 VertLayout(g, 1);
10406 DrawArea(g, DrawAll, 0, 0);
10409 void
10410 XmLGridReorderColumns(Widget w,
10411 int *newPositions,
10412 int position,
10413 int count)
10415 XmLGridWidget g;
10416 XmLGridRow row;
10417 int i, *np, p, rowCount, status;
10419 g = WidgetToGrid(w, "ReorderColumns()");
10420 if (!g)
10421 return;
10422 if (count <= 0)
10423 return;
10424 p = ColTypePosToPos(g, XmCONTENT, position, 0);
10425 np = (int *)malloc(sizeof(int) * count);
10426 for (i = 0; i < count; i++)
10427 np[i] = ColTypePosToPos(g, XmCONTENT, newPositions[i], 0);
10428 status = XmLArrayReorder(g->grid.colArray, np, p, count);
10429 if (status < 0)
10431 free((char *)np);
10432 XmLWarning(w, "ReorderColumns() - invalid position/count");
10433 return;
10435 rowCount = XmLArrayGetCount(g->grid.rowArray);
10436 for (i = 0; i < rowCount; i++)
10438 row = XmLArrayGet(g->grid.rowArray, i);
10439 XmLArrayReorder(XmLGridRowCells(row), np, p, count);
10441 free((char *)np);
10442 VisPosChanged(g, 0);
10443 HorizLayout(g, 1);
10444 DrawArea(g, DrawAll, 0, 0);
10447 void
10448 XmLGridReorderRows(Widget w,
10449 int *newPositions,
10450 int position,
10451 int count)
10453 XmLGridWidget g;
10454 int i, *np, p, status;
10456 g = WidgetToGrid(w, "ReorderRows()");
10457 if (!g)
10458 return;
10459 if (count <= 0)
10460 return;
10461 p = RowTypePosToPos(g, XmCONTENT, position, 0);
10462 np = (int *)malloc(sizeof(int) * count);
10463 for (i = 0; i < count; i++)
10464 np[i] = RowTypePosToPos(g, XmCONTENT, newPositions[i], 0);
10465 status = XmLArrayReorder(g->grid.rowArray, np, p, count);
10466 free((char *)np);
10467 if (status == -1)
10469 XmLWarning(w, "ReorderRows() - invalid position/count");
10470 return;
10472 VisPosChanged(g, 1);
10473 VertLayout(g, 1);
10474 DrawArea(g, DrawAll, 0, 0);
10478 XmLGridRowColumnToXY(Widget w,
10479 unsigned char rowType,
10480 int row,
10481 unsigned char columnType,
10482 int column,
10483 Boolean clipped,
10484 XRectangle *rect)
10486 XmLGridWidget g;
10487 int r, c;
10489 g = WidgetToGrid(w, "RowColumnToXY()");
10490 if (!g)
10491 return -1;
10492 r = RowTypePosToPos(g, rowType, row, 0);
10493 c = ColTypePosToPos(g, columnType, column, 0);
10494 if (r < 0 || r >= XmLArrayGetCount(g->grid.rowArray) ||
10495 c < 0 || c >= XmLArrayGetCount(g->grid.colArray))
10497 /* XmLWarning(w, "RowColumnToXY() - invalid position");*/
10498 return -1;
10500 return RowColToXY(g, r, c, clipped, rect);
10503 Boolean
10504 XmLGridRowIsVisible(Widget w, int row)
10506 XmLGridWidget g;
10508 g = WidgetToGrid(w, "RowIsVisible()");
10509 if (!g)
10510 return -1;
10511 if (!RowIsVisible(g, g->grid.headingRowCount + row))
10512 return False;
10513 return True;
10516 void
10517 XmLGridSelectAllRows(Widget w,
10518 Boolean notify)
10520 XmLGridWidget g;
10522 g = WidgetToGrid(w, "SelectAllRows()");
10523 if (!g)
10524 return;
10525 SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, True, notify);
10528 void
10529 XmLGridSelectAllColumns(Widget w,
10530 Boolean notify)
10532 XmLGridWidget g;
10534 g = WidgetToGrid(w, "SelectAllColumns()");
10535 if (!g)
10536 return;
10537 SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, True, notify);
10540 void
10541 XmLGridSelectAllCells(Widget w,
10542 Boolean notify)
10544 XmLGridWidget g;
10546 g = WidgetToGrid(w, "SelectAllCells()");
10547 if (!g)
10548 return;
10549 SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, True, notify);
10552 void
10553 XmLGridSelectCell(Widget w,
10554 int row,
10555 int column,
10556 Boolean notify)
10558 XmLGridWidget g;
10560 g = WidgetToGrid(w, "SelectCell()");
10561 if (!g)
10562 return;
10563 SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, True, notify);
10566 void
10567 XmLGridSelectColumn(Widget w,
10568 int column,
10569 Boolean notify)
10571 XmLGridWidget g;
10573 g = WidgetToGrid(w, "SelectColumn()");
10574 if (!g)
10575 return;
10576 SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, True, notify);
10579 void
10580 XmLGridSelectRow(Widget w,
10581 int row,
10582 Boolean notify)
10584 XmLGridWidget g;
10586 g = WidgetToGrid(w, "SelectRow()");
10587 if (!g)
10588 return;
10589 SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, True, notify);
10593 XmLGridSetFocus(Widget w,
10594 int row,
10595 int column)
10597 XmLGridWidget g;
10598 int r, c;
10600 g = WidgetToGrid(w, "SetFocus()");
10601 if (!g)
10602 return -1;
10603 if (row < 0 || row >= g->grid.rowCount)
10605 XmLWarning(w, "SetFocus() - invalid row");
10606 return -1;
10608 if (column < 0 || column >= g->grid.colCount)
10610 XmLWarning(w, "SetFocus() - invalid column");
10611 return -1;
10613 r = RowTypePosToPos(g, XmCONTENT, row, 0);
10614 c = ColTypePosToPos(g, XmCONTENT, column, 0);
10615 return SetFocus(g, r, c, 0, 0);
10619 XmLGridXYToRowColumn(Widget w,
10620 int x,
10621 int y,
10622 unsigned char *rowType,
10623 int *row,
10624 unsigned char *columnType,
10625 int *column)
10627 XmLGridWidget g;
10628 int r, c;
10630 g = WidgetToGrid(w, "XYToRowColumn()");
10631 if (!g)
10632 return -1;
10633 if (XYToRowCol(g, x, y, &r, &c) == -1)
10634 return -1;
10635 *rowType = RowPosToType(g, r);
10636 *row = RowPosToTypePos(g, *rowType, r);
10637 *columnType = ColPosToType(g, c);
10638 *column = ColPosToTypePos(g, *columnType, c);
10639 return 0;
10642 void
10643 XmLGridRedrawAll(Widget w)
10645 XmLGridWidget g;
10647 g = WidgetToGrid(w, "RedrawAll()");
10648 if (!g)
10649 return;
10650 DrawArea(g, DrawAll, 0, 0);
10653 void
10654 XmLGridRedrawCell(Widget w,
10655 unsigned char rowType,
10656 int row,
10657 unsigned char columnType,
10658 int column)
10660 XmLGridWidget g;
10661 int r, c;
10663 g = WidgetToGrid(w, "RedrawCell()");
10664 if (!g)
10665 return;
10666 r = RowTypePosToPos(g, rowType, row, 0);
10667 c = ColTypePosToPos(g, columnType, column, 0);
10668 DrawArea(g, DrawCell, r, c);
10671 void
10672 XmLGridRedrawColumn(Widget w,
10673 unsigned char type,
10674 int column)
10676 XmLGridWidget g;
10677 int c;
10679 g = WidgetToGrid(w, "RedrawColumn()");
10680 if (!g)
10681 return;
10682 c = ColTypePosToPos(g, type, column, 0);
10683 DrawArea(g, DrawCol, 0, c);
10686 void
10687 XmLGridRedrawRow(Widget w,
10688 unsigned char type,
10689 int row)
10691 XmLGridWidget g;
10692 int r;
10694 g = WidgetToGrid(w, "RedrawRow()");
10695 if (!g)
10696 return;
10697 r = RowTypePosToPos(g, type, row, 0);
10698 DrawArea(g, DrawRow, r, 0);
10702 XmLGridRead(Widget w,
10703 FILE *file,
10704 int format,
10705 char delimiter)
10707 XmLGridWidget g;
10708 char *data;
10709 int n;
10711 g = WidgetToGrid(w, "Read()");
10712 if (!g)
10713 return 0;
10714 if (!file)
10716 XmLWarning(w, "Read() - file is NULL");
10717 return 0;
10719 data = FileToString(file);
10720 if (!data)
10722 XmLWarning(w, "Read() - error loading file");
10723 return 0;
10725 n = Read(g, format, delimiter, 0, 0, data);
10726 free((char *)data);
10727 return n;
10731 XmLGridReadPos(Widget w,
10732 FILE *file,
10733 int format,
10734 char delimiter,
10735 unsigned char rowType,
10736 int row,
10737 unsigned char columnType,
10738 int column)
10740 XmLGridWidget g;
10741 char *data;
10742 int r, c, n;
10744 g = WidgetToGrid(w, "ReadPos()");
10745 if (!g)
10746 return 0;
10747 if (!file)
10749 XmLWarning(w, "ReadPos() - file is NULL");
10750 return 0;
10752 data = FileToString(file);
10753 if (!data)
10755 XmLWarning(w, "ReadPos() - error loading file");
10756 return 0;
10758 r = RowTypePosToPos(g, rowType, row, 0);
10759 c = ColTypePosToPos(g, columnType, column, 0);
10760 n = Read(g, format, delimiter, r, c, data);
10761 free((char *)data);
10762 return n;
10766 XmLGridSetStrings(Widget w,
10767 char *data)
10769 XmLGridWidget g;
10771 g = WidgetToGrid(w, "SetStrings()");
10772 if (!g)
10773 return 0;
10774 return Read(g, XmFORMAT_DELIMITED, '|', 0, 0, data);
10778 XmLGridSetStringsPos(Widget w,
10779 unsigned char rowType,
10780 int row,
10781 unsigned char columnType,
10782 int column,
10783 char *data)
10785 XmLGridWidget g;
10786 int r, c;
10788 g = WidgetToGrid(w, "SetStringsPos()");
10789 if (!g)
10790 return 0;
10791 r = RowTypePosToPos(g, rowType, row, 0);
10792 c = ColTypePosToPos(g, columnType, column, 0);
10793 return Read(g, XmFORMAT_DELIMITED, '|', r, c, data);
10797 XmLGridWrite(Widget w,
10798 FILE *file,
10799 int format,
10800 char delimiter,
10801 Boolean skipHidden)
10803 XmLGridWidget g;
10804 int nrow, ncol;
10806 g = WidgetToGrid(w, "Write()");
10807 if (!g)
10808 return 0;
10809 nrow = XmLArrayGetCount(g->grid.rowArray);
10810 ncol = XmLArrayGetCount(g->grid.colArray);
10811 Write(g, file, format, delimiter, skipHidden, 0, 0, nrow, ncol);
10812 return 0;
10816 XmLGridWritePos(Widget w,
10817 FILE *file,
10818 int format,
10819 char delimiter,
10820 Boolean skipHidden,
10821 unsigned char rowType,
10822 int row,
10823 unsigned char columnType,
10824 int column,
10825 int nrow,
10826 int ncolumn)
10828 XmLGridWidget g;
10829 int r, c;
10831 g = WidgetToGrid(w, "WritePos()");
10832 if (!g)
10833 return 0;
10834 r = RowTypePosToPos(g, rowType, row, 0);
10835 c = ColTypePosToPos(g, columnType, column, 0);
10836 Write(g, file, format, delimiter, skipHidden, r, c, nrow, ncolumn);
10837 return 0;
10840 Boolean
10841 XmLGridCopyPos(Widget w,
10842 Time time,
10843 unsigned char rowType,
10844 int row,
10845 unsigned char columnType,
10846 int column,
10847 int nrow,
10848 int ncolumn)
10850 XmLGridWidget g;
10851 int r, c;
10853 g = WidgetToGrid(w, "CopyPos()");
10854 if (!g)
10855 return False;
10856 r = RowTypePosToPos(g, rowType, row, 0);
10857 c = ColTypePosToPos(g, columnType, column, 0);
10858 return Copy(g, time, 0, r, c, nrow, ncolumn);
10861 Boolean
10862 XmLGridCopySelected(Widget w,
10863 Time time)
10865 XmLGridWidget g;
10867 g = WidgetToGrid(w, "CopySelected()");
10868 if (!g)
10869 return False;
10870 return Copy(g, time, 1, 0, 0, 0, 0);
10873 Boolean
10874 XmLGridPaste(Widget w)
10876 XmLGridWidget g;
10877 int r, c;
10879 g = WidgetToGrid(w, "Paste()");
10880 if (!g)
10881 return False;
10882 r = g->grid.focusRow;
10883 c = g->grid.focusCol;
10884 if (r < 0 || c < 0)
10886 XmLWarning(w, "Paste() - no cell has focus");
10887 return False;
10889 return Paste(g, r, c);
10892 Boolean
10893 XmLGridPastePos(Widget w,
10894 unsigned char rowType,
10895 int row,
10896 unsigned char columnType,
10897 int column)
10899 XmLGridWidget g;
10900 int r, c;
10902 g = WidgetToGrid(w, "PastePos()");
10903 if (!g)
10904 return False;
10905 r = RowTypePosToPos(g, rowType, row, 0);
10906 c = ColTypePosToPos(g, columnType, column, 0);
10907 return Paste(g, r, c);
10910 /* XFE Additions below here */
10911 static void
10912 EditTimer(XtPointer clientData,
10913 XtIntervalId *intervalId)
10915 XmLGridWidget g;
10917 g = (XmLGridWidget)clientData;
10919 g->grid.editTimerSet = 0;
10920 g->grid.lastSelectTime = 0;
10921 TextAction(g,TEXT_EDIT_INSERT);
10924 void
10925 XmLGridSetVisibleColumnCount(Widget w, int new_num_visible)
10927 XmLGridWidget g = (XmLGridWidget)w;
10928 int ii, num_columns, visible_count;
10929 XmLGridColumn colp;
10932 visible_count = 0;
10933 num_columns = XmLArrayGetCount(g->grid.colArray);
10935 if (new_num_visible == 0)
10936 return;
10937 for (ii = 0; ii < num_columns; ii ++)
10939 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
10941 if (colp->grid.hidden && visible_count < new_num_visible)
10943 colp->grid.hidden = False;
10945 else if (!colp->grid.hidden && visible_count >= new_num_visible)
10947 colp->grid.hidden = True;
10949 if (!colp->grid.hidden)
10950 visible_count++;
10952 if (visible_count < num_columns)
10953 g->grid.visibleCols = visible_count;
10954 else
10955 g->grid.visibleCols = 0;
10957 setHideUnhideSensitivity(w);
10959 HorizLayout(g, 1);
10960 DrawArea(g, DrawAll, 0, 0);
10963 static void
10964 HideColumn(Widget w, XtPointer clientData, XtPointer callData)
10966 Widget g = (Widget) clientData;
10968 XmLGridHideRightColumn(g);
10970 static void
10971 UnhideColumn(Widget w, XtPointer clientData, XtPointer callData)
10973 Widget g = (Widget) clientData;
10975 XmLGridUnhideRightColumn(g);
10978 static void
10979 CreateHideUnhideButtons(XmLGridWidget g)
10981 if (!g->grid.hideUnhideButtons)
10983 XmLWarning((Widget)g,"CreateHideUnhideButtons - Creating buttons when XmNhideUnhideButtons is False.");
10984 return;
10987 g->grid.hideButton = XtVaCreateWidget(
10988 "hide", xmDrawnButtonWidgetClass,
10989 (Widget)g, XmNhighlightThickness, 0,
10990 XmNshadowThickness, 1,
10991 XmNtraversalOn, False,
10992 XmNbackground, g->core.background_pixel,
10993 XmNforeground, g->manager.foreground,
10994 XmNtopShadowColor, g->manager.top_shadow_color,
10995 XmNbottomShadowColor, g->manager.bottom_shadow_color,
10996 NULL);
10998 g->grid.unhideButton = XtVaCreateWidget(
10999 "unhide", xmDrawnButtonWidgetClass,
11000 (Widget)g, XmNhighlightThickness, 0,
11001 XmNshadowThickness, 1,
11002 XmNtraversalOn, False,
11003 XmNbackground, g->core.background_pixel,
11004 XmNforeground, g->manager.foreground,
11005 XmNtopShadowColor, g->manager.top_shadow_color,
11006 XmNbottomShadowColor, g->manager.bottom_shadow_color,
11007 NULL);
11009 XmLDrawnButtonSetType(g->grid.hideButton, XmDRAWNB_SMALLARROW,
11010 XmDRAWNB_RIGHT);
11011 XmLDrawnButtonSetType(g->grid.unhideButton, XmDRAWNB_SMALLARROW,
11012 XmDRAWNB_LEFT);
11015 XtAddCallback(g->grid.hideButton, XmNactivateCallback,
11016 HideColumn, (XtPointer)g);
11017 XtAddCallback(g->grid.unhideButton, XmNactivateCallback,
11018 UnhideColumn, (XtPointer)g);
11019 #if 0
11020 XtOverrideTranslations(g->grid.unhideButton,
11021 g->grid.unhideButtonTrans);
11022 XtOverrideTranslations(g->grid.hideButton,
11023 g->grid.hideButtonTrans);
11024 #endif /*0*/
11027 static void
11028 HideAction(Widget w,
11029 XEvent *event,
11030 String *params,
11031 Cardinal *num_params)
11033 XmLGridHideRightColumn(w);
11036 static void
11037 UnhideAction(Widget w,
11038 XEvent *event,
11039 String *params,
11040 Cardinal *num_params)
11042 XmLGridUnhideRightColumn(w);
11045 static void
11046 setHideUnhideSensitivity(Widget w)
11048 XmLGridWidget g = (XmLGridWidget)w;
11049 int total_columns = XmLArrayGetCount(g->grid.colArray);
11050 Boolean can_unhide, can_hide;
11052 if (!g->grid.hideUnhideButtons) return;
11054 /* If visibleCols is zero, that means all the columns are visible. */
11055 if (g->grid.visibleCols == 0) {
11056 can_unhide = 0;
11057 can_hide = (total_columns > 1);
11058 } else {
11059 can_unhide = (g->grid.visibleCols < total_columns);
11060 can_hide = (g->grid.visibleCols > 1);
11062 XtSetSensitive(g->grid.unhideButton, can_unhide);
11063 XtSetSensitive(g->grid.hideButton, can_hide);
11066 void
11067 XmLGridHideRightColumn(Widget w)
11069 XmLGridWidget g = (XmLGridWidget)w;
11070 int total_columns = XmLArrayGetCount(g->grid.colArray);
11071 if (total_columns <= 1)
11072 return;
11074 /* If visibleCols is zero, that means all the columns are visible. */
11075 if (g->grid.visibleCols == 0 || g->grid.visibleCols > total_columns)
11076 XmLGridSetVisibleColumnCount(w, total_columns - 1);
11077 else
11078 XmLGridSetVisibleColumnCount(w, g->grid.visibleCols - 1);
11081 void
11082 XmLGridUnhideRightColumn(Widget w)
11084 XmLGridWidget g = (XmLGridWidget)w;
11085 int total_columns = XmLArrayGetCount(g->grid.colArray);
11087 /* If visibleCols is zero, that means all the columns are visible. */
11088 if ( g->grid.visibleCols != 0 && g->grid.visibleCols < total_columns)
11089 XmLGridSetVisibleColumnCount(w, g->grid.visibleCols + 1);
11092 static void
11093 MenuArm(Widget w,
11094 XEvent *event,
11095 String *params,
11096 Cardinal *num_params)
11098 XmLGridWidget g = (XmLGridWidget)w;
11100 SelectTypeArea(g, SelectRow, (XEvent *)0, g->grid.lastSelectRow, 0, False, False);
11102 g->grid.inMode = InSelect;
11105 static void
11106 MenuDisarm(Widget w,
11107 XEvent *event,
11108 String *params,
11109 Cardinal *num_params)
11111 XmLGridWidget g = (XmLGridWidget)w;
11113 g->grid.inMode = InNormal;
11116 static void
11117 ResizeColumnToFit(XmLGridWidget g, int new_x)
11119 XmLGridColumn colp;
11120 int width = 0;
11121 XRectangle rect;
11122 if (!RowColToXY(g, 0, g->grid.resizeCol, False, &rect))
11124 if (new_x > rect.x)
11125 width = (new_x - rect.x) -
11126 (rect.width - GetColWidth(g, g->grid.resizeCol));
11127 if (width < g->grid.minColWidth)
11128 width = g->grid.minColWidth;
11130 /*printf("col(%d) resize_xy(%3d) colx(%3d) colw(%3d) column_width(%3d) new_width(%3d)\n", g->grid.resizeCol, g->grid.resizeLineXY, rect.x, rect.width, GetColWidth(g, g->grid.resizeCol), width);*/
11132 /* Resize all columns to the right */
11133 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray,
11134 g->grid.resizeCol);
11135 colp->grid.width = width;
11136 SizeColumnsToFit(g, g->grid.resizeCol + 1);
11137 HorizLayout(g, 0);
11138 DrawArea(g, DrawAll, 0, 0);
11139 g->grid.resizeLineXY = rect.x + width;
11144 static int
11145 SizeColumnsToFit(XmLGridWidget g, int starting_at)
11147 int resizable_width = 0;
11148 int delta = 0;
11149 float hidden_col_adjust;
11150 int ii, num_columns;
11151 XmLGridColumn colp;
11153 /* Total the width of the columns and
11154 also total how much of that can be resized */
11155 delta = g->core.width;
11156 delta -= g->manager.shadow_thickness * 2;
11158 if (g->grid.hideUnhideButtons)
11160 delta -= g->grid.unhideButton->core.width;
11161 delta -= g->grid.hideButton->core.width;
11163 else if (XtIsManaged(g->grid.vsb))
11165 delta -= g->grid.vsb->core.width;
11168 num_columns = g->grid.colCount + g->grid.headingColCount
11169 + g->grid.footerColCount;
11170 for (ii = 0; ii < num_columns; ii ++)
11172 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11174 if (colp->grid.sizePolicy != XmCONSTANT)
11176 if (g->grid.debugLevel)
11177 XmLWarning((Widget)g, "SizeColumnsToFit() - only valid for XmNcolumnSizePolicy == XmCONSTANT");
11178 colp->grid.sizePolicy = XmCONSTANT;
11180 if (!g->grid.visibleCols || ii < g->grid.visibleCols)
11182 delta -= colp->grid.width;
11184 if (ii >= starting_at && colp->grid.resizable)
11185 resizable_width += colp->grid.width;
11188 if (delta == 0 || resizable_width <= 0)
11189 return delta;
11191 if (g->grid.debugLevel)
11193 fprintf(stderr,"Applying delta(%d) from %d to %d (%d resizable)\n",
11194 delta, starting_at, num_columns - 1, resizable_width);
11197 hidden_col_adjust = (float)delta / resizable_width;
11199 /* Adjust each column to fit based on its percentage of the total width */
11200 for (ii = starting_at; ii < num_columns ; ii ++)
11202 int col_width;
11203 int col_delta;
11204 int new_col_width;
11206 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11207 col_width = colp->grid.width;
11209 if (!colp->grid.resizable || col_width == 0)
11210 continue;
11212 if (colp->grid.hidden)
11213 col_delta = (int)(hidden_col_adjust * col_width);
11214 else
11215 if (col_width < resizable_width && resizable_width > 0)
11216 col_delta = delta * ((float)col_width / resizable_width);
11217 else
11218 col_delta = delta;
11220 new_col_width = col_width + col_delta;
11222 if (new_col_width < g->grid.minColWidth)
11224 new_col_width = g->grid.minColWidth;
11225 col_delta = col_width - new_col_width;
11228 if (!colp->grid.hidden)
11230 delta -= col_delta;
11231 resizable_width -= col_width;
11234 colp->grid.width = new_col_width;
11236 if (g->grid.debugLevel)
11237 fprintf (stderr, "Column %d, width %d -> %d, new delta %d, new resizable width %d\n",
11238 ii, col_width, new_col_width,
11239 delta, resizable_width);
11242 return delta;
11246 void
11247 XmLGridGetSort(Widget w, int *column, unsigned char *sortType)
11249 XmLGridWidget g = (XmLGridWidget)w;
11250 XmLGridColumn colp;
11251 int num_columns = XmLArrayGetCount(g->grid.colArray);
11252 int ii;
11254 *column = 0;
11255 *sortType = XmSORT_NONE;
11257 for (ii = 0; ii < num_columns; ii ++)
11259 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
11261 if (colp && colp->grid.sort != XmSORT_NONE)
11263 *column = ii;
11264 *sortType = colp->grid.sort;
11265 break;
11270 void
11271 XmLGridSetSort(Widget w, int column, unsigned char sortType)
11273 XmLGridWidget g = (XmLGridWidget)w;
11274 XmLGridRow rowp;
11275 XmLGridColumn colp;
11276 XmLGridCell cellp;
11277 int old_sort_column;
11278 unsigned char old_sort_type;
11280 /*printf("XmLGridSetSort: (%d,%s)\n", column,
11281 sortType == XmSORT_NONE ? "none" :
11282 sortType == XmSORT_ASCENDING ? "ascending" : "descending");
11285 /* Clear old sort resource */
11286 XmLGridGetSort(w, &old_sort_column, &old_sort_type);
11287 if (old_sort_type != XmSORT_NONE)
11289 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, old_sort_column);
11290 if (colp)
11291 colp->grid.sort = XmSORT_NONE;
11294 colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, column);
11295 colp->grid.sort = sortType;
11297 /* Clear any existing cell sort masks. */
11298 rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
11299 if (rowp)
11301 int ii, count;
11303 count = XmLArrayGetCount(rowp->grid.cellArray);
11304 for (ii = 0; ii < count; ii++)
11306 cellp = (XmLGridCell)XmLArrayGet(rowp->grid.cellArray, ii);
11308 if (XmLGridCellDrawSort(cellp))
11310 DrawArea(g, DrawCell, 0, ii);
11311 XmLGridCellSetDrawSort(cellp, False);
11316 /* Set the cell mask of the heading cell. */
11317 cellp = GetCell(g, 0, column);
11319 if (cellp)
11321 XmLGridCellSetDrawSort(cellp, True);
11322 if (sortType == XmSORT_NONE)
11323 XmLGridCellSetDrawSort(cellp, False);
11324 else if (sortType == XmSORT_ASCENDING)
11325 XmLGridCellSetSortAscending(cellp, True);
11326 else if (sortType == XmSORT_DESCENDING)
11327 XmLGridCellSetSortAscending(cellp, False);
11329 DrawArea(g, DrawCell, 0, column);
11334 /*----------------------------------------------------------------------*/
11335 static void
11336 GridInvokeCallbacks(Widget w,
11337 XtCallbackList list,
11338 int reason,
11339 XEvent * event)
11341 XmLGridWidget g = (XmLGridWidget)w;
11343 /* Make sure widget is alive and callback list is not NULL */
11344 if (!g->core.being_destroyed && list)
11346 XmAnyCallbackStruct cbs;
11348 cbs.event = event;
11349 cbs.reason = reason;
11351 /* Invoke the Callback List */
11352 XtCallCallbackList(w,list,&cbs);
11355 /*----------------------------------------------------------------------*/
11356 static void
11357 GridInvokeCellCrossingCallbacks(Widget w,
11358 XtCallbackList list,
11359 int reason,
11360 XEvent * event,
11361 int row,
11362 int col)
11364 XmLGridWidget g = (XmLGridWidget)w;
11366 /* Make sure widget is alive and callback list is not NULL */
11367 if (!g->core.being_destroyed && list)
11369 if (row != -1 && col != -1)
11371 XmLGridCell cell;
11372 XmLGridCallbackStruct cbs;
11374 cell = GetCell(g, row, col);
11376 if (cell)
11378 cbs.reason = XmCR_CELL_FOCUS_OUT;
11379 cbs.columnType = ColPosToType(g, col);
11380 cbs.column = ColPosToTypePos(g, cbs.columnType, col);
11381 cbs.rowType = RowPosToType(g, row);
11382 cbs.row = RowPosToTypePos(g, cbs.rowType, row);
11384 /* XmLGridCellAction(cell, (Widget)g, &cbs); */
11386 /* Invoke the Callback List */
11387 XtCallCallbackList(w,list,&cbs);
11392 /*----------------------------------------------------------------------*/
11393 static void
11394 GridCrossingEH(Widget w,
11395 XtPointer closure,
11396 XEvent * event,
11397 Boolean * ctd)
11399 XmLGridWidget g = (XmLGridWidget)w;
11401 if (event)
11403 if (event->type == EnterNotify)
11405 /* Invoke XmNenterGridCallback */
11406 GridInvokeCallbacks(w,
11407 g->grid.enterGridCallback,
11408 XmCR_ENTER_GRID,
11409 event);
11411 /* printf("Enter(%s)\n",XtName(w)); */
11413 else if (event->type == LeaveNotify)
11415 g->grid.lastCursorMotionRow = -1;
11416 g->grid.lastCursorMotionCol = -1;
11418 /* Invoke XmNleaveGridCallback */
11419 GridInvokeCallbacks(w,
11420 g->grid.leaveGridCallback,
11421 XmCR_LEAVE_GRID,
11422 event);
11424 /* printf("Leave(%s)\n",XtName(w)); */
11428 *ctd = True;
11430 /*----------------------------------------------------------------------*/