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
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.
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 ***** */
54 /* DATABASE PROTOTYPE FUNCTIONS */
56 int dbTableNumRows
= 14;
57 int dbTableNumColumns
= 5;
60 ID
, Desc
, Price
, Qty
, UnitPrice
, Buyer
69 unsigned char cellAlignment
;
73 DbTableColumn dbTableColumns
[] =
75 { Desc
, "Description", 16, XmALIGNMENT_LEFT
, True
},
76 { Price
, "Price", 9, XmALIGNMENT_LEFT
, True
},
77 { Qty
, "Qty", 5, XmALIGNMENT_LEFT
, True
},
78 { UnitPrice
, "Unit Prc", 9, XmALIGNMENT_LEFT
, False
},
79 { Buyer
, "Buyer", 15, XmALIGNMENT_LEFT
, True
},
91 DbTableRow dbTableRows
[] =
93 { "key01", "Staples", 1.32, 100, "Tim Pick" },
94 { "key02", "Notebooks", 1.11, 4, "Mary Miner" },
95 { "key03", "3-Ring Binders", 2.59, 2, "Mary Miner" },
96 { "key04", "Pads", 1.23, 3, "Tim Pick" },
97 { "key05", "Scissors", 4.41, 1, "Mary Miner" },
98 { "key06", "Pens", .29, 4, "Mary Miner" },
99 { "key07", "Pencils", .10, 5, "Tim Pick" },
100 { "key08", "Markers", .95, 3, "Mary Miner" },
101 { "key09", "Fax Paper", 3.89, 100, "Bob Coal" },
102 { "key10", "3.5\" Disks", 15.23, 30, "Tim Pick" },
103 { "key11", "8mm Tape", 32.22, 2, "Bob Coal" },
104 { "key12", "Toner", 35.69, 1, "Tim Pick" },
105 { "key13", "Paper Cups", 4.25, 3, "Bob Coal" },
106 { "key14", "Paper Clips", 2.09, 3, "Tim Pick" },
109 DbTableRow
*dbFindRow(rowKey
)
114 for (i
= 0; i
< dbTableNumRows
; i
++)
115 if (!strcmp(rowKey
, dbTableRows
[i
].key
))
116 return &dbTableRows
[i
];
120 int dbCompareRowKeys(userData
, l
, r
)
125 DbTableRow
*dbRow1
, *dbRow2
;
128 dbRow1
= dbFindRow(*(char **)l
);
129 dbRow2
= dbFindRow(*(char **)r
);
130 switch ((int)userData
)
133 return strcmp(dbRow1
->desc
, dbRow2
->desc
);
135 u1
= dbRow1
->price
- dbRow2
->price
;
142 return dbRow1
->qty
- dbRow2
->qty
;
144 u1
= dbRow1
->price
/ (float)dbRow1
->qty
;
145 u2
= dbRow2
->price
/ (float)dbRow2
->qty
;
153 return strcmp(dbRow1
->buyer
, dbRow2
->buyer
);
155 return (int)(dbRow1
- dbRow2
);
158 char **dbGetRowKeysSorted(sortColumnID
)
164 keys
= (char **)malloc(sizeof(char *) * dbTableNumRows
);
165 for (i
= 0; i
< dbTableNumRows
; i
++)
166 keys
[i
] = dbTableRows
[i
].key
;
167 XmLSort(keys
, dbTableNumRows
, sizeof(char *),
168 dbCompareRowKeys
, (void *)sortColumnID
);
174 void setRowKeysInGridSorted(grid
, sortColumnID
)
181 keys
= dbGetRowKeysSorted(sortColumnID
);
182 /* Place a pointer to each row key in each rows userData */
183 for (i
= 0; i
< dbTableNumRows
; i
++)
186 XmNrowUserData
, (XtPointer
)keys
[i
],
191 void cellSelect(w
, clientData
, callData
)
193 XtPointer clientData
;
196 XmLGridCallbackStruct
*cbs
;
197 XmLGridColumn column
;
198 XtPointer columnUserData
;
200 cbs
= (XmLGridCallbackStruct
*)callData
;
202 if (cbs
->rowType
!= XmHEADING
)
205 /* Cancel any edits in progress */
206 XmLGridEditCancel(w
);
208 column
= XmLGridGetColumn(w
, cbs
->columnType
, cbs
->column
);
210 XmNcolumnPtr
, column
,
211 XmNcolumnUserData
, &columnUserData
,
214 XmNcolumn
, cbs
->column
,
215 XmNcolumnSortType
, XmSORT_ASCENDING
,
217 setRowKeysInGridSorted(w
, (DbTableColumnID
)columnUserData
);
221 void cellDraw(w
, clientData
, callData
)
223 XtPointer clientData
;
226 XmLGridCallbackStruct
*cbs
;
227 XmLGridDrawStruct
*ds
;
229 XmLGridColumn column
;
230 XtPointer rowUserData
, columnUserData
;
233 int horizMargin
, vertMargin
;
237 cbs
= (XmLGridCallbackStruct
*)callData
;
238 if (cbs
->rowType
!= XmCONTENT
)
243 /* Retrieve userData from the cells row */
244 row
= XmLGridGetRow(w
, cbs
->rowType
, cbs
->row
);
247 XmNrowUserData
, &rowUserData
,
250 /* Retrieve userData from cells column */
251 column
= XmLGridGetColumn(w
, cbs
->columnType
, cbs
->column
);
253 XmNcolumnPtr
, column
,
254 XmNcolumnUserData
, &columnUserData
,
257 /* Retrieve the cells value from the database */
258 dbRow
= dbFindRow((char *)rowUserData
);
259 switch ((DbTableColumnID
)columnUserData
)
262 sprintf(buf
, "%s", dbRow
->desc
);
265 sprintf(buf
, "$%4.2f", dbRow
->price
);
268 sprintf(buf
, "%d", dbRow
->qty
);
271 sprintf(buf
, "$%4.2f", dbRow
->price
/ (float)dbRow
->qty
);
274 sprintf(buf
, "%s", dbRow
->buyer
);
278 /* Compensate for cell margins */
279 cellRect
= *ds
->cellRect
;
280 horizMargin
= ds
->leftMargin
+ ds
->rightMargin
;
281 vertMargin
= ds
->topMargin
+ ds
->bottomMargin
;
282 if (horizMargin
>= (int)cellRect
.width
||
283 vertMargin
>= (int)cellRect
.height
)
285 cellRect
.x
+= ds
->leftMargin
;
286 cellRect
.y
+= ds
->topMargin
;
287 cellRect
.width
-= horizMargin
;
288 cellRect
.height
-= vertMargin
;
290 /* Draw the string */
291 str
= XmStringCreateSimple(buf
);
292 if (ds
->drawSelected
== True
)
293 XSetForeground(XtDisplay(w
), ds
->gc
, ds
->selectForeground
);
295 XSetForeground(XtDisplay(w
), ds
->gc
, ds
->foreground
);
296 XmLStringDraw(w
, str
, ds
->stringDirection
, ds
->fontList
,
297 ds
->alignment
, ds
->gc
, &cellRect
, cbs
->clipRect
);
301 void cellEdit(w
, clientData
, callData
)
303 XtPointer clientData
;
306 XmLGridCallbackStruct
*cbs
;
308 XmLGridColumn column
;
309 XtPointer rowUserData
, columnUserData
;
317 cbs
= (XmLGridCallbackStruct
*)callData
;
319 /* For a production version, this function should also
320 handle XmCR_EDIT_INSERT by retrieving the current value
321 from the database and performing an XmTextSetString on
322 the text widget in the grid with that value. This allows
323 a user to hit insert or F2 to modify an existing cell value */
325 if (cbs
->reason
!= XmCR_EDIT_COMPLETE
)
328 /* Get the value the user just typed in */
330 XmNtextWidget
, &text
,
332 value
= XmTextGetString(text
);
336 /* Retrieve userData from the cells row */
337 row
= XmLGridGetRow(w
, cbs
->rowType
, cbs
->row
);
340 XmNrowUserData
, &rowUserData
,
343 /* Retrieve userData from cells column */
344 column
= XmLGridGetColumn(w
, cbs
->columnType
, cbs
->column
);
346 XmNcolumnPtr
, column
,
347 XmNcolumnUserData
, &columnUserData
,
350 /* Set new value in the database */
352 dbRow
= dbFindRow((char *)rowUserData
);
353 switch ((DbTableColumnID
)columnUserData
)
356 if ((int)strlen(value
) < 20)
357 strcpy(dbRow
->desc
, value
);
360 if (sscanf(value
, "%f", &f
) == 1)
367 if (sscanf(value
, "%d", &i
) == 1)
374 if ((int)strlen(value
) < 20)
375 strcpy(dbRow
->buyer
, value
);
379 /* Redraw the row if we need to redisplay unit price */
380 if (redrawRow
== True
)
381 XmLGridRedrawRow(w
, cbs
->rowType
, cbs
->row
);
383 /* Set the cellString to NULL - its is set to the value the
384 user typed in the text widget at this point */
387 XmNcolumn
, cbs
->column
,
403 shell
= XtAppInitialize(&app
, "Grid6", NULL
, 0,
404 &argc
, argv
, NULL
, NULL
, 0);
406 grid
= XtVaCreateManagedWidget("grid",
407 xmlGridWidgetClass
, shell
,
408 XmNhorizontalSizePolicy
, XmVARIABLE
,
410 XmNvsbDisplayPolicy
, XmSTATIC
,
411 XmNselectionPolicy
, XmSELECT_NONE
,
412 XmNshadowThickness
, 0,
413 XtVaTypedArg
, XmNbackground
, XmRString
, "#C0C0C0", 8,
414 XtVaTypedArg
, XmNforeground
, XmRString
, "black", 6,
416 XtAddCallback(grid
, XmNcellDrawCallback
, cellDraw
, NULL
);
417 XtAddCallback(grid
, XmNeditCallback
, cellEdit
, NULL
);
418 XtAddCallback(grid
, XmNselectCallback
, cellSelect
, NULL
);
421 XmNlayoutFrozen
, True
,
424 XmLGridAddColumns(grid
, XmCONTENT
, -1, dbTableNumColumns
);
426 /* Setup columns and column cell defaults based on */
427 /* database description */
428 for (i
= 0; i
< dbTableNumColumns
; i
++)
430 /* Set the width and the id on the column */
433 XmNcolumnUserData
, (XtPointer
)dbTableColumns
[i
].id
,
434 XmNcolumnWidth
, dbTableColumns
[i
].width
,
437 /* Set the default cell alignment and editibility for */
438 /* cells in the column */
440 XmNcellDefaults
, True
,
442 XmNcellAlignment
, dbTableColumns
[i
].cellAlignment
,
443 XmNcellEditable
, dbTableColumns
[i
].cellEditable
,
447 /* Add the heading row */
448 XmLGridAddRows(grid
, XmHEADING
, -1, 1);
450 /* Set the column headings */
451 for (i
= 0; i
< dbTableNumColumns
; i
++)
453 /* Set the column heading label */
454 str
= XmStringCreateSimple(dbTableColumns
[i
].label
);
456 XmNrowType
, XmHEADING
,
464 /* Set cell defaults for content rows */
466 XmNcellDefaults
, True
,
467 XtVaTypedArg
, XmNcellBackground
, XmRString
, "white", 6,
468 XmNcellLeftBorderType
, XmBORDER_NONE
,
469 XmNcellRightBorderType
, XmBORDER_NONE
,
470 XmNcellTopBorderType
, XmBORDER_NONE
,
471 XmNcellBottomBorderType
, XmBORDER_NONE
,
472 XmNcellMarginLeft
, 1,
473 XmNcellMarginRight
, 1,
476 XmLGridAddRows(grid
, XmCONTENT
, -1, dbTableNumRows
);
479 XmNlayoutFrozen
, False
,
482 /* Set the row keys in the rows */
483 setRowKeysInGridSorted(grid
, Desc
);
485 XtRealizeWidget(shell
);