UNIXworkcode

1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 3 * ***** BEGIN LICENSE BLOCK ***** 4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 7 * 1.1 (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * http://www.mozilla.org/MPL/ 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 * 16 * The Original Code is the Microline Widget Library, originally made available under the NPL by Neuron Data <http://www.neurondata.com>. 17 * 18 * The Initial Developer of the Original Code is 19 * Netscape Communications Corporation. 20 * Portions created by the Initial Developer are Copyright (C) 1998 21 * the Initial Developer. All Rights Reserved. 22 * 23 * Contributor(s): 24 * 25 * Alternatively, the contents of this file may be used under the terms of 26 * either the GNU General Public License Version 2 or later (the "GPL"), or 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 * in which case the provisions of the GPL or the LGPL are applicable instead 29 * of those above. If you wish to allow use of your version of this file only 30 * under the terms of either the GPL or the LGPL, and not to allow others to 31 * use your version of this file under the terms of the MPL, indicate your 32 * decision by deleting the provisions above and replace them with the notice 33 * and other provisions required by the GPL or the LGPL. If you do not delete 34 * the provisions above, a recipient may use your version of this file under 35 * the terms of any one of the MPL, the GPL or the LGPL. 36 * 37 * In addition, as a special exception to the GNU GPL, the copyright holders 38 * give permission to link the code of this program with the Motif and Open 39 * Motif libraries (or with modified versions of these that use the same 40 * license), and distribute linked combinations including the two. You 41 * must obey the GNU General Public License in all respects for all of 42 * the code used other than linking with Motif/Open Motif. If you modify 43 * this file, you may extend this exception to your version of the file, 44 * but you are not obligated to do so. If you do not wish to do so, 45 * delete this exception statement from your version. 46 * 47 * ***** END LICENSE BLOCK ***** */ 48 49 50 #include <Xm/Xm.h> 51 #include <Xm/Form.h> 52 #include <Xm/Text.h> 53 #include <Xm/Label.h> 54 #include <Xm/PushB.h> 55 #include <XmL/Grid.h> 56 57 Widget label, text, grid, gridText; 58 59 static int busy = 0; 60 61 void cellFocus(); 62 void textModify(); 63 void copy(); 64 void paste(); 65 66 main(argc, argv) 67 int argc; 68 char *argv[]; 69 { 70 XtAppContext app; 71 Widget shell, form, copyButton, pasteButton; 72 XmString str; 73 char buf[4]; 74 int i; 75 76 shell = XtAppInitialize(&app, "Grid3", NULL, 0, 77 &argc, argv, NULL, NULL, 0); 78 79 form = XtVaCreateManagedWidget("form", 80 xmFormWidgetClass, shell, 81 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 82 XmNshadowThickness, 0, 83 NULL); 84 85 str = XmStringCreateSimple("(A 1)"); 86 label = XtVaCreateManagedWidget("label", 87 xmLabelWidgetClass, form, 88 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 89 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 90 XmNtopAttachment, XmATTACH_FORM, 91 XmNmarginHeight, 4, 92 XmNleftAttachment, XmATTACH_FORM, 93 XmNlabelString, str, 94 NULL); 95 XmStringFree(str); 96 97 pasteButton = XtVaCreateManagedWidget("Paste To Focus", 98 xmPushButtonWidgetClass, form, 99 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 100 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 101 XmNrightAttachment, XmATTACH_FORM, 102 XmNmarginHeight, 0, 103 NULL); 104 XtAddCallback(pasteButton, XmNactivateCallback, paste, NULL); 105 106 copyButton = XtVaCreateManagedWidget("Copy Selected", 107 xmPushButtonWidgetClass, form, 108 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 109 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 110 XmNrightAttachment, XmATTACH_WIDGET, 111 XmNrightWidget, pasteButton, 112 XmNmarginHeight, 0, 113 NULL); 114 XtAddCallback(copyButton, XmNactivateCallback, copy, NULL); 115 116 text = XtVaCreateManagedWidget("text", 117 xmTextWidgetClass, form, 118 XtVaTypedArg, XmNbackground, XmRString, "white", 6, 119 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 120 XmNtopAttachment, XmATTACH_FORM, 121 XmNleftAttachment, XmATTACH_WIDGET, 122 XmNleftWidget, label, 123 XmNrightAttachment, XmATTACH_WIDGET, 124 XmNrightWidget, copyButton, 125 XmNmarginHeight, 0, 126 NULL); 127 128 /* Create a Grid with 1 heading column and 1 heading row */ 129 grid = XtVaCreateManagedWidget("grid", 130 xmlGridWidgetClass, form, 131 XtVaTypedArg, XmNbackground, XmRString, "#C0C0C0", 8, 132 XtVaTypedArg, XmNforeground, XmRString, "black", 6, 133 XmNheadingColumns, 1, 134 XmNcolumns, 26, 135 XmNvisibleColumns, 8, 136 XmNhsbDisplayPolicy, XmSTATIC, 137 XmNrows, 100, 138 XmNheadingRows, 1, 139 XmNvisibleRows, 12, 140 XmNvsbDisplayPolicy, XmSTATIC, 141 XmNallowDragSelected, True, 142 XmNallowDrop, True, 143 XmNallowRowResize, True, 144 XmNallowColumnResize, True, 145 XmNtopAttachment, XmATTACH_WIDGET, 146 XmNtopWidget, text, 147 XmNtopOffset, 2, 148 XmNbottomAttachment, XmATTACH_FORM, 149 XmNleftAttachment, XmATTACH_FORM, 150 XmNrightAttachment, XmATTACH_FORM, 151 XmNshadowThickness, 0, 152 XmNselectionPolicy, XmSELECT_CELL, 153 NULL); 154 155 /* Make all cells in the content rows and content columns */ 156 /* (the data cells) editable and set their borders and color */ 157 XtVaSetValues(grid, 158 XmNcellEditable, True, 159 XtVaTypedArg, XmNcellBackground, XmRString, "white", 6, 160 XmNcellAlignment, XmALIGNMENT_RIGHT, 161 XmNcellTopBorderType, XmBORDER_NONE, 162 XmNcellLeftBorderType, XmBORDER_NONE, 163 XtVaTypedArg, XmNcellRightBorderColor, XmRString, "#606060", 8, 164 XtVaTypedArg, XmNcellBottomBorderColor, XmRString, "#606060", 8, 165 NULL); 166 167 /* Add callbacks which update the Label and to synchronize */ 168 /* the Text widget outside the Grid with the one inside the Grid */ 169 XtAddCallback(grid, XmNcellFocusCallback, cellFocus, NULL); 170 XtAddCallback(text, XmNvalueChangedCallback, textModify, NULL); 171 XtVaGetValues(grid, 172 XmNtextWidget, &gridText, 173 NULL); 174 XtAddCallback(gridText, XmNvalueChangedCallback, textModify, NULL); 175 176 XtVaSetValues(gridText, 177 XtVaTypedArg, XmNbackground, XmRString, "white", 6, 178 NULL); 179 180 /* Set the labels on the heading rows and columns */ 181 for (i = 0; i < 26; i++) 182 { 183 sprintf(buf, "%c", 'A' + i); 184 XmLGridSetStringsPos(grid, XmHEADING, 0, XmCONTENT, i, buf); 185 } 186 for (i = 0; i < 100; i++) 187 { 188 sprintf(buf, "%d", i + 1); 189 XmLGridSetStringsPos(grid, XmCONTENT, i, XmHEADING, 0, buf); 190 } 191 192 XtRealizeWidget(shell); 193 XtAppMainLoop(app); 194 } 195 196 197 void cellFocus(w, clientData, callData) 198 Widget w; 199 XtPointer clientData; 200 XtPointer callData; 201 { 202 XmLGridCallbackStruct *cbs; 203 XmLGridRow row; 204 XmLGridColumn column; 205 Widget sharedText; 206 XmString str; 207 char buf[10], *c; 208 209 cbs = (XmLGridCallbackStruct *)callData; 210 if (cbs->reason != XmCR_CELL_FOCUS_IN) 211 return; 212 213 /* Update the Label to reflect the new focus position */ 214 sprintf(buf, "(%c %d)", 'A' + cbs->column, cbs->row + 1); 215 str = XmStringCreateSimple(buf); 216 XtVaSetValues(label, 217 XmNlabelString, str, 218 NULL); 219 XmStringFree(str); 220 221 /* Set the Text widget outside the Grid to the string contained */ 222 /* in the new focus cell. We set busy here because this change will */ 223 /* generate a valueChanged callback and we want to notify our */ 224 /* valueChanged callback not to do any processing because of */ 225 /* this change */ 226 if (busy) 227 return; 228 busy = 1; 229 row = XmLGridGetRow(w, cbs->rowType, cbs->row); 230 column = XmLGridGetColumn(w, cbs->columnType, cbs->column); 231 XtVaGetValues(w, 232 XmNrowPtr, row, 233 XmNcolumnPtr, column, 234 XmNcellString, &str, 235 NULL); 236 c = 0; 237 if (str) 238 XmStringGetLtoR(str, XmSTRING_DEFAULT_CHARSET, &c); 239 if (c) 240 { 241 XmTextSetString(text, c); 242 XtFree(c); 243 XmTextSetSelection(text, 0, XmTextGetLastPosition(text), 244 CurrentTime); 245 } 246 else 247 XmTextSetString(text, ""); 248 if (str) 249 XmStringFree(str); 250 busy = 0; 251 } 252 253 void textModify(w, clientData, callData) 254 Widget w; 255 XtPointer clientData; 256 XtPointer callData; 257 { 258 int row, column; 259 Boolean focusIn; 260 XmString str; 261 char *c; 262 263 /* If either Text widget changes (the Grid's Text widget or */ 264 /* the Text widget outside of the Grid), update the other one */ 265 /* to reflect to change and update the Grid itself if the */ 266 /* Text widget outside the Grid changes. We set busy in this */ 267 /* function to keep the XmTextSetString() from causing this */ 268 /* callback to be called while inside the callback. */ 269 if (busy) 270 return; 271 busy = 1; 272 c = XmTextGetString(w); 273 if (w == gridText) 274 XmTextSetString(text, c); 275 else 276 { 277 XmLGridGetFocus(grid, &row, &column, &focusIn); 278 if (row != -1 && column != -1) 279 { 280 str = XmStringCreateSimple(c); 281 XtVaSetValues(grid, 282 XmNrow, row, 283 XmNcolumn, column, 284 XmNcellString, str, 285 NULL); 286 XmStringFree(str); 287 XmTextSetString(gridText, c); 288 } 289 } 290 XtFree(c); 291 busy = 0; 292 } 293 294 void copy(w, clientData, callData) 295 Widget w; 296 XtPointer clientData; 297 XtPointer callData; 298 { 299 XmLGridCopySelected(grid, CurrentTime); 300 } 301 302 void paste(w, clientData, callData) 303 Widget w; 304 XtPointer clientData; 305 XtPointer callData; 306 { 307 /* This pastes starting at the current focus cell, an alternative */ 308 /* method of pasting would be to have the user select an area */ 309 /* to paste into. To perform this, we could get the selected area */ 310 /* and use XmLGridPastePos() to paste into that area */ 311 XmLGridPaste(grid); 312 } 313