mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
11409 lines
283 KiB
C
11409 lines
283 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
/*
|
|
* The following source code is part of the Microline Widget Library.
|
|
* The Microline widget library is made available to Mozilla developers
|
|
* under the Netscape Public License (NPL) by Neuron Data. To learn
|
|
* more about Neuron Data, please visit the Neuron Data Home Page at
|
|
* http://www.neurondata.com.
|
|
*/
|
|
|
|
#include "GridP.h"
|
|
|
|
#include <Xm/ScrollBar.h>
|
|
#include <Xm/Text.h>
|
|
#include <Xm/DrawnB.h>
|
|
#include <Xm/CutPaste.h>
|
|
#ifndef MOTIF11
|
|
#include <Xm/DropSMgr.h>
|
|
#endif
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/cursorfont.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef SUNOS4
|
|
int fprintf(FILE *, char *, ...);
|
|
int fseek(FILE *, long, int);
|
|
int fread(char *, int, int, FILE *);
|
|
#endif
|
|
|
|
/* Create and Destroy */
|
|
static void ClassInitialize(void);
|
|
static void ClassPartInitialize(WidgetClass wc);
|
|
static void Initialize(Widget req, Widget newW, ArgList args, Cardinal *nargs);
|
|
static void Destroy(Widget w);
|
|
|
|
/* Geometry, Drawing, Entry and Picking */
|
|
static void Realize(Widget w, XtValueMask *valueMask,
|
|
XSetWindowAttributes *attr);
|
|
static void Redisplay(Widget w, XExposeEvent *event, Region region);
|
|
static void DrawResizeLine(XmLGridWidget g, int xy, int erase);
|
|
static void DrawXORRect(XmLGridWidget g, int xy, int size,
|
|
int isVert, int erase);
|
|
static void DefineCursor(XmLGridWidget g, char defineCursor);
|
|
static void DrawArea(XmLGridWidget g, int type, int row, int col);
|
|
static void ExtendSelectRange(XmLGridWidget g, int *type,
|
|
int *fr, int *lr, int *fc, int *lc);
|
|
static void ExtendSelect(XmLGridWidget g, XEvent *event, Boolean set,
|
|
int row, int col);
|
|
static void SelectTypeArea(XmLGridWidget g, int type, XEvent *event,
|
|
int row, int col, Boolean select, Boolean notify);
|
|
static int GetSelectedArea(XmLGridWidget g, int type, int *rowPos,
|
|
int *colPos, int count);
|
|
static void ChangeManaged(Widget w);
|
|
static void Resize(Widget w);
|
|
static void PlaceScrollbars(XmLGridWidget w);
|
|
static void VertLayout(XmLGridWidget g, int resizeIfNeeded);
|
|
static void HorizLayout(XmLGridWidget g, int resizeIfNeeded);
|
|
static void ApplyVisibleRows(XmLGridWidget g);
|
|
static void ApplyVisibleCols(XmLGridWidget g);
|
|
static void VisPosChanged(XmLGridWidget g, int isVert);
|
|
static void RecalcVisPos(XmLGridWidget g, int isVert);
|
|
static int PosToVisPos(XmLGridWidget g, int pos, int isVert);
|
|
static int VisPosToPos(XmLGridWidget g, int visPos, int isVert);
|
|
static unsigned char ColPosToType(XmLGridWidget g, int pos);
|
|
static int ColPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
|
|
static unsigned char RowPosToType(XmLGridWidget g, int pos);
|
|
static int RowPosToTypePos(XmLGridWidget g, unsigned char type, int pos);
|
|
static int ColTypePosToPos(XmLGridWidget g, unsigned char type,
|
|
int pos, int allowNeg);
|
|
static int RowTypePosToPos(XmLGridWidget g, unsigned char type,
|
|
int pos, int allowNeg);
|
|
static int ScrollRowBottomPos(XmLGridWidget g, int row);
|
|
static int ScrollColRightPos(XmLGridWidget g, int col);
|
|
static int PosIsResize(XmLGridWidget g, int x, int y,
|
|
int *row, int *col, int *isVert);
|
|
static int XYToRowCol(XmLGridWidget g, int x, int y, int *row, int *col);
|
|
static int RowColToXY(XmLGridWidget g, int row, int col,
|
|
Boolean clipped, XRectangle *rect);
|
|
static int RowColFirstSpan(XmLGridWidget g, int row, int col,
|
|
int *spanRow, int *spanCol, XRectangle *rect, Boolean lookLeft,
|
|
Boolean lookUp);
|
|
static void RowColSpanRect(XmLGridWidget g, int row, int col, XRectangle *rect);
|
|
static XmLGridCell GetCell(XmLGridWidget g, int row, int col);
|
|
static int GetColWidth(XmLGridWidget g, int col);
|
|
static int GetRowHeight(XmLGridWidget g, int row);
|
|
static int ColIsVisible(XmLGridWidget g, int col);
|
|
static int RowIsVisible(XmLGridWidget g, int row);
|
|
static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
|
|
XtWidgetGeometry *);
|
|
static void ScrollCB(Widget w, XtPointer, XtPointer);
|
|
static int FindNextFocus(XmLGridWidget g, int row, int col,
|
|
int rowDir, int colDir, int *nextRow, int *nextCol);
|
|
static int SetFocus(XmLGridWidget g, int row, int col, int rowDir, int colDir);
|
|
static void ChangeFocus(XmLGridWidget g, int row, int col);
|
|
static void MakeColVisible(XmLGridWidget g, int col);
|
|
static void MakeRowVisible(XmLGridWidget g, int row);
|
|
static void TextAction(XmLGridWidget g, int action);
|
|
|
|
/* Getting and Setting Values */
|
|
static void GetSubValues(Widget w, ArgList args, Cardinal *nargs);
|
|
static void SetSubValues(Widget w, ArgList args, Cardinal *nargs);
|
|
static Boolean SetValues(Widget curW, Widget, Widget newW,
|
|
ArgList args, Cardinal *nargs);
|
|
static void CopyFontList(XmLGridWidget g);
|
|
static Boolean CvtStringToSizePolicy(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToSelectionPolicy(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToRowColType(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToCellAlignment(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToCellType(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToCellBorderType(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static void SetSimpleHeadings(XmLGridWidget g, char *data);
|
|
static void SetSimpleWidths(XmLGridWidget g, char *data);
|
|
|
|
/* Getting and Setting Row Values */
|
|
static void GetRowValueMask(XmLGridWidget g, char *s, long *mask);
|
|
static void _GetRowValueMask(XmLGridWidget g, char *s, long *mask);
|
|
static void GetRowValue(XmLGridWidget g, XmLGridRow row,
|
|
XtArgVal value, long mask);
|
|
static void _GetRowValue(XmLGridWidget g, XmLGridRow row,
|
|
XtArgVal value, long mask);
|
|
static int SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
|
|
static int _SetRowValues(XmLGridWidget g, XmLGridRow row, long mask);
|
|
|
|
/* Getting and Setting Column Values */
|
|
static void GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
|
|
static void _GetColumnValueMask(XmLGridWidget g, char *s, long *mask);
|
|
static void GetColumnValue(XmLGridWidget g, XmLGridColumn col,
|
|
XtArgVal value, long mask);
|
|
static void _GetColumnValue(XmLGridWidget g, XmLGridColumn col,
|
|
XtArgVal value, long mask);
|
|
static int SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
|
|
static int _SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask);
|
|
|
|
/* Getting and Setting Cell Values */
|
|
static void CellValueGetMask(char *s, long *mask);
|
|
static void GetCellValue(XmLGridCell cell, XtArgVal value, long mask);
|
|
static XmLGridCellRefValues *CellRefValuesCreate(XmLGridWidget g,
|
|
XmLGridCellRefValues *copy);
|
|
static void SetCellValuesPreprocess(XmLGridWidget g, long mask);
|
|
static int SetCellHasRefValues(long mask);
|
|
static int SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
|
|
XmLGridColumn col, XmLGridCell cell, long mask);
|
|
static int _SetCellValuesResize(XmLGridWidget g, XmLGridRow row,
|
|
XmLGridColumn col, XmLGridCell cell, long mask);
|
|
static void SetCellValues(XmLGridWidget g, XmLGridCell cell, long mask);
|
|
static void SetCellRefValues(XmLGridWidget g, XmLGridCellRefValues *values,
|
|
long mask);
|
|
static int SetCellRefValuesCompare(void *, void **, void **);
|
|
static void SetCellRefValuesPreprocess(XmLGridWidget g, int row, int col,
|
|
XmLGridCell cell, long mask);
|
|
|
|
/* Read, Write, Copy, Paste */
|
|
static int Read(XmLGridWidget g, int format, char delimiter,
|
|
int row, int col, char *data);
|
|
static void Write(XmLGridWidget g, FILE *file, int format, char delimiter,
|
|
Boolean skipHidden, int row, int col, int nrow, int ncol);
|
|
static char *CopyDataCreate(XmLGridWidget g, int selected, int row, int col,
|
|
int nrow, int ncol);
|
|
static Boolean Copy(XmLGridWidget g, Time time, int selected,
|
|
int row, int col, int nrow, int ncol);
|
|
static Boolean Paste(XmLGridWidget g, int row, int col);
|
|
|
|
/* Utility */
|
|
static void GetCoreBackground(Widget w, int, XrmValue *value);
|
|
static void GetManagerForeground(Widget w, int, XrmValue *value);
|
|
static void ClipRectToReg(XmLGridWidget g, XRectangle *rect, GridReg *reg);
|
|
static char *FileToString(FILE *file);
|
|
static char *CvtXmStringToStr(XmString str);
|
|
static XmLGridWidget WidgetToGrid(Widget w, char *funcname);
|
|
|
|
/* Actions, Callbacks and Handlers */
|
|
static void ButtonMotion(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void DragTimer(XtPointer, XtIntervalId *);
|
|
static void CursorMotion(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void Edit(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void EditCancel(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void EditComplete(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void DragStart(Widget w, XEvent *event, String *, Cardinal *);
|
|
static Boolean DragConvert(Widget w, Atom *selection, Atom *target,
|
|
Atom *type, XtPointer *value, unsigned long *length, int *format);
|
|
static void DragFinish(Widget w, XtPointer clientData, XtPointer callData);
|
|
static void DropRegister(XmLGridWidget g, Boolean set);
|
|
static void DropStart(Widget w, XtPointer clientData, XtPointer callData);
|
|
static void DropTransfer(Widget w, XtPointer clientData, Atom *selType,
|
|
Atom *type, XtPointer value, unsigned long *length, int *format);
|
|
static void Select(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void PopupSelect(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void TextActivate(Widget w, XtPointer clientData, XtPointer callData);
|
|
static void TextFocus(Widget w, XtPointer clientData, XtPointer callData);
|
|
static void TextMapped(Widget w, XtPointer closure, XEvent *event,
|
|
Boolean *ctd);
|
|
static void TextModifyVerify(Widget w, XtPointer clientData,
|
|
XtPointer callData);
|
|
static void Traverse(Widget w, XEvent *event, String *, Cardinal *);
|
|
|
|
/* XFE Additions */
|
|
static void EditTimer(XtPointer, XtIntervalId *);
|
|
static void CreateHideUnhideButtons(XmLGridWidget g);
|
|
static void HideAction(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void UnhideAction(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void setHideUnhideSensitivity(Widget w);
|
|
static void MenuArm(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void MenuDisarm(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void ResizeColumnToFit(XmLGridWidget g, int x);
|
|
static int SizeColumnsToFit(XmLGridWidget g, int start_at);
|
|
static void GridCrossingEH(Widget w, XtPointer closure, XEvent *event,
|
|
Boolean *ctd);
|
|
static void GridInvokeCellCrossingCallbacks(Widget w,XtCallbackList list,
|
|
int reason,XEvent * event,
|
|
int row,int col);
|
|
static void GridCrossingEH(Widget w,XtPointer closure,XEvent * event,
|
|
Boolean * ctd);
|
|
|
|
/* XmLGridRow */
|
|
|
|
static XmLGridRow XmLGridRowNew(Widget grid);
|
|
static void XmLGridRowFree(Widget grid, XmLGridRow row);
|
|
static XmLGridRow _GridRowNew(Widget grid);
|
|
static void _GridRowFree(XmLGridRow row);
|
|
static XmLArray XmLGridRowCells(XmLGridRow row);
|
|
static int XmLGridRowGetPos(XmLGridRow row);
|
|
static int XmLGridRowGetVisPos(XmLGridRow row);
|
|
static Boolean XmLGridRowIsHidden(XmLGridRow row);
|
|
static Boolean XmLGridRowIsSelected(XmLGridRow row);
|
|
static void XmLGridRowSetSelected(XmLGridRow row, Boolean selected);
|
|
static void XmLGridRowSetVisPos(XmLGridRow row, int visPos);
|
|
static int XmLGridRowHeightInPixels(XmLGridRow row);
|
|
static void XmLGridRowHeightChanged(XmLGridRow row);
|
|
|
|
/* XmLGridColumn */
|
|
|
|
static XmLGridColumn XmLGridColumnNew(Widget grid);
|
|
static void XmLGridColumnFree(Widget grid, XmLGridColumn column);
|
|
static XmLGridColumn _GridColumnNew(Widget grid);
|
|
static void _GridColumnFree(XmLGridColumn column);
|
|
static int XmLGridColumnGetPos(XmLGridColumn column);
|
|
static int XmLGridColumnGetVisPos(XmLGridColumn column);
|
|
static Boolean XmLGridColumnIsHidden(XmLGridColumn column);
|
|
static Boolean XmLGridColumnIsSelected(XmLGridColumn column);
|
|
static void XmLGridColumnSetSelected(XmLGridColumn column, Boolean selected);
|
|
static void XmLGridColumnSetVisPos(XmLGridColumn column, int visPos);
|
|
static int XmLGridColumnWidthInPixels(XmLGridColumn column);
|
|
static void XmLGridColumnWidthChanged(XmLGridColumn column);
|
|
|
|
/* XmLGridCell */
|
|
|
|
static XmLGridCell XmLGridCellNew();
|
|
static void XmLGridCellFree(Widget grid, XmLGridCell cell);
|
|
static int XmLGridCellAction(XmLGridCell cell, Widget w,
|
|
XmLGridCallbackStruct *cbs);
|
|
static int _GridCellAction(XmLGridCell cell, Widget w,
|
|
XmLGridCallbackStruct *cbs);
|
|
static XmLGridCellRefValues *XmLGridCellGetRefValues(XmLGridCell cell);
|
|
static void XmLGridCellSetRefValues(XmLGridCell cell,
|
|
XmLGridCellRefValues *values);
|
|
static void XmLGridCellDerefValues(XmLGridCellRefValues *values);
|
|
static Boolean XmLGridCellInRowSpan(XmLGridCell cell);
|
|
static Boolean XmLGridCellInColumnSpan(XmLGridCell cell);
|
|
static Boolean XmLGridCellIsSelected(XmLGridCell cell);
|
|
static Boolean XmLGridCellIsValueSet(XmLGridCell cell);
|
|
static void XmLGridCellSetValueSet(XmLGridCell cell, Boolean set);
|
|
static void XmLGridCellSetInRowSpan(XmLGridCell cell, Boolean set);
|
|
static void XmLGridCellSetInColumnSpan(XmLGridCell cell, Boolean set);
|
|
static void XmLGridCellSetSelected(XmLGridCell cell, Boolean selected);
|
|
static void XmLGridCellAllocIcon(XmLGridCell cell);
|
|
static void XmLGridCellAllocPixmap(XmLGridCell cell);
|
|
static void XmLGridCellSetString(XmLGridCell cell, XmString string,
|
|
Boolean copy);
|
|
static XmString XmLGridCellGetString(XmLGridCell cell);
|
|
static void XmLGridCellSetToggle(XmLGridCell cell, Boolean state);
|
|
static Boolean XmLGridCellGetToggle(XmLGridCell cell);
|
|
static void XmLGridCellSetPixmap(XmLGridCell cell, Pixmap pixmap,
|
|
Dimension width, Dimension height);
|
|
static void XmLGridCellSetPixmask(XmLGridCell cell, Pixmap pixmask);
|
|
static XmLGridCellPixmap *XmLGridCellGetPixmap(XmLGridCell cell);
|
|
/* static void XmLGridCellClearTextString(XmLGridCell cell, Widget w); */
|
|
static int _XmLGridCellConfigureText(XmLGridCell cell, Widget w,
|
|
XRectangle *rect);
|
|
static int _XmLGridCellBeginTextEdit(XmLGridCell cell, Widget w,
|
|
XRectangle *clipRect);
|
|
static void _XmLGridCellCompleteTextEdit(XmLGridCell cell, Widget w);
|
|
static void _XmLGridCellInsertText(XmLGridCell cell, Widget w);
|
|
static int _XmLGridCellGetHeight(XmLGridCell cell, Widget w,XmLGridRow row);
|
|
static int _XmLGridCellGetWidth(XmLGridCell cell, Widget w,XmLGridColumn col);
|
|
static void _XmLGridCellFreeValue(XmLGridCell cell);
|
|
|
|
/*Xfe Additions*/
|
|
static Boolean XmLGridCellDrawSort(XmLGridCell cell);
|
|
static Boolean XmLGridCellSortAscending(XmLGridCell cell);
|
|
static void XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort);
|
|
static void XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending);
|
|
|
|
static XtActionsRec actions[] =
|
|
{
|
|
{ "XmLGridEditComplete", EditComplete },
|
|
{ "XmLGridButtonMotion", ButtonMotion },
|
|
{ "XmLGridCursorMotion", CursorMotion },
|
|
{ "XmLGridEditCancel", EditCancel },
|
|
{ "XmLGridEdit", Edit },
|
|
{ "XmLGridSelect", Select },
|
|
{ "XmLGridPopupSelect", PopupSelect },
|
|
{ "XmLGridDragStart", DragStart },
|
|
{ "XmLGridTraverse", Traverse },
|
|
/* XFE Additions */
|
|
{ "XmLGridHideColumn", HideAction },
|
|
{ "XmLGridUnhideColumn", UnhideAction },
|
|
{ "MenuArm", MenuArm },
|
|
{ "MenuDisarm", MenuDisarm },
|
|
};
|
|
|
|
#define TEXT_HIDE 1
|
|
#define TEXT_SHOW 2
|
|
#define TEXT_EDIT 3
|
|
#define TEXT_EDIT_CANCEL 4
|
|
#define TEXT_EDIT_COMPLETE 5
|
|
#define TEXT_EDIT_INSERT 6
|
|
|
|
/* future defines */
|
|
#define XmTOGGLE_CELL 240
|
|
|
|
/* backwards compatibility defines */
|
|
#define XmTEXT_CELL 250
|
|
#define XmLABEL_CELL 251
|
|
|
|
/* Cursors */
|
|
|
|
#define horizp_width 19
|
|
#define horizp_height 13
|
|
static unsigned char horizp_bits[] = {
|
|
0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x00,
|
|
0x00, 0x06, 0x00, 0x20, 0x46, 0x00, 0x30, 0xc6, 0x00, 0x38, 0xc6, 0x01,
|
|
0xfc, 0xff, 0x03, 0x38, 0xc6, 0x01, 0x30, 0xc6, 0x00, 0x20, 0x46, 0x00,
|
|
0x00, 0x06, 0x00 };
|
|
|
|
#define horizm_width 19
|
|
#define horizm_height 13
|
|
static unsigned char horizm_bits[] = {
|
|
0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00,
|
|
0x60, 0x6f, 0x00, 0x70, 0xef, 0x00, 0x78, 0xef, 0x01, 0xfc, 0xff, 0x03,
|
|
0xfe, 0xff, 0x07, 0xfc, 0xff, 0x03, 0x78, 0xef, 0x01, 0x70, 0xef, 0x00,
|
|
0x60, 0x6f, 0x00 };
|
|
|
|
#define vertp_width 13
|
|
#define vertp_height 19
|
|
static unsigned char vertp_bits[] = {
|
|
0x06, 0x00, 0x06, 0x00, 0x06, 0x01, 0x86, 0x03, 0xc6, 0x07, 0xe6, 0x0f,
|
|
0x06, 0x01, 0x06, 0x01, 0x06, 0x01, 0xfe, 0x1f, 0xfe, 0x1f, 0x00, 0x01,
|
|
0x00, 0x01, 0x00, 0x01, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03, 0x00, 0x01,
|
|
0x00, 0x00};
|
|
|
|
#define vertm_width 13
|
|
#define vertm_height 19
|
|
static unsigned char vertm_bits[] = {
|
|
0x0f, 0x00, 0x0f, 0x01, 0x8f, 0x03, 0xcf, 0x07, 0xef, 0x0f, 0xff, 0x1f,
|
|
0xff, 0x1f, 0x8f, 0x03, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f,
|
|
0x80, 0x03, 0xf0, 0x1f, 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03,
|
|
0x00, 0x01};
|
|
|
|
/* Grid Translations */
|
|
|
|
static char translations[] =
|
|
"<Btn1Motion>: XmLGridButtonMotion()\n\
|
|
<MotionNotify>: XmLGridCursorMotion()\n\
|
|
~Ctrl ~Shift <Btn1Down>: XmLGridSelect(BEGIN)\n\
|
|
~Ctrl Shift <Btn1Down>: XmLGridSelect(EXTEND)\n\
|
|
Ctrl ~Shift <Btn1Down>: XmLGridSelect(TOGGLE)\n\
|
|
<Btn1Up>: XmLGridSelect(END)\n\
|
|
<Btn2Down>: XmLGridDragStart()\n\
|
|
~Ctrl ~Shift <Btn3Down>: XmLGridPopupSelect(BEGIN)\n\
|
|
~Ctrl Shift <Btn3Down>: XmLGridPopupSelect(EXTEND)\n\
|
|
Ctrl ~Shift <Btn3Down>: XmLGridPopupSelect(TOGGLE)\n\
|
|
<EnterWindow>: ManagerEnter()\n\
|
|
<LeaveWindow>: ManagerLeave()\n\
|
|
<FocusOut>: ManagerFocusOut()\n\
|
|
<FocusIn>: ManagerFocusIn()";
|
|
|
|
/* Text Translations */
|
|
|
|
static char traverseTranslations[] =
|
|
"~Ctrl ~Shift <Key>osfUp: XmLGridTraverse(UP)\n\
|
|
~Ctrl Shift <Key>osfUp: XmLGridTraverse(EXTEND_UP)\n\
|
|
Ctrl ~Shift <Key>osfUp: XmLGridTraverse(PAGE_UP)\n\
|
|
~Ctrl ~Shift <Key>osfDown: XmLGridTraverse(DOWN)\n\
|
|
~Ctrl Shift <Key>osfDown: XmLGridTraverse(EXTEND_DOWN)\n\
|
|
Ctrl ~Shift <Key>osfDown: XmLGridTraverse(PAGE_DOWN)\n\
|
|
~Ctrl ~Shift <Key>osfLeft: XmLGridTraverse(LEFT)\n\
|
|
~Ctrl Shift <Key>osfLeft: XmLGridTraverse(EXTEND_LEFT)\n\
|
|
Ctrl ~Shift <Key>osfLeft: XmLGridTraverse(PAGE_LEFT)\n\
|
|
~Ctrl ~Shift <Key>osfRight: XmLGridTraverse(RIGHT)\n\
|
|
~Ctrl Shift <Key>osfRight: XmLGridTraverse(EXTEND_RIGHT)\n\
|
|
Ctrl ~Shift <Key>osfRight: XmLGridTraverse(PAGE_RIGHT)\n\
|
|
~Ctrl ~Shift <Key>osfPageUp: XmLGridTraverse(PAGE_UP)\n\
|
|
~Ctrl Shift <Key>osfPageUp: XmLGridTraverse(EXTEND_PAGE_UP)\n\
|
|
Ctrl ~Shift <Key>osfPageUp: XmLGridTraverse(PAGE_LEFT)\n\
|
|
Ctrl Shift <Key>osfPageUp: XmLGridTraverse(EXTEND_PAGE_LEFT)\n\
|
|
~Ctrl Shift <Key>osfPageDown: XmLGridTraverse(EXTEND_PAGE_DOWN)\n\
|
|
Ctrl ~Shift <Key>osfPageDown: XmLGridTraverse(PAGE_RIGHT)\n\
|
|
~Ctrl ~Shift <Key>osfPageDown: XmLGridTraverse(PAGE_DOWN)\n\
|
|
Ctrl Shift <Key>osfPageDown: XmLGridTraverse(EXTEND_PAGE_RIGHT)\n\
|
|
~Ctrl ~Shift <Key>Tab: XmLGridTraverse(RIGHT)\n\
|
|
~Ctrl Shift <Key>Tab: XmLGridTraverse(LEFT)\n\
|
|
~Ctrl ~Shift <Key>Home: XmLGridTraverse(TO_TOP)\n\
|
|
~Ctrl ~Shift <Key>osfBeginLine: XmLGridTraverse(TO_TOP)\n\
|
|
Ctrl ~Shift <Key>Home: XmLGridTraverse(TO_TOP_LEFT)\n\
|
|
~Ctrl ~Shift <Key>End: XmLGridTraverse(TO_BOTTOM)\n\
|
|
~Ctrl ~Shift <Key>osfEndLine: XmLGridTraverse(TO_BOTTOM)\n\
|
|
Ctrl ~Shift <Key>End: XmLGridTraverse(TO_BOTTOM_RIGHT)\n\
|
|
<Key>osfInsert: XmLGridEdit()\n\
|
|
<Key>F2: XmLGridEdit()\n\
|
|
~Ctrl ~Shift <KeyDown>space: XmLGridSelect(BEGIN)\n\
|
|
~Ctrl Shift <KeyDown>space: XmLGridSelect(EXTEND)\n\
|
|
Ctrl ~Shift <KeyDown>space: XmLGridSelect(TOGGLE)\n\
|
|
<KeyUp>space: XmLGridSelect(END)";
|
|
|
|
/* You can't put multiple actions for any translation
|
|
where one translation changes the translation table
|
|
XmLGridComplete() and XmLGridCancel() do this and these
|
|
actions can't be combined with others */
|
|
static char editTranslations[] =
|
|
"~Ctrl ~Shift <Key>osfDown: XmLGridEditComplete(DOWN)\n\
|
|
~Ctrl Shift <Key>Tab: XmLGridEditComplete(LEFT)\n\
|
|
~Ctrl ~Shift <Key>Tab: XmLGridEditComplete(RIGHT)\n\
|
|
~Ctrl ~Shift <Key>osfUp: XmLGridEditComplete(UP)\n\
|
|
<Key>osfCancel: XmLGridEditCancel()\n\
|
|
<Key>Escape: XmLGridEditCancel()";
|
|
|
|
#if 0
|
|
static char hideButtonTranslations[] =
|
|
"<BtnDown>,<BtnUp>: XmLGridHideColumn()";
|
|
|
|
static char unhideButtonTranslations[] =
|
|
"<BtnDown>,<BtnUp>: XmLGridUnhideColumn()";
|
|
#endif /*0*/
|
|
|
|
static XtResource resources[] =
|
|
{
|
|
/* Grid Resources */
|
|
{
|
|
XmNactivateCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.activateCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNaddCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.addCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNallowColumnHide, XmCAllowColumnHide,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowColHide),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNallowColumnResize, XmCAllowColumnResize,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowColResize),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNallowDragSelected, XmCAllowDragSelected,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowDrag),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNallowDrop, XmCAllowDrop,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowDrop),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNallowRowHide, XmCAllowRowHide,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowRowHide),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNallowRowResize, XmCAllowRowResize,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.allowRowResize),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNautoSelect, XmCAutoSelect,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.autoSelect),
|
|
XmRImmediate, (XtPointer)True,
|
|
},
|
|
{
|
|
XmNblankBackground, XmCBlankBackground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.blankBg),
|
|
XmRCallProc, (XtPointer)GetCoreBackground,
|
|
},
|
|
{
|
|
XmNbottomFixedCount, XmCBottomFixedCount,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.bottomFixedCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNbottomFixedMargin, XmCBottomFixedMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.bottomFixedMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellDefaults, XmCCellDefaults,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.cellDefaults),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNcellDrawCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.cellDrawCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellDropCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.cellDropCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellFocusCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.cellFocusCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellPasteCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.cellPasteCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcolumns, XmCColumns,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.colCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNdeleteCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.deleteCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNdeselectCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.deselectCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNdebugLevel, XmCDebugLevel,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.debugLevel),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNeditCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.editCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNeditTranslations, XmCTranslations,
|
|
XmRTranslationTable, sizeof(XtTranslations),
|
|
XtOffset(XmLGridWidget, grid.editTrans),
|
|
XmRString, (XtPointer)editTranslations,
|
|
},
|
|
{
|
|
XmNfontList, XmCFontList,
|
|
XmRFontList, sizeof(XmFontList),
|
|
XtOffset(XmLGridWidget, grid.fontList),
|
|
XmRImmediate, (XtPointer)0
|
|
},
|
|
{
|
|
XmNfooterColumns, XmCFooterColumns,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.footerColCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNfooterRows, XmCFooterRows,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.footerRowCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNglobalPixmapHeight, XmCGlobalPixmapHeight,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.globalPixmapHeight),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNglobalPixmapWidth, XmCGlobalPixmapWidth,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.globalPixmapWidth),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNheadingColumns, XmCHeadingColumns,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.headingColCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNheadingRows, XmCHeadingRows,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.headingRowCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNhiddenColumns, XmCHiddenColumns,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.hiddenColCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNhiddenRows, XmCHiddenRows,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.hiddenRowCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNhighlightRowMode, XmCHighlightRowMode,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.highlightRowMode),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNhighlightThickness, XmCHighlightThickness,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.highlightThickness),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
{
|
|
XmNhorizontalScrollBar, XmCHorizontalScrollBar,
|
|
XmRWidget, sizeof(Widget),
|
|
XtOffset(XmLGridWidget, grid.hsb),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNhorizontalSizePolicy, XmCHorizontalSizePolicy,
|
|
XmRGridSizePolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.hsPolicy),
|
|
XmRImmediate, (XtPointer)XmCONSTANT,
|
|
},
|
|
{
|
|
XmNhsbDisplayPolicy, XmCHsbDisplayPolicy,
|
|
XmRScrollBarDisplayPolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.hsbDisplayPolicy),
|
|
XmRImmediate, (XtPointer)XmAS_NEEDED,
|
|
},
|
|
{
|
|
XmNimmediateDraw, XmCImmediateDraw,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.immediateDraw),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNlayoutFrozen, XmCLayoutFrozen,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.layoutFrozen),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNleftFixedCount, XmCLeftFixedCount,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.leftFixedCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNleftFixedMargin, XmCLeftFixedMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.leftFixedMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNminColumnWidth, XmCMinColumnWidth,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.minColWidth),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrightFixedCount, XmCRightFixedCount,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.rightFixedCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrightFixedMargin, XmCRightFixedMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.rightFixedMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNresizeCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.resizeCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrows, XmCRows,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.rowCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNscrollBarMargin, XmCScrollBarMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.scrollBarMargin),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
{
|
|
XmNscrollCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.scrollCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNscrollColumn, XmCScrollColumn,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cScrollCol),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNscrollRow, XmCScrollRow,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cScrollRow),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNselectCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.selectCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNselectionPolicy, XmCGridSelectionPolicy,
|
|
XmRGridSelectionPolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.selectionPolicy),
|
|
XmRImmediate, (XtPointer)XmSELECT_BROWSE_ROW,
|
|
},
|
|
{
|
|
XmNselectBackground, XmCSelectBackground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.selectBg),
|
|
XmRCallProc, (XtPointer)GetManagerForeground,
|
|
},
|
|
{
|
|
XmNselectForeground, XmCSelectForeground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.selectFg),
|
|
XmRCallProc, (XtPointer)GetCoreBackground,
|
|
},
|
|
{
|
|
XmNshadowRegions, XmCShadowRegions,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.shadowRegions),
|
|
XmRImmediate, (XtPointer)511,
|
|
},
|
|
{
|
|
XmNshadowType, XmCShadowType,
|
|
XmRShadowType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.shadowType),
|
|
XmRImmediate, (XtPointer)XmSHADOW_IN,
|
|
},
|
|
{
|
|
XmNsimpleHeadings, XmCSimpleHeadings,
|
|
XmRString, sizeof(char *),
|
|
XtOffset(XmLGridWidget, grid.simpleHeadings),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNsimpleWidths, XmCSimpleWidths,
|
|
XmRString, sizeof(char *),
|
|
XtOffset(XmLGridWidget, grid.simpleWidths),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtextWidget, XmCTextWidget,
|
|
XmRWidget, sizeof(Widget),
|
|
XtOffset(XmLGridWidget, grid.text),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtoggleBottomColor, XmCToggleBottomColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.toggleBotColor),
|
|
XmRCallProc, (XtPointer)GetManagerForeground,
|
|
},
|
|
{
|
|
XmNtoggleTopColor, XmCToggleTopColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.toggleTopColor),
|
|
XmRCallProc, (XtPointer)GetManagerForeground,
|
|
},
|
|
{
|
|
XmNtoggleSize, XmCToggleSize,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.toggleSize),
|
|
XmRImmediate, (XtPointer)16,
|
|
},
|
|
{
|
|
XmNtraverseTranslations, XmCTranslations,
|
|
XmRTranslationTable, sizeof(XtTranslations),
|
|
XtOffset(XmLGridWidget, grid.traverseTrans),
|
|
XmRString, (XtPointer)traverseTranslations,
|
|
},
|
|
{
|
|
XmNtopFixedCount, XmCTopFixedCount,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.topFixedCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtopFixedMargin, XmCTopFixedMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.topFixedMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNuseAverageFontWidth, XmCUseAverageFontWidth,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.useAvgWidth),
|
|
XmRImmediate, (XtPointer)True,
|
|
},
|
|
{
|
|
XmNverticalScrollBar, XmCVerticalScrollBar,
|
|
XmRWidget, sizeof(Widget),
|
|
XtOffset(XmLGridWidget, grid.vsb),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNverticalSizePolicy, XmCVerticalSizePolicy,
|
|
XmRGridSizePolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.vsPolicy),
|
|
XmRImmediate, (XtPointer)XmCONSTANT,
|
|
},
|
|
{
|
|
XmNvisibleColumns, XmCVisibleColumns,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.visibleCols),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNvisibleRows, XmCVisibleRows,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.visibleRows),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNvsbDisplayPolicy, XmCVsbDisplayPolicy,
|
|
XmRScrollBarDisplayPolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.vsbDisplayPolicy),
|
|
XmRImmediate, (XtPointer)XmAS_NEEDED,
|
|
},
|
|
/* Xfe Additions*/
|
|
{
|
|
XmNpopupCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid.popupCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNenterCellCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid . enterCellCallback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNleaveCellCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid . leaveCellCallback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNenterGridCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid . enterGridCallback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
{
|
|
XmNleaveGridCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffset(XmLGridWidget, grid . leaveGridCallback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
|
|
/* Row Resources */
|
|
{
|
|
XmNrow, XmCGridRow,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellRow),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNrowUserData, XmCUserData,
|
|
XmRPointer, sizeof(XtPointer),
|
|
XtOffset(XmLGridWidget, grid.rowUserData),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrowHeight, XmCRowHeight,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.rowHeight),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrowRangeEnd, XmCRowRangeEnd,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellRowRangeEnd),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNrowRangeStart, XmCRowRangeStart,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellRowRangeStart),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNrowSizePolicy, XmCRowSizePolicy,
|
|
XmRGridSizePolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.rowSizePolicy),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNrowStep, XmCRowStep,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.rowStep),
|
|
XmRImmediate, (XtPointer)1,
|
|
},
|
|
{
|
|
XmNrowType, XmCRowType,
|
|
XmRRowType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.rowType),
|
|
XmRImmediate, (XtPointer)XmINVALID_TYPE,
|
|
},
|
|
/* Column Resources */
|
|
{
|
|
XmNcolumn, XmCGridColumn,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellCol),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNcolumnUserData, XmCUserData,
|
|
XmRPointer, sizeof(XtPointer),
|
|
XtOffset(XmLGridWidget, grid.colUserData),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcolumnResizable, XmCColumnResizable,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.colResizable),
|
|
XmRImmediate, (XtPointer)TRUE,
|
|
},
|
|
{
|
|
XmNcolumnWidth, XmCColumnWidth,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.colWidth),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcolumnRangeEnd, XmCColumnRangeEnd,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellColRangeEnd),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNcolumnRangeStart, XmCColumnRangeStart,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellColRangeStart),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNcolumnSizePolicy, XmCColumnSizePolicy,
|
|
XmRGridSizePolicy, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.colSizePolicy),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcolumnStep, XmCColumnStep,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.colStep),
|
|
XmRImmediate, (XtPointer)1,
|
|
},
|
|
{
|
|
XmNcolumnType, XmCColumnType,
|
|
XmRColumnType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.colType),
|
|
XmRImmediate, (XtPointer)XmINVALID_TYPE,
|
|
},
|
|
/* xfe Column Resource additions */
|
|
{
|
|
XmNcolumnHidden, XmCColumnHidden,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.colHidden),
|
|
XmRImmediate, (XtPointer)FALSE,
|
|
},
|
|
{
|
|
XmNcolumnSortType, XmCColumnSortType,
|
|
XmRColumnSortType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.colSortType),
|
|
XmRImmediate, (XtPointer)XmSORT_NONE,
|
|
},
|
|
/* Cell Resources */
|
|
{
|
|
XmNcellAlignment, XmCCellAlignment,
|
|
XmRCellAlignment, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.alignment),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellBackground, XmCCellBackground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.background),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellBottomBorderColor, XmCCellBottomBorderColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.bottomBorderColor),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellBottomBorderType, XmCCellBottomBorderType,
|
|
XmRCellBorderType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.bottomBorderType),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellColumnSpan, XmCCellColumnSpan,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellValues.columnSpan),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellEditable, XmCCellEditable,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.cellValues.editable),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNcellFontList, XmCCellFontList,
|
|
XmRFontList, sizeof(XmFontList),
|
|
XtOffset(XmLGridWidget, grid.cellValues.fontList),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellForeground, XmCCellForeground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.foreground),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellLeftBorderColor, XmCCellLeftBorderColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.leftBorderColor),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellLeftBorderType, XmCCellLeftBorderType,
|
|
XmRCellBorderType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.leftBorderType),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellMarginBottom, XmCCellMarginBottom,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.cellValues.bottomMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellMarginLeft, XmCCellMarginLeft,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.cellValues.leftMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellMarginRight, XmCCellMarginRight,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.cellValues.rightMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellMarginTop, XmCCellMarginTop,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.cellValues.topMargin),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellPixmap, XmCCellPixmap,
|
|
XmRManForegroundPixmap, sizeof(Pixmap),
|
|
XtOffset(XmLGridWidget, grid.cellPixmap),
|
|
XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
|
|
},
|
|
{
|
|
XmNcellPixmapMask, XmCCellPixmapMask,
|
|
XtRBitmap, sizeof(Pixmap),
|
|
XtOffset(XmLGridWidget, grid.cellPixmapMask),
|
|
XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
|
|
},
|
|
{
|
|
XmNcellRightBorderColor, XmCCellRightBorderColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.rightBorderColor),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellRightBorderType, XmCCellRightBorderType,
|
|
XmRCellBorderType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.rightBorderType),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellRowSpan, XmCCellRowSpan,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLGridWidget, grid.cellValues.rowSpan),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellString, XmCXmString,
|
|
XmRXmString, sizeof(XmString),
|
|
XtOffset(XmLGridWidget, grid.cellString),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellToggleSet, XmCCellToggleSet,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.cellToggleSet),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNcellTopBorderColor, XmCCellTopBorderColor,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLGridWidget, grid.cellValues.topBorderColor),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellTopBorderType, XmCCellTopBorderType,
|
|
XmRCellBorderType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.topBorderType),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNcellType, XmCCellType,
|
|
XmRCellType, sizeof(unsigned char),
|
|
XtOffset(XmLGridWidget, grid.cellValues.type),
|
|
XmRImmediate, (XtPointer)XmSTRING_CELL,
|
|
},
|
|
{
|
|
XmNcellUserData, XmCUserData,
|
|
XmRPointer, sizeof(XtPointer),
|
|
XtOffset(XmLGridWidget, grid.cellValues.userData),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
/* Overridden inherited resources */
|
|
{
|
|
XmNshadowThickness, XmCShadowThickness,
|
|
XmRHorizontalDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, manager.shadow_thickness),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
/* XFE Addition*/
|
|
{
|
|
XmNhideUnhideButtons, XmCHideUnhideButtons,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.hideUnhideButtons),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNsingleClickActivation, XmCSingleClickActivation,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.singleClickActivation),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
#if 0
|
|
{
|
|
XmNhideButtonTranslations, XmCTranslations,
|
|
XmRTranslationTable, sizeof(XtTranslations),
|
|
XtOffset(XmLGridWidget, grid.hideButtonTrans),
|
|
XmRString, (XtPointer)hideButtonTranslations,
|
|
},
|
|
{
|
|
XmNunhideButtonTranslations, XmCTranslations,
|
|
XmRTranslationTable, sizeof(XtTranslations),
|
|
XtOffset(XmLGridWidget, grid.unhideButtonTrans),
|
|
XmRString, (XtPointer)unhideButtonTranslations,
|
|
},
|
|
#endif /*0*/
|
|
{
|
|
XmNuseTextWidget, XmCUseTextWidget,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLGridWidget, grid.useTextWidget),
|
|
XmRImmediate, (XtPointer)True,
|
|
},
|
|
{
|
|
XmNiconSpacing, XmCIconSpacing,
|
|
XmRHorizontalDimension, sizeof(Dimension),
|
|
XtOffset(XmLGridWidget, grid.iconSpacing),
|
|
XmRImmediate, (XtPointer) 4,
|
|
},
|
|
};
|
|
|
|
XmLGridClassRec xmlGridClassRec =
|
|
{
|
|
{ /* core_class */
|
|
(WidgetClass)&xmManagerClassRec, /* superclass */
|
|
"XmLGrid", /* class_name */
|
|
sizeof(XmLGridRec), /* widget_size */
|
|
ClassInitialize, /* class_init */
|
|
ClassPartInitialize, /* class_part_init */
|
|
FALSE, /* class_inited */
|
|
(XtInitProc)Initialize, /* initialize */
|
|
0, /* initialize_hook */
|
|
(XtRealizeProc)Realize, /* realize */
|
|
(XtActionList)actions, /* actions */
|
|
(Cardinal)XtNumber(actions), /* num_actions */
|
|
(XtResource *)resources, /* resources */
|
|
XtNumber(resources), /* num_resources */
|
|
NULLQUARK, /* xrm_class */
|
|
TRUE, /* compress_motion */
|
|
XtExposeCompressMaximal, /* compress_exposure */
|
|
TRUE, /* compress_enterleav */
|
|
TRUE, /* visible_interest */
|
|
(XtWidgetProc)Destroy, /* destroy */
|
|
(XtWidgetProc)Resize, /* resize */
|
|
(XtExposeProc)Redisplay, /* expose */
|
|
(XtSetValuesFunc)SetValues, /* set_values */
|
|
0, /* set_values_hook */
|
|
XtInheritSetValuesAlmost, /* set_values_almost */
|
|
(XtArgsProc)GetSubValues, /* get_values_hook */
|
|
0, /* accept_focus */
|
|
XtVersion, /* version */
|
|
0, /* callback_private */
|
|
translations, /* tm_table */
|
|
0, /* query_geometry */
|
|
0, /* display_accelerato */
|
|
0, /* extension */
|
|
},
|
|
{ /* composite_class */
|
|
(XtGeometryHandler)GeometryManager, /* geometry_manager */
|
|
(XtWidgetProc)ChangeManaged, /* change_managed */
|
|
XtInheritInsertChild, /* insert_child */
|
|
XtInheritDeleteChild, /* delete_child */
|
|
0, /* extension */
|
|
},
|
|
{ /* constraint_class */
|
|
0, /* subresources */
|
|
0, /* subresource_count */
|
|
sizeof(XmLGridConstraintRec), /* constraint_size */
|
|
0, /* initialize */
|
|
0, /* destroy */
|
|
0, /* set_values */
|
|
0, /* extension */
|
|
},
|
|
{ /* manager_class */
|
|
XtInheritTranslations, /* translations */
|
|
0, /* syn resources */
|
|
0, /* num syn_resources */
|
|
0, /* get_cont_resources */
|
|
0, /* num_get_cont_res */
|
|
XmInheritParentProcess, /* parent_process */
|
|
0, /* extension */
|
|
},
|
|
{ /* grid_class */
|
|
0, /* initial rows */
|
|
0, /* initial columns */
|
|
XmInheritGridPreLayout, /* pre layout */
|
|
sizeof(struct _XmLGridRowRec), /* row rec size */
|
|
_GridRowNew, /* row new */
|
|
_GridRowFree, /* row free */
|
|
_GetRowValueMask, /* get row value mask */
|
|
_GetRowValue, /* get row value */
|
|
_SetRowValues, /* set row values */
|
|
sizeof(struct _XmLGridColumnRec), /* column rec size */
|
|
_GridColumnNew, /* column new */
|
|
_GridColumnFree, /* column free */
|
|
_GetColumnValueMask, /* get col value mask */
|
|
_GetColumnValue, /* get column value */
|
|
_SetColumnValues, /* set column values */
|
|
_SetCellValuesResize, /* set cell vl resize */
|
|
_GridCellAction, /* cell action */
|
|
}
|
|
};
|
|
|
|
WidgetClass xmlGridWidgetClass = (WidgetClass)&xmlGridClassRec;
|
|
|
|
/*
|
|
Create and Destroy
|
|
*/
|
|
|
|
static void
|
|
ClassInitialize(void)
|
|
{
|
|
int off1, off2;
|
|
|
|
XmLInitialize();
|
|
|
|
XtSetTypeConverter(XmRString, XmRGridSizePolicy,
|
|
CvtStringToSizePolicy, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRColumnType,
|
|
CvtStringToRowColType, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRRowType,
|
|
CvtStringToRowColType, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRGridSelectionPolicy,
|
|
CvtStringToSelectionPolicy, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRCellAlignment,
|
|
CvtStringToCellAlignment, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRCellType,
|
|
CvtStringToCellType, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRCellBorderType,
|
|
CvtStringToCellBorderType, 0, 0, XtCacheNone, 0);
|
|
/* long must be > 2 bytes for cell mask to work */
|
|
if (sizeof(long) < 3)
|
|
fprintf(stderr, "xmlGridClass: fatal error: long < 3 bytes\n");
|
|
/* compiler sanity check - make sure array pos lines up */
|
|
off1 = XtOffset(XmLArrayItem *, pos);
|
|
off2 = XtOffset(XmLGridColumn, grid.pos);
|
|
if (off1 != off2)
|
|
fprintf(stderr, "xmlGridClass: fatal error: column pos offset bad\n");
|
|
off2 = XtOffset(XmLGridRow, grid.pos);
|
|
if (off1 != off2)
|
|
fprintf(stderr, "xmlGridClass: fatal error: row pos offset bad\n");
|
|
}
|
|
|
|
static void
|
|
ClassPartInitialize(WidgetClass wc)
|
|
{
|
|
XmLGridWidgetClass c, sc;
|
|
|
|
c = (XmLGridWidgetClass)wc;
|
|
sc = (XmLGridWidgetClass)c->core_class.superclass;
|
|
|
|
#define INHERIT_PROC(proc, inherit) \
|
|
if (c->grid_class.proc == inherit) \
|
|
c->grid_class.proc = sc->grid_class.proc;
|
|
|
|
INHERIT_PROC(rowNewProc, XmInheritGridRowNew)
|
|
INHERIT_PROC(rowFreeProc, XmInheritGridRowFree)
|
|
INHERIT_PROC(getRowValueMaskProc, XmInheritGridGetRowValueMask)
|
|
INHERIT_PROC(getRowValueProc, XmInheritGridGetRowValue)
|
|
INHERIT_PROC(setRowValuesProc, XmInheritGridSetRowValues)
|
|
|
|
INHERIT_PROC(columnNewProc, XmInheritGridColumnNew)
|
|
INHERIT_PROC(columnFreeProc, XmInheritGridColumnFree)
|
|
INHERIT_PROC(getColumnValueMaskProc, XmInheritGridGetColumnValueMask)
|
|
INHERIT_PROC(getColumnValueProc, XmInheritGridGetColumnValue)
|
|
INHERIT_PROC(setColumnValuesProc, XmInheritGridSetColumnValues)
|
|
|
|
INHERIT_PROC(setCellValuesResizeProc, XmInheritGridSetCellValuesResize)
|
|
INHERIT_PROC(cellActionProc, XmInheritGridCellAction)
|
|
|
|
#undef INHERIT_PROC
|
|
}
|
|
|
|
static void
|
|
Initialize(Widget reqW,
|
|
Widget newW,
|
|
ArgList args,
|
|
Cardinal *narg)
|
|
{
|
|
XmLGridWidget g, request;
|
|
Display *dpy;
|
|
Pixmap pix, pixMask;
|
|
Pixel white, black;
|
|
XColor fg, bg;
|
|
GridReg *reg;
|
|
int i, valid, hc, c, fc, hr, r, fr;
|
|
Boolean layoutFrozen;
|
|
#ifdef POINTER_FOCUS_CHECK
|
|
unsigned char kfp;
|
|
Widget shell;
|
|
#endif
|
|
|
|
g = (XmLGridWidget)newW;
|
|
dpy = XtDisplay((Widget)g);
|
|
request = (XmLGridWidget)reqW;
|
|
|
|
#ifdef POINTER_FOCUS_CHECK
|
|
shell = XmLShellOfWidget(newW);
|
|
if (shell && XmIsVendorShell(shell))
|
|
{
|
|
XtVaGetValues(shell,
|
|
XmNkeyboardFocusPolicy, &kfp,
|
|
NULL);
|
|
if (kfp == XmPOINTER)
|
|
XmLWarning(newW, "keyboardFocusPolicy of XmPOINTER not supported");
|
|
}
|
|
#endif
|
|
|
|
black = BlackPixelOfScreen(XtScreen((Widget)g));
|
|
white = WhitePixelOfScreen(XtScreen((Widget)g));
|
|
|
|
g->grid.rowArray = XmLArrayNew(1, 1);
|
|
g->grid.colArray = XmLArrayNew(1, 1);
|
|
|
|
if (g->core.width <= 0)
|
|
g->core.width = 100;
|
|
if (g->core.height <= 0)
|
|
g->core.height = 100;
|
|
|
|
CopyFontList(g);
|
|
|
|
if (g->grid.useTextWidget) {
|
|
g->grid.text = XtVaCreateManagedWidget("text", xmTextWidgetClass, (Widget)g,
|
|
XmNmarginHeight, 0,
|
|
XmNmarginWidth, 3,
|
|
XmNshadowThickness, 0,
|
|
XmNhighlightThickness, 0,
|
|
XmNx, 0,
|
|
XmNy, 0,
|
|
XmNwidth, 40,
|
|
XmNheight, 40,
|
|
XmNbackground, g->core.background_pixel,
|
|
XmNforeground, g->manager.foreground,
|
|
NULL);
|
|
XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
|
|
XtAddEventHandler(g->grid.text, StructureNotifyMask,
|
|
True, (XtEventHandler)TextMapped, (XtPointer)0);
|
|
XtAddCallback(g->grid.text, XmNactivateCallback, TextActivate, 0);
|
|
XtAddCallback(g->grid.text, XmNfocusCallback, TextFocus, 0);
|
|
XtAddCallback(g->grid.text, XmNlosingFocusCallback, TextFocus, 0);
|
|
XtAddCallback(g->grid.text, XmNmodifyVerifyCallback, TextModifyVerify, 0);
|
|
}
|
|
|
|
g->grid.hsb = XtVaCreateWidget(
|
|
"hsb", xmScrollBarWidgetClass, (Widget)g,
|
|
XmNincrement, 1,
|
|
XmNorientation, XmHORIZONTAL,
|
|
XmNtraversalOn, False,
|
|
XmNbackground, g->core.background_pixel,
|
|
/* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
|
|
#ifndef IRIX
|
|
XmNforeground, g->manager.foreground,
|
|
#endif
|
|
XmNtopShadowColor, g->manager.top_shadow_color,
|
|
XmNbottomShadowColor, g->manager.bottom_shadow_color,
|
|
NULL);
|
|
XtAddCallback(g->grid.hsb, XmNdragCallback, ScrollCB, 0);
|
|
XtAddCallback(g->grid.hsb, XmNvalueChangedCallback, ScrollCB, 0);
|
|
g->grid.vsb = XtVaCreateWidget(
|
|
"vsb", xmScrollBarWidgetClass, (Widget)g,
|
|
XmNorientation, XmVERTICAL,
|
|
XmNincrement, 1,
|
|
XmNtraversalOn, False,
|
|
XmNbackground, g->core.background_pixel,
|
|
/* Don't force foreground on IRIX - it screws up the thumb color in sgiMode */
|
|
#ifndef IRIX
|
|
XmNforeground, g->manager.foreground,
|
|
#endif
|
|
XmNtopShadowColor, g->manager.top_shadow_color,
|
|
XmNbottomShadowColor, g->manager.bottom_shadow_color,
|
|
NULL);
|
|
XtAddCallback(g->grid.vsb, XmNdragCallback, ScrollCB, 0);
|
|
XtAddCallback(g->grid.vsb, XmNvalueChangedCallback, ScrollCB, 0);
|
|
|
|
if (g->grid.hideUnhideButtons)
|
|
{
|
|
CreateHideUnhideButtons(g);
|
|
}
|
|
else
|
|
{
|
|
g->grid.hideButton = 0;
|
|
g->grid.unhideButton = 0;
|
|
}
|
|
|
|
g->grid.inResize = False;
|
|
|
|
/* Cursors */
|
|
fg.red = ~0;
|
|
fg.green = ~0;
|
|
fg.blue = ~0;
|
|
fg.pixel = white;
|
|
fg.flags = DoRed | DoGreen | DoBlue;
|
|
bg.red = 0;
|
|
bg.green = 0;
|
|
bg.blue = 0;
|
|
bg.pixel = black;
|
|
bg.flags = DoRed | DoGreen | DoBlue;
|
|
pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
|
|
(char *)horizp_bits, horizp_width, horizp_height, 0, 1, 1);
|
|
pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
|
|
(char *)horizm_bits, horizm_width, horizm_height, 1, 0, 1);
|
|
g->grid.hResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
|
|
&fg, &bg, 9, 9);
|
|
XFreePixmap(dpy, pix);
|
|
XFreePixmap(dpy, pixMask);
|
|
pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
|
|
(char *)vertp_bits, vertp_width, vertp_height, 0, 1, 1);
|
|
pixMask = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
|
|
(char *)vertm_bits, vertm_width, vertm_height, 1, 0, 1);
|
|
g->grid.vResizeCursor = XCreatePixmapCursor(dpy, pix, pixMask,
|
|
&fg, &bg, 9, 9);
|
|
XFreePixmap(dpy, pix);
|
|
XFreePixmap(dpy, pixMask);
|
|
|
|
g->grid.cursorDefined = CursorNormal;
|
|
g->grid.focusIn = 0;
|
|
g->grid.focusRow = -1;
|
|
g->grid.focusCol = -1;
|
|
g->grid.mayHaveRowSpans = 0;
|
|
g->grid.scrollCol = 0;
|
|
g->grid.scrollRow = 0;
|
|
g->grid.textHidden = 1;
|
|
g->grid.inMode = InNormal;
|
|
g->grid.inEdit = 0;
|
|
g->grid.singleColScrollMode = 0;
|
|
g->grid.layoutStack = 0;
|
|
g->grid.needsHorizLayout = 0;
|
|
g->grid.needsVertLayout = 0;
|
|
g->grid.recalcHorizVisPos = 0;
|
|
g->grid.recalcVertVisPos = 0;
|
|
g->grid.vertVisChangedHint = 0;
|
|
g->grid.defCellValues = CellRefValuesCreate(g, 0);
|
|
g->grid.defCellValues->refCount = 1;
|
|
g->grid.ignoreModifyVerify = 0;
|
|
g->grid.extendRow = -1;
|
|
g->grid.extendCol = -1;
|
|
g->grid.extendToRow = -1;
|
|
g->grid.extendToCol = -1;
|
|
g->grid.extendSelect = True;
|
|
g->grid.lastSelectRow = -1;
|
|
g->grid.lastSelectCol = -1;
|
|
g->grid.lastSelectTime = 0;
|
|
g->grid.dragTimerSet = 0;
|
|
g->grid.editTimerSet = 0;
|
|
g->grid.gc = 0;
|
|
|
|
/*
|
|
* Support for:
|
|
*
|
|
* XmNenterCellCallback
|
|
* XmNenterCellCallback
|
|
* XmNenterCallback
|
|
* XmNleaveCallback
|
|
*/
|
|
g->grid.lastCursorMotionRow = -1;
|
|
g->grid.lastCursorMotionCol = -1;
|
|
|
|
XtAddEventHandler(newW,
|
|
EnterWindowMask | LeaveWindowMask,
|
|
True,
|
|
(XtEventHandler) GridCrossingEH,
|
|
(XtPointer) NULL);
|
|
|
|
reg = g->grid.reg;
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
reg[i].x = 0;
|
|
reg[i].y = 0;
|
|
reg[i].width = 0;
|
|
reg[i].height = 0;
|
|
reg[i].row = 0;
|
|
reg[i].col = 0;
|
|
reg[i].nrow = 0;
|
|
reg[i].ncol = 0;
|
|
}
|
|
|
|
layoutFrozen = g->grid.layoutFrozen;
|
|
g->grid.layoutFrozen = True;
|
|
|
|
if (g->grid.hiddenColCount || g->grid.hiddenRowCount)
|
|
{
|
|
XmLWarning(newW, "Initialize() - can't set hidden rows or columns");
|
|
g->grid.hiddenColCount = 0;
|
|
g->grid.hiddenRowCount = 0;
|
|
}
|
|
hc = g->grid.headingColCount;
|
|
c = XmLGridClassPartOfWidget(g).initialCols;
|
|
if (c < g->grid.colCount)
|
|
c = g->grid.colCount;
|
|
fc = g->grid.footerColCount;
|
|
hr = g->grid.headingRowCount;
|
|
r = XmLGridClassPartOfWidget(g).initialRows;
|
|
if (r < g->grid.rowCount)
|
|
r = g->grid.rowCount ;
|
|
fr = g->grid.footerRowCount;
|
|
g->grid.headingColCount = 0;
|
|
g->grid.colCount = 0;
|
|
g->grid.footerColCount = 0;
|
|
g->grid.headingRowCount = 0;
|
|
g->grid.rowCount = 0;
|
|
g->grid.footerRowCount = 0;
|
|
XmLGridAddColumns(newW, XmHEADING, -1, hc);
|
|
XmLGridAddColumns(newW, XmCONTENT, -1, c);
|
|
XmLGridAddColumns(newW, XmFOOTER, -1, fc);
|
|
XmLGridAddRows(newW, XmHEADING, -1, hr);
|
|
XmLGridAddRows(newW, XmCONTENT, -1, r);
|
|
XmLGridAddRows(newW, XmFOOTER, -1, fr);
|
|
if (g->grid.simpleHeadings)
|
|
{
|
|
g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
|
|
SetSimpleHeadings(g, g->grid.simpleHeadings);
|
|
}
|
|
if (g->grid.simpleWidths)
|
|
{
|
|
g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
|
|
SetSimpleWidths(g, g->grid.simpleWidths);
|
|
}
|
|
if (g->grid.visibleRows)
|
|
ApplyVisibleRows(g);
|
|
if (g->grid.visibleCols && g->grid.hsPolicy == XmCONSTANT)
|
|
ApplyVisibleCols(g);
|
|
|
|
g->grid.layoutFrozen = layoutFrozen;
|
|
VertLayout(g, 1);
|
|
HorizLayout(g, 1);
|
|
PlaceScrollbars(g);
|
|
|
|
valid = 1;
|
|
for (i = 0; i < *narg; i++)
|
|
{
|
|
if (!args[i].name)
|
|
continue;
|
|
if (!strcmp(args[i].name, XmNrows) ||
|
|
!strcmp(args[i].name, XmNcolumns))
|
|
continue;
|
|
if (!strncmp(args[i].name, "row", 3) ||
|
|
!strncmp(args[i].name, "column", 6) ||
|
|
!strncmp(args[i].name, "cell", 4))
|
|
valid = 0;
|
|
}
|
|
if (!valid)
|
|
XmLWarning(newW,
|
|
"Initialize() - can't set row,column or cell values in init");
|
|
|
|
DropRegister(g, g->grid.allowDrop);
|
|
}
|
|
|
|
static void
|
|
Destroy(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
int i, count;
|
|
|
|
g = (XmLGridWidget)w;
|
|
dpy = XtDisplay(w);
|
|
if (g->grid.dragTimerSet)
|
|
XtRemoveTimeOut(g->grid.dragTimerId);
|
|
if (g->grid.editTimerSet)
|
|
XtRemoveTimeOut(g->grid.editTimerId);
|
|
DefineCursor(g, CursorNormal);
|
|
XFreeCursor(dpy, g->grid.hResizeCursor);
|
|
XFreeCursor(dpy, g->grid.vResizeCursor);
|
|
if (g->grid.gc)
|
|
{
|
|
XFreeGC(dpy, g->grid.gc);
|
|
XFreeFont(dpy, g->grid.fallbackFont);
|
|
}
|
|
XmFontListFree(g->grid.fontList);
|
|
XmLGridCellDerefValues(g->grid.defCellValues);
|
|
ExtendSelect(g, (XEvent *)0, False, -1, -1);
|
|
count = XmLArrayGetCount(g->grid.rowArray);
|
|
for (i = 0; i < count; i++)
|
|
XmLGridRowFree(w, (XmLGridRow)XmLArrayGet(g->grid.rowArray, i));
|
|
XmLArrayFree(g->grid.rowArray);
|
|
count = XmLArrayGetCount(g->grid.colArray);
|
|
for (i = 0; i < count; i++)
|
|
XmLGridColumnFree(w, (XmLGridColumn)XmLArrayGet(g->grid.colArray, i));
|
|
XmLArrayFree(g->grid.colArray);
|
|
if (g->grid.simpleHeadings)
|
|
free((char *)g->grid.simpleHeadings);
|
|
if (g->grid.simpleWidths)
|
|
free((char *)g->grid.simpleWidths);
|
|
}
|
|
|
|
/*
|
|
Geometry, Drawing, Entry and Picking
|
|
*/
|
|
|
|
static void
|
|
Realize(Widget w,
|
|
XtValueMask *valueMask,
|
|
XSetWindowAttributes *attr)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
WidgetClass superClass;
|
|
XtRealizeProc realize;
|
|
XGCValues values;
|
|
XtGCMask mask;
|
|
static char dashes[2] = { 1, 1 };
|
|
|
|
g = (XmLGridWidget)w;
|
|
dpy = XtDisplay(g);
|
|
superClass = xmlGridWidgetClass->core_class.superclass;
|
|
realize = superClass->core_class.realize;
|
|
(*realize)(w, valueMask, attr);
|
|
|
|
if (!g->grid.gc)
|
|
{
|
|
g->grid.fallbackFont = XLoadQueryFont(dpy, "fixed");
|
|
values.foreground = g->manager.foreground;
|
|
values.font = g->grid.fallbackFont->fid;
|
|
mask = GCForeground | GCFont;
|
|
g->grid.gc = XCreateGC(dpy, XtWindow(g), mask, &values);
|
|
XSetDashes(dpy, g->grid.gc, 0, dashes, 2);
|
|
if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
|
|
g->grid.autoSelect == True &&
|
|
g->grid.rowCount)
|
|
XmLGridSelectRow(w, 0, False);
|
|
}
|
|
}
|
|
|
|
static void
|
|
Redisplay(Widget w,
|
|
XExposeEvent *event,
|
|
Region region)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
Window win;
|
|
XmLGridCell cell;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCellRefValues *cellValues;
|
|
XmLGridDrawStruct ds;
|
|
XmLGridCallbackStruct cbs;
|
|
GridReg *reg;
|
|
XRectangle eRect, rRect, clipRect, rect[6];
|
|
int i, n, st, c, r, sc, sr, width, height, rowHeight;
|
|
int lastVisPos, visPos, hasDrawCB;
|
|
Boolean spanUp, spanLeft;
|
|
|
|
g = (XmLGridWidget)w;
|
|
if (!XtIsRealized((Widget)g))
|
|
return;
|
|
if (!g->core.visible)
|
|
return;
|
|
if (g->grid.layoutFrozen == True)
|
|
XmLWarning(w, "Redisplay() - layout frozen is True during redraw");
|
|
dpy = XtDisplay(g);
|
|
win = XtWindow(g);
|
|
st = g->manager.shadow_thickness;
|
|
reg = g->grid.reg;
|
|
if (event)
|
|
{
|
|
eRect.x = event->x;
|
|
eRect.y = event->y;
|
|
eRect.width = event->width;
|
|
eRect.height = event->height;
|
|
if (g->grid.debugLevel > 1)
|
|
fprintf(stderr, "XmLGrid: Redisplay x %d y %d w %d h %d\n",
|
|
event->x, event->y, event->width, event->height);
|
|
}
|
|
else
|
|
{
|
|
eRect.x = 0;
|
|
eRect.y = 0;
|
|
eRect.width = g->core.width;
|
|
eRect.height = g->core.height;
|
|
}
|
|
if (!eRect.width || !eRect.height)
|
|
return;
|
|
/* Hide any XORed graphics */
|
|
DrawResizeLine(g, 0, 1);
|
|
hasDrawCB = 0;
|
|
if (XtHasCallbacks(w, XmNcellDrawCallback) == XtCallbackHasSome)
|
|
hasDrawCB = 1;
|
|
|
|
/* Add extra shadow around the whole widget
|
|
* if 512 is set for shadow regions
|
|
*/
|
|
if (g->grid.shadowRegions == 512
|
|
&& g->manager.shadow_thickness
|
|
&& XmLRectIntersect(&eRect, &rRect) != XmLRectInside)
|
|
{
|
|
#ifdef MOTIF11
|
|
_XmDrawShadow(dpy, win,
|
|
g->manager.bottom_shadow_GC,
|
|
g->manager.top_shadow_GC,
|
|
g->manager.shadow_thickness,
|
|
0,0,
|
|
g->core.width, g->core.height);
|
|
#else
|
|
_XmDrawShadows(dpy, win,
|
|
g->manager.top_shadow_GC,
|
|
g->manager.bottom_shadow_GC,
|
|
0,0,
|
|
g->core.width, g->core.height,
|
|
g->manager.shadow_thickness,
|
|
g->grid.shadowType);
|
|
#endif
|
|
}
|
|
/* end of extra shadow */
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
rRect.x = reg[i].x;
|
|
rRect.y = reg[i].y;
|
|
rRect.width = reg[i].width;
|
|
rRect.height = reg[i].height;
|
|
if (XmLRectIntersect(&eRect, &rRect) == XmLRectOutside)
|
|
continue;
|
|
if (g->grid.debugLevel > 2)
|
|
fprintf(stderr, "XmLGrid: Redisplay region %d shadows\n", i);
|
|
rRect.x += st;
|
|
rRect.width -= st * 2;
|
|
rRect.y += st;
|
|
rRect.height -= st * 2;
|
|
if (XmLRectIntersect(&eRect, &rRect) != XmLRectInside
|
|
&& g->manager.shadow_thickness
|
|
&& g->grid.shadowRegions != 512)
|
|
{
|
|
if (g->grid.shadowRegions & (1 << i))
|
|
#ifdef MOTIF11
|
|
_XmDrawShadow(dpy, win,
|
|
g->manager.bottom_shadow_GC,
|
|
g->manager.top_shadow_GC,
|
|
g->manager.shadow_thickness,
|
|
reg[i].x, reg[i].y,
|
|
reg[i].width, reg[i].height);
|
|
#else
|
|
_XmDrawShadows(dpy, win,
|
|
g->manager.top_shadow_GC,
|
|
g->manager.bottom_shadow_GC,
|
|
reg[i].x, reg[i].y,
|
|
reg[i].width, reg[i].height,
|
|
g->manager.shadow_thickness,
|
|
g->grid.shadowType);
|
|
#endif
|
|
else
|
|
#ifdef MOTIF11
|
|
_XmEraseShadow(dpy, win,
|
|
g->manager.shadow_thickness,
|
|
reg[i].x, reg[i].y,
|
|
reg[i].width, reg[i].height);
|
|
#else
|
|
_XmClearBorder(dpy, win,
|
|
reg[i].x, reg[i].y,
|
|
reg[i].width, reg[i].height,
|
|
g->manager.shadow_thickness);
|
|
#endif
|
|
}
|
|
rRect.x += st;
|
|
height = 0;
|
|
if (g->grid.debugLevel > 2)
|
|
fprintf(stderr, "XmLGrid: Redisplay region %d content\n", i);
|
|
for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
|
|
{
|
|
rowHeight = GetRowHeight(g, r);
|
|
if (!rowHeight && !g->grid.mayHaveRowSpans)
|
|
continue;
|
|
width = 0;
|
|
for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
|
|
{
|
|
rRect.x = reg[i].x + st + width;
|
|
rRect.y = reg[i].y + st + height;
|
|
if (g->grid.singleColScrollMode)
|
|
rRect.x -= g->grid.singleColScrollPos;
|
|
rRect.width = GetColWidth(g, c);
|
|
#if 0
|
|
if (i == 1 && r == reg[1].row && c == reg[1].col - 1)
|
|
{
|
|
rRect.width -= 10;
|
|
}
|
|
#endif /*0 slamm */
|
|
rRect.height = rowHeight;
|
|
width += rRect.width;
|
|
cell = GetCell(g, r, c);
|
|
if (!cell)
|
|
continue;
|
|
cellValues = XmLGridCellGetRefValues(cell);
|
|
|
|
spanUp = False;
|
|
spanLeft = False;
|
|
if (XmLGridCellInRowSpan(cell))
|
|
{
|
|
if (r == reg[i].row)
|
|
{
|
|
spanUp = True;
|
|
if (c == reg[i].col)
|
|
spanLeft = True;
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
if (XmLGridCellInColumnSpan(cell))
|
|
{
|
|
if (c == reg[i].col)
|
|
spanLeft = True;
|
|
else
|
|
continue;
|
|
}
|
|
sr = r;
|
|
sc = c;
|
|
if (spanUp == True || spanLeft == True ||
|
|
cellValues->rowSpan || cellValues->columnSpan)
|
|
{
|
|
if (RowColFirstSpan(g, r, c, &sr, &sc, &rRect,
|
|
spanLeft, spanUp) == -1)
|
|
continue;
|
|
RowColSpanRect(g, sr, sc, &rRect);
|
|
}
|
|
if (!rRect.width || !rRect.height)
|
|
continue;
|
|
clipRect = rRect;
|
|
ClipRectToReg(g, &clipRect, ®[i]);
|
|
if (!clipRect.width || !clipRect.height)
|
|
continue;
|
|
if (event && XRectInRegion(region, clipRect.x, clipRect.y,
|
|
clipRect.width, clipRect.height) == RectangleOut)
|
|
continue;
|
|
cell = GetCell(g, sr, sc);
|
|
if (!cell)
|
|
continue;
|
|
cellValues = XmLGridCellGetRefValues(cell);
|
|
cbs.reason = XmCR_CELL_DRAW;
|
|
cbs.event = (XEvent *)event;
|
|
cbs.rowType = RowPosToType(g, sr);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, sr);
|
|
cbs.columnType = ColPosToType(g, sc);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, sc);
|
|
cbs.clipRect = &clipRect;
|
|
cbs.drawInfo = &ds;
|
|
ds.gc = g->grid.gc;
|
|
ds.cellRect = &rRect;
|
|
ds.topMargin = cellValues->topMargin;
|
|
ds.bottomMargin = cellValues->bottomMargin;
|
|
ds.leftMargin = cellValues->leftMargin;
|
|
ds.rightMargin = cellValues->rightMargin;
|
|
ds.background = cellValues->background;
|
|
ds.foreground = cellValues->foreground;
|
|
ds.fontList = cellValues->fontList;
|
|
ds.alignment = cellValues->alignment;
|
|
ds.selectBackground = g->grid.selectBg;
|
|
ds.selectForeground = g->grid.selectFg;
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, sr);
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, sc);
|
|
ds.drawFocusType = XmDRAW_FOCUS_NONE;
|
|
if (g->grid.focusRow == sr &&
|
|
g->grid.highlightRowMode == True &&
|
|
g->grid.focusIn)
|
|
{
|
|
RecalcVisPos(g, 0);
|
|
visPos = XmLGridColumnGetVisPos(col);
|
|
lastVisPos = XmLArrayGetCount(g->grid.colArray) -
|
|
g->grid.hiddenColCount - 1;
|
|
if (visPos == 0 && visPos == lastVisPos)
|
|
ds.drawFocusType = XmDRAW_FOCUS_CELL;
|
|
else if (visPos == 0)
|
|
ds.drawFocusType = XmDRAW_FOCUS_LEFT;
|
|
else if (visPos == lastVisPos)
|
|
ds.drawFocusType = XmDRAW_FOCUS_RIGHT;
|
|
else
|
|
ds.drawFocusType = XmDRAW_FOCUS_MID;
|
|
}
|
|
if (g->grid.focusRow == sr &&
|
|
g->grid.focusCol == sc &&
|
|
g->grid.highlightRowMode == False &&
|
|
g->grid.focusIn)
|
|
ds.drawFocusType = XmDRAW_FOCUS_CELL;
|
|
if (XmLGridRowIsSelected(row) == True ||
|
|
XmLGridColumnIsSelected(col) == True ||
|
|
XmLGridCellIsSelected(cell) == True)
|
|
ds.drawSelected = True;
|
|
else
|
|
ds.drawSelected = False;
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL &&
|
|
g->grid.focusIn && g->grid.focusRow == sr &&
|
|
g->grid.focusCol == sc)
|
|
ds.drawSelected = False;
|
|
ds.stringDirection = g->manager.string_direction;
|
|
XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
if (hasDrawCB)
|
|
XtCallCallbackList(w, g->grid.cellDrawCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
height += rowHeight;
|
|
}
|
|
}
|
|
if (g->grid.debugLevel > 1)
|
|
fprintf(stderr, "XmLGrid: Redisplay non-cell areas\n");
|
|
n = 0;
|
|
if (reg[0].width && g->grid.leftFixedMargin)
|
|
{
|
|
rect[n].x = reg[0].width;
|
|
rect[n].y = 0;
|
|
rect[n].width = g->grid.leftFixedMargin;
|
|
rect[n].height = g->core.height;
|
|
n++;
|
|
}
|
|
if (reg[2].width && g->grid.rightFixedMargin)
|
|
{
|
|
width = 0;
|
|
if (reg[0].ncol)
|
|
width += reg[0].width + g->grid.leftFixedMargin;
|
|
if (reg[1].ncol)
|
|
width += reg[1].width;
|
|
rect[n].x = width;
|
|
rect[n].y = 0;
|
|
rect[n].width = g->grid.rightFixedMargin;
|
|
rect[n].height = g->core.height;
|
|
n++;
|
|
}
|
|
if (reg[0].height && g->grid.topFixedMargin)
|
|
{
|
|
rect[n].x = 0;
|
|
rect[n].y = reg[0].height;
|
|
rect[n].width = g->core.width;
|
|
rect[n].height = g->grid.topFixedMargin;
|
|
n++;
|
|
}
|
|
if (reg[6].height && g->grid.bottomFixedMargin)
|
|
{
|
|
rect[n].x = 0;
|
|
height = 0;
|
|
if (reg[0].nrow)
|
|
height += reg[0].height + g->grid.topFixedMargin;
|
|
if (reg[3].nrow)
|
|
height += reg[3].height;
|
|
rect[n].y = height;
|
|
rect[n].width = g->core.width;
|
|
rect[n].height = g->grid.bottomFixedMargin;
|
|
n++;
|
|
}
|
|
width = reg[1].width;
|
|
if (reg[0].ncol)
|
|
width += reg[0].width + g->grid.leftFixedMargin;
|
|
if (reg[2].ncol)
|
|
width += g->grid.rightFixedMargin + reg[2].width;
|
|
if (width < (int)g->core.width)
|
|
{
|
|
rect[n].x = width;
|
|
rect[n].y = 0;
|
|
rect[n].width = g->core.width - width;
|
|
rect[n].height = g->core.height;
|
|
n++;
|
|
}
|
|
height = reg[3].height;
|
|
if (reg[0].nrow)
|
|
height += reg[0].height + g->grid.topFixedMargin;
|
|
if (reg[6].nrow)
|
|
height += g->grid.bottomFixedMargin + reg[6].height;
|
|
if (height < (int)g->core.height)
|
|
{
|
|
rect[n].x = 0;
|
|
rect[n].y = height;
|
|
rect[n].width = g->core.width;
|
|
rect[n].height = g->core.height - height;
|
|
n++;
|
|
}
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
|
|
continue;
|
|
XClearArea(dpy, win, rect[i].x, rect[i].y, rect[i].width,
|
|
rect[i].height, False);
|
|
}
|
|
n = 0;
|
|
if (reg[1].width)
|
|
{
|
|
width = 0;
|
|
for (c = reg[1].col; c < reg[1].col + reg[1].ncol; c++)
|
|
width += GetColWidth(g, c);
|
|
for (i = 1; i < 9; i += 3)
|
|
if (reg[i].height && width < reg[i].width - st * 2)
|
|
{
|
|
rect[n].x = reg[i].x + st + width;
|
|
rect[n].y = reg[i].y + st;
|
|
rect[n].width = reg[i].x + reg[i].width -
|
|
rect[n].x - st;
|
|
rect[n].height = reg[i].height - st * 2;
|
|
n++;
|
|
}
|
|
}
|
|
if (reg[3].height)
|
|
{
|
|
height = 0;
|
|
for (r = reg[3].row; r < reg[3].row + reg[3].nrow; r++)
|
|
height += GetRowHeight(g, r);
|
|
for (i = 3; i < 6; i++)
|
|
if (reg[i].width && height < reg[i].height - st * 2)
|
|
{
|
|
rect[n].x = reg[i].x + st;
|
|
rect[n].y = reg[i].y + st + height;
|
|
rect[n].width = reg[i].width - st * 2;
|
|
rect[n].height = reg[i].y + reg[i].height -
|
|
rect[n].y - st;
|
|
n++;
|
|
}
|
|
}
|
|
XSetForeground(dpy, g->grid.gc, g->grid.blankBg);
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (XmLRectIntersect(&eRect, &rect[i]) == XmLRectOutside)
|
|
continue;
|
|
XFillRectangle(dpy, win, g->grid.gc, rect[i].x, rect[i].y,
|
|
rect[i].width, rect[i].height);
|
|
}
|
|
/* Show any XORed graphics */
|
|
DrawResizeLine(g, 0, 1);
|
|
}
|
|
|
|
static void
|
|
DrawResizeLine(XmLGridWidget g,
|
|
int xy,
|
|
int erase)
|
|
{
|
|
if (g->grid.inMode != InResize)
|
|
return;
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && !g->grid.resizeIsVert)
|
|
return;
|
|
DrawXORRect(g, xy, 2, g->grid.resizeIsVert, erase);
|
|
}
|
|
|
|
static void
|
|
DrawXORRect(XmLGridWidget g,
|
|
int xy,
|
|
int size,
|
|
int isVert,
|
|
int erase)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
GC gc;
|
|
Pixel black, white;
|
|
int oldXY, maxX, maxY;
|
|
|
|
if (!XtIsRealized((Widget)g))
|
|
return;
|
|
/* erase is (0 == none) (1 == hide/show) (2 == permenent erase) */
|
|
dpy = XtDisplay(g);
|
|
win = XtWindow(g);
|
|
gc = g->grid.gc;
|
|
XSetFunction(dpy, gc, GXinvert);
|
|
black = BlackPixelOfScreen(XtScreen((Widget)g));
|
|
white = WhitePixelOfScreen(XtScreen((Widget)g));
|
|
XSetForeground(dpy, gc, black ^ white);
|
|
maxX = g->core.width;
|
|
if (XtIsManaged(g->grid.vsb))
|
|
maxX -= g->grid.vsb->core.width + g->grid.scrollBarMargin;
|
|
maxY = g->core.height;
|
|
if (XtIsManaged(g->grid.hsb))
|
|
maxY -= g->grid.hsb->core.height + g->grid.scrollBarMargin;
|
|
oldXY = g->grid.resizeLineXY;
|
|
if (isVert)
|
|
{
|
|
if (oldXY != -1)
|
|
XFillRectangle(dpy, win, gc, 0, oldXY, maxX, size);
|
|
}
|
|
else
|
|
{
|
|
if (oldXY != -1)
|
|
XFillRectangle(dpy, win, gc, oldXY, 0, size, maxY);
|
|
}
|
|
if (!erase)
|
|
{
|
|
if (isVert)
|
|
{
|
|
if (xy > maxY)
|
|
xy = maxY - 2;
|
|
if (xy < 0)
|
|
xy = 0;
|
|
XFillRectangle(dpy, win, gc, 0, xy, maxX, size);
|
|
}
|
|
else
|
|
{
|
|
if (xy > maxX)
|
|
xy = maxX - 2;
|
|
if (xy < 0)
|
|
xy = 0;
|
|
XFillRectangle(dpy, win, gc, xy, 0, size, maxY);
|
|
}
|
|
g->grid.resizeLineXY = xy;
|
|
}
|
|
else if (erase == 2)
|
|
g->grid.resizeLineXY = -1;
|
|
XSetFunction(dpy, gc, GXcopy);
|
|
}
|
|
|
|
static void
|
|
DefineCursor(XmLGridWidget g,
|
|
char defineCursor)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
|
|
if (!XtIsRealized((Widget)g))
|
|
return;
|
|
dpy = XtDisplay(g);
|
|
win = XtWindow(g);
|
|
if (defineCursor != g->grid.cursorDefined)
|
|
XUndefineCursor(dpy, win);
|
|
if (defineCursor == CursorVResize)
|
|
XDefineCursor(dpy, win, g->grid.vResizeCursor);
|
|
else if (defineCursor == CursorHResize)
|
|
XDefineCursor(dpy, win, g->grid.hResizeCursor);
|
|
g->grid.cursorDefined = defineCursor;
|
|
}
|
|
|
|
static void
|
|
DrawArea(XmLGridWidget g,
|
|
int type,
|
|
int row,
|
|
int col)
|
|
{
|
|
GridReg *reg;
|
|
Display *dpy;
|
|
Window win;
|
|
XExposeEvent event;
|
|
XRectangle rect[3];
|
|
Region region;
|
|
int i, j, n;
|
|
Dimension width, height, st;
|
|
|
|
if (g->grid.layoutFrozen == True)
|
|
return;
|
|
if (!XtIsRealized((Widget)g))
|
|
return;
|
|
if (!g->core.visible)
|
|
return;
|
|
dpy = XtDisplay(g);
|
|
win = XtWindow(g);
|
|
reg = g->grid.reg;
|
|
st = g->manager.shadow_thickness;
|
|
if (g->grid.debugLevel > 1)
|
|
fprintf(stderr, "XmLGrid: DrawArea %d %d %d\n", type, row, col);
|
|
|
|
n = 0;
|
|
switch (type)
|
|
{
|
|
case DrawAll:
|
|
{
|
|
rect[n].x = 0;
|
|
rect[n].y = 0;
|
|
rect[n].width = g->core.width;
|
|
rect[n].height = g->core.height;
|
|
n++;
|
|
break;
|
|
}
|
|
case DrawHScroll:
|
|
{
|
|
for (i = 1; i < 9; i += 3)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
rect[n].x = reg[i].x + st;
|
|
rect[n].y = reg[i].y + st;
|
|
rect[n].width = reg[i].width - st * 2;
|
|
rect[n].height = reg[i].height - st * 2;
|
|
n++;
|
|
}
|
|
break;
|
|
}
|
|
case DrawVScroll:
|
|
{
|
|
for (i = 3; i < 6; i++)
|
|
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
rect[n].x = reg[i].x + st;
|
|
rect[n].y = reg[i].y + st;
|
|
rect[n].width = reg[i].width - st * 2;
|
|
rect[n].height = reg[i].height - st * 2;
|
|
n++;
|
|
}
|
|
break;
|
|
}
|
|
case DrawRow:
|
|
{
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
if (!(row >= reg[i].row &&
|
|
row < reg[i].row + reg[i].nrow))
|
|
continue;
|
|
height = 0;
|
|
for (j = reg[i].row; j < row; j++)
|
|
height += GetRowHeight(g, j);
|
|
rect[n].x = reg[i].x + st;
|
|
rect[n].y = reg[i].y + st + height;
|
|
rect[n].width = reg[i].width - st * 2;
|
|
rect[n].height = GetRowHeight(g, row);
|
|
ClipRectToReg(g, &rect[n], ®[i]);
|
|
n++;
|
|
}
|
|
break;
|
|
}
|
|
case DrawCol:
|
|
{
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
if (!(col >= reg[i].col &&
|
|
col < reg[i].col + reg[i].ncol))
|
|
continue;
|
|
width = 0;
|
|
for (j = reg[i].col; j < col; j++)
|
|
width += GetColWidth(g, j);
|
|
rect[n].x = reg[i].x + st + width;
|
|
rect[n].y = reg[i].y + st;
|
|
rect[n].width = GetColWidth(g, col);
|
|
rect[n].height = reg[i].height - st * 2;
|
|
ClipRectToReg(g, &rect[n], ®[i]);
|
|
n++;
|
|
}
|
|
break;
|
|
}
|
|
case DrawCell:
|
|
{
|
|
if (!RowColToXY(g, row, col, True, &rect[n]))
|
|
n++;
|
|
break;
|
|
}
|
|
}
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (!rect[i].width || !rect[i].height)
|
|
continue;
|
|
event.type = Expose;
|
|
event.window = win;
|
|
event.display = dpy;
|
|
event.x = rect[i].x;
|
|
event.y = rect[i].y;
|
|
event.width = rect[i].width;
|
|
event.height = rect[i].height;
|
|
event.send_event = True;
|
|
event.count = 0;
|
|
if (g->grid.immediateDraw)
|
|
{
|
|
region = XCreateRegion();
|
|
XUnionRectWithRegion(&rect[i], region, region);
|
|
Redisplay((Widget)g, &event, region);
|
|
XDestroyRegion(region);
|
|
}
|
|
else
|
|
XSendEvent(dpy, win, False, ExposureMask, (XEvent *)&event);
|
|
if (g->grid.debugLevel > 1)
|
|
fprintf(stderr, "XmLGrid: DrawArea expose x %d y %d w %d h %d\n",
|
|
event.x, event.y, event.width, event.height);
|
|
}
|
|
}
|
|
|
|
static void
|
|
ExtendSelectRange(XmLGridWidget g,
|
|
int *type,
|
|
int *fr,
|
|
int *lr,
|
|
int *fc,
|
|
int *lc)
|
|
{
|
|
int r, c;
|
|
|
|
if ((g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW) ||
|
|
(ColPosToType(g, g->grid.extendCol) != XmCONTENT))
|
|
*type = SelectRow;
|
|
else if (RowPosToType(g, g->grid.extendRow) != XmCONTENT)
|
|
*type = SelectCol;
|
|
else
|
|
*type = SelectCell;
|
|
|
|
r = g->grid.extendToRow;
|
|
if (r < g->grid.headingRowCount)
|
|
r = g->grid.headingRowCount;
|
|
if (r >= g->grid.headingRowCount + g->grid.rowCount)
|
|
r = g->grid.headingRowCount + g->grid.rowCount - 1;
|
|
if (*type == SelectCol)
|
|
{
|
|
*fr = 0;
|
|
*lr = 1;
|
|
}
|
|
else if (g->grid.extendRow < r)
|
|
{
|
|
*fr = g->grid.extendRow;
|
|
*lr = r;
|
|
}
|
|
else
|
|
{
|
|
*fr = r;
|
|
*lr = g->grid.extendRow;
|
|
}
|
|
c = g->grid.extendToCol;
|
|
if (c < g->grid.headingColCount)
|
|
c = g->grid.headingColCount;
|
|
if (c >= g->grid.headingColCount + g->grid.colCount)
|
|
c = g->grid.headingColCount + g->grid.colCount - 1;
|
|
if (*type == SelectRow)
|
|
{
|
|
*fc = 0;
|
|
*lc = 1;
|
|
}
|
|
else if (g->grid.extendCol < c)
|
|
{
|
|
*fc = g->grid.extendCol;
|
|
*lc = c;
|
|
}
|
|
else
|
|
{
|
|
*fc = c;
|
|
*lc = g->grid.extendCol;
|
|
}
|
|
}
|
|
|
|
static void
|
|
ExtendSelect(XmLGridWidget g,
|
|
XEvent *event,
|
|
Boolean set,
|
|
int row,
|
|
int col)
|
|
{
|
|
int type;
|
|
int r, fr, lr;
|
|
int c, fc, lc;
|
|
|
|
if (row == -1 || col == -1)
|
|
{
|
|
g->grid.extendRow = -1;
|
|
g->grid.extendCol = -1;
|
|
g->grid.extendToRow = -1;
|
|
g->grid.extendToCol = -1;
|
|
g->grid.extendSelect = True;
|
|
return;
|
|
}
|
|
if (RowPosToType(g, row) == XmFOOTER || ColPosToType(g, col) == XmFOOTER)
|
|
return;
|
|
if ((g->grid.extendToRow == row && g->grid.extendToCol == col) ||
|
|
(g->grid.extendRow == -1 && row == g->grid.focusRow &&
|
|
g->grid.extendCol == -1 && col == g->grid.focusCol))
|
|
return;
|
|
if (g->grid.extendRow != -1 && g->grid.extendCol != -1)
|
|
{
|
|
/* clear previous extend */
|
|
ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
|
|
for (r = fr; r <= lr; r += 1)
|
|
for (c = fc; c <= lc; c += 1)
|
|
SelectTypeArea(g, type, event,
|
|
RowPosToTypePos(g, XmCONTENT, r),
|
|
ColPosToTypePos(g, XmCONTENT, c), False, True);
|
|
}
|
|
else
|
|
{
|
|
g->grid.extendRow = g->grid.focusRow;
|
|
g->grid.extendCol = g->grid.focusCol;
|
|
}
|
|
if (set == True)
|
|
{
|
|
g->grid.extendRow = row;
|
|
g->grid.extendCol = col;
|
|
}
|
|
if (g->grid.extendRow < 0 || g->grid.extendCol < 0)
|
|
return;
|
|
g->grid.extendToRow = row;
|
|
g->grid.extendToCol = col;
|
|
|
|
/* set new extend */
|
|
ExtendSelectRange(g, &type, &fr, &lr, &fc, &lc);
|
|
for (r = fr; r <= lr; r += 1)
|
|
for (c = fc; c <= lc; c += 1)
|
|
SelectTypeArea(g, type, event,
|
|
RowPosToTypePos(g, XmCONTENT, r),
|
|
ColPosToTypePos(g, XmCONTENT, c),
|
|
g->grid.extendSelect, True);
|
|
}
|
|
|
|
static void
|
|
SelectTypeArea(XmLGridWidget g,
|
|
int type,
|
|
XEvent *event,
|
|
int row,
|
|
int col,
|
|
Boolean select,
|
|
Boolean notify)
|
|
{
|
|
Widget w;
|
|
XmLGridRow rowp;
|
|
XmLGridColumn colp;
|
|
XmLGridCell cellp;
|
|
int r, fr, lr, hrc;
|
|
int c, fc, lc, hcc;
|
|
int badPos, hasCB;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
w = (Widget)g;
|
|
hrc = g->grid.headingRowCount;
|
|
hcc = g->grid.headingColCount;
|
|
cbs.event = event;
|
|
cbs.rowType = XmCONTENT;
|
|
cbs.columnType = XmCONTENT;
|
|
hasCB = 0;
|
|
if (select == True)
|
|
{
|
|
if (type == SelectRow)
|
|
cbs.reason = XmCR_SELECT_ROW;
|
|
else if (type == SelectCol)
|
|
cbs.reason = XmCR_SELECT_COLUMN;
|
|
else if (type == SelectCell)
|
|
cbs.reason = XmCR_SELECT_CELL;
|
|
if (XtHasCallbacks(w, XmNselectCallback) == XtCallbackHasSome)
|
|
hasCB = 1;
|
|
}
|
|
else
|
|
{
|
|
if (type == SelectRow)
|
|
cbs.reason = XmCR_DESELECT_ROW;
|
|
else if (type == SelectCol)
|
|
cbs.reason = XmCR_DESELECT_COLUMN;
|
|
else if (type == SelectCell)
|
|
cbs.reason = XmCR_DESELECT_CELL;
|
|
if (XtHasCallbacks(w, XmNdeselectCallback) == XtCallbackHasSome)
|
|
hasCB = 1;
|
|
}
|
|
if (row != -1)
|
|
{
|
|
fr = hrc + row;
|
|
lr = fr + 1;
|
|
}
|
|
else
|
|
{
|
|
fr = hrc;
|
|
lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
|
|
}
|
|
if (col != -1)
|
|
{
|
|
fc = hcc + col;
|
|
lc = fc + 1;
|
|
}
|
|
else
|
|
{
|
|
fc = hcc;
|
|
lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
|
|
}
|
|
badPos = 0;
|
|
for (r = fr; r < lr; r++)
|
|
for (c = fc; c < lc; c++)
|
|
{
|
|
if (type == SelectRow)
|
|
{
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (!rowp)
|
|
{
|
|
badPos = 1;
|
|
continue;
|
|
}
|
|
if (XmLGridRowIsSelected(rowp) == select)
|
|
continue;
|
|
if (select == True &&
|
|
(g->grid.selectionPolicy == XmSELECT_BROWSE_ROW ||
|
|
g->grid.selectionPolicy == XmSELECT_SINGLE_ROW))
|
|
SelectTypeArea(g, SelectRow, event, -1, 0, False, notify);
|
|
XmLGridRowSetSelected(rowp, select);
|
|
if (RowIsVisible(g, r))
|
|
DrawArea(g, DrawRow, r, 0);
|
|
if (notify && hasCB)
|
|
{
|
|
cbs.row = r - hrc;
|
|
if (select == True)
|
|
XtCallCallbackList(w, g->grid.selectCallback,
|
|
(XtPointer)&cbs);
|
|
else
|
|
XtCallCallbackList(w, g->grid.deselectCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
else if (type == SelectCol)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (!colp)
|
|
{
|
|
badPos = 1;
|
|
continue;
|
|
}
|
|
if (XmLGridColumnIsSelected(colp) == select)
|
|
continue;
|
|
XmLGridColumnSetSelected(colp, select);
|
|
if (ColIsVisible(g, c))
|
|
DrawArea(g, DrawCol, 0, c);
|
|
if (notify && hasCB)
|
|
{
|
|
cbs.column = c - hcc;
|
|
if (select == True)
|
|
XtCallCallbackList(w, g->grid.selectCallback,
|
|
(XtPointer)&cbs);
|
|
else
|
|
XtCallCallbackList(w, g->grid.deselectCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
else if (type == SelectCell)
|
|
{
|
|
cellp = GetCell(g, r, c);
|
|
if (!cellp)
|
|
{
|
|
badPos = 1;
|
|
continue;
|
|
}
|
|
if (XmLGridCellIsSelected(cellp) == select)
|
|
continue;
|
|
XmLGridCellSetSelected(cellp, select);
|
|
DrawArea(g, DrawCell, r, c);
|
|
if (notify && hasCB)
|
|
{
|
|
cbs.column = c - hcc;
|
|
cbs.row = r - hrc;
|
|
if (select == True)
|
|
XtCallCallbackList(w, g->grid.selectCallback,
|
|
(XtPointer)&cbs);
|
|
else
|
|
XtCallCallbackList(w, g->grid.deselectCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
}
|
|
if (badPos)
|
|
XmLWarning((Widget)g, "SelectTypeArea() - bad position");
|
|
}
|
|
|
|
static int
|
|
GetSelectedArea(XmLGridWidget g,
|
|
int type,
|
|
int *rowPos,
|
|
int *colPos,
|
|
int count)
|
|
{
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCell cell;
|
|
int r, fr, lr;
|
|
int c, fc, lc;
|
|
int n;
|
|
|
|
if (type == SelectCol)
|
|
{
|
|
fr = 0;
|
|
lr = 1;
|
|
}
|
|
else
|
|
{
|
|
fr = g->grid.headingRowCount;
|
|
lr = XmLArrayGetCount(g->grid.rowArray) - g->grid.footerRowCount;
|
|
}
|
|
if (type == SelectRow)
|
|
{
|
|
fc = 0;
|
|
lc = 1;
|
|
}
|
|
else
|
|
{
|
|
fc = g->grid.headingColCount;
|
|
lc = XmLArrayGetCount(g->grid.colArray) - g->grid.footerColCount;
|
|
}
|
|
n = 0;
|
|
for (r = fr; r < lr; r++)
|
|
for (c = fc; c < lc; c++)
|
|
{
|
|
if (type == SelectRow)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (row && XmLGridRowIsSelected(row) == True)
|
|
{
|
|
if (rowPos && n < count)
|
|
rowPos[n] = r - fr;
|
|
n++;
|
|
}
|
|
}
|
|
else if (type == SelectCol)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (col && XmLGridColumnIsSelected(col) == True)
|
|
{
|
|
if (colPos && n < count)
|
|
colPos[n] = c - fc;
|
|
n++;
|
|
}
|
|
}
|
|
else if (type == SelectCell)
|
|
{
|
|
cell = GetCell(g, r, c);
|
|
if (cell && XmLGridCellIsSelected(cell) == True)
|
|
{
|
|
if (rowPos && colPos && n < count)
|
|
{
|
|
rowPos[n] = r - fr;
|
|
colPos[n] = c - fc;
|
|
}
|
|
n++;
|
|
}
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static void
|
|
ChangeManaged(Widget w)
|
|
{
|
|
_XmNavigChangeManaged(w);
|
|
}
|
|
|
|
static void
|
|
Resize(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
g = (XmLGridWidget)w;
|
|
|
|
if (!g->grid.inResize)
|
|
{
|
|
cbs.reason = XmCR_RESIZE_GRID;
|
|
|
|
g->grid.inResize = True;
|
|
XtCallCallbackList((Widget)g, g->grid.resizeCallback,
|
|
(XtPointer)&cbs);
|
|
g->grid.inResize = False;
|
|
}
|
|
|
|
VertLayout(g, 0);
|
|
HorizLayout(g, 0);
|
|
PlaceScrollbars(g);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
static void
|
|
PlaceScrollbars(XmLGridWidget g)
|
|
{
|
|
int x, y;
|
|
int width, height;
|
|
Widget vsb, hsb;
|
|
Dimension st, headingRowHeight = 0;
|
|
|
|
st = g->manager.shadow_thickness;
|
|
vsb = g->grid.vsb;
|
|
hsb = g->grid.hsb;
|
|
width = g->core.width;
|
|
if (XtIsManaged(vsb))
|
|
width -= vsb->core.width;
|
|
if (width <= 0)
|
|
width = 1;
|
|
y = g->core.height - hsb->core.height;
|
|
XtConfigureWidget(hsb, 0, y, width, hsb->core.height, 0);
|
|
|
|
height = g->core.height;
|
|
if (XtIsManaged(hsb))
|
|
height -= hsb->core.height;
|
|
|
|
y = 0;
|
|
|
|
if (g->grid.headingRowCount > 0)
|
|
{
|
|
XmLGridRow rowp;
|
|
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
|
|
|
|
headingRowHeight = XmLGridRowHeightInPixels(rowp) + st;
|
|
}
|
|
|
|
if (g->grid.hideUnhideButtons
|
|
&& g->grid.hideButton && g->grid.unhideButton)
|
|
{
|
|
int buttonWidth = vsb->core.width - 4;
|
|
|
|
if (headingRowHeight == 0)
|
|
headingRowHeight = 20;
|
|
|
|
/* if there is at least heading row, we make the
|
|
height of the button the height of the first
|
|
heading row.
|
|
|
|
This is pretty braindead... */
|
|
|
|
XtConfigureWidget(g->grid.unhideButton,
|
|
g->core.width - buttonWidth*2 - st,
|
|
y + st,
|
|
buttonWidth,
|
|
headingRowHeight - st, 0);
|
|
XtConfigureWidget(g->grid.hideButton,
|
|
g->core.width - buttonWidth - st,
|
|
y + st,
|
|
buttonWidth,
|
|
headingRowHeight - st, 0);
|
|
|
|
setHideUnhideSensitivity((Widget)g);
|
|
|
|
/* once we've positioned it, make sure it's managed.
|
|
Doing it in this order (position, then manage) reduces
|
|
screen flickering -- the button doesn't flash on in the
|
|
upper left corner for an instant. */
|
|
if (!XtIsManaged(g->grid.hideButton))
|
|
XtManageChild(g->grid.hideButton);
|
|
if (!XtIsManaged(g->grid.unhideButton))
|
|
XtManageChild(g->grid.unhideButton);
|
|
}
|
|
|
|
if (height <= 0)
|
|
width = 1;
|
|
x = g->core.width - vsb->core.width;
|
|
XtConfigureWidget(vsb,
|
|
x, y + headingRowHeight + g->manager.shadow_thickness,
|
|
vsb->core.width, height - headingRowHeight - g->manager.shadow_thickness,
|
|
0);
|
|
}
|
|
|
|
void
|
|
_XmLGridLayout(XmLGridWidget g)
|
|
{
|
|
VertLayout(g, 1);
|
|
HorizLayout(g, 1);
|
|
}
|
|
|
|
static void
|
|
VertLayout(XmLGridWidget g,
|
|
int resizeIfNeeded)
|
|
{
|
|
GridReg *reg;
|
|
int i, j, st2, height, rowCount;
|
|
int topNRow, topHeight;
|
|
int midRow, midY, midNRow, midHeight;
|
|
int botRow, botY, botNRow, botHeight;
|
|
int scrollChanged, needsSB, needsResize, cRow;
|
|
int maxRow, maxPos, maxHeight, newHeight, sliderSize;
|
|
int horizSizeChanged;
|
|
XtWidgetGeometry req;
|
|
XmLGridCallbackStruct cbs;
|
|
XmLGridPreLayoutProc preLayoutProc;
|
|
|
|
if (g->grid.layoutFrozen == True)
|
|
{
|
|
g->grid.needsVertLayout = 1;
|
|
return;
|
|
}
|
|
|
|
maxRow = maxPos = maxHeight = newHeight = horizSizeChanged = 0;
|
|
preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
|
|
if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
|
|
horizSizeChanged = preLayoutProc(g, 1);
|
|
|
|
scrollChanged = 0;
|
|
needsResize = 0;
|
|
needsSB = 0;
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
reg = g->grid.reg;
|
|
st2 = g->manager.shadow_thickness * 2;
|
|
TextAction(g, TEXT_HIDE);
|
|
|
|
topHeight = 0;
|
|
topNRow = g->grid.topFixedCount;
|
|
if (topNRow > g->grid.rowCount + g->grid.headingRowCount)
|
|
topNRow = g->grid.rowCount + g->grid.headingRowCount;
|
|
if (topNRow)
|
|
{
|
|
topHeight += st2;
|
|
for (i = 0; i < topNRow; i++)
|
|
topHeight += GetRowHeight(g, i);
|
|
}
|
|
botHeight = 0;
|
|
botNRow = g->grid.bottomFixedCount;
|
|
if (topNRow + botNRow > rowCount)
|
|
botNRow = rowCount - topNRow;
|
|
botRow = rowCount - botNRow;
|
|
if (botNRow)
|
|
{
|
|
botHeight += st2;
|
|
for (i = botRow; i < rowCount; i++)
|
|
botHeight += GetRowHeight(g, i);
|
|
}
|
|
height = 0;
|
|
if (topNRow)
|
|
height += topHeight + g->grid.topFixedMargin;
|
|
midY = height;
|
|
if (botNRow)
|
|
height += botHeight + g->grid.bottomFixedMargin;
|
|
if (XtIsManaged(g->grid.hsb))
|
|
{
|
|
height += g->grid.hsb->core.height;
|
|
height += g->grid.scrollBarMargin;
|
|
}
|
|
maxHeight = g->core.height - height;
|
|
if (g->grid.vsPolicy != XmCONSTANT)
|
|
{
|
|
if (rowCount == topNRow + botNRow)
|
|
midHeight = 0;
|
|
else
|
|
midHeight = st2;
|
|
for (i = topNRow; i < rowCount - botNRow; i++)
|
|
midHeight += GetRowHeight(g, i);
|
|
midRow = topNRow;
|
|
midNRow = rowCount - topNRow - botNRow;
|
|
needsResize = 1;
|
|
newHeight = midHeight + height;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout VARIABLE height\n");
|
|
}
|
|
else
|
|
{
|
|
if (maxHeight < st2)
|
|
maxHeight = 0;
|
|
height = st2;
|
|
j = rowCount - botNRow - 1;
|
|
for (i = j; i >= topNRow; i--)
|
|
{
|
|
height += GetRowHeight(g, i);
|
|
if (height > maxHeight)
|
|
break;
|
|
}
|
|
i++;
|
|
if (i > j)
|
|
i = j;
|
|
maxRow = i;
|
|
if (maxRow < topNRow)
|
|
maxRow = topNRow;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout max scroll row %d\n", i);
|
|
if (maxRow == topNRow)
|
|
{
|
|
if (g->grid.scrollRow != topNRow)
|
|
{
|
|
scrollChanged = 1;
|
|
g->grid.scrollRow = topNRow;
|
|
}
|
|
midRow = topNRow;
|
|
midHeight = maxHeight;
|
|
midNRow = rowCount - topNRow - botNRow;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout everything fits\n");
|
|
}
|
|
else
|
|
{
|
|
if (g->grid.scrollRow < topNRow)
|
|
{
|
|
scrollChanged = 1;
|
|
g->grid.scrollRow = topNRow;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout scrolled < topRow\n");
|
|
}
|
|
if (g->grid.scrollRow > maxRow)
|
|
{
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout scrolled > maxRow\n");
|
|
scrollChanged = 1;
|
|
g->grid.scrollRow = maxRow;
|
|
}
|
|
height = st2;
|
|
midNRow = 0;
|
|
for (i = g->grid.scrollRow; i < rowCount - botNRow; i++)
|
|
{
|
|
midNRow++;
|
|
height += GetRowHeight(g, i);
|
|
if (height >= maxHeight)
|
|
break;
|
|
}
|
|
needsSB = 1;
|
|
midRow = g->grid.scrollRow;
|
|
midHeight = maxHeight;
|
|
}
|
|
}
|
|
botY = midY + midHeight;
|
|
if (botNRow)
|
|
botY += g->grid.bottomFixedMargin;
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
reg[i].y = 0;
|
|
reg[i].height = topHeight;
|
|
reg[i].row = 0;
|
|
reg[i].nrow = topNRow;
|
|
}
|
|
for (i = 3; i < 6; i++)
|
|
{
|
|
reg[i].y = midY;
|
|
reg[i].height = midHeight;
|
|
reg[i].row = midRow;
|
|
reg[i].nrow = midNRow;
|
|
}
|
|
for (i = 6; i < 9; i++)
|
|
{
|
|
reg[i].y = botY;
|
|
reg[i].height = botHeight;
|
|
reg[i].row = botRow;
|
|
reg[i].nrow = botNRow;
|
|
}
|
|
if (g->grid.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLGrid: VertLayout TOP %3dy %3dh %3dr %3dnr\n",
|
|
reg[0].y, reg[0].height, reg[0].row, reg[0].nrow);
|
|
fprintf(stderr, "XmLGrid: VertLayout MID %3dy %3dh %3dr %3dnr\n",
|
|
reg[3].y, reg[3].height, reg[3].row, reg[3].nrow);
|
|
fprintf(stderr, "XmLGrid: VertLayout BOT %3dy %3dh %3dr %3dnr\n",
|
|
reg[6].y, reg[6].height, reg[6].row, reg[6].nrow);
|
|
}
|
|
if (needsSB)
|
|
{
|
|
if (!XtIsManaged(g->grid.vsb))
|
|
{
|
|
XtManageChild(g->grid.vsb);
|
|
horizSizeChanged = 1;
|
|
}
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout set sb values\n");
|
|
maxPos = PosToVisPos(g, maxRow, 1);
|
|
sliderSize = PosToVisPos(g, rowCount - botNRow - 1, 1) - maxPos + 1;
|
|
XtVaSetValues(g->grid.vsb,
|
|
XmNminimum, PosToVisPos(g, topNRow, 1),
|
|
XmNmaximum, maxPos + sliderSize,
|
|
XmNsliderSize, sliderSize,
|
|
XmNpageIncrement, sliderSize,
|
|
XmNvalue, PosToVisPos(g, g->grid.scrollRow, 1),
|
|
NULL);
|
|
}
|
|
else if (g->grid.vsPolicy == XmCONSTANT &&
|
|
g->grid.vsbDisplayPolicy == XmSTATIC)
|
|
{
|
|
if (!XtIsManaged(g->grid.vsb))
|
|
{
|
|
XtManageChild(g->grid.vsb);
|
|
horizSizeChanged = 1;
|
|
}
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout vsb not needed but static\n");
|
|
XtVaSetValues(g->grid.vsb,
|
|
XmNminimum, 0,
|
|
XmNmaximum, 1,
|
|
XmNsliderSize, 1,
|
|
XmNpageIncrement, 1,
|
|
XmNvalue, 0,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
if (XtIsManaged(g->grid.vsb))
|
|
{
|
|
XtUnmanageChild(g->grid.vsb);
|
|
horizSizeChanged = 1;
|
|
}
|
|
}
|
|
if (needsResize && resizeIfNeeded)
|
|
{
|
|
if (newHeight < 1)
|
|
newHeight = 1;
|
|
req.request_mode = CWHeight;
|
|
req.height = newHeight;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: VertLayout Req h %d\n", (int)newHeight);
|
|
XtMakeGeometryRequest((Widget)g, &req, NULL);
|
|
PlaceScrollbars(g);
|
|
}
|
|
if (scrollChanged)
|
|
DrawArea(g, DrawVScroll, 0, 0);
|
|
TextAction(g, TEXT_SHOW);
|
|
cRow = g->grid.scrollRow - g->grid.headingRowCount;
|
|
if (cRow != g->grid.cScrollRow)
|
|
{
|
|
g->grid.cScrollRow = cRow;
|
|
cbs.reason = XmCR_SCROLL_ROW;
|
|
cbs.rowType = XmCONTENT;
|
|
cbs.row = cRow;
|
|
XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
|
|
}
|
|
if (horizSizeChanged)
|
|
{
|
|
if (g->grid.layoutStack > 2)
|
|
XmLWarning((Widget)g, "VertLayout() - recursion error");
|
|
else
|
|
{
|
|
g->grid.layoutStack++;
|
|
HorizLayout(g, resizeIfNeeded);
|
|
g->grid.layoutStack--;
|
|
}
|
|
PlaceScrollbars(g);
|
|
}
|
|
}
|
|
|
|
static void
|
|
HorizLayout(XmLGridWidget g,
|
|
int resizeIfNeeded)
|
|
{
|
|
GridReg *reg;
|
|
int i, j, st2, width, colCount;
|
|
int leftNCol, leftWidth;
|
|
int midCol, midX, midNCol, midWidth;
|
|
int rightCol, rightX, rightNCol, rightWidth;
|
|
int scrollChanged, needsSB, needsResize, cCol;
|
|
int maxCol, maxPos, maxWidth, newWidth, sliderSize;
|
|
int vertSizeChanged;
|
|
XtWidgetGeometry req;
|
|
XmLGridCallbackStruct cbs;
|
|
XmLGridPreLayoutProc preLayoutProc;
|
|
|
|
if (g->grid.layoutFrozen == True)
|
|
{
|
|
g->grid.needsHorizLayout = 1;
|
|
return;
|
|
}
|
|
|
|
maxCol = maxPos = newWidth = vertSizeChanged = 0;
|
|
preLayoutProc = XmLGridClassPartOfWidget(g).preLayoutProc;
|
|
if (g->grid.layoutStack < 2 && preLayoutProc != XmInheritGridPreLayout)
|
|
vertSizeChanged = preLayoutProc(g, 0);
|
|
|
|
scrollChanged = 0;
|
|
needsResize = 0;
|
|
needsSB = 0;
|
|
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE && g->grid.visibleCols)
|
|
colCount = g->grid.visibleCols;
|
|
else
|
|
colCount = g->grid.colCount + g->grid.headingColCount
|
|
+ g->grid.footerColCount;
|
|
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
{
|
|
SizeColumnsToFit(g, 0);
|
|
}
|
|
|
|
reg = g->grid.reg;
|
|
st2 = g->manager.shadow_thickness * 2;
|
|
TextAction(g, TEXT_HIDE);
|
|
|
|
leftWidth = 0;
|
|
leftNCol = g->grid.leftFixedCount;
|
|
if (leftNCol > g->grid.colCount + g->grid.headingColCount)
|
|
leftNCol = g->grid.colCount + g->grid.headingColCount;
|
|
if (leftNCol)
|
|
{
|
|
leftWidth += st2;
|
|
for (i = 0; i < leftNCol; i++)
|
|
leftWidth += GetColWidth(g, i);
|
|
}
|
|
rightWidth = 0;
|
|
rightNCol = g->grid.rightFixedCount;
|
|
if (rightNCol + leftNCol > colCount)
|
|
rightNCol = colCount - leftNCol;
|
|
rightCol = colCount - rightNCol;
|
|
if (rightNCol)
|
|
{
|
|
rightWidth += st2;
|
|
for (i = rightCol; i < colCount; i++)
|
|
rightWidth += GetColWidth(g, i);
|
|
}
|
|
width = 0;
|
|
if (leftNCol)
|
|
width += leftWidth + g->grid.leftFixedMargin;
|
|
midX = width;
|
|
if (rightNCol)
|
|
width += rightWidth + g->grid.rightFixedMargin;
|
|
if (XtIsManaged(g->grid.vsb))
|
|
{
|
|
width += g->grid.vsb->core.width;
|
|
width += g->grid.scrollBarMargin;
|
|
}
|
|
maxWidth = g->core.width - width;
|
|
if (g->grid.hsPolicy == XmVARIABLE ||
|
|
g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
{
|
|
if (colCount == leftNCol + rightNCol)
|
|
midWidth = 0;
|
|
else
|
|
midWidth = st2;
|
|
|
|
/* This assumes the show/hide buttons will be wider
|
|
than the vertical scrollbar
|
|
*/
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
{
|
|
if (g->grid.hideUnhideButtons)
|
|
midWidth += XtWidth(g->grid.hideButton) * 2;
|
|
else if (XtIsManaged(g->grid.vsb))
|
|
midWidth += XtWidth(g->grid.vsb);
|
|
}
|
|
|
|
|
|
for (i = leftNCol; i < colCount - rightNCol; i++)
|
|
midWidth += GetColWidth(g, i);
|
|
midCol = leftNCol;
|
|
midNCol = colCount - leftNCol - rightNCol;
|
|
needsResize = 1;
|
|
newWidth = midWidth + width;
|
|
if (g->grid.debugLevel)
|
|
{
|
|
if (g->grid.hsPolicy == XmVARIABLE)
|
|
fprintf(stderr, "XmLGrid: HorizLayout VARIABLE width\n");
|
|
else
|
|
fprintf(stderr, "XmLGrid: HorizLayout REZISE_IF_POSSIBLE\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (maxWidth < st2)
|
|
maxWidth = 0;
|
|
width = st2;
|
|
j = colCount - rightNCol - 1;
|
|
for (i = j; i >= leftNCol; i--)
|
|
{
|
|
width += GetColWidth(g, i);
|
|
if (width > maxWidth)
|
|
break;
|
|
}
|
|
i++;
|
|
if (i > j)
|
|
i = j;
|
|
maxCol = i;
|
|
if (maxCol < leftNCol)
|
|
maxCol = leftNCol;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout max scroll col %d\n", i);
|
|
if (maxCol == leftNCol)
|
|
{
|
|
if (g->grid.scrollCol != leftNCol)
|
|
{
|
|
scrollChanged = 1;
|
|
g->grid.scrollCol = leftNCol;
|
|
}
|
|
midCol = leftNCol;
|
|
midWidth = maxWidth;
|
|
midNCol = colCount - leftNCol - rightNCol;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout everything fits\n");
|
|
}
|
|
else
|
|
{
|
|
if (g->grid.scrollCol < leftNCol)
|
|
{
|
|
scrollChanged = 1;
|
|
g->grid.scrollCol = leftNCol;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout scroll < leftCol\n");
|
|
}
|
|
if (g->grid.scrollCol > maxCol)
|
|
{
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout scroll > maxCol\n");
|
|
scrollChanged = 1;
|
|
g->grid.scrollCol = maxCol;
|
|
}
|
|
width = st2;
|
|
midNCol = 0;
|
|
for (i = g->grid.scrollCol; i < colCount - rightNCol; i++)
|
|
{
|
|
midNCol++;
|
|
width += GetColWidth(g, i);
|
|
if (width >= maxWidth)
|
|
break;
|
|
}
|
|
needsSB = 1;
|
|
midCol = g->grid.scrollCol;
|
|
midWidth = maxWidth;
|
|
}
|
|
}
|
|
rightX = midX + midWidth;
|
|
if (rightNCol)
|
|
rightX += g->grid.rightFixedMargin;
|
|
for (i = 0; i < 9; i += 3)
|
|
{
|
|
reg[i].x = 0;
|
|
reg[i].width = leftWidth;
|
|
reg[i].col = 0;
|
|
reg[i].ncol = leftNCol;
|
|
}
|
|
for (i = 1; i < 9; i += 3)
|
|
{
|
|
reg[i].x = midX;
|
|
reg[i].width = midWidth;
|
|
reg[i].col = midCol;
|
|
reg[i].ncol = midNCol;
|
|
}
|
|
for (i = 2; i < 9; i += 3)
|
|
{
|
|
reg[i].x = rightX;
|
|
reg[i].width = rightWidth;
|
|
reg[i].col = rightCol;
|
|
reg[i].ncol = rightNCol;
|
|
}
|
|
|
|
if (g->grid.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLGrid: HorizLayout LFT %3dx %3dw %3dc %3dnc\n",
|
|
reg[0].x, reg[0].width, reg[0].col, reg[0].ncol);
|
|
fprintf(stderr, "XmLGrid: HorizLayout MID %3dx %3dw %3dc %3dnc\n",
|
|
reg[1].x, reg[1].width, reg[1].col, reg[1].ncol);
|
|
fprintf(stderr, "XmLGrid: HorizLayout RHT %3dx %3dw %3dc %3dnc\n",
|
|
reg[2].x, reg[2].width, reg[2].col, reg[2].ncol);
|
|
}
|
|
if (g->grid.hsPolicy == XmCONSTANT && colCount == 1 &&
|
|
g->grid.colCount == 1 && width > maxWidth)
|
|
{
|
|
/* Single Column Pixel Scroll Mode */
|
|
if (g->grid.singleColScrollMode)
|
|
{
|
|
i = g->grid.singleColScrollPos;
|
|
if (i < 0)
|
|
i = 0;
|
|
else if (i > width - maxWidth)
|
|
i = width - maxWidth;
|
|
}
|
|
else
|
|
i = 0;
|
|
XtVaSetValues(g->grid.hsb,
|
|
XmNminimum, 0,
|
|
XmNmaximum, width - maxWidth + 1,
|
|
XmNsliderSize, 1,
|
|
XmNpageIncrement, ((width - maxWidth) / 4) + 1,
|
|
XmNvalue, i,
|
|
NULL);
|
|
if (!XtIsManaged(g->grid.hsb))
|
|
{
|
|
XtManageChild(g->grid.hsb);
|
|
vertSizeChanged = 1;
|
|
}
|
|
g->grid.singleColScrollMode = 1;
|
|
g->grid.singleColScrollPos = i;
|
|
}
|
|
else
|
|
g->grid.singleColScrollMode = 0;
|
|
if (g->grid.singleColScrollMode)
|
|
;
|
|
else if (needsSB)
|
|
{
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout set sb values\n");
|
|
if (!XtIsManaged(g->grid.hsb))
|
|
{
|
|
XtManageChild(g->grid.hsb);
|
|
vertSizeChanged = 1;
|
|
}
|
|
maxPos = PosToVisPos(g, maxCol, 0);
|
|
sliderSize = PosToVisPos(g, colCount - rightNCol - 1, 0) - maxPos + 1;
|
|
XtVaSetValues(g->grid.hsb,
|
|
XmNminimum, PosToVisPos(g, leftNCol, 0),
|
|
XmNmaximum, maxPos + sliderSize,
|
|
XmNsliderSize, sliderSize,
|
|
XmNpageIncrement, sliderSize,
|
|
XmNvalue, PosToVisPos(g, g->grid.scrollCol, 0),
|
|
NULL);
|
|
}
|
|
else if (g->grid.hsPolicy == XmCONSTANT &&
|
|
g->grid.hsbDisplayPolicy == XmSTATIC)
|
|
{
|
|
if (!XtIsManaged(g->grid.hsb))
|
|
{
|
|
XtManageChild(g->grid.hsb);
|
|
vertSizeChanged = 1;
|
|
}
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout hsb not needed - static\n");
|
|
XtVaSetValues(g->grid.hsb,
|
|
XmNminimum, 0,
|
|
XmNmaximum, 1,
|
|
XmNsliderSize, 1,
|
|
XmNpageIncrement, 1,
|
|
XmNvalue, 0,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
if (XtIsManaged(g->grid.hsb))
|
|
{
|
|
XtUnmanageChild(g->grid.hsb);
|
|
vertSizeChanged = 1;
|
|
}
|
|
}
|
|
if (needsResize && resizeIfNeeded)
|
|
{
|
|
if (newWidth < 1)
|
|
newWidth = 1;
|
|
req.request_mode = CWWidth;
|
|
req.width = newWidth;
|
|
if (g->grid.debugLevel)
|
|
fprintf(stderr, "XmLGrid: HorizLayout Req w %d\n", (int)newWidth);
|
|
XtMakeGeometryRequest((Widget)g, &req, NULL);
|
|
PlaceScrollbars(g);
|
|
}
|
|
if (scrollChanged)
|
|
DrawArea(g, DrawHScroll, 0, 0);
|
|
TextAction(g, TEXT_SHOW);
|
|
cCol = g->grid.scrollCol - g->grid.headingColCount;
|
|
if (cCol != g->grid.cScrollCol)
|
|
{
|
|
g->grid.cScrollCol = cCol;
|
|
cbs.reason = XmCR_SCROLL_COLUMN;
|
|
cbs.columnType = XmCONTENT;
|
|
cbs.column = cCol;
|
|
XtCallCallbackList((Widget)g, g->grid.scrollCallback, (XtPointer)&cbs);
|
|
}
|
|
if (vertSizeChanged)
|
|
{
|
|
if (g->grid.layoutStack > 2)
|
|
XmLWarning((Widget)g, "HorizLayout() - recursion error");
|
|
else
|
|
{
|
|
g->grid.layoutStack++;
|
|
VertLayout(g, resizeIfNeeded);
|
|
g->grid.layoutStack--;
|
|
}
|
|
PlaceScrollbars(g);
|
|
}
|
|
}
|
|
|
|
static void
|
|
ApplyVisibleRows(XmLGridWidget g)
|
|
{
|
|
XtWidgetGeometry req;
|
|
XmLGridCellRefValues *cellValues;
|
|
|
|
if (g->grid.vsPolicy != XmCONSTANT)
|
|
{
|
|
XmLWarning((Widget)g,
|
|
"verticalSizePolicy must be XmCONSTANT to set visibleRows");
|
|
return;
|
|
}
|
|
cellValues = g->grid.defCellValues;
|
|
req.request_mode = CWHeight;
|
|
req.height = g->manager.shadow_thickness * 2 + g->grid.visibleRows *
|
|
(4 + cellValues->fontHeight + cellValues->topMargin +
|
|
cellValues->bottomMargin);
|
|
if (g->grid.hsPolicy == XmCONSTANT &&
|
|
g->grid.hsbDisplayPolicy == XmSTATIC)
|
|
req.height += g->grid.scrollBarMargin + XtHeight(g->grid.hsb);
|
|
XtMakeGeometryRequest((Widget)g, &req, NULL);
|
|
}
|
|
|
|
static void
|
|
ApplyVisibleCols(XmLGridWidget g)
|
|
{
|
|
XtWidgetGeometry req;
|
|
XmLGridCellRefValues *cellValues;
|
|
|
|
if (g->grid.hsPolicy != XmCONSTANT)
|
|
{
|
|
XmLWarning((Widget)g,
|
|
"horizontalSizePolicy must be XmCONSTANT to set visibleColumns");
|
|
return;
|
|
}
|
|
cellValues = g->grid.defCellValues;
|
|
req.request_mode = CWWidth;
|
|
req.width = g->manager.shadow_thickness * 2 + g->grid.visibleCols *
|
|
(4 + 8 * cellValues->fontWidth + cellValues->leftMargin +
|
|
cellValues->rightMargin);
|
|
if (g->grid.vsPolicy == XmCONSTANT &&
|
|
g->grid.vsbDisplayPolicy == XmSTATIC)
|
|
req.width += g->grid.scrollBarMargin + XtWidth(g->grid.vsb);
|
|
XtMakeGeometryRequest((Widget)g, &req, NULL);
|
|
}
|
|
|
|
static void
|
|
VisPosChanged(XmLGridWidget g,
|
|
int isVert)
|
|
{
|
|
if (isVert)
|
|
{
|
|
g->grid.recalcVertVisPos = 1;
|
|
g->grid.vertVisChangedHint = 1;
|
|
}
|
|
else
|
|
g->grid.recalcHorizVisPos = 1;
|
|
}
|
|
|
|
static void
|
|
RecalcVisPos(XmLGridWidget g,
|
|
int isVert)
|
|
{
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
int i, count, visPos;
|
|
|
|
if (g->grid.layoutFrozen == True)
|
|
XmLWarning((Widget)g, "RecalcVisPos() - layout is frozen");
|
|
visPos = 0;
|
|
if (isVert)
|
|
{
|
|
if (!g->grid.recalcVertVisPos)
|
|
return;
|
|
count = XmLArrayGetCount(g->grid.rowArray);
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
|
|
XmLGridRowSetVisPos(row, visPos);
|
|
if (!XmLGridRowIsHidden(row))
|
|
visPos++;
|
|
}
|
|
g->grid.recalcVertVisPos = 0;
|
|
}
|
|
else
|
|
{
|
|
if (!g->grid.recalcHorizVisPos)
|
|
return;
|
|
count = XmLArrayGetCount(g->grid.colArray);
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
XmLGridColumnSetVisPos(col, visPos);
|
|
if (!XmLGridColumnIsHidden(col))
|
|
visPos++;
|
|
}
|
|
g->grid.recalcHorizVisPos = 0;
|
|
}
|
|
}
|
|
|
|
static int
|
|
PosToVisPos(XmLGridWidget g,
|
|
int pos,
|
|
int isVert)
|
|
{
|
|
int visPos;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
|
|
if (isVert)
|
|
{
|
|
if (!g->grid.hiddenRowCount)
|
|
visPos = pos;
|
|
else
|
|
{
|
|
RecalcVisPos(g, isVert);
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
|
|
if (row)
|
|
visPos = XmLGridRowGetVisPos(row);
|
|
else
|
|
visPos = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!g->grid.hiddenColCount)
|
|
visPos = pos;
|
|
else
|
|
{
|
|
RecalcVisPos(g, isVert);
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
|
|
if (col)
|
|
visPos = XmLGridColumnGetVisPos(col);
|
|
else
|
|
visPos = -1;
|
|
}
|
|
}
|
|
if (visPos == -1)
|
|
XmLWarning((Widget)g, "PosToVisPos() - invalid pos");
|
|
return visPos;
|
|
}
|
|
|
|
static int
|
|
VisPosToPos(XmLGridWidget g,
|
|
int visPos,
|
|
int isVert)
|
|
{
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
int i1, i2, vp1, vp2, ic, mid, val, count;
|
|
|
|
if (isVert)
|
|
{
|
|
if (!g->grid.hiddenRowCount)
|
|
return visPos;
|
|
count = XmLArrayGetCount(g->grid.rowArray);
|
|
if (!count)
|
|
{
|
|
XmLWarning((Widget)g, "VisPosToPos() - called when no rows exist");
|
|
return -1;
|
|
}
|
|
RecalcVisPos(g, isVert);
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
|
|
vp1 = XmLGridRowGetVisPos(row);
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, count - 1);
|
|
vp2 = XmLGridRowGetVisPos(row);
|
|
if (visPos < vp1 || visPos > vp2)
|
|
{
|
|
XmLWarning((Widget)g, "VisPosToPos() - invalid Vert visPos");
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!g->grid.hiddenColCount)
|
|
return visPos;
|
|
count = XmLArrayGetCount(g->grid.colArray);
|
|
if (!count)
|
|
{
|
|
XmLWarning((Widget)g, "VisPosToPos() - called when no cols exist");
|
|
return -1;
|
|
}
|
|
RecalcVisPos(g, isVert);
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, 0);
|
|
vp1 = XmLGridColumnGetVisPos(col);
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, count - 1);
|
|
vp2 = XmLGridColumnGetVisPos(col);
|
|
if (visPos < vp1 || visPos > vp2)
|
|
{
|
|
XmLWarning((Widget)g, "VisPosToPos() - invalid Horiz visPos");
|
|
return -1;
|
|
}
|
|
}
|
|
i1 = 0;
|
|
i2 = count;
|
|
ic = 0;
|
|
while (1)
|
|
{
|
|
mid = i1 + (i2 - i1) / 2;
|
|
if (isVert)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, mid);
|
|
val = XmLGridRowGetVisPos(row);
|
|
}
|
|
else
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, mid);
|
|
val = XmLGridColumnGetVisPos(col);
|
|
}
|
|
if (visPos > val)
|
|
i1 = mid;
|
|
else if (visPos < val)
|
|
i2 = mid;
|
|
else
|
|
break;
|
|
if (++ic > 1000)
|
|
return -1; /* inf loop */
|
|
}
|
|
return mid;
|
|
}
|
|
|
|
static unsigned char
|
|
ColPosToType(XmLGridWidget g,
|
|
int pos)
|
|
{
|
|
unsigned char type;
|
|
|
|
if (pos < g->grid.headingColCount)
|
|
type = XmHEADING;
|
|
else if (pos < g->grid.headingColCount + g->grid.colCount)
|
|
type = XmCONTENT;
|
|
else
|
|
type = XmFOOTER;
|
|
return type;
|
|
}
|
|
|
|
static int
|
|
ColPosToTypePos(XmLGridWidget g,
|
|
unsigned char type,
|
|
int pos)
|
|
{
|
|
int c;
|
|
|
|
if (type == XmHEADING)
|
|
c = pos;
|
|
else if (type == XmCONTENT)
|
|
c = pos - g->grid.headingColCount;
|
|
else
|
|
c = pos - g->grid.headingColCount - g->grid.colCount;
|
|
return c;
|
|
}
|
|
|
|
static unsigned char
|
|
RowPosToType(XmLGridWidget g,
|
|
int pos)
|
|
{
|
|
unsigned char type;
|
|
|
|
if (pos < g->grid.headingRowCount)
|
|
type = XmHEADING;
|
|
else if (pos < g->grid.headingRowCount + g->grid.rowCount)
|
|
type = XmCONTENT;
|
|
else
|
|
type = XmFOOTER;
|
|
return type;
|
|
}
|
|
|
|
static int
|
|
RowPosToTypePos(XmLGridWidget g,
|
|
unsigned char type,
|
|
int pos)
|
|
{
|
|
int r;
|
|
|
|
if (type == XmHEADING)
|
|
r = pos;
|
|
else if (type == XmCONTENT)
|
|
r = pos - g->grid.headingRowCount;
|
|
else
|
|
r = pos - g->grid.headingRowCount - g->grid.rowCount;
|
|
return r;
|
|
}
|
|
|
|
static int
|
|
ColTypePosToPos(XmLGridWidget g,
|
|
unsigned char type,
|
|
int pos,
|
|
int allowNeg)
|
|
{
|
|
if (pos < 0)
|
|
{
|
|
if (!allowNeg)
|
|
return -1;
|
|
if (type == XmHEADING)
|
|
pos = g->grid.headingColCount;
|
|
else if (type == XmFOOTER || type == XmALL_TYPES)
|
|
pos = g->grid.headingColCount + g->grid.colCount +
|
|
g->grid.footerColCount;
|
|
else /* XmCONTENT */
|
|
pos = g->grid.headingColCount + g->grid.colCount;
|
|
}
|
|
else
|
|
{
|
|
if (type == XmALL_TYPES)
|
|
;
|
|
else if (type == XmHEADING)
|
|
{
|
|
if (pos >= g->grid.headingColCount)
|
|
return -1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
if (pos >= g->grid.footerColCount)
|
|
return -1;
|
|
pos += g->grid.headingColCount + g->grid.colCount;
|
|
}
|
|
else /* XmCONTENT */
|
|
{
|
|
if (pos >= g->grid.colCount)
|
|
return -1;
|
|
pos += g->grid.headingColCount;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
static int
|
|
RowTypePosToPos(XmLGridWidget g,
|
|
unsigned char type,
|
|
int pos,
|
|
int allowNeg)
|
|
{
|
|
if (pos < 0)
|
|
{
|
|
if (!allowNeg)
|
|
return -1;
|
|
if (type == XmHEADING)
|
|
pos = g->grid.headingRowCount;
|
|
else if (type == XmFOOTER || type == XmALL_TYPES)
|
|
pos = g->grid.headingRowCount + g->grid.rowCount +
|
|
g->grid.footerRowCount;
|
|
else /* XmCONTENT */
|
|
pos = g->grid.headingRowCount + g->grid.rowCount;
|
|
}
|
|
else
|
|
{
|
|
if (type == XmALL_TYPES)
|
|
;
|
|
else if (type == XmHEADING)
|
|
{
|
|
if (pos >= g->grid.headingRowCount)
|
|
return -1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
if (pos >= g->grid.footerRowCount)
|
|
return -1;
|
|
pos += g->grid.headingRowCount + g->grid.rowCount;
|
|
}
|
|
else /* XmCONTENT */
|
|
{
|
|
if (pos >= g->grid.rowCount)
|
|
return -1;
|
|
pos += g->grid.headingRowCount;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
static int
|
|
ScrollRowBottomPos(XmLGridWidget g,
|
|
int row)
|
|
{
|
|
int r, h, height;
|
|
|
|
if (g->grid.vsPolicy == XmVARIABLE)
|
|
return -1;
|
|
height = g->grid.reg[4].height;
|
|
h = 0;
|
|
r = row;
|
|
while (r >= 0)
|
|
{
|
|
h += GetRowHeight(g, r);
|
|
if (h > height)
|
|
break;
|
|
r--;
|
|
}
|
|
if (r != row)
|
|
r++;
|
|
return r;
|
|
}
|
|
|
|
static int
|
|
ScrollColRightPos(XmLGridWidget g,
|
|
int col)
|
|
{
|
|
int c, w, width;
|
|
|
|
if (g->grid.hsPolicy == XmVARIABLE)
|
|
return -1;
|
|
width = g->grid.reg[4].width;
|
|
w = 0;
|
|
c = col;
|
|
while (c >= 0)
|
|
{
|
|
w += GetColWidth(g, c);
|
|
if (w >= width)
|
|
break;
|
|
c--;
|
|
}
|
|
if (c != col)
|
|
c++;
|
|
return c;
|
|
}
|
|
|
|
static int
|
|
PosIsResize(XmLGridWidget g,
|
|
int x,
|
|
int y,
|
|
int *row,
|
|
int *col,
|
|
int *isVert)
|
|
{
|
|
XRectangle rect;
|
|
int i, nx, ny, margin;
|
|
|
|
/* check for bottom resize */
|
|
if (g->grid.allowRowResize == True)
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
nx = x;
|
|
ny = y - (4 * i);
|
|
|
|
if (XYToRowCol(g, nx, ny, row, col) != -1
|
|
&& RowColToXY(g, *row, *col, False, &rect) != -1
|
|
&& ColPosToType(g, *col) == XmHEADING)
|
|
{
|
|
margin = ny - (rect.y + rect.height);
|
|
if (margin > -5 && margin < 5)
|
|
{
|
|
*isVert = 1;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
/* check for right resize */
|
|
if (g->grid.allowColResize == True)
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
XmLGridColumn colp;
|
|
int c;
|
|
|
|
nx = x - (4 * i);
|
|
ny = y;
|
|
|
|
if (XYToRowCol(g, nx, ny, row, col) != -1
|
|
&& RowColToXY(g, *row, *col, False, &rect) != -1
|
|
&& RowPosToType(g, *row) == XmHEADING
|
|
&& *col != XmLArrayGetCount(g->grid.colArray) - 1)
|
|
{
|
|
Boolean foundResizable = 0;
|
|
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, *col);
|
|
|
|
if (!colp->grid.resizable)
|
|
continue;
|
|
|
|
for (c = *col + 1;
|
|
c < XmLArrayGetCount(g->grid.colArray);
|
|
c ++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
|
|
if (colp->grid.resizable
|
|
&& (g->grid.hsPolicy != XmRESIZE_IF_POSSIBLE
|
|
|| (g->grid.visibleCols == 0
|
|
|| c < g->grid.visibleCols))
|
|
)
|
|
{
|
|
foundResizable = True;
|
|
break;
|
|
}
|
|
}
|
|
if (!foundResizable) return 0;
|
|
|
|
margin = nx - (rect.x + rect.width);
|
|
if (margin > -5 && margin < 5)
|
|
{
|
|
*isVert = 0;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
XmLGridPosIsResize(Widget g,
|
|
int x,
|
|
int y)
|
|
{
|
|
int row, col;
|
|
int isVert;
|
|
return PosIsResize((XmLGridWidget) g, x, y, &row, &col, &isVert);
|
|
}
|
|
|
|
static int
|
|
XYToRowCol(XmLGridWidget g,
|
|
int x,
|
|
int y,
|
|
int *row,
|
|
int *col)
|
|
{
|
|
XRectangle xyRect, rect;
|
|
GridReg *reg;
|
|
int i, r, c;
|
|
int width, height;
|
|
int st;
|
|
|
|
reg = g->grid.reg;
|
|
st = g->manager.shadow_thickness;
|
|
xyRect.x = x;
|
|
xyRect.y = y;
|
|
xyRect.width = 1;
|
|
xyRect.height = 1;
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
rect.x = reg[i].x + st;
|
|
rect.y = reg[i].y + st;
|
|
rect.width = reg[i].width - st * 2;
|
|
rect.height = reg[i].height - st * 2;
|
|
if (XmLRectIntersect(&xyRect, &rect) == XmLRectOutside)
|
|
continue;
|
|
height = 0;
|
|
for (r = reg[i].row; r < reg[i].row + reg[i].nrow; r++)
|
|
{
|
|
width = 0;
|
|
for (c = reg[i].col; c < reg[i].col + reg[i].ncol; c++)
|
|
{
|
|
rect.x = reg[i].x + st + width;
|
|
rect.y = reg[i].y + st + height;
|
|
rect.width = GetColWidth(g, c);
|
|
rect.height = GetRowHeight(g, r);
|
|
if (g->grid.singleColScrollMode)
|
|
rect.x -= g->grid.singleColScrollPos;
|
|
ClipRectToReg(g, &rect, ®[i]);
|
|
if (XmLRectIntersect(&xyRect, &rect) != XmLRectOutside)
|
|
{
|
|
if (!RowColFirstSpan(g, r, c, row, col, 0, True, True))
|
|
return 0; /* SUCCESS */
|
|
else
|
|
return -1;
|
|
}
|
|
width += GetColWidth(g, c);
|
|
}
|
|
height += GetRowHeight(g, r);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static int
|
|
RowColToXY(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
Boolean clipped,
|
|
XRectangle *rect)
|
|
{
|
|
XmLGridCell cell;
|
|
XmLGridCellRefValues *cellValues;
|
|
GridReg *reg;
|
|
Dimension st;
|
|
int i, r, c, off;
|
|
|
|
reg = g->grid.reg;
|
|
st = g->manager.shadow_thickness;
|
|
cell = GetCell(g, row, col);
|
|
if (!cell)
|
|
return -1;
|
|
cellValues = XmLGridCellGetRefValues(cell);
|
|
|
|
if (!cellValues) return -1;
|
|
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (!reg[i].width || !reg[i].height)
|
|
continue;
|
|
if (!(col >= reg[i].col &&
|
|
col < reg[i].col + reg[i].ncol &&
|
|
row >= reg[i].row &&
|
|
row < reg[i].row + reg[i].nrow))
|
|
continue;
|
|
off = 0;
|
|
for (r = reg[i].row; r < row; r++)
|
|
off += GetRowHeight(g, r);
|
|
rect->y = reg[i].y + st + off;
|
|
rect->height = GetRowHeight(g, row);
|
|
if (cellValues->rowSpan)
|
|
for (r = row + 1; r <= row + cellValues->rowSpan; r++)
|
|
rect->height += GetRowHeight(g, r);
|
|
off = 0;
|
|
for (c = reg[i].col; c < col; c++)
|
|
off += GetColWidth(g, c);
|
|
rect->x = reg[i].x + st + off;
|
|
rect->width = GetColWidth(g, col);
|
|
if (cellValues->columnSpan)
|
|
for (c = col + 1; c <= col + cellValues->columnSpan; c++)
|
|
rect->width += GetColWidth(g, c);
|
|
if (g->grid.singleColScrollMode)
|
|
rect->x -= g->grid.singleColScrollPos;
|
|
if (clipped == True)
|
|
ClipRectToReg(g, rect, ®[i]);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static int
|
|
RowColFirstSpan(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
int *firstRow,
|
|
int *firstCol,
|
|
XRectangle *rect,
|
|
Boolean lookLeft,
|
|
Boolean lookUp)
|
|
{
|
|
XmLGridCell cell;
|
|
int done;
|
|
|
|
done = 0;
|
|
while (!done)
|
|
{
|
|
cell = GetCell(g, row, col);
|
|
if (!cell)
|
|
return -1;
|
|
if (XmLGridCellInRowSpan(cell) == True)
|
|
{
|
|
if (lookUp == True)
|
|
{
|
|
row--;
|
|
if (rect)
|
|
rect->y -= GetRowHeight(g, row);
|
|
}
|
|
else
|
|
row = -1;
|
|
if (row < 0)
|
|
done = 1;
|
|
}
|
|
else if (XmLGridCellInColumnSpan(cell) == True)
|
|
{
|
|
if (lookLeft == True)
|
|
{
|
|
col--;
|
|
if (rect)
|
|
rect->x -= GetColWidth(g, col);
|
|
}
|
|
else
|
|
col = -1;
|
|
if (col < 0)
|
|
done = 1;
|
|
}
|
|
else
|
|
done = 1;
|
|
}
|
|
if (row < 0 || col < 0)
|
|
return -1;
|
|
*firstRow = row;
|
|
*firstCol = col;
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
RowColSpanRect(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
XRectangle *rect)
|
|
{
|
|
XmLGridCell cell;
|
|
XmLGridCellRefValues *cellValues;
|
|
int r, c;
|
|
|
|
cell = GetCell(g, row, col);
|
|
cellValues = XmLGridCellGetRefValues(cell);
|
|
rect->width = 0;
|
|
rect->height = 0;
|
|
for (r = row; r <= row + cellValues->rowSpan; r++)
|
|
rect->height += GetRowHeight(g, r);
|
|
for (c = col; c <= col + cellValues->columnSpan; c++)
|
|
rect->width += GetColWidth(g, c);
|
|
}
|
|
|
|
static XmLGridCell
|
|
GetCell(XmLGridWidget g,
|
|
int row,
|
|
int col)
|
|
{
|
|
XmLGridRow rowp;
|
|
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (!rowp)
|
|
return 0;
|
|
return (XmLGridCell)XmLArrayGet(XmLGridRowCells(rowp), col);
|
|
}
|
|
|
|
static int
|
|
GetColWidth(XmLGridWidget g,
|
|
int col)
|
|
{
|
|
XmLGridColumn colp;
|
|
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
|
|
if (!colp)
|
|
return 0;
|
|
return XmLGridColumnWidthInPixels(colp);
|
|
}
|
|
|
|
static int
|
|
GetRowHeight(XmLGridWidget g,
|
|
int row)
|
|
{
|
|
XmLGridRow rowp;
|
|
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (!rowp)
|
|
return 0;
|
|
return XmLGridRowHeightInPixels(rowp);
|
|
}
|
|
|
|
static int
|
|
ColIsVisible(XmLGridWidget g,
|
|
int col)
|
|
{
|
|
XmLGridColumn c;
|
|
int i, c1, c2;
|
|
|
|
c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
|
|
if (!c)
|
|
{
|
|
XmLWarning((Widget)g, "ColumnIsVisible() - invalid column");
|
|
return -1;
|
|
}
|
|
if (XmLGridColumnIsHidden(c) == True)
|
|
return 0;
|
|
if (g->grid.hsPolicy != XmCONSTANT)
|
|
return 1;
|
|
for (i = 0; i < 3; i ++)
|
|
{
|
|
c1 = g->grid.reg[i].col;
|
|
c2 = c1 + g->grid.reg[i].ncol;
|
|
if (col >= c1 && col < c2)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
RowIsVisible(XmLGridWidget g,
|
|
int row)
|
|
{
|
|
XmLGridRow r;
|
|
int i, r1, r2;
|
|
|
|
r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (!r)
|
|
{
|
|
XmLWarning((Widget)g, "RowIsVisible() - invalid row");
|
|
return -1;
|
|
}
|
|
if (XmLGridRowIsHidden(r) == True)
|
|
return 0;
|
|
if (g->grid.vsPolicy != XmCONSTANT)
|
|
return 1;
|
|
for (i = 0; i < 9; i += 3)
|
|
{
|
|
r1 = g->grid.reg[i].row;
|
|
r2 = r1 + g->grid.reg[i].nrow;
|
|
if (row >= r1 && row < r2)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static XtGeometryResult
|
|
GeometryManager(Widget w,
|
|
XtWidgetGeometry *request,
|
|
XtWidgetGeometry *allow)
|
|
{
|
|
if (request->request_mode & CWWidth)
|
|
w->core.width = request->width;
|
|
if (request->request_mode & CWHeight)
|
|
w->core.height = request->height;
|
|
if (request->request_mode & CWX)
|
|
w->core.x = request->x;
|
|
if (request->request_mode & CWY)
|
|
w->core.y = request->y;
|
|
if (request->request_mode & CWBorderWidth)
|
|
w->core.border_width = request->border_width;
|
|
return XtGeometryYes;
|
|
}
|
|
|
|
static void
|
|
ScrollCB(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
XmLGridWidget g;
|
|
XmScrollBarCallbackStruct *cbs;
|
|
unsigned char orientation;
|
|
int visPos;
|
|
|
|
g = (XmLGridWidget)(XtParent(w));
|
|
cbs = (XmScrollBarCallbackStruct *)callData;
|
|
visPos = cbs->value;
|
|
XtVaGetValues(w, XmNorientation, &orientation, NULL);
|
|
if (orientation == XmHORIZONTAL && g->grid.singleColScrollMode)
|
|
{
|
|
g->grid.singleColScrollPos = visPos;
|
|
DrawArea(g, DrawHScroll, 0, 0);
|
|
}
|
|
else if (orientation == XmVERTICAL)
|
|
{
|
|
if (visPos == PosToVisPos(g, g->grid.scrollRow, 1))
|
|
return;
|
|
g->grid.scrollRow = VisPosToPos(g, visPos, 1);
|
|
VertLayout(g, 0);
|
|
DrawArea(g, DrawVScroll, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
if (visPos == PosToVisPos(g, g->grid.scrollCol, 0))
|
|
return;
|
|
g->grid.scrollCol = VisPosToPos(g, visPos, 0);
|
|
HorizLayout(g, 0);
|
|
DrawArea(g, DrawHScroll, 0, 0);
|
|
}
|
|
}
|
|
|
|
static int
|
|
FindNextFocus(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
int rowDir,
|
|
int colDir,
|
|
int *nextRow,
|
|
int *nextCol)
|
|
{
|
|
int traverse;
|
|
int hrc, hcc, rc, cc;
|
|
XmLGridColumn colp;
|
|
XmLGridRow rowp;
|
|
XmLGridCell cell;
|
|
|
|
hcc = g->grid.headingColCount;
|
|
cc = g->grid.colCount;
|
|
hrc = g->grid.headingRowCount;
|
|
rc = g->grid.rowCount;
|
|
if (!rc || !cc)
|
|
return -1;
|
|
if (col < hcc)
|
|
col = hcc;
|
|
else if (col >= hcc + cc)
|
|
col = hcc + cc - 1;
|
|
if (row < hrc)
|
|
row = hrc;
|
|
else if (row >= hrc + rc)
|
|
row = hrc + rc - 1;
|
|
traverse = 0;
|
|
while (1)
|
|
{
|
|
if (row < hrc || row >= hrc + rc)
|
|
break;
|
|
if (col < hcc || col >= hcc + cc)
|
|
break;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
|
|
cell = GetCell(g, row, col);
|
|
if (cell &&
|
|
RowPosToType(g, row) == XmCONTENT &&
|
|
ColPosToType(g, col) == XmCONTENT &&
|
|
XmLGridCellInRowSpan(cell) == False &&
|
|
XmLGridCellInColumnSpan(cell) == False &&
|
|
XmLGridRowIsHidden(rowp) == False &&
|
|
XmLGridColumnIsHidden(colp) == False)
|
|
{
|
|
traverse = 1;
|
|
break;
|
|
}
|
|
if (!rowDir && !colDir)
|
|
break;
|
|
row += rowDir;
|
|
col += colDir;
|
|
}
|
|
if (!traverse)
|
|
return -1;
|
|
*nextRow = row;
|
|
*nextCol = col;
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
SetFocus(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
int rowDir,
|
|
int colDir)
|
|
{
|
|
if (FindNextFocus(g, row, col, rowDir, colDir, &row, &col) == -1)
|
|
return -1;
|
|
ChangeFocus(g, row, col);
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
ChangeFocus(XmLGridWidget g,
|
|
int row,
|
|
int col)
|
|
{
|
|
XmLGridCell cell;
|
|
XmLGridCallbackStruct cbs;
|
|
int focusRow, focusCol;
|
|
|
|
focusRow = g->grid.focusRow;
|
|
focusCol = g->grid.focusCol;
|
|
g->grid.focusRow = row;
|
|
g->grid.focusCol = col;
|
|
if (focusRow != -1 && focusCol != -1)
|
|
{
|
|
cell = GetCell(g, focusRow, focusCol);
|
|
if (cell)
|
|
{
|
|
if (g->grid.highlightRowMode == True)
|
|
DrawArea(g, DrawRow, focusRow, 0);
|
|
else
|
|
DrawArea(g, DrawCell, focusRow, focusCol);
|
|
cbs.reason = XmCR_CELL_FOCUS_OUT;
|
|
cbs.columnType = ColPosToType(g, focusCol);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, focusCol);
|
|
cbs.rowType = RowPosToType(g, focusRow);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, focusRow);
|
|
XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
if (row != -1 && col != -1)
|
|
{
|
|
cell = GetCell(g, row, col);
|
|
if (cell)
|
|
{
|
|
if (g->grid.highlightRowMode == True)
|
|
DrawArea(g, DrawRow, row, 0);
|
|
else
|
|
DrawArea(g, DrawCell, row, col);
|
|
cbs.reason = XmCR_CELL_FOCUS_IN;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
XtCallCallbackList((Widget)g, g->grid.cellFocusCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
else
|
|
{
|
|
if (!XmLArrayGet(g->grid.rowArray, row))
|
|
g->grid.focusRow = -1;
|
|
if (!XmLArrayGet(g->grid.colArray, col))
|
|
g->grid.focusCol = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
MakeColVisible(XmLGridWidget g,
|
|
int col)
|
|
{
|
|
int st, width, scrollWidth, scrollCol, prevScrollCol;
|
|
|
|
if (g->grid.hsPolicy != XmCONSTANT)
|
|
return;
|
|
if (col < g->grid.leftFixedCount ||
|
|
col >= XmLArrayGetCount(g->grid.colArray) - g->grid.rightFixedCount)
|
|
return;
|
|
st = g->manager.shadow_thickness;
|
|
scrollCol = col;
|
|
if (col > g->grid.scrollCol)
|
|
{
|
|
scrollWidth = g->grid.reg[4].width - st * 2;
|
|
width = 0;
|
|
while (1)
|
|
{
|
|
width += GetColWidth(g, scrollCol);
|
|
if (width > scrollWidth)
|
|
break;
|
|
if (scrollCol < g->grid.leftFixedCount)
|
|
break;
|
|
scrollCol--;
|
|
}
|
|
scrollCol++;
|
|
if (scrollCol > col)
|
|
scrollCol = col;
|
|
/* only scroll if needed */
|
|
if (scrollCol < g->grid.scrollCol)
|
|
scrollCol = g->grid.scrollCol;
|
|
}
|
|
if (scrollCol == g->grid.scrollCol)
|
|
return;
|
|
prevScrollCol = g->grid.scrollCol;
|
|
g->grid.scrollCol = scrollCol;
|
|
HorizLayout(g, 0);
|
|
if (g->grid.scrollCol != prevScrollCol)
|
|
DrawArea(g, DrawHScroll, 0, 0);
|
|
}
|
|
|
|
static void
|
|
MakeRowVisible(XmLGridWidget g,
|
|
int row)
|
|
{
|
|
int st, height, scrollHeight, scrollRow, prevScrollRow;
|
|
|
|
if (g->grid.vsPolicy != XmCONSTANT)
|
|
return;
|
|
if (row < g->grid.topFixedCount ||
|
|
row >= XmLArrayGetCount(g->grid.rowArray) - g->grid.bottomFixedCount)
|
|
return;
|
|
st = g->manager.shadow_thickness;
|
|
scrollRow = row;
|
|
if (row > g->grid.scrollRow)
|
|
{
|
|
scrollHeight = g->grid.reg[4].height - st * 2;
|
|
height = 0;
|
|
while (1)
|
|
{
|
|
height += GetRowHeight(g, scrollRow);
|
|
if (height > scrollHeight)
|
|
break;
|
|
if (scrollRow < g->grid.topFixedCount)
|
|
break;
|
|
scrollRow--;
|
|
}
|
|
scrollRow++;
|
|
if (scrollRow > row)
|
|
scrollRow = row;
|
|
/* only scroll if needed */
|
|
if (scrollRow < g->grid.scrollRow)
|
|
scrollRow = g->grid.scrollRow;
|
|
}
|
|
if (scrollRow == g->grid.scrollRow)
|
|
return;
|
|
prevScrollRow = g->grid.scrollRow;
|
|
g->grid.scrollRow = scrollRow;
|
|
VertLayout(g, 0);
|
|
if (g->grid.scrollRow != prevScrollRow)
|
|
DrawArea(g, DrawVScroll, 0, 0);
|
|
}
|
|
|
|
static void
|
|
TextAction(XmLGridWidget g,
|
|
int action)
|
|
{
|
|
int row, col, reason, ret, isVisible;
|
|
XRectangle rect;
|
|
XtTranslations trans;
|
|
WidgetClass wc;
|
|
XmLGridCell cellp;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
if (!g->grid.text || !XtIsRealized(g->grid.text))
|
|
return;
|
|
row = g->grid.focusRow;
|
|
col = g->grid.focusCol;
|
|
if (row == -1 || col == -1)
|
|
return;
|
|
isVisible = 0;
|
|
if (RowColToXY(g, row, col, True, &rect) != -1)
|
|
isVisible = 1;
|
|
cellp = GetCell(g, row, col);
|
|
if (!cellp)
|
|
return;
|
|
cbs.rowType = XmCONTENT;
|
|
cbs.row = RowPosToTypePos(g, XmCONTENT, row);
|
|
cbs.columnType = XmCONTENT;
|
|
cbs.column = ColPosToTypePos(g, XmCONTENT, col);
|
|
cbs.clipRect = ▭
|
|
switch (action)
|
|
{
|
|
case TEXT_EDIT:
|
|
case TEXT_EDIT_INSERT:
|
|
{
|
|
if (g->grid.inEdit || !isVisible)
|
|
return;
|
|
g->grid.inEdit = 1;
|
|
if (action == TEXT_EDIT)
|
|
cbs.reason = XmCR_EDIT_BEGIN;
|
|
else
|
|
cbs.reason = XmCR_EDIT_INSERT;
|
|
ret = XmLGridCellAction(cellp, (Widget)g, &cbs);
|
|
if (ret)
|
|
{
|
|
reason = cbs.reason;
|
|
cbs.reason = XmCR_CONF_TEXT;
|
|
XmLGridCellAction(cellp, (Widget)g, &cbs);
|
|
cbs.reason = reason;
|
|
wc = g->grid.text->core.widget_class;
|
|
trans = (XtTranslations)wc->core_class.tm_table;
|
|
XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
|
|
XtOverrideTranslations(g->grid.text, g->grid.editTrans);
|
|
XtMapWidget(g->grid.text);
|
|
g->grid.textHidden = 0;
|
|
XtCallCallbackList((Widget)g, g->grid.editCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
else
|
|
g->grid.inEdit = 0;
|
|
break;
|
|
}
|
|
case TEXT_EDIT_CANCEL:
|
|
case TEXT_EDIT_COMPLETE:
|
|
{
|
|
if (!g->grid.inEdit)
|
|
return;
|
|
if (action == TEXT_EDIT_COMPLETE)
|
|
cbs.reason = XmCR_EDIT_COMPLETE;
|
|
else
|
|
cbs.reason = XmCR_EDIT_CANCEL;
|
|
XmLGridCellAction(cellp, (Widget)g, &cbs);
|
|
wc = g->grid.text->core.widget_class;
|
|
trans = (XtTranslations)wc->core_class.tm_table;
|
|
XtVaSetValues(g->grid.text, XmNtranslations, trans, NULL);
|
|
XtOverrideTranslations(g->grid.text, g->grid.traverseTrans);
|
|
XtCallCallbackList((Widget)g, g->grid.editCallback,
|
|
(XtPointer)&cbs);
|
|
XmTextSetString(g->grid.text, "");
|
|
XmTextSetInsertionPosition(g->grid.text, 0);
|
|
g->grid.inEdit = 0;
|
|
XtUnmapWidget(g->grid.text);
|
|
g->grid.textHidden = 1;
|
|
XtConfigureWidget(g->grid.text, 0, 0, 30, 10, 0);
|
|
break;
|
|
}
|
|
case TEXT_HIDE:
|
|
{
|
|
if (g->grid.textHidden || !isVisible)
|
|
return;
|
|
XtUnmapWidget(g->grid.text);
|
|
g->grid.textHidden = 1;
|
|
break;
|
|
}
|
|
case TEXT_SHOW:
|
|
{
|
|
if (!g->grid.textHidden || !g->grid.inEdit || !isVisible)
|
|
return;
|
|
if (rect.width == 0 || rect.height == 0)
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
else
|
|
{
|
|
cbs.reason = XmCR_CONF_TEXT;
|
|
XmLGridCellAction(cellp, (Widget)g, &cbs);
|
|
XtMapWidget(g->grid.text);
|
|
g->grid.textHidden = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Getting and Setting Values
|
|
*/
|
|
|
|
static void
|
|
GetSubValues(Widget w,
|
|
ArgList args,
|
|
Cardinal *nargs)
|
|
{
|
|
XmLGridWidget g;
|
|
int i, c;
|
|
long mask;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCell cell;
|
|
|
|
g = (XmLGridWidget)w;
|
|
row = 0;
|
|
col = 0;
|
|
for (i = 0; i < *nargs; i++)
|
|
{
|
|
if (!args[i].name)
|
|
continue;
|
|
if (!strncmp(args[i].name, "row", 3))
|
|
{
|
|
if (!strcmp(args[i].name, XmNrowPtr))
|
|
{
|
|
row = (XmLGridRow)args[i].value;
|
|
continue;
|
|
}
|
|
mask = 0;
|
|
GetRowValueMask(g, args[i].name, &mask);
|
|
if (!mask)
|
|
continue;
|
|
if (!row)
|
|
{
|
|
XmLWarning(w, "GetValues() - invalid row");
|
|
continue;
|
|
}
|
|
GetRowValue(g, row, args[i].value, mask);
|
|
}
|
|
else if (!strncmp(args[i].name, "column", 6))
|
|
{
|
|
if (!strcmp(args[i].name, XmNcolumnPtr))
|
|
{
|
|
col = (XmLGridColumn)args[i].value;
|
|
continue;
|
|
}
|
|
mask = 0;
|
|
GetColumnValueMask(g, args[i].name, &mask);
|
|
if (!mask)
|
|
continue;
|
|
if (!col)
|
|
{
|
|
XmLWarning(w, "GetValues() - invalid column");
|
|
continue;
|
|
}
|
|
GetColumnValue(g, col, args[i].value, mask);
|
|
}
|
|
else if (!strncmp(args[i].name, "cell", 4))
|
|
{
|
|
mask = 0;
|
|
CellValueGetMask(args[i].name, &mask);
|
|
if (!mask)
|
|
continue;
|
|
if (!row || !col)
|
|
{
|
|
XmLWarning(w, "GetValues() - invalid cell");
|
|
continue;
|
|
}
|
|
c = XmLGridColumnGetPos(col);
|
|
cell = (XmLGridCell)XmLArrayGet(XmLGridRowCells(row), c);
|
|
GetCellValue(cell, args[i].value, mask);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
SetSubValues(Widget w,
|
|
ArgList args,
|
|
Cardinal *nargs)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCell cell;
|
|
XmLGridCellRefValues *values, *newValues, *prevValues;
|
|
XmLArray cellArray;
|
|
int r, r1, r2, rowsValid;
|
|
int c, c1, c2, cd1, cd2, colsValid;
|
|
unsigned char rowType, colType;
|
|
long rowMask, colMask, cellMask;
|
|
int i, nRefValues, allCols;
|
|
int needsHorizResize, needsVertResize;
|
|
char buf[256];
|
|
|
|
newValues = (XmLGridCellRefValues *)NULL;
|
|
g = (XmLGridWidget)w;
|
|
needsHorizResize = 0;
|
|
needsVertResize = 0;
|
|
rowMask = 0;
|
|
colMask = 0;
|
|
cellMask = 0;
|
|
for (i = 0; i < *nargs; i++)
|
|
{
|
|
if (!args[i].name)
|
|
continue;
|
|
if (!strncmp(args[i].name, "row", 3))
|
|
{
|
|
if (!strcmp(args[i].name, XmNrowPtr))
|
|
XmLWarning(w, "SetValues() - can't use XmNrowPtr");
|
|
GetRowValueMask(g, args[i].name, &rowMask);
|
|
}
|
|
else if (!strncmp(args[i].name, "column", 6))
|
|
{
|
|
if (!strcmp(args[i].name, XmNcolumnPtr))
|
|
XmLWarning(w, "SetValues() - can't use XmNcolumnPtr");
|
|
GetColumnValueMask(g, args[i].name, &colMask);
|
|
}
|
|
else if (!strncmp(args[i].name, "cell", 4))
|
|
CellValueGetMask(args[i].name, &cellMask);
|
|
else if (rowMask || colMask || cellMask)
|
|
{
|
|
sprintf(buf, "SetValues() - %s is not a row/column/cell resource",
|
|
args[i].name);
|
|
XmLWarning(w, buf);
|
|
}
|
|
}
|
|
if (rowMask || colMask || cellMask)
|
|
{
|
|
if (g->grid.rowType == XmINVALID_TYPE)
|
|
rowType = XmCONTENT;
|
|
else
|
|
rowType = g->grid.rowType;
|
|
rowsValid = 1;
|
|
if (g->grid.cellRowRangeStart != -1 && g->grid.cellRowRangeEnd != -1)
|
|
{
|
|
r1 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeStart, 0);
|
|
r2 = RowTypePosToPos(g, rowType, g->grid.cellRowRangeEnd, 0);
|
|
if (r1 < 0 || r2 < 0 || r1 > r2)
|
|
rowsValid = 0;
|
|
r2++;
|
|
}
|
|
else if (g->grid.cellRow != -1)
|
|
{
|
|
r1 = RowTypePosToPos(g, rowType, g->grid.cellRow, 0);
|
|
if (r1 == -1)
|
|
rowsValid = 0;
|
|
r2 = r1 + 1;
|
|
}
|
|
else
|
|
{
|
|
r1 = RowTypePosToPos(g, rowType, 0, 0);
|
|
if (r1 == -1)
|
|
r1 = 0;
|
|
r2 = RowTypePosToPos(g, rowType, -1, 1);
|
|
}
|
|
if (!rowsValid)
|
|
{
|
|
XmLWarning(w, "SetValues() - invalid row(s) specified");
|
|
r1 = 0;
|
|
r2 = 0;
|
|
}
|
|
if (g->grid.colType == XmINVALID_TYPE)
|
|
colType = XmCONTENT;
|
|
else
|
|
colType = g->grid.colType;
|
|
colsValid = 1;
|
|
if (g->grid.cellColRangeStart != -1 && g->grid.cellColRangeEnd != -1)
|
|
{
|
|
c1 = ColTypePosToPos(g, colType, g->grid.cellColRangeStart, 0);
|
|
c2 = ColTypePosToPos(g, colType, g->grid.cellColRangeEnd, 0);
|
|
if (c1 < 0 || c2 < 0 || c1 > c2)
|
|
colsValid = 0;
|
|
c2++;
|
|
}
|
|
else if (g->grid.cellCol != -1)
|
|
{
|
|
c1 = ColTypePosToPos(g, colType, g->grid.cellCol, 0);
|
|
if (c1 == -1)
|
|
colsValid = 0;
|
|
c2 = c1 + 1;
|
|
}
|
|
else
|
|
{
|
|
c1 = ColTypePosToPos(g, colType, 0, 0);
|
|
if (c1 == -1)
|
|
c1 = 0;
|
|
c2 = ColTypePosToPos(g, colType, -1, 1);
|
|
}
|
|
if (!colsValid)
|
|
{
|
|
XmLWarning(w, "SetValues() - invalid column(s) specified");
|
|
c1 = 0;
|
|
c2 = 0;
|
|
}
|
|
if (g->grid.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLGrid: SetValues for rows %d to %d\n", r1, r2);
|
|
fprintf(stderr, "XmLGrid: & columns %d to %d\n", c1, c2);
|
|
}
|
|
if (rowMask)
|
|
for (r = r1; r < r2; r += g->grid.rowStep)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (!row)
|
|
continue;
|
|
if (SetRowValues(g, row, rowMask))
|
|
needsVertResize = 1;
|
|
DrawArea(g, DrawRow, r, 0);
|
|
}
|
|
if (colMask)
|
|
for (c = c1; c < c2; c += g->grid.colStep)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (!col)
|
|
continue;
|
|
if (SetColumnValues(g, col, colMask))
|
|
needsHorizResize = 1;
|
|
DrawArea(g, DrawCol, 0, c);
|
|
}
|
|
if (cellMask)
|
|
SetCellValuesPreprocess(g, cellMask);
|
|
if (cellMask && g->grid.cellDefaults == True)
|
|
{
|
|
allCols = 0;
|
|
if (g->grid.colType == XmINVALID_TYPE &&
|
|
g->grid.cellCol == -1 &&
|
|
g->grid.cellColRangeStart == -1 &&
|
|
g->grid.cellColRangeEnd == -1 &&
|
|
g->grid.colStep == 1)
|
|
allCols = 1;
|
|
|
|
if (allCols)
|
|
{
|
|
/* set cell default values */
|
|
newValues = CellRefValuesCreate(g, g->grid.defCellValues);
|
|
newValues->refCount = 1;
|
|
SetCellRefValues(g, newValues, cellMask);
|
|
if (newValues->rowSpan || newValues->columnSpan)
|
|
{
|
|
newValues->rowSpan = 0;
|
|
newValues->columnSpan = 0;
|
|
XmLWarning((Widget)g,
|
|
"SetValues() - can't set default cell spans");
|
|
}
|
|
XmLGridCellDerefValues(g->grid.defCellValues);
|
|
g->grid.defCellValues = newValues;
|
|
cd1 = 0;
|
|
cd2 = XmLArrayGetCount(g->grid.colArray);
|
|
}
|
|
else
|
|
{
|
|
cd1 = c1;
|
|
cd2 = c2;
|
|
}
|
|
/* set column cell default values */
|
|
for (c = cd1; c < cd2; c += g->grid.colStep)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (!col)
|
|
continue;
|
|
if (allCols && !col->grid.defCellValues)
|
|
continue;
|
|
if (col->grid.defCellValues)
|
|
newValues = CellRefValuesCreate(g, col->grid.defCellValues);
|
|
else
|
|
newValues = CellRefValuesCreate(g, g->grid.defCellValues);
|
|
newValues->refCount = 1;
|
|
SetCellRefValues(g, newValues, cellMask);
|
|
if (newValues->rowSpan || newValues->columnSpan)
|
|
{
|
|
newValues->rowSpan = 0;
|
|
newValues->columnSpan = 0;
|
|
XmLWarning((Widget)g,
|
|
"SetValues() - can't set default cell spans");
|
|
}
|
|
if (col->grid.defCellValues)
|
|
XmLGridCellDerefValues(col->grid.defCellValues);
|
|
col->grid.defCellValues = newValues;
|
|
}
|
|
}
|
|
else if (cellMask)
|
|
{
|
|
/* set cell values */
|
|
if (SetCellHasRefValues(cellMask))
|
|
{
|
|
cellArray = XmLArrayNew(0, 0);
|
|
XmLArrayAdd(cellArray, -1, (r2 - r1) * (c2 - c1));
|
|
nRefValues = 0;
|
|
for (r = r1; r < r2; r += g->grid.rowStep)
|
|
for (c = c1; c < c2; c += g->grid.colStep)
|
|
{
|
|
cell = GetCell(g, r, c);
|
|
if (!cell)
|
|
continue;
|
|
SetCellRefValuesPreprocess(g, r, c, cell, cellMask);
|
|
XmLArraySet(cellArray, nRefValues, cell);
|
|
nRefValues++;
|
|
}
|
|
XmLArraySort(cellArray, SetCellRefValuesCompare,
|
|
(void *)&cellMask, 0, nRefValues);
|
|
prevValues = 0;
|
|
for (i = 0; i < nRefValues; i++)
|
|
{
|
|
cell = (XmLGridCell)XmLArrayGet(cellArray, i);
|
|
values = XmLGridCellGetRefValues(cell);
|
|
if (values != prevValues)
|
|
{
|
|
newValues = CellRefValuesCreate(g, values);
|
|
SetCellRefValues(g, newValues, cellMask);
|
|
}
|
|
XmLGridCellSetRefValues(cell, newValues);
|
|
prevValues = values;
|
|
}
|
|
XmLArrayFree(cellArray);
|
|
}
|
|
for (r = r1; r < r2; r += g->grid.rowStep)
|
|
for (c = c1; c < c2; c += g->grid.colStep)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
cell = GetCell(g, r, c);
|
|
if (!row || !col || !cell)
|
|
continue;
|
|
if (SetCellValuesResize(g, row, col, cell, cellMask))
|
|
{
|
|
needsHorizResize = 1;
|
|
needsVertResize = 1;
|
|
}
|
|
SetCellValues(g, cell, cellMask);
|
|
if (!needsHorizResize && !needsVertResize)
|
|
DrawArea(g, DrawCell, r, c);
|
|
}
|
|
}
|
|
}
|
|
if (needsHorizResize)
|
|
HorizLayout(g, 1);
|
|
if (needsVertResize)
|
|
VertLayout(g, 1);
|
|
if (needsHorizResize || needsVertResize)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
g->grid.rowType = XmINVALID_TYPE;
|
|
g->grid.colType = XmINVALID_TYPE;
|
|
g->grid.rowStep = 1;
|
|
g->grid.colStep = 1;
|
|
g->grid.cellRow = -1;
|
|
g->grid.cellRowRangeStart = -1;
|
|
g->grid.cellRowRangeEnd = -1;
|
|
g->grid.cellCol = -1;
|
|
g->grid.cellColRangeStart = -1;
|
|
g->grid.cellColRangeEnd = -1;
|
|
g->grid.cellDefaults = False;
|
|
}
|
|
|
|
static Boolean
|
|
SetValues(Widget curW,
|
|
Widget reqW,
|
|
Widget newW,
|
|
ArgList args,
|
|
Cardinal *nargs)
|
|
{
|
|
XmLGridWidget g, cur;
|
|
int hc, c, fc, hr, r, fr;
|
|
int tfc, bfc, lfc, rfc;
|
|
int needsVertLayout, needsHorizLayout, needsRedraw;
|
|
XmLGridCellRefValues *cellValues;
|
|
|
|
g = (XmLGridWidget)newW;
|
|
cur = (XmLGridWidget)curW;
|
|
needsRedraw = 0;
|
|
needsVertLayout = 0;
|
|
needsHorizLayout = 0;
|
|
|
|
#define NE(value) (g->value != cur->value)
|
|
if (NE(grid.cScrollCol))
|
|
{
|
|
g->grid.scrollCol = g->grid.cScrollCol + g->grid.headingColCount;
|
|
needsHorizLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.cScrollRow))
|
|
{
|
|
g->grid.scrollRow = g->grid.cScrollRow + g->grid.headingRowCount;
|
|
needsVertLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.bottomFixedCount) ||
|
|
NE(grid.bottomFixedMargin) ||
|
|
NE(grid.topFixedCount) ||
|
|
NE(grid.topFixedMargin) ||
|
|
NE(grid.vsbDisplayPolicy))
|
|
{
|
|
needsVertLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.leftFixedCount) ||
|
|
NE(grid.leftFixedMargin) ||
|
|
NE(grid.rightFixedCount) ||
|
|
NE(grid.rightFixedMargin) ||
|
|
NE(grid.hsbDisplayPolicy))
|
|
{
|
|
needsHorizLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.layoutFrozen))
|
|
{
|
|
if (g->grid.layoutFrozen == False)
|
|
{
|
|
if (g->grid.needsVertLayout == True)
|
|
{
|
|
needsVertLayout = 1;
|
|
g->grid.needsVertLayout = False;
|
|
}
|
|
if (g->grid.needsHorizLayout == True)
|
|
{
|
|
needsHorizLayout = 1;
|
|
g->grid.needsHorizLayout = False;
|
|
}
|
|
needsRedraw = 1;
|
|
}
|
|
}
|
|
if (NE(grid.scrollBarMargin) ||
|
|
NE(manager.shadow_thickness) ||
|
|
NE(core.border_width) ||
|
|
NE(grid.vsPolicy) ||
|
|
NE(grid.hsPolicy))
|
|
{
|
|
needsVertLayout = 1;
|
|
needsHorizLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.blankBg) ||
|
|
NE(grid.highlightThickness) ||
|
|
NE(grid.selectBg) ||
|
|
NE(grid.selectFg) ||
|
|
NE(grid.toggleTopColor) ||
|
|
NE(grid.toggleBotColor) ||
|
|
NE(grid.shadowRegions) ||
|
|
NE(grid.shadowType))
|
|
needsRedraw = 1;
|
|
if (NE(grid.fontList))
|
|
{
|
|
XmFontListFree(cur->grid.fontList);
|
|
CopyFontList(g);
|
|
cellValues = CellRefValuesCreate(g, g->grid.defCellValues);
|
|
cellValues->refCount = 1;
|
|
XmFontListFree(cellValues->fontList);
|
|
cellValues->fontList = XmFontListCopy(g->grid.fontList);
|
|
XmLFontListGetDimensions(cellValues->fontList,
|
|
&cellValues->fontWidth, &cellValues->fontHeight,
|
|
g->grid.useAvgWidth);
|
|
XmLGridCellDerefValues(g->grid.defCellValues);
|
|
g->grid.defCellValues = cellValues;
|
|
}
|
|
if (NE(grid.allowDrop))
|
|
DropRegister(g, g->grid.allowDrop);
|
|
if (g->grid.rowStep < 1)
|
|
{
|
|
XmLWarning(newW, "SetValues() - rowStep can't be < 1");
|
|
g->grid.rowStep = 1;
|
|
}
|
|
if (g->grid.colStep < 1)
|
|
{
|
|
XmLWarning(newW, "SetValues() - colStep can't be < 1");
|
|
g->grid.colStep = 1;
|
|
}
|
|
if (NE(grid.hsb) ||
|
|
NE(grid.vsb) ||
|
|
NE(grid.text))
|
|
{
|
|
XmLWarning(newW, "SetValues() - child Widgets are read-only");
|
|
g->grid.hsb = cur->grid.hsb;
|
|
g->grid.vsb = cur->grid.vsb;
|
|
g->grid.text = cur->grid.text;
|
|
}
|
|
if (NE(grid.useTextWidget))
|
|
{
|
|
XmLWarning(newW, "SetValues() - can't set use of text widget");
|
|
g->grid.useTextWidget = cur->grid.useTextWidget;
|
|
}
|
|
if (NE(grid.hiddenColCount) ||
|
|
NE(grid.hiddenRowCount))
|
|
{
|
|
XmLWarning(newW, "SetValues() - can't set hidden rows or columns");
|
|
g->grid.hiddenColCount = cur->grid.hiddenColCount;
|
|
g->grid.hiddenRowCount = cur->grid.hiddenRowCount;
|
|
}
|
|
|
|
/* store fixed counts, add/removing rows/columns can change these */
|
|
tfc = -1;
|
|
bfc = -1;
|
|
lfc = -1;
|
|
rfc = -1;
|
|
if (NE(grid.topFixedCount))
|
|
tfc = g->grid.topFixedCount;
|
|
if (NE(grid.bottomFixedCount))
|
|
bfc = g->grid.bottomFixedCount;
|
|
if (NE(grid.leftFixedCount))
|
|
lfc = g->grid.leftFixedCount;
|
|
if (NE(grid.rightFixedCount))
|
|
rfc = g->grid.rightFixedCount;
|
|
g->grid.topFixedCount = cur->grid.topFixedCount;
|
|
g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
|
|
g->grid.leftFixedCount = cur->grid.leftFixedCount;
|
|
g->grid.rightFixedCount = cur->grid.rightFixedCount;
|
|
|
|
hc = g->grid.headingColCount - cur->grid.headingColCount;
|
|
c = g->grid.colCount - cur->grid.colCount;
|
|
fc = g->grid.footerColCount - cur->grid.footerColCount;
|
|
hr = g->grid.headingRowCount - cur->grid.headingRowCount;
|
|
r = g->grid.rowCount - cur->grid.rowCount;
|
|
fr = g->grid.footerRowCount - cur->grid.footerRowCount;
|
|
g->grid.headingColCount = cur->grid.headingColCount;
|
|
g->grid.colCount = cur->grid.colCount;
|
|
g->grid.footerColCount = cur->grid.footerColCount;
|
|
g->grid.headingRowCount = cur->grid.headingRowCount;
|
|
g->grid.rowCount = cur->grid.rowCount;
|
|
g->grid.footerRowCount = cur->grid.footerRowCount;
|
|
if (hc > 0)
|
|
XmLGridAddColumns((Widget)g, XmHEADING, -1, hc);
|
|
if (hc < 0)
|
|
XmLGridDeleteColumns((Widget)g, XmHEADING,
|
|
g->grid.headingColCount + hc, -(hc));
|
|
if (c > 0)
|
|
XmLGridAddColumns((Widget)g, XmCONTENT, -1, c);
|
|
if (c < 0)
|
|
XmLGridDeleteColumns((Widget)g, XmCONTENT,
|
|
g->grid.colCount + c, -(c));
|
|
if (fc > 0)
|
|
XmLGridAddColumns((Widget)g, XmFOOTER, -1, fc);
|
|
if (fc < 0)
|
|
XmLGridDeleteColumns((Widget)g, XmFOOTER,
|
|
g->grid.footerColCount + fc, -(fc));
|
|
if (hr > 0)
|
|
XmLGridAddRows((Widget)g, XmHEADING, -1, hr);
|
|
if (hr < 0)
|
|
XmLGridDeleteRows((Widget)g, XmHEADING,
|
|
g->grid.headingRowCount + hr, -(hr));
|
|
if (r > 0)
|
|
XmLGridAddRows((Widget)g, XmCONTENT, -1, r);
|
|
if (r < 0)
|
|
XmLGridDeleteRows((Widget)g, XmCONTENT,
|
|
g->grid.rowCount + r, -(r));
|
|
if (fr > 0)
|
|
XmLGridAddRows((Widget)g, XmFOOTER, -1, fr);
|
|
if (fr < 0)
|
|
XmLGridDeleteRows((Widget)g, XmFOOTER,
|
|
g->grid.footerRowCount + fr, -(fr));
|
|
|
|
/* restore fixed counts if user specified */
|
|
if (tfc != -1)
|
|
g->grid.topFixedCount = tfc;
|
|
if (bfc != -1)
|
|
g->grid.bottomFixedCount = bfc;
|
|
if (lfc != -1)
|
|
g->grid.leftFixedCount = lfc;
|
|
if (rfc != -1)
|
|
g->grid.rightFixedCount = rfc;
|
|
|
|
if (g->grid.topFixedCount < g->grid.headingRowCount)
|
|
{
|
|
XmLWarning(newW,
|
|
"SetValues() - can't set topFixedCount < headingRowCount");
|
|
g->grid.topFixedCount = cur->grid.topFixedCount;
|
|
}
|
|
if (g->grid.bottomFixedCount < g->grid.footerRowCount)
|
|
{
|
|
XmLWarning(newW,
|
|
"SetValues() - can't set bottomFixedCount < footerRowCount");
|
|
g->grid.bottomFixedCount = cur->grid.bottomFixedCount;
|
|
}
|
|
if (g->grid.leftFixedCount < g->grid.headingColCount)
|
|
{
|
|
XmLWarning(newW,
|
|
"SetValues() - can't set leftFixedCount < headingColumnCount");
|
|
g->grid.leftFixedCount = cur->grid.leftFixedCount;
|
|
}
|
|
if (g->grid.rightFixedCount < g->grid.footerColCount)
|
|
{
|
|
XmLWarning(newW,
|
|
"SetValues() - can't set rightFixedCount < footerColumnCount");
|
|
g->grid.rightFixedCount = cur->grid.rightFixedCount;
|
|
}
|
|
|
|
if (NE(grid.simpleHeadings))
|
|
{
|
|
if (cur->grid.simpleHeadings)
|
|
free((char *)cur->grid.simpleHeadings);
|
|
if (g->grid.simpleHeadings)
|
|
{
|
|
g->grid.simpleHeadings = (char *)strdup(g->grid.simpleHeadings);
|
|
SetSimpleHeadings(g, g->grid.simpleHeadings);
|
|
}
|
|
}
|
|
if (NE(grid.simpleWidths))
|
|
{
|
|
if (cur->grid.simpleWidths)
|
|
free((char *)cur->grid.simpleWidths);
|
|
if (g->grid.simpleWidths)
|
|
{
|
|
g->grid.simpleWidths = (char *)strdup(g->grid.simpleWidths);
|
|
SetSimpleWidths(g, g->grid.simpleWidths);
|
|
}
|
|
}
|
|
if (NE(grid.visibleRows))
|
|
{
|
|
ApplyVisibleRows(g);
|
|
needsVertLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
if (NE(grid.visibleCols))
|
|
{
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
XmLGridSetVisibleColumnCount((Widget)g, g->grid.visibleCols);
|
|
else
|
|
ApplyVisibleCols(g);
|
|
needsHorizLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
|
|
/* for the hidden columns stuff */
|
|
if (NE(grid.hideUnhideButtons))
|
|
{
|
|
if (g->grid.hideUnhideButtons)
|
|
{
|
|
CreateHideUnhideButtons(g);
|
|
}
|
|
else
|
|
{
|
|
XtDestroyWidget(g->grid.hideButton);
|
|
XtDestroyWidget(g->grid.unhideButton);
|
|
g->grid.hideButton = 0;
|
|
g->grid.unhideButton = 0;
|
|
}
|
|
|
|
needsVertLayout = 1;
|
|
needsHorizLayout = 1;
|
|
needsRedraw = 1;
|
|
}
|
|
#undef NE
|
|
|
|
SetSubValues(newW, args, nargs);
|
|
|
|
if (needsVertLayout)
|
|
VertLayout(g, 1);
|
|
if (needsHorizLayout)
|
|
HorizLayout(g, 1);
|
|
if (needsRedraw)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
return (False);
|
|
}
|
|
|
|
static void
|
|
CopyFontList(XmLGridWidget g)
|
|
{
|
|
if (!g->grid.fontList)
|
|
g->grid.fontList = XmLFontListCopyDefault((Widget)g);
|
|
else
|
|
g->grid.fontList = XmFontListCopy(g->grid.fontList);
|
|
if (!g->grid.fontList)
|
|
XmLWarning((Widget)g, "- fatal error - font list NULL");
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToSizePolicy(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "CONSTANT", XmCONSTANT },
|
|
{ "VARIABLE", XmVARIABLE },
|
|
{ "RESIZE_IF_POSSIBLE", XmRESIZE_IF_POSSIBLE },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRGridSizePolicy", map, fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToRowColType(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "HEADING", XmHEADING },
|
|
{ "CONTENT", XmCONTENT },
|
|
{ "FOOTER", XmFOOTER },
|
|
{ "ALL_TYPES", XmALL_TYPES },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRRowColType", map, fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToSelectionPolicy(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "SELECT_NONE", XmSELECT_NONE },
|
|
{ "SELECT_SINGLE_ROW", XmSELECT_SINGLE_ROW },
|
|
{ "SELECT_BROWSE_ROW", XmSELECT_BROWSE_ROW },
|
|
{ "SELECT_MULTIPLE_ROW", XmSELECT_MULTIPLE_ROW },
|
|
{ "SELECT_CELL", XmSELECT_CELL },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRGridSelectionPolicy", map,
|
|
fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToCellAlignment(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "ALIGNMENT_LEFT", XmALIGNMENT_LEFT },
|
|
{ "ALIGNMENT_CENTER", XmALIGNMENT_CENTER },
|
|
{ "ALIGNMENT_RIGHT", XmALIGNMENT_RIGHT },
|
|
{ "ALIGNMENT_TOP_LEFT", XmALIGNMENT_TOP_LEFT },
|
|
{ "ALIGNMENT_TOP", XmALIGNMENT_TOP },
|
|
{ "ALIGNMENT_TOP_RIGHT", XmALIGNMENT_TOP_RIGHT },
|
|
{ "ALIGNMENT_BOTTOM_LEFT", XmALIGNMENT_BOTTOM_LEFT },
|
|
{ "ALIGNMENT_BOTTOM", XmALIGNMENT_BOTTOM },
|
|
{ "ALIGNMENT_BOTTOM_RIGHT", XmALIGNMENT_BOTTOM_RIGHT },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRGridCellAlignment", map,
|
|
fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToCellBorderType(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "BORDER_NONE", XmBORDER_NONE },
|
|
{ "BORDER_LINE", XmBORDER_LINE },
|
|
{ "BORDER_DASH", XmBORDER_DASH },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRGridCellBorderType", map,
|
|
fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToCellType(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "ICON_CELL", XmICON_CELL },
|
|
{ "STRING_CELL", XmSTRING_CELL },
|
|
{ "PIXMAP_CELL", XmPIXMAP_CELL },
|
|
{ "TOGGLE_CELL", XmTOGGLE_CELL },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRGridCellType", map, fromVal, toVal);
|
|
}
|
|
|
|
static void
|
|
SetSimpleHeadings(XmLGridWidget g,
|
|
char *data)
|
|
{
|
|
char *c;
|
|
int n, count;
|
|
|
|
if (!data || !*data)
|
|
return;
|
|
c = data;
|
|
n = 1;
|
|
while (*c)
|
|
{
|
|
if (*c == '|')
|
|
n++;
|
|
c++;
|
|
}
|
|
count = XmLArrayGetCount(g->grid.colArray);
|
|
if (n > count)
|
|
{
|
|
XmLWarning((Widget)g,
|
|
"SetSimpleHeadings() - headings given for non-existing columns");
|
|
return;
|
|
}
|
|
if (g->grid.headingRowCount < 1)
|
|
{
|
|
XmLWarning((Widget)g, "SetSimpleHeadings() - no heading row exists");
|
|
return;
|
|
}
|
|
XmLGridSetStrings((Widget)g, data);
|
|
}
|
|
|
|
static void
|
|
SetSimpleWidths(XmLGridWidget g,
|
|
char *data)
|
|
{
|
|
XmLGridColumn colp;
|
|
int i, n, colCount, valid;
|
|
Dimension prevWidth;
|
|
unsigned char prevSizePolicy;
|
|
long mask;
|
|
struct WidthRec
|
|
{
|
|
Dimension width;
|
|
unsigned char sizePolicy;
|
|
} *widths;
|
|
|
|
if (!data)
|
|
return;
|
|
i = ((int)strlen(data) / 2) + 1;
|
|
widths = (struct WidthRec *)malloc(i * sizeof(struct WidthRec));
|
|
valid = 1;
|
|
n = 0;
|
|
while (*data)
|
|
{
|
|
if (*data >= '0' && *data <= '9')
|
|
{
|
|
widths[n].width = atoi(data);
|
|
while (*data >= '0' && *data <= '9')
|
|
data++;
|
|
}
|
|
else
|
|
{
|
|
valid = 0;
|
|
break;
|
|
}
|
|
if (*data == 'c' || *data == 'C')
|
|
{
|
|
widths[n].sizePolicy = XmVARIABLE;
|
|
data++;
|
|
}
|
|
else if (*data == 'p' || *data == 'P')
|
|
{
|
|
widths[n].sizePolicy = XmCONSTANT;
|
|
data++;
|
|
}
|
|
else
|
|
{
|
|
valid = 0;
|
|
break;
|
|
}
|
|
while (*data == ' ')
|
|
data++;
|
|
n++;
|
|
}
|
|
if (!valid)
|
|
{
|
|
free((char *)widths);
|
|
XmLWarning((Widget)g, "SetSimpleWidths() - invalid widths string");
|
|
return;
|
|
}
|
|
colCount = XmLArrayGetCount(g->grid.colArray);
|
|
if (n > colCount)
|
|
{
|
|
free((char *)widths);
|
|
XmLWarning((Widget)g,
|
|
"SetSimpleWidths() - widths given for non-existing columns");
|
|
return;
|
|
}
|
|
prevWidth = g->grid.colWidth;
|
|
prevSizePolicy = g->grid.colSizePolicy;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
if (!colp)
|
|
continue;
|
|
GetColumnValueMask(g, XmNcolumnWidth, &mask);
|
|
GetColumnValueMask(g, XmNcolumnSizePolicy, &mask);
|
|
g->grid.colWidth = widths[i].width;
|
|
g->grid.colSizePolicy = widths[i].sizePolicy;
|
|
SetColumnValues(g, colp, mask);
|
|
}
|
|
free((char *)widths);
|
|
g->grid.colWidth = prevWidth;
|
|
g->grid.colSizePolicy = prevSizePolicy;
|
|
HorizLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
/*
|
|
Getting and Setting Row Values
|
|
*/
|
|
|
|
static void
|
|
GetRowValueMask(XmLGridWidget g,
|
|
char *s,
|
|
long *mask)
|
|
{
|
|
XmLGridClassPartOfWidget(g).getRowValueMaskProc(g, s, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GetRowValueMask(XmLGridWidget g,
|
|
char *s,
|
|
long *mask)
|
|
{
|
|
static XrmQuark qHeight, qSizePolicy, qUserData;
|
|
static int quarksValid = 0;
|
|
XrmQuark q;
|
|
|
|
if (!quarksValid)
|
|
{
|
|
qHeight = XrmStringToQuark(XmNrowHeight);
|
|
qSizePolicy = XrmStringToQuark(XmNrowSizePolicy);
|
|
qUserData = XrmStringToQuark(XmNrowUserData);
|
|
quarksValid = 1;
|
|
}
|
|
q = XrmStringToQuark(s);
|
|
if (q == qHeight)
|
|
*mask |= XmLGridRowHeight;
|
|
else if (q == qSizePolicy)
|
|
*mask |= XmLGridRowSizePolicy;
|
|
else if (q == qUserData)
|
|
*mask |= XmLGridRowUserData;
|
|
}
|
|
|
|
static void
|
|
GetRowValue(XmLGridWidget g,
|
|
XmLGridRow row,
|
|
XtArgVal value,
|
|
long mask)
|
|
{
|
|
XmLGridClassPartOfWidget(g).getRowValueProc(g, row, value, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GetRowValue(XmLGridWidget g,
|
|
XmLGridRow row,
|
|
XtArgVal value,
|
|
long mask)
|
|
{
|
|
switch (mask)
|
|
{
|
|
case XmLGridRowHeight:
|
|
*((Dimension *)value) = row->grid.height;
|
|
break;
|
|
case XmLGridRowSizePolicy:
|
|
*((unsigned char *)value) = row->grid.sizePolicy;
|
|
break;
|
|
case XmLGridRowUserData:
|
|
*((XtPointer *)value) = (XtPointer)row->grid.userData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int
|
|
SetRowValues(XmLGridWidget g,
|
|
XmLGridRow row,
|
|
long mask)
|
|
{
|
|
return XmLGridClassPartOfWidget(g).setRowValuesProc(g, row, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static int
|
|
_SetRowValues(XmLGridWidget g, XmLGridRow row, long mask)
|
|
{
|
|
int needsResize = 0, visible = 0;
|
|
Boolean newIsHidden;
|
|
|
|
if (mask & XmLGridRowHeight || mask & XmLGridRowSizePolicy)
|
|
{
|
|
visible = RowIsVisible(g, XmLGridRowGetPos(row));
|
|
XmLGridRowHeightChanged(row);
|
|
}
|
|
if (mask & XmLGridRowHeight)
|
|
{
|
|
if (g->grid.rowHeight > 0)
|
|
newIsHidden = False;
|
|
else
|
|
newIsHidden = True;
|
|
if (XmLGridRowIsHidden(row) != newIsHidden)
|
|
{
|
|
if (newIsHidden == True)
|
|
g->grid.hiddenRowCount++;
|
|
else
|
|
g->grid.hiddenRowCount--;
|
|
VisPosChanged(g, 1);
|
|
needsResize = 1;
|
|
}
|
|
if (visible && !g->grid.inResize)
|
|
needsResize = 1;
|
|
row->grid.height = g->grid.rowHeight;
|
|
}
|
|
if (mask & XmLGridRowSizePolicy)
|
|
{
|
|
row->grid.sizePolicy = g->grid.rowSizePolicy;
|
|
if (visible && !g->grid.inResize)
|
|
needsResize = 1;
|
|
}
|
|
if (mask & XmLGridRowUserData)
|
|
row->grid.userData = g->grid.rowUserData;
|
|
return needsResize;
|
|
}
|
|
|
|
/*
|
|
Getting and Setting Column Values
|
|
*/
|
|
|
|
static void
|
|
GetColumnValueMask(XmLGridWidget g,
|
|
char *s,
|
|
long *mask)
|
|
{
|
|
XmLGridClassPartOfWidget(g).getColumnValueMaskProc(g, s, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GetColumnValueMask(XmLGridWidget g,
|
|
char *s,
|
|
long *mask)
|
|
{
|
|
static XrmQuark qWidth, qSizePolicy, qUserData, qResizable;
|
|
static XrmQuark qHidden, qSortType;
|
|
static int quarksValid = 0;
|
|
XrmQuark q;
|
|
|
|
if (!quarksValid)
|
|
{
|
|
qWidth = XrmStringToQuark(XmNcolumnWidth);
|
|
qSizePolicy = XrmStringToQuark(XmNcolumnSizePolicy);
|
|
qUserData = XrmStringToQuark(XmNcolumnUserData);
|
|
qResizable = XrmStringToQuark(XmNcolumnResizable);
|
|
qHidden = XrmStringToQuark(XmNcolumnHidden);
|
|
qSortType = XrmStringToQuark(XmNcolumnSortType);
|
|
quarksValid = 1;
|
|
}
|
|
q = XrmStringToQuark(s);
|
|
if (q == qWidth)
|
|
*mask |= XmLGridColumnWidth;
|
|
else if (q == qSizePolicy)
|
|
*mask |= XmLGridColumnSizePolicy;
|
|
else if (q == qUserData)
|
|
*mask |= XmLGridColumnUserData;
|
|
else if (q == qResizable)
|
|
*mask |= XmLGridColumnResizable;
|
|
else if (q == qHidden)
|
|
*mask |= XmLGridColumnHidden;
|
|
else if (q == qSortType)
|
|
*mask |= XmLGridColumnSortType;
|
|
}
|
|
|
|
static void
|
|
GetColumnValue(XmLGridWidget g,
|
|
XmLGridColumn col,
|
|
XtArgVal value,
|
|
long mask)
|
|
{
|
|
XmLGridClassPartOfWidget(g).getColumnValueProc(g, col, value, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GetColumnValue(XmLGridWidget g,
|
|
XmLGridColumn col,
|
|
XtArgVal value,
|
|
long mask)
|
|
{
|
|
switch (mask)
|
|
{
|
|
case XmLGridColumnWidth:
|
|
*((Dimension *)value) = col->grid.width;
|
|
break;
|
|
case XmLGridColumnSizePolicy:
|
|
*((unsigned char *)value) = col->grid.sizePolicy;
|
|
break;
|
|
case XmLGridColumnUserData:
|
|
*((XtPointer *)value) = col->grid.userData;
|
|
break;
|
|
case XmLGridColumnResizable:
|
|
*((Boolean *)value) = col->grid.resizable;
|
|
break;
|
|
case XmLGridColumnHidden:
|
|
*((Boolean *)value) = col->grid.hidden;
|
|
break;
|
|
case XmLGridColumnSortType:
|
|
*((unsigned char *)value) = col->grid.sort;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
static int
|
|
SetColumnValues(XmLGridWidget g,
|
|
XmLGridColumn col,
|
|
long mask)
|
|
{
|
|
return XmLGridClassPartOfWidget(g).setColumnValuesProc(g, col, mask);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static int
|
|
_SetColumnValues(XmLGridWidget g, XmLGridColumn col, long mask)
|
|
{
|
|
int needsResize = 0, visible = 0;
|
|
Boolean newIsHidden;
|
|
|
|
if (mask & XmLGridColumnWidth || mask & XmLGridColumnSizePolicy)
|
|
{
|
|
visible = ColIsVisible(g, XmLGridColumnGetPos(col));
|
|
XmLGridColumnWidthChanged(col);
|
|
}
|
|
if (mask & XmLGridColumnWidth)
|
|
{
|
|
if (g->grid.colWidth > 0)
|
|
newIsHidden = False;
|
|
else
|
|
newIsHidden = True;
|
|
if (XmLGridColumnIsHidden(col) != newIsHidden)
|
|
{
|
|
if (newIsHidden == True)
|
|
g->grid.hiddenColCount++;
|
|
else
|
|
g->grid.hiddenRowCount--;
|
|
VisPosChanged(g, 0);
|
|
needsResize = 1;
|
|
}
|
|
if (visible && !g->grid.inResize)
|
|
needsResize = 1;
|
|
col->grid.width = g->grid.colWidth;
|
|
}
|
|
if (mask & XmLGridColumnSizePolicy)
|
|
{
|
|
col->grid.sizePolicy = g->grid.colSizePolicy;
|
|
if (visible && !g->grid.inResize)
|
|
needsResize = 1;
|
|
if (col->grid.sizePolicy != XmCONSTANT
|
|
&& g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
{
|
|
XmLWarning((Widget)g, "XmNcolumnSizePolicy must equal XmCONSTANT");
|
|
}
|
|
}
|
|
if (mask & XmLGridColumnUserData)
|
|
col->grid.userData = g->grid.colUserData;
|
|
if (mask & XmLGridColumnResizable)
|
|
col->grid.resizable = g->grid.colResizable;
|
|
if (mask & XmLGridColumnHidden)
|
|
col->grid.hidden = g->grid.colHidden;
|
|
if (mask & XmLGridColumnSortType)
|
|
XmLGridSetSort((Widget)g, XmLGridColumnGetPos(col), g->grid.colSortType);
|
|
return needsResize;
|
|
}
|
|
|
|
/*
|
|
Getting and Setting Cell Values
|
|
*/
|
|
|
|
static void
|
|
CellValueGetMask(char *s,
|
|
long *mask)
|
|
{
|
|
static XrmQuark qAlignment, qBackground, qBottomBorderColor;
|
|
static XrmQuark qBottomBorderType, qColumnSpan;
|
|
static XrmQuark qEditable, qFontList, qForeground;
|
|
static XrmQuark qLeftBorderColor, qLeftBorderType;
|
|
static XrmQuark qMarginBottom, qMarginLeft, qMarginRight;
|
|
static XrmQuark qMarginTop, qPixmap, qPixmapMask;
|
|
static XrmQuark qRightBorderColor, qRightBorderType;
|
|
static XrmQuark qRowSpan, qString, qToggleSet;
|
|
static XrmQuark qTopBorderColor, qTopBorderType, qType;
|
|
static XrmQuark qUserData;
|
|
static int quarksValid = 0;
|
|
XrmQuark q;
|
|
|
|
if (!quarksValid)
|
|
{
|
|
qAlignment = XrmStringToQuark(XmNcellAlignment);
|
|
qBackground = XrmStringToQuark(XmNcellBackground);
|
|
qBottomBorderColor = XrmStringToQuark(XmNcellBottomBorderColor);
|
|
qBottomBorderType = XrmStringToQuark(XmNcellBottomBorderType);
|
|
qColumnSpan = XrmStringToQuark(XmNcellColumnSpan);
|
|
qEditable = XrmStringToQuark(XmNcellEditable);
|
|
qFontList = XrmStringToQuark(XmNcellFontList);
|
|
qForeground = XrmStringToQuark(XmNcellForeground);
|
|
qLeftBorderColor = XrmStringToQuark(XmNcellLeftBorderColor);
|
|
qLeftBorderType = XrmStringToQuark(XmNcellLeftBorderType);
|
|
qMarginBottom = XrmStringToQuark(XmNcellMarginBottom);
|
|
qMarginLeft = XrmStringToQuark(XmNcellMarginLeft);
|
|
qMarginRight = XrmStringToQuark(XmNcellMarginRight);
|
|
qMarginTop= XrmStringToQuark(XmNcellMarginTop);
|
|
qPixmap = XrmStringToQuark(XmNcellPixmap);
|
|
qPixmapMask = XrmStringToQuark(XmNcellPixmapMask);
|
|
qRightBorderColor = XrmStringToQuark(XmNcellRightBorderColor);
|
|
qRightBorderType = XrmStringToQuark(XmNcellRightBorderType);
|
|
qRowSpan = XrmStringToQuark(XmNcellRowSpan);
|
|
qString = XrmStringToQuark(XmNcellString);
|
|
qToggleSet = XrmStringToQuark(XmNcellToggleSet);
|
|
qTopBorderColor = XrmStringToQuark(XmNcellTopBorderColor);
|
|
qTopBorderType = XrmStringToQuark(XmNcellTopBorderType);
|
|
qType = XrmStringToQuark(XmNcellType);
|
|
qUserData = XrmStringToQuark(XmNcellUserData);
|
|
quarksValid = 1;
|
|
}
|
|
q = XrmStringToQuark(s);
|
|
if (q == qAlignment)
|
|
*mask |= XmLGridCellAlignment;
|
|
else if (q == qBackground)
|
|
*mask |= XmLGridCellBackground;
|
|
else if (q == qBottomBorderColor)
|
|
*mask |= XmLGridCellBottomBorderColor;
|
|
else if (q == qBottomBorderType)
|
|
*mask |= XmLGridCellBottomBorderType;
|
|
else if (q == qColumnSpan)
|
|
*mask |= XmLGridCellColumnSpan;
|
|
else if (q == qEditable)
|
|
*mask |= XmLGridCellEditable;
|
|
else if (q == qFontList)
|
|
*mask |= XmLGridCellFontList;
|
|
else if (q == qForeground)
|
|
*mask |= XmLGridCellForeground;
|
|
else if (q == qLeftBorderColor)
|
|
*mask |= XmLGridCellLeftBorderColor;
|
|
else if (q == qLeftBorderType)
|
|
*mask |= XmLGridCellLeftBorderType;
|
|
else if (q == qMarginBottom)
|
|
*mask |= XmLGridCellMarginBottom;
|
|
else if (q == qMarginLeft)
|
|
*mask |= XmLGridCellMarginLeft;
|
|
else if (q == qMarginRight)
|
|
*mask |= XmLGridCellMarginRight;
|
|
else if (q == qMarginTop)
|
|
*mask |= XmLGridCellMarginTop;
|
|
else if (q == qPixmap)
|
|
*mask |= XmLGridCellPixmapF;
|
|
else if (q == qPixmapMask)
|
|
*mask |= XmLGridCellPixmapMask;
|
|
else if (q == qRightBorderColor)
|
|
*mask |= XmLGridCellRightBorderColor;
|
|
else if (q == qRightBorderType)
|
|
*mask |= XmLGridCellRightBorderType;
|
|
else if (q == qRowSpan)
|
|
*mask |= XmLGridCellRowSpan;
|
|
else if (q == qString)
|
|
*mask |= XmLGridCellString;
|
|
else if (q == qToggleSet)
|
|
*mask |= XmLGridCellToggleSet;
|
|
else if (q == qTopBorderColor)
|
|
*mask |= XmLGridCellTopBorderColor;
|
|
else if (q == qTopBorderType)
|
|
*mask |= XmLGridCellTopBorderType;
|
|
else if (q == qType)
|
|
*mask |= XmLGridCellType;
|
|
else if (q == qUserData)
|
|
*mask |= XmLGridCellUserData;
|
|
}
|
|
|
|
static void
|
|
GetCellValue(XmLGridCell cell,
|
|
XtArgVal value,
|
|
long mask)
|
|
{
|
|
XmLGridCellRefValues *values;
|
|
XmLGridCellPixmap *pix;
|
|
XmString str;
|
|
|
|
values = XmLGridCellGetRefValues(cell);
|
|
switch (mask)
|
|
{
|
|
case XmLGridCellAlignment:
|
|
*((unsigned char *)value) = values->alignment;
|
|
break;
|
|
case XmLGridCellBackground:
|
|
*((Pixel *)value) = values->background;
|
|
break;
|
|
case XmLGridCellBottomBorderColor:
|
|
*((Pixel *)value) = values->bottomBorderColor;
|
|
break;
|
|
case XmLGridCellBottomBorderType:
|
|
*((unsigned char *)value) = values->bottomBorderType;
|
|
break;
|
|
case XmLGridCellColumnSpan:
|
|
*((int *)value) = values->columnSpan;
|
|
break;
|
|
case XmLGridCellEditable:
|
|
*((Boolean *)value) = values->editable;
|
|
break;
|
|
case XmLGridCellFontList:
|
|
*((XmFontList *)value) = values->fontList;
|
|
break;
|
|
case XmLGridCellForeground:
|
|
*((Pixel *)value) = values->foreground;
|
|
break;
|
|
case XmLGridCellLeftBorderColor:
|
|
*((Pixel *)value) = values->leftBorderColor;
|
|
break;
|
|
case XmLGridCellLeftBorderType:
|
|
*((unsigned char *)value) = values->leftBorderType;
|
|
break;
|
|
case XmLGridCellMarginBottom:
|
|
*((Dimension *)value) = values->bottomMargin;
|
|
break;
|
|
case XmLGridCellMarginLeft:
|
|
*((Dimension *)value) = values->leftMargin;
|
|
break;
|
|
case XmLGridCellMarginRight:
|
|
*((Dimension *)value) = values->rightMargin;
|
|
break;
|
|
case XmLGridCellMarginTop:
|
|
*((Dimension *)value) = values->topMargin;
|
|
break;
|
|
case XmLGridCellPixmapF:
|
|
pix = XmLGridCellGetPixmap(cell);
|
|
if (pix)
|
|
*((Pixmap *)value) = pix->pixmap;
|
|
else
|
|
*((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
|
|
break;
|
|
case XmLGridCellPixmapMask:
|
|
pix = XmLGridCellGetPixmap(cell);
|
|
if (pix)
|
|
*((Pixmap *)value) = pix->pixmask;
|
|
else
|
|
*((Pixmap *)value) = (Pixmap)XmUNSPECIFIED_PIXMAP;
|
|
break;
|
|
case XmLGridCellRightBorderColor:
|
|
*((Pixel *)value) = values->rightBorderColor;
|
|
break;
|
|
case XmLGridCellRightBorderType:
|
|
*((unsigned char *)value) = values->rightBorderType;
|
|
break;
|
|
case XmLGridCellRowSpan:
|
|
*((int *)value) = values->rowSpan;
|
|
break;
|
|
case XmLGridCellString:
|
|
str = XmLGridCellGetString(cell);
|
|
if (str)
|
|
*((XmString *)value) = XmStringCopy(str);
|
|
else
|
|
*((XmString *)value) = 0;
|
|
break;
|
|
case XmLGridCellToggleSet:
|
|
*((Boolean *)value) = XmLGridCellGetToggle(cell);
|
|
break;
|
|
case XmLGridCellTopBorderColor:
|
|
*((Pixel *)value) = values->topBorderColor;
|
|
break;
|
|
case XmLGridCellTopBorderType:
|
|
*((unsigned char *)value) = values->topBorderType;
|
|
break;
|
|
case XmLGridCellType:
|
|
*((unsigned char *)value) = values->type;
|
|
break;
|
|
case XmLGridCellUserData:
|
|
*((XtPointer *)value) = (XtPointer)values->userData;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static XmLGridCellRefValues *
|
|
CellRefValuesCreate(XmLGridWidget g,
|
|
XmLGridCellRefValues *copy)
|
|
{
|
|
short width, height;
|
|
XmLGridCellRefValues *values;
|
|
|
|
values = (XmLGridCellRefValues *)malloc(sizeof(XmLGridCellRefValues));
|
|
if (!copy)
|
|
{
|
|
/* default values */
|
|
values->bottomBorderType = XmBORDER_LINE;
|
|
values->leftBorderType = XmBORDER_LINE;
|
|
values->rightBorderType = XmBORDER_LINE;
|
|
values->topBorderType = XmBORDER_LINE;
|
|
XmLFontListGetDimensions(g->grid.fontList, &width, &height,
|
|
g->grid.useAvgWidth);
|
|
values->alignment = XmALIGNMENT_CENTER;
|
|
values->background = g->core.background_pixel;
|
|
values->bottomBorderColor = g->manager.bottom_shadow_color;
|
|
values->bottomMargin = 0;
|
|
values->columnSpan = 0;
|
|
values->editable = False;
|
|
values->fontHeight = height;
|
|
values->fontList = XmFontListCopy(g->grid.fontList);
|
|
values->fontWidth = width;
|
|
values->foreground = g->manager.foreground;
|
|
values->leftBorderColor = g->manager.top_shadow_color;
|
|
values->leftMargin = 0;
|
|
values->refCount = 0;
|
|
values->rightBorderColor = g->manager.bottom_shadow_color;
|
|
values->rightMargin = 0;
|
|
values->rowSpan = 0;
|
|
values->topBorderColor = g->manager.top_shadow_color;
|
|
values->topMargin = 0;
|
|
values->type = XmSTRING_CELL;
|
|
values->userData = 0;
|
|
}
|
|
else
|
|
{
|
|
/* copy values */
|
|
*values = *copy;
|
|
values->fontList = XmFontListCopy(copy->fontList);
|
|
values->refCount = 0;
|
|
}
|
|
return values;
|
|
}
|
|
|
|
static void
|
|
SetCellValuesPreprocess(XmLGridWidget g,
|
|
long mask)
|
|
{
|
|
XmLGridCellRefValues *newValues;
|
|
int x, y;
|
|
short width, height;
|
|
Display *dpy;
|
|
Window pixRoot;
|
|
unsigned int pixWidth, pixHeight;
|
|
unsigned int pixBW, pixDepth;
|
|
|
|
/* calculate font width and height if set */
|
|
newValues = &g->grid.cellValues;
|
|
if (mask & XmLGridCellFontList)
|
|
{
|
|
XmLFontListGetDimensions(newValues->fontList, &width, &height,
|
|
g->grid.useAvgWidth);
|
|
newValues->fontWidth = width;
|
|
newValues->fontHeight = height;
|
|
}
|
|
if (mask & XmLGridCellPixmapF)
|
|
{
|
|
if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP &&
|
|
g->grid.globalPixmapWidth &&
|
|
g->grid.globalPixmapHeight)
|
|
{
|
|
g->grid.cellPixmapWidth = g->grid.globalPixmapWidth;
|
|
g->grid.cellPixmapHeight = g->grid.globalPixmapHeight;
|
|
}
|
|
else if (g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
dpy = XtDisplay(g);
|
|
XGetGeometry(dpy, g->grid.cellPixmap, &pixRoot,
|
|
&x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
|
|
g->grid.cellPixmapWidth = (Dimension)pixWidth;
|
|
g->grid.cellPixmapHeight = (Dimension)pixHeight;
|
|
}
|
|
else
|
|
{
|
|
g->grid.cellPixmapWidth = 0;
|
|
g->grid.cellPixmapHeight = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int
|
|
SetCellHasRefValues(long mask)
|
|
{
|
|
long unrefMask;
|
|
|
|
/* return 1 if mask contains any reference counted values */
|
|
unrefMask = XmLGridCellPixmapF | XmLGridCellPixmapMask |
|
|
XmLGridCellString | XmLGridCellToggleSet;
|
|
mask = mask | unrefMask;
|
|
mask = mask ^ unrefMask;
|
|
if (!mask)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
SetCellValuesResize(XmLGridWidget g,
|
|
XmLGridRow row,
|
|
XmLGridColumn col,
|
|
XmLGridCell cell,
|
|
long mask)
|
|
{
|
|
return XmLGridClassPartOfWidget(g).setCellValuesResizeProc(g, row, col,
|
|
cell, mask);
|
|
}
|
|
|
|
static int
|
|
_SetCellValuesResize(XmLGridWidget g,
|
|
XmLGridRow row,
|
|
XmLGridColumn col,
|
|
XmLGridCell cell,
|
|
long mask)
|
|
{
|
|
XmLGridCellPixmap *cellPix;
|
|
int pixResize, needsResize, rowVisible, colVisible;
|
|
|
|
needsResize = 0;
|
|
pixResize = 0;
|
|
if (mask & XmLGridCellPixmapF)
|
|
{
|
|
pixResize = 1;
|
|
if (!(mask & XmLGridCellType))
|
|
{
|
|
/* no resize needed if we replace with an equal size pixmap */
|
|
cellPix = XmLGridCellGetPixmap(cell);
|
|
if (cellPix && cellPix->pixmap != XmUNSPECIFIED_PIXMAP &&
|
|
g->grid.cellPixmap != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
if (cellPix->width == g->grid.cellPixmapWidth &&
|
|
cellPix->height == g->grid.cellPixmapHeight)
|
|
pixResize = 0;
|
|
}
|
|
}
|
|
}
|
|
if (mask & XmLGridCellType || mask & XmLGridCellFontList || pixResize ||
|
|
mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan ||
|
|
mask & XmLGridCellMarginLeft || mask & XmLGridCellMarginRight ||
|
|
mask & XmLGridCellMarginTop || mask & XmLGridCellMarginBottom)
|
|
{
|
|
XmLGridRowHeightChanged(row);
|
|
XmLGridColumnWidthChanged(col);
|
|
rowVisible = RowIsVisible(g, XmLGridRowGetPos(row));
|
|
colVisible = ColIsVisible(g, XmLGridColumnGetPos(col));
|
|
if (rowVisible | colVisible)
|
|
needsResize = 1;
|
|
}
|
|
return needsResize;
|
|
}
|
|
|
|
static void
|
|
SetCellValues(XmLGridWidget g,
|
|
XmLGridCell cell,
|
|
long mask)
|
|
{
|
|
/* set non-reference counted cell values */
|
|
if (mask & XmLGridCellPixmapF)
|
|
XmLGridCellSetPixmap(cell, g->grid.cellPixmap,
|
|
g->grid.cellPixmapWidth, g->grid.cellPixmapHeight);
|
|
if (mask & XmLGridCellPixmapMask)
|
|
XmLGridCellSetPixmask(cell, g->grid.cellPixmapMask);
|
|
if (mask & XmLGridCellString)
|
|
XmLGridCellSetString(cell, g->grid.cellString, True);
|
|
if (mask & XmLGridCellToggleSet)
|
|
XmLGridCellSetToggle(cell, g->grid.cellToggleSet);
|
|
}
|
|
|
|
static void
|
|
SetCellRefValues(XmLGridWidget g,
|
|
XmLGridCellRefValues *values,
|
|
long mask)
|
|
{
|
|
XmLGridCellRefValues *newValues;
|
|
|
|
/* set reference counted cell values */
|
|
newValues = &g->grid.cellValues;
|
|
if (mask & XmLGridCellAlignment)
|
|
values->alignment = newValues->alignment;
|
|
if (mask & XmLGridCellBackground)
|
|
values->background = newValues->background;
|
|
if (mask & XmLGridCellBottomBorderColor)
|
|
values->bottomBorderColor = newValues->bottomBorderColor;
|
|
if (mask & XmLGridCellBottomBorderType)
|
|
values->bottomBorderType = newValues->bottomBorderType;
|
|
if (mask & XmLGridCellColumnSpan)
|
|
values->columnSpan = newValues->columnSpan;
|
|
if (mask & XmLGridCellEditable)
|
|
values->editable = newValues->editable;
|
|
if (mask & XmLGridCellFontList)
|
|
{
|
|
XmFontListFree(values->fontList);
|
|
values->fontList = XmFontListCopy(newValues->fontList);
|
|
values->fontWidth = newValues->fontWidth;
|
|
values->fontHeight = newValues->fontHeight;
|
|
}
|
|
if (mask & XmLGridCellForeground)
|
|
values->foreground = newValues->foreground;
|
|
if (mask & XmLGridCellLeftBorderColor)
|
|
values->leftBorderColor = newValues->leftBorderColor;
|
|
if (mask & XmLGridCellLeftBorderType)
|
|
values->leftBorderType = newValues->leftBorderType;
|
|
if (mask & XmLGridCellRightBorderColor)
|
|
values->rightBorderColor = newValues->rightBorderColor;
|
|
if (mask & XmLGridCellRightBorderType)
|
|
values->rightBorderType = newValues->rightBorderType;
|
|
if (mask & XmLGridCellMarginBottom)
|
|
values->bottomMargin = newValues->bottomMargin;
|
|
if (mask & XmLGridCellMarginLeft)
|
|
values->leftMargin = newValues->leftMargin;
|
|
if (mask & XmLGridCellMarginRight)
|
|
values->rightMargin = newValues->rightMargin;
|
|
if (mask & XmLGridCellMarginTop)
|
|
values->topMargin = newValues->topMargin;
|
|
if (mask & XmLGridCellRowSpan)
|
|
values->rowSpan = newValues->rowSpan;
|
|
if (mask & XmLGridCellTopBorderColor)
|
|
values->topBorderColor = newValues->topBorderColor;
|
|
if (mask & XmLGridCellTopBorderType)
|
|
values->topBorderType = newValues->topBorderType;
|
|
if (mask & XmLGridCellType)
|
|
{
|
|
values->type = newValues->type;
|
|
/* backwards compatibility cell types */
|
|
if (values->type == XmLABEL_CELL)
|
|
{
|
|
values->type = XmSTRING_CELL;
|
|
values->editable = False;
|
|
}
|
|
else if (values->type == XmTEXT_CELL)
|
|
{
|
|
values->type = XmSTRING_CELL;
|
|
values->editable = True;
|
|
}
|
|
}
|
|
if (mask & XmLGridCellUserData)
|
|
values->userData = newValues->userData;
|
|
}
|
|
|
|
static int
|
|
SetCellRefValuesCompare(void *userData,
|
|
void **item1,
|
|
void **item2)
|
|
{
|
|
XmLGridCell cell1, cell2;
|
|
XmLGridCellRefValues *values1, *values2;
|
|
long mask;
|
|
|
|
mask = *((long *)userData);
|
|
cell1 = (XmLGridCell)*item1;
|
|
cell2 = (XmLGridCell)*item2;
|
|
values1 = XmLGridCellGetRefValues(cell1);
|
|
values2 = XmLGridCellGetRefValues(cell2);
|
|
if (values1 == values2)
|
|
return 0;
|
|
|
|
#define RVCOMPARE(res, var) \
|
|
if (!(mask & res)) \
|
|
{ \
|
|
if (values1->var < values2->var) \
|
|
return -1; \
|
|
if (values1->var > values2->var) \
|
|
return 1; \
|
|
}
|
|
RVCOMPARE(XmLGridCellAlignment, alignment)
|
|
RVCOMPARE(XmLGridCellBackground, background)
|
|
RVCOMPARE(XmLGridCellBottomBorderColor, bottomBorderColor)
|
|
RVCOMPARE(XmLGridCellBottomBorderType, bottomBorderType)
|
|
RVCOMPARE(XmLGridCellColumnSpan, columnSpan)
|
|
RVCOMPARE(XmLGridCellEditable, editable)
|
|
RVCOMPARE(XmLGridCellFontList, fontList)
|
|
RVCOMPARE(XmLGridCellForeground, foreground)
|
|
RVCOMPARE(XmLGridCellLeftBorderColor, leftBorderColor)
|
|
RVCOMPARE(XmLGridCellLeftBorderType, leftBorderType)
|
|
RVCOMPARE(XmLGridCellMarginBottom, bottomMargin)
|
|
RVCOMPARE(XmLGridCellMarginLeft, leftMargin)
|
|
RVCOMPARE(XmLGridCellMarginRight, rightMargin)
|
|
RVCOMPARE(XmLGridCellMarginTop, topMargin)
|
|
RVCOMPARE(XmLGridCellRightBorderColor, rightBorderColor)
|
|
RVCOMPARE(XmLGridCellRightBorderType, rightBorderType)
|
|
RVCOMPARE(XmLGridCellRowSpan, rowSpan)
|
|
RVCOMPARE(XmLGridCellTopBorderColor, topBorderColor)
|
|
RVCOMPARE(XmLGridCellTopBorderType, topBorderType)
|
|
RVCOMPARE(XmLGridCellType, type)
|
|
RVCOMPARE(XmLGridCellUserData, userData)
|
|
#undef RVCOMPARE
|
|
|
|
/* If the two cell values are equal, we merge them
|
|
into one record here. This speeds up the sort
|
|
and will allow the merge to compare just the values
|
|
pointers to test equality. Note that this will not
|
|
merge every possible item that could be merged, we
|
|
don't want to do that because of the performance impact */
|
|
if (values1 < values2)
|
|
XmLGridCellSetRefValues(cell1, values2);
|
|
else
|
|
XmLGridCellSetRefValues(cell2, values1);
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
SetCellRefValuesPreprocess(XmLGridWidget g,
|
|
int row,
|
|
int col,
|
|
XmLGridCell cell,
|
|
long mask)
|
|
{
|
|
int r, c, rowSpan, colSpan;
|
|
XmLGridCell spanCell;
|
|
XmLGridCellRefValues *oldValues, *newValues;
|
|
unsigned char oldType, newType;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
if (mask & XmLGridCellType)
|
|
{
|
|
oldType = XmLGridCellGetRefValues(cell)->type;
|
|
newType = g->grid.cellValues.type;
|
|
if (oldType != newType)
|
|
{
|
|
cbs.reason = XmCR_FREE_VALUE;
|
|
XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
}
|
|
}
|
|
if (mask & XmLGridCellRowSpan || mask & XmLGridCellColumnSpan)
|
|
{
|
|
/* expose old cell area in case the span area shrinks */
|
|
DrawArea(g, DrawCell, row, col);
|
|
oldValues = XmLGridCellGetRefValues(cell);
|
|
newValues = &g->grid.cellValues;
|
|
if (mask & XmLGridCellRowSpan)
|
|
{
|
|
g->grid.mayHaveRowSpans = 1;
|
|
if (newValues->rowSpan < 0)
|
|
{
|
|
XmLWarning((Widget)g,
|
|
"SetValues() - row span can't be < 0");
|
|
newValues->rowSpan = 0;
|
|
}
|
|
rowSpan = newValues->rowSpan;
|
|
}
|
|
else
|
|
rowSpan = oldValues->rowSpan;
|
|
if (mask & XmLGridCellColumnSpan)
|
|
{
|
|
if (newValues->columnSpan < 0)
|
|
{
|
|
XmLWarning((Widget)g,
|
|
"SetValues() - column span can't be < 0");
|
|
newValues->columnSpan = 0;
|
|
}
|
|
colSpan = newValues->columnSpan;
|
|
}
|
|
else
|
|
colSpan = oldValues->columnSpan;
|
|
/* clear old span */
|
|
for (c = col; c <= col + oldValues->columnSpan; c++)
|
|
for (r = row; r <= row + oldValues->rowSpan; r++)
|
|
{
|
|
/* skip the cell itself */
|
|
if (c == col && r == row)
|
|
continue;
|
|
spanCell = GetCell(g, r, c);
|
|
if (!spanCell)
|
|
continue;
|
|
XmLGridCellSetInRowSpan(spanCell, False);
|
|
XmLGridCellSetInColumnSpan(spanCell, False);
|
|
}
|
|
/* set new span */
|
|
for (c = col; c <= col + colSpan; c++)
|
|
for (r = row; r <= row + rowSpan; r++)
|
|
{
|
|
/* skip the cell itself */
|
|
if (c == col && r == row)
|
|
continue;
|
|
spanCell = GetCell(g, r, c);
|
|
if (!spanCell)
|
|
continue;
|
|
if (r == row)
|
|
XmLGridCellSetInColumnSpan(spanCell, True);
|
|
else
|
|
XmLGridCellSetInRowSpan(spanCell, True);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Read, Write, Copy, Paste
|
|
*/
|
|
|
|
static int
|
|
Read(XmLGridWidget g,
|
|
int format,
|
|
char delimiter,
|
|
int row,
|
|
int col,
|
|
char *data)
|
|
{
|
|
char *c1, *c2, buf[256], *bufp;
|
|
int r, c, i, j, len, n, needsResize, allowSet, done;
|
|
XmString str;
|
|
XmLGridCell cell;
|
|
XmLGridRow rowp;
|
|
XmLGridColumn colp;
|
|
XmLGridCellRefValues *cellValues;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
if (format == XmFORMAT_PAD)
|
|
{
|
|
XmLWarning((Widget)g, "Read() - FORMAT_PAD not supported");
|
|
return 0;
|
|
}
|
|
if (format == XmFORMAT_XL ||
|
|
format == XmFORMAT_DROP ||
|
|
format == XmFORMAT_PASTE)
|
|
delimiter = '\t';
|
|
c1 = data;
|
|
c2 = data;
|
|
r = row;
|
|
c = col;
|
|
needsResize = 0;
|
|
done = 0;
|
|
n = 0;
|
|
while (!done)
|
|
{
|
|
if (!(*c2) || *c2 == delimiter || *c2 == '\n')
|
|
{
|
|
len = c2 - c1;
|
|
if (len < 256)
|
|
bufp = buf;
|
|
else
|
|
bufp = (char *)malloc(len + 1);
|
|
if (format == XmFORMAT_XL)
|
|
{
|
|
/* strip leading and trailing double-quotes */
|
|
if (len && c1[0] == '"')
|
|
{
|
|
c1++;
|
|
len--;
|
|
}
|
|
if (len && c1[len - 1] == '"')
|
|
len--;
|
|
}
|
|
j = 0;
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (c1[0] == '\\' && c1[1] == 'n')
|
|
{
|
|
bufp[j++] = '\n';
|
|
c1 += 2;
|
|
i++;
|
|
}
|
|
else
|
|
bufp[j++] = *c1++;
|
|
}
|
|
bufp[j] = 0;
|
|
j = 0;
|
|
str = XmStringCreateLtoR(bufp, XmSTRING_DEFAULT_CHARSET);
|
|
if (bufp != buf)
|
|
free((char *)bufp);
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
cell = GetCell(g, r, c);
|
|
allowSet = 1;
|
|
if (cell && (format == XmFORMAT_PASTE || format == XmFORMAT_DROP))
|
|
{
|
|
cellValues = XmLGridCellGetRefValues(cell);
|
|
if (cellValues->type != XmSTRING_CELL ||
|
|
cellValues->editable != True ||
|
|
RowPosToType(g, r) != XmCONTENT ||
|
|
ColPosToType(g, c) != XmCONTENT)
|
|
allowSet = 0;
|
|
}
|
|
if (cell && allowSet)
|
|
{
|
|
XmLGridCellSetString(cell, str, False);
|
|
if (SetCellValuesResize(g, rowp, colp, cell, XmLGridCellString))
|
|
needsResize = 1;
|
|
if (!needsResize)
|
|
DrawArea(g, DrawCell, r, c);
|
|
cbs.columnType = ColPosToType(g, c);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, c);
|
|
cbs.rowType = RowPosToType(g, r);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, r);
|
|
if (format == XmFORMAT_PASTE)
|
|
{
|
|
cbs.reason = XmCR_CELL_PASTE;
|
|
XtCallCallbackList((Widget)g, g->grid.cellPasteCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
else if (format == XmFORMAT_DROP)
|
|
{
|
|
cbs.reason = XmCR_CELL_DROP;
|
|
XtCallCallbackList((Widget)g, g->grid.cellDropCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
n++;
|
|
}
|
|
else
|
|
XmStringFree(str);
|
|
}
|
|
if (!(*c2))
|
|
done = 1;
|
|
else if (*c2 == delimiter)
|
|
{
|
|
c++;
|
|
c1 = c2 + 1;
|
|
}
|
|
else if (*c2 == '\n')
|
|
{
|
|
r++;
|
|
c = col;
|
|
c1 = c2 + 1;
|
|
}
|
|
c2++;
|
|
}
|
|
if (needsResize)
|
|
{
|
|
VertLayout(g, 1);
|
|
HorizLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static void
|
|
Write(XmLGridWidget g,
|
|
FILE *file,
|
|
int format,
|
|
char delimiter,
|
|
Boolean skipHidden,
|
|
int row,
|
|
int col,
|
|
int nrow,
|
|
int ncol)
|
|
{
|
|
int r, c, i, first, last;
|
|
char *cs = NULL;
|
|
Boolean set;
|
|
XmString str;
|
|
XmLGridColumn colp;
|
|
XmLGridRow rowp;
|
|
XmLGridCell cell;
|
|
|
|
first = 1;
|
|
for (r = row; r < row + nrow; r++)
|
|
{
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (!rowp)
|
|
continue;
|
|
if (skipHidden == True && XmLGridRowIsHidden(rowp) == True)
|
|
continue;
|
|
if (first)
|
|
first = 0;
|
|
else
|
|
fprintf(file, "\n");
|
|
for (c = col; c < col + ncol; c++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (!colp)
|
|
continue;
|
|
if (skipHidden == True && XmLGridColumnIsHidden(colp) == True)
|
|
continue;
|
|
cell = GetCell(g, r, c);
|
|
if (!cell)
|
|
continue;
|
|
str = XmLGridCellGetString(cell);
|
|
set = False;
|
|
if (str)
|
|
{
|
|
cs = CvtXmStringToStr(str);
|
|
if (cs)
|
|
set = True;
|
|
}
|
|
if (set == False)
|
|
cs = "";
|
|
fprintf(file, "%s", cs);
|
|
|
|
last = 0;
|
|
if (c == col + ncol - 1)
|
|
last = 1;
|
|
if (!last && format == XmFORMAT_DELIMITED)
|
|
fprintf(file, "%c", delimiter);
|
|
else if (!last && format == XmFORMAT_XL)
|
|
fprintf(file, "\t");
|
|
else if (format == XmFORMAT_PAD)
|
|
{
|
|
if (colp->grid.sizePolicy == XmVARIABLE)
|
|
for (i = 0; i < (int)(colp->grid.width - strlen(cs)); i++)
|
|
fprintf(file, " ");
|
|
}
|
|
|
|
if (set == True)
|
|
free(cs);
|
|
}
|
|
}
|
|
}
|
|
|
|
static char *
|
|
CopyDataCreate(XmLGridWidget g, int selected, int row, int col, int nrow, int ncol)
|
|
{
|
|
XmLGridColumn colp;
|
|
XmLGridRow rowp;
|
|
XmLGridCell cell;
|
|
char *buf, *cs = NULL;
|
|
XmString str;
|
|
Boolean set;
|
|
int r, c, wroteStr, bufsize, buflen, len;
|
|
|
|
if (selected)
|
|
{
|
|
row = 0;
|
|
nrow = XmLArrayGetCount(g->grid.rowArray);
|
|
col = 0;
|
|
ncol = XmLArrayGetCount(g->grid.colArray);
|
|
}
|
|
bufsize = 1024;
|
|
buflen = 0;
|
|
buf = (char *)malloc(bufsize);
|
|
|
|
for (r = row; r < row + nrow; r++)
|
|
{
|
|
wroteStr = 0;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (!rowp)
|
|
continue;
|
|
for (c = col; c < col + ncol; c++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (!colp)
|
|
continue;
|
|
cell = GetCell(g, r, c);
|
|
if (!cell)
|
|
continue;
|
|
if (selected &&
|
|
XmLGridRowIsSelected(rowp) == False &&
|
|
XmLGridColumnIsSelected(colp) == False &&
|
|
XmLGridCellIsSelected(cell) == False)
|
|
continue;
|
|
str = XmLGridCellGetString(cell);
|
|
set = False;
|
|
if (str)
|
|
{
|
|
cs = CvtXmStringToStr(str);
|
|
if (cs)
|
|
set = True;
|
|
}
|
|
if (set == False)
|
|
cs = "";
|
|
if (wroteStr)
|
|
buf[buflen++] = '\t';
|
|
|
|
len = strlen(cs);
|
|
/* allocate if string plus tab plus new-line plus 0 if too large */
|
|
while (len + buflen + 3 > bufsize)
|
|
bufsize *= 2;
|
|
buf = (char *)realloc(buf, bufsize);
|
|
strcpy(&buf[buflen], cs);
|
|
buflen += len;
|
|
if (set == True)
|
|
free(cs);
|
|
wroteStr = 1;
|
|
}
|
|
if (wroteStr)
|
|
buf[buflen++] = '\n';
|
|
}
|
|
if (!buflen)
|
|
{
|
|
free((char *)buf);
|
|
return 0;
|
|
}
|
|
buf[buflen - 1] = 0;
|
|
return buf;
|
|
}
|
|
|
|
static Boolean
|
|
Copy(XmLGridWidget g,
|
|
Time time,
|
|
int selected,
|
|
int row,
|
|
int col,
|
|
int nrow,
|
|
int ncol)
|
|
{
|
|
int i;
|
|
long itemID;
|
|
Display *dpy;
|
|
Window win;
|
|
XmString clipStr;
|
|
char *buf;
|
|
#ifdef MOTIF11
|
|
int dataID;
|
|
#else
|
|
long ldataID;
|
|
#endif
|
|
|
|
if (!XtIsRealized((Widget)g))
|
|
{
|
|
XmLWarning((Widget)g, "Copy() - widget not realized");
|
|
return False;
|
|
}
|
|
dpy = XtDisplay((Widget)g);
|
|
win = XtWindow((Widget)g);
|
|
buf = CopyDataCreate(g, selected, row, col, nrow, ncol);
|
|
if (!buf)
|
|
return False;
|
|
clipStr = XmStringCreateSimple("Grid Copy");
|
|
for (i = 0; i < 10000; i++)
|
|
if (XmClipboardStartCopy(dpy, win, clipStr, time, NULL,
|
|
NULL, &itemID) == ClipboardSuccess)
|
|
break;
|
|
XmStringFree(clipStr);
|
|
if (i == 10000)
|
|
{
|
|
XmLWarning((Widget)g, "Copy() - start clipboard copy failed");
|
|
return False;
|
|
}
|
|
for (i = 0; i < 10000; i++)
|
|
#ifdef MOTIF11
|
|
if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
|
|
(long)strlen(buf) + 1, 0, &dataID) == ClipboardSuccess)
|
|
#else
|
|
if (XmClipboardCopy(dpy, win, itemID, "STRING", buf,
|
|
(long)strlen(buf) + 1, 0, &ldataID) == ClipboardSuccess)
|
|
#endif
|
|
break;
|
|
free((char *)buf);
|
|
if (i == 10000)
|
|
{
|
|
XmLWarning((Widget)g, "Copy() - clipboard copy transfer failed");
|
|
return False;
|
|
}
|
|
for (i = 0; i < 10000; i++)
|
|
if (XmClipboardEndCopy(dpy, win, itemID) == ClipboardSuccess)
|
|
break;
|
|
if (i == 10000)
|
|
{
|
|
XmLWarning((Widget)g, "Copy() - end clipboard copy failed");
|
|
return False;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
static Boolean
|
|
Paste(XmLGridWidget g,
|
|
int row,
|
|
int col)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
int i, res, done;
|
|
unsigned long len, reclen;
|
|
char *buf;
|
|
|
|
if (!XtIsRealized((Widget)g))
|
|
{
|
|
XmLWarning((Widget)g, "Paste() - widget not realized");
|
|
return False;
|
|
}
|
|
dpy = XtDisplay((Widget)g);
|
|
win = XtWindow((Widget)g);
|
|
for (i = 0; i < 10000; i++)
|
|
if (XmClipboardInquireLength(dpy, win, "STRING", &len) ==
|
|
ClipboardSuccess)
|
|
break;
|
|
if (i == 10000)
|
|
{
|
|
XmLWarning((Widget)g, "Paste() - can't retrieve clipboard length");
|
|
return False;
|
|
}
|
|
if (!len)
|
|
return False;
|
|
buf = (char *)malloc((int)len);
|
|
done = 0;
|
|
while (!done)
|
|
{
|
|
res = XmClipboardRetrieve(dpy, win, "STRING", buf, len,
|
|
&reclen, NULL);
|
|
switch (res)
|
|
{
|
|
case ClipboardSuccess:
|
|
done = 2;
|
|
break;
|
|
case ClipboardTruncate:
|
|
case ClipboardNoData:
|
|
done = 1;
|
|
break;
|
|
case ClipboardLocked:
|
|
break;
|
|
}
|
|
}
|
|
if (done != 2 || reclen != len)
|
|
{
|
|
free((char *)buf);
|
|
XmLWarning((Widget)g, "Paste() - retrieve from clipboard failed");
|
|
return False;
|
|
}
|
|
Read(g, XmFORMAT_PASTE, 0, row, col, buf);
|
|
free((char *)buf);
|
|
return True;
|
|
}
|
|
|
|
/*
|
|
Utility
|
|
*/
|
|
|
|
static void
|
|
GetCoreBackground(Widget w,
|
|
int offset,
|
|
XrmValue *value)
|
|
{
|
|
value->addr = (caddr_t)&w->core.background_pixel;
|
|
}
|
|
|
|
static void
|
|
GetManagerForeground(Widget w,
|
|
int offset,
|
|
XrmValue *value)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)w;
|
|
value->addr = (caddr_t)&g->manager.foreground;
|
|
}
|
|
|
|
static void
|
|
ClipRectToReg(XmLGridWidget g,
|
|
XRectangle *rect,
|
|
GridReg *reg)
|
|
{
|
|
int i, st;
|
|
XRectangle regRect;
|
|
|
|
st = g->manager.shadow_thickness;
|
|
if (!reg->width || !reg->height)
|
|
i = XmLRectOutside;
|
|
else
|
|
{
|
|
regRect.x = reg->x + st;
|
|
regRect.y = reg->y + st;
|
|
regRect.width = reg->width - st * 2;
|
|
regRect.height = reg->height - st * 2;
|
|
i = XmLRectIntersect(rect, ®Rect);
|
|
}
|
|
if (i == XmLRectInside)
|
|
return;
|
|
if (i == XmLRectOutside)
|
|
{
|
|
rect->width = 0;
|
|
rect->height = 0;
|
|
return;
|
|
}
|
|
if (rect->y + (int)rect->height - 1 >= reg->y + (int)reg->height - st)
|
|
rect->height = reg->y + reg->height - rect->y - st;
|
|
if (rect->x + (int)rect->width - 1 >= reg->x + (int)reg->width - st)
|
|
rect->width = reg->x + reg->width - rect->x - st;
|
|
if (rect->y < reg->y + st)
|
|
{
|
|
rect->height -= (reg->y + st) - rect->y;
|
|
rect->y = reg->y + st;
|
|
}
|
|
if (rect->x < reg->x + st)
|
|
{
|
|
rect->width -= (reg->x + st) - rect->x;
|
|
rect->x = reg->x + st;
|
|
}
|
|
}
|
|
|
|
static char *
|
|
FileToString(FILE *file)
|
|
{
|
|
long len, n;
|
|
char *s;
|
|
|
|
if (!file)
|
|
return 0;
|
|
fseek(file, 0L, 2);
|
|
len = ftell(file);
|
|
s = (char *)malloc((int)len + 1);
|
|
if (!s)
|
|
return 0;
|
|
s[len] = 0;
|
|
fseek(file, 0L, 0);
|
|
n = fread(s, 1, (int)len, file);
|
|
if (n != len)
|
|
{
|
|
free((char *)s);
|
|
return 0;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
static char *
|
|
CvtXmStringToStr(XmString str)
|
|
{
|
|
XmStringContext context;
|
|
XmStringCharSet charset;
|
|
XmStringDirection dir;
|
|
Boolean sep;
|
|
char *text, *c;
|
|
int len, size;
|
|
|
|
if (!XmStringInitContext(&context, str))
|
|
return 0;
|
|
size = 0;
|
|
c = 0;
|
|
while (XmStringGetNextSegment(context, &text, &charset, &dir, &sep))
|
|
{
|
|
len = strlen(text);
|
|
size += len + 3;
|
|
if (!c)
|
|
{
|
|
c = (char *)malloc(size);
|
|
*c = 0;
|
|
}
|
|
else
|
|
c = (char *)realloc(c, size);
|
|
strcat(c, text);
|
|
if (sep == True)
|
|
{
|
|
len = strlen(c);
|
|
c[len] = '\\';
|
|
c[len + 1] = 'n';
|
|
c[len + 2] = 0;
|
|
}
|
|
XtFree(text);
|
|
XtFree(charset);
|
|
}
|
|
XmStringFreeContext(context);
|
|
return c;
|
|
}
|
|
|
|
static XmLGridWidget
|
|
WidgetToGrid(Widget w,
|
|
char *funcname)
|
|
{
|
|
char buf[256];
|
|
|
|
if (!XmLIsGrid(w))
|
|
{
|
|
sprintf(buf, "%s - widget not an XmLGrid", funcname);
|
|
XmLWarning(w, buf);
|
|
return 0;
|
|
}
|
|
return (XmLGridWidget)w;
|
|
}
|
|
|
|
/*
|
|
Actions, Callbacks and Handlers
|
|
*/
|
|
|
|
static void
|
|
ButtonMotion(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
XMotionEvent *me;
|
|
char dragTimerSet;
|
|
int row, col, x, y;
|
|
|
|
if (event->type != MotionNotify)
|
|
return;
|
|
g = (XmLGridWidget)w;
|
|
me = (XMotionEvent *)event;
|
|
if (g->grid.inMode == InResize)
|
|
{
|
|
if (g->grid.resizeIsVert)
|
|
DrawResizeLine(g, me->y, 0);
|
|
else
|
|
{
|
|
DrawResizeLine(g, me->x, 0);
|
|
if (g->grid.hsPolicy == XmRESIZE_IF_POSSIBLE)
|
|
ResizeColumnToFit(g, me->x);
|
|
}
|
|
}
|
|
|
|
/* drag scrolling */
|
|
dragTimerSet = 0;
|
|
if (g->grid.inMode == InSelect)
|
|
{
|
|
if (g->grid.vsPolicy == XmCONSTANT)
|
|
{
|
|
y = g->grid.reg[4].y;
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL &&
|
|
g->grid.extendRow != -1 &&
|
|
g->grid.extendCol != -1 &&
|
|
RowPosToType(g, g->grid.extendRow) == XmHEADING)
|
|
;
|
|
else if (me->y < y)
|
|
dragTimerSet |= DragUp;
|
|
y += g->grid.reg[4].height;
|
|
if (me->y > y)
|
|
dragTimerSet |= DragDown;
|
|
}
|
|
if (g->grid.hsPolicy == XmCONSTANT)
|
|
{
|
|
x = g->grid.reg[4].x;
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL &&
|
|
g->grid.extendCol != -1 &&
|
|
g->grid.extendRow != -1 &&
|
|
ColPosToType(g, g->grid.extendCol) == XmHEADING)
|
|
;
|
|
else if (me->x < x)
|
|
dragTimerSet |= DragLeft;
|
|
x += g->grid.reg[4].width;
|
|
if (me->x > x)
|
|
dragTimerSet |= DragRight;
|
|
}
|
|
}
|
|
if (!g->grid.dragTimerSet && dragTimerSet)
|
|
g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
|
|
80, DragTimer, (caddr_t)g);
|
|
else if (g->grid.dragTimerSet && !dragTimerSet)
|
|
XtRemoveTimeOut(g->grid.dragTimerId);
|
|
g->grid.dragTimerSet = dragTimerSet;
|
|
|
|
/* Extend Selection */
|
|
if (g->grid.inMode == InSelect && XYToRowCol(g, me->x, me->y,
|
|
&row, &col) != -1)
|
|
{
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
|
|
RowPosToType(g, row) == XmCONTENT)
|
|
ExtendSelect(g, event, False, row, col);
|
|
else if (g->grid.selectionPolicy == XmSELECT_CELL)
|
|
ExtendSelect(g, event, False, row, col);
|
|
}
|
|
|
|
if (g->grid.inMode == InSelect &&
|
|
g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
|
|
XYToRowCol(g, me->x, me->y, &row, &col) != -1)
|
|
{
|
|
if (RowPosToType(g, row) == XmCONTENT)
|
|
{
|
|
if (!SetFocus(g, row, col, 0, 1))
|
|
SelectTypeArea(g, SelectRow, event,
|
|
RowPosToTypePos(g, XmCONTENT,
|
|
g->grid.focusRow), 0, True, True);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
DragTimer(XtPointer clientData,
|
|
XtIntervalId *intervalId)
|
|
{
|
|
Widget w;
|
|
XmLGridWidget g;
|
|
XRectangle rect;
|
|
XmLGridRow rowp;
|
|
XmLGridColumn colp;
|
|
int r, c, min, max, inc, pi, ss, value, newValue;
|
|
int extRow, extCol;
|
|
|
|
g = (XmLGridWidget)clientData;
|
|
w = (Widget)g;
|
|
extRow = -1;
|
|
extCol = -1;
|
|
if (g->grid.vsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragUp) ||
|
|
(g->grid.dragTimerSet & DragDown)))
|
|
{
|
|
XtVaGetValues(g->grid.vsb,
|
|
XmNminimum, &min,
|
|
XmNmaximum, &max,
|
|
XmNvalue, &value,
|
|
XmNsliderSize, &ss,
|
|
XmNincrement, &inc,
|
|
XmNpageIncrement, &pi,
|
|
NULL);
|
|
newValue = value;
|
|
if (g->grid.dragTimerSet & DragUp)
|
|
newValue--;
|
|
else
|
|
newValue++;
|
|
if (newValue != value && newValue >= min && newValue <= (max - ss))
|
|
{
|
|
XmScrollBarSetValues(g->grid.vsb, newValue, ss, inc, pi, True);
|
|
r = g->grid.reg[4].row;
|
|
if (g->grid.dragTimerSet & DragDown)
|
|
r += g->grid.reg[4].nrow - 1;
|
|
/* simple check to make sure row selected is totally visible */
|
|
if (g->grid.reg[4].nrow)
|
|
{
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, r);
|
|
if (rowp && !RowColToXY(g, r, 0, True, &rect))
|
|
{
|
|
if (GetRowHeight(g, r) != rect.height)
|
|
r--;
|
|
}
|
|
}
|
|
if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
|
|
{
|
|
if (!SetFocus(g, r, g->grid.focusCol, -1, 1))
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0,
|
|
RowPosToTypePos(g, XmCONTENT, g->grid.focusRow),
|
|
0, True, True);
|
|
}
|
|
else if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW)
|
|
ExtendSelect(g, (XEvent *)0, False, r, g->grid.focusCol);
|
|
else if (g->grid.selectionPolicy == XmSELECT_CELL)
|
|
{
|
|
extRow = r;
|
|
extCol = g->grid.extendToCol;
|
|
}
|
|
}
|
|
}
|
|
if (g->grid.hsPolicy == XmCONSTANT && ((g->grid.dragTimerSet & DragLeft) ||
|
|
(g->grid.dragTimerSet & DragRight)))
|
|
{
|
|
XtVaGetValues(g->grid.hsb,
|
|
XmNminimum, &min,
|
|
XmNmaximum, &max,
|
|
XmNvalue, &value,
|
|
XmNsliderSize, &ss,
|
|
XmNincrement, &inc,
|
|
XmNpageIncrement, &pi,
|
|
NULL);
|
|
newValue = value;
|
|
if (g->grid.dragTimerSet & DragLeft)
|
|
newValue--;
|
|
else
|
|
newValue++;
|
|
if (newValue != value && newValue >= min && newValue <= (max - ss))
|
|
{
|
|
XmScrollBarSetValues(g->grid.hsb, newValue, ss, inc, pi, True);
|
|
c = g->grid.reg[4].col;
|
|
if (g->grid.dragTimerSet & DragRight)
|
|
c += g->grid.reg[4].ncol - 1;
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL)
|
|
{
|
|
/* simple check to make sure col selected is totally visible */
|
|
if (g->grid.reg[4].ncol)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, c);
|
|
if (colp && !RowColToXY(g, c, 0, True, &rect))
|
|
{
|
|
if (GetColWidth(g, c) != rect.width)
|
|
c--;
|
|
}
|
|
}
|
|
if (extRow == -1)
|
|
extRow = g->grid.extendToRow;
|
|
extCol = c;
|
|
}
|
|
}
|
|
}
|
|
if (extRow != -1 && extCol != -1)
|
|
ExtendSelect(g, (XEvent *)0, False, extRow, extCol);
|
|
g->grid.dragTimerId = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
|
|
80, DragTimer, (caddr_t)g);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
CursorMotion(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
XMotionEvent *me;
|
|
int isVert, row, col;
|
|
char defineCursor;
|
|
|
|
if (event->type != MotionNotify)
|
|
return;
|
|
g = (XmLGridWidget)w;
|
|
me = (XMotionEvent *)event;
|
|
defineCursor = CursorNormal;
|
|
|
|
{
|
|
int motionRow;
|
|
int motionCol;
|
|
int newMotionRow = -1;
|
|
int newMotionCol = -1;
|
|
Boolean invokeEnterCellCallback = False;
|
|
|
|
if (XYToRowCol(g,me->x,me->y,&motionRow,&motionCol) != -1)
|
|
{
|
|
if (motionRow != g->grid.lastCursorMotionRow ||
|
|
motionCol != g->grid.lastCursorMotionCol)
|
|
{
|
|
newMotionRow = motionRow;
|
|
newMotionCol = motionCol;
|
|
|
|
invokeEnterCellCallback = True;
|
|
}
|
|
}
|
|
|
|
if (g->grid.lastCursorMotionRow != -1 &&
|
|
g->grid.lastCursorMotionCol != -1)
|
|
{
|
|
/* Invoke XmNleaveCellCallback */
|
|
GridInvokeCellCrossingCallbacks(w,
|
|
g->grid.leaveCellCallback,
|
|
XmCR_LEAVE_CELL,
|
|
event,
|
|
g->grid.lastCursorMotionRow,
|
|
g->grid.lastCursorMotionCol);
|
|
}
|
|
|
|
if (invokeEnterCellCallback)
|
|
{
|
|
/* Invoke XmNenterCellCallback */
|
|
GridInvokeCellCrossingCallbacks(w,
|
|
g->grid.enterCellCallback,
|
|
XmCR_ENTER_CELL,
|
|
event,
|
|
newMotionRow,
|
|
newMotionCol);
|
|
}
|
|
|
|
g->grid.lastCursorMotionRow = newMotionRow;
|
|
g->grid.lastCursorMotionCol = newMotionCol;
|
|
}
|
|
|
|
if (PosIsResize(g, me->x, me->y, &row, &col, &isVert))
|
|
{
|
|
if (isVert)
|
|
defineCursor = CursorVResize;
|
|
else
|
|
defineCursor = CursorHResize;
|
|
}
|
|
|
|
DefineCursor(g, defineCursor);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Edit(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)XtParent(w);
|
|
TextAction(g, TEXT_EDIT_INSERT);
|
|
}
|
|
|
|
static void
|
|
EditCancel(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)XtParent(w);
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
}
|
|
|
|
static void
|
|
EditComplete(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)XtParent(w);
|
|
TextAction(g, TEXT_EDIT_COMPLETE);
|
|
if (*nparam == 1)
|
|
Traverse(w, event, params, nparam);
|
|
}
|
|
|
|
#ifndef MOTIF11
|
|
extern Widget _XmGetTextualDragIcon(Widget);
|
|
#endif
|
|
|
|
static void
|
|
DragStart(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
#ifndef MOTIF11
|
|
XmLGridWidget g;
|
|
Widget dragIcon;
|
|
Atom exportTargets[1];
|
|
Arg args[10];
|
|
char *data;
|
|
XButtonEvent *be;
|
|
int row, col;
|
|
XmLGridColumn colp;
|
|
XmLGridRow rowp;
|
|
XmLGridCell cell;
|
|
static XtCallbackRec dragFinish[2] =
|
|
{ { DragFinish, NULL }, { NULL, NULL } };
|
|
|
|
g = (XmLGridWidget)w;
|
|
be = (XButtonEvent *)event;
|
|
if (!g->grid.allowDrag || !be)
|
|
return;
|
|
if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
|
|
return;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
|
|
cell = GetCell(g, row, col);
|
|
if (!rowp || !colp || !cell)
|
|
return;
|
|
if (XmLGridRowIsSelected(rowp) == False &&
|
|
XmLGridColumnIsSelected(colp) == False &&
|
|
XmLGridCellIsSelected(cell) == False)
|
|
return;
|
|
data = CopyDataCreate(g, 1, 0, 0, 0, 0);
|
|
if (!data)
|
|
return;
|
|
dragIcon = _XmGetTextualDragIcon((Widget)w);
|
|
exportTargets[0] = XA_STRING;
|
|
dragFinish[0].closure = (XtPointer)data;
|
|
XtSetArg(args[0], XmNconvertProc, DragConvert);
|
|
XtSetArg(args[1], XmNexportTargets, exportTargets);
|
|
XtSetArg(args[2], XmNnumExportTargets, 1);
|
|
XtSetArg(args[3], XmNdragOperations, XmDROP_COPY);
|
|
XtSetArg(args[4], XmNsourceCursorIcon, dragIcon);
|
|
XtSetArg(args[4], XmNclientData, (XtPointer)data);
|
|
XtSetArg(args[5], XmNdragDropFinishCallback, dragFinish);
|
|
XmDragStart(w, event, args, 6);
|
|
#endif
|
|
}
|
|
|
|
static Boolean
|
|
DragConvert(Widget w,
|
|
Atom *selection,
|
|
Atom *target,
|
|
Atom *type,
|
|
XtPointer *value,
|
|
unsigned long *length,
|
|
int *format)
|
|
{
|
|
#ifdef MOTIF11
|
|
return FALSE;
|
|
#else
|
|
Atom targetsA, timestampA, multipleA, *exportTargets;
|
|
int n;
|
|
char *data, *dataCopy;
|
|
|
|
if (!XmIsDragContext(w))
|
|
return FALSE;
|
|
targetsA = XInternAtom(XtDisplay(w), "TARGETS", FALSE);
|
|
timestampA = XInternAtom(XtDisplay(w), "TIMESTAMP", FALSE);
|
|
multipleA = XInternAtom(XtDisplay(w), "MULTIPLE", FALSE);
|
|
if (*target == targetsA)
|
|
{
|
|
n = 4;
|
|
exportTargets = (Atom *)XtMalloc(sizeof(Atom) * n);
|
|
exportTargets[0] = XA_STRING;
|
|
exportTargets[1] = targetsA;
|
|
exportTargets[2] = multipleA;
|
|
exportTargets[3] = timestampA;
|
|
*type = XA_ATOM;
|
|
*value = (XtPointer)exportTargets;
|
|
*format = 32;
|
|
*length = (n * sizeof(Atom)) >> 2;
|
|
return TRUE;
|
|
}
|
|
else if (*target == XA_STRING)
|
|
{
|
|
XtVaGetValues(w, XmNclientData, &data, NULL);
|
|
*type = XA_STRING;
|
|
dataCopy = XtMalloc(strlen(data));
|
|
strncpy(dataCopy, data, strlen(data));
|
|
*value = (XtPointer)dataCopy;
|
|
*length = strlen(data);
|
|
*format = 8;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
DragFinish(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
free ((char *)clientData);
|
|
}
|
|
|
|
static void
|
|
DropRegister(XmLGridWidget g, Boolean set)
|
|
{
|
|
#ifndef MOTIF11
|
|
Atom importTargets[1];
|
|
Arg args[4];
|
|
|
|
if (set == True)
|
|
{
|
|
importTargets[0] = XA_STRING;
|
|
XtSetArg(args[0], XmNdropSiteOperations, XmDROP_COPY);
|
|
XtSetArg(args[1], XmNimportTargets, importTargets);
|
|
XtSetArg(args[2], XmNnumImportTargets, 1);
|
|
XtSetArg(args[3], XmNdropProc, DropStart);
|
|
XmDropSiteRegister((Widget)g, args, 4);
|
|
}
|
|
else
|
|
XmDropSiteUnregister((Widget)g);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
DropStart(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
#ifndef MOTIF11
|
|
XmLGridWidget g;
|
|
XmDropProcCallbackStruct *cbs;
|
|
XmDropTransferEntryRec te[2];
|
|
Atom *exportTargets;
|
|
Arg args[10];
|
|
int row, col, i, n, valid;
|
|
|
|
g = (XmLGridWidget)w;
|
|
cbs = (XmDropProcCallbackStruct *)callData;
|
|
if (g->grid.allowDrop == False || cbs->dropAction == XmDROP_HELP)
|
|
{
|
|
cbs->dropSiteStatus = XmINVALID_DROP_SITE;
|
|
return;
|
|
}
|
|
valid = 0;
|
|
if (XYToRowCol(g, cbs->x, cbs->y, &row, &col) != -1 &&
|
|
cbs->dropAction == XmDROP && cbs->operation == XmDROP_COPY)
|
|
{
|
|
XtVaGetValues(cbs->dragContext,
|
|
XmNexportTargets, &exportTargets,
|
|
XmNnumExportTargets, &n,
|
|
NULL);
|
|
for (i = 0; i < n; i++)
|
|
if (exportTargets[i] == XA_STRING)
|
|
valid = 1;
|
|
}
|
|
if (!valid)
|
|
{
|
|
cbs->operation = (long)XmDROP_NOOP;
|
|
cbs->dropSiteStatus = XmINVALID_DROP_SITE;
|
|
XtSetArg(args[0], XmNtransferStatus, XmTRANSFER_FAILURE);
|
|
XtSetArg(args[1], XmNnumDropTransfers, 0);
|
|
XmDropTransferStart(cbs->dragContext, args, 2);
|
|
return;
|
|
}
|
|
g->grid.dropLoc.row = row;
|
|
g->grid.dropLoc.col = col;
|
|
cbs->operation = (long)XmDROP_COPY;
|
|
te[0].target = XA_STRING;
|
|
te[0].client_data = (XtPointer)g;
|
|
XtSetArg(args[0], XmNdropTransfers, te);
|
|
XtSetArg(args[1], XmNnumDropTransfers, 1);
|
|
XtSetArg(args[2], XmNtransferProc, DropTransfer);
|
|
XmDropTransferStart(cbs->dragContext, args, 3);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
DropTransfer(Widget w,
|
|
XtPointer clientData,
|
|
Atom *selType,
|
|
Atom *type,
|
|
XtPointer value,
|
|
unsigned long *length,
|
|
int *format)
|
|
{
|
|
#ifndef MOTIF11
|
|
XmLGridWidget g;
|
|
char *buf;
|
|
int len;
|
|
|
|
if (!value)
|
|
return;
|
|
g = (XmLGridWidget)clientData;
|
|
len = (int)*length;
|
|
if (len < 0)
|
|
return;
|
|
buf = (char *)malloc(len + 1);
|
|
strncpy(buf, (char *)value, len);
|
|
XtFree((char *)value);
|
|
buf[len] = 0;
|
|
Read(g, XmFORMAT_DROP, 0, g->grid.dropLoc.row, g->grid.dropLoc.col, buf);
|
|
free((char *)buf);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
Select(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
Window win;
|
|
static XrmQuark qACTIVATE, qBEGIN, qEXTEND, qEND;
|
|
static XrmQuark qTOGGLE;
|
|
static int quarksValid = 0;
|
|
XrmQuark q;
|
|
int isVert;
|
|
int row, col, resizeRow, resizeCol;
|
|
XButtonEvent *be;
|
|
XRectangle rect;
|
|
XmLGridRow rowp;
|
|
XmLGridCell cellp;
|
|
XmLGridColumn colp;
|
|
XmLGridCallbackStruct cbs;
|
|
Boolean flag;
|
|
|
|
if (*nparam != 1)
|
|
return;
|
|
|
|
if (XmLIsGrid(w))
|
|
g = (XmLGridWidget)w;
|
|
else
|
|
g = (XmLGridWidget)XtParent(w);
|
|
dpy = XtDisplay(g);
|
|
win = XtWindow(g);
|
|
if (!quarksValid)
|
|
{
|
|
qACTIVATE = XrmStringToQuark("ACTIVATE");
|
|
qBEGIN = XrmStringToQuark("BEGIN");
|
|
qEXTEND = XrmStringToQuark("EXTEND");
|
|
qEND = XrmStringToQuark("END");
|
|
qTOGGLE = XrmStringToQuark("TOGGLE");
|
|
}
|
|
q = XrmStringToQuark(params[0]);
|
|
be = 0;
|
|
if (event->type == KeyPress || event->type == KeyRelease)
|
|
{
|
|
row = g->grid.focusRow;
|
|
col = g->grid.focusCol;
|
|
}
|
|
else /* Button */
|
|
{
|
|
be = (XButtonEvent *)event;
|
|
if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
|
|
{
|
|
row = -1;
|
|
col = -1;
|
|
}
|
|
}
|
|
|
|
/* double click activate check */
|
|
if (q == qBEGIN && be)
|
|
{
|
|
if (row != -1 && col != -1
|
|
&& row == g->grid.focusRow && col == g->grid.focusCol
|
|
)
|
|
{
|
|
int doubleClickTime = XtGetMultiClickTime(dpy);
|
|
Time timeSinceLastClick = be->time - g->grid.lastSelectTime;
|
|
if (timeSinceLastClick < doubleClickTime)
|
|
{
|
|
/* Clear inplace editing if some other event happens */
|
|
if (g->grid.editTimerSet)
|
|
{
|
|
XtRemoveTimeOut(g->grid.editTimerId);
|
|
g->grid.editTimerSet = 0;
|
|
}
|
|
|
|
/* Second click came within double click time */
|
|
q = qACTIVATE;
|
|
}
|
|
else if (!g->grid.editTimerSet && g->grid.lastSelectTime != 0)
|
|
{
|
|
/* Only begin an edit when we are sure we don't
|
|
* have a double click
|
|
*/
|
|
if (!g->grid.singleClickActivation) {
|
|
g->grid.editTimerId =
|
|
XtAppAddTimeOut(XtWidgetToApplicationContext(w),
|
|
doubleClickTime*2, EditTimer, (caddr_t)g);
|
|
g->grid.editTimerSet = 1;
|
|
}
|
|
}
|
|
}
|
|
g->grid.lastSelectRow = row;
|
|
g->grid.lastSelectCol = col;
|
|
g->grid.lastSelectTime = be->time;
|
|
}
|
|
else if (q == qBEGIN)
|
|
g->grid.lastSelectTime = 0;
|
|
|
|
if (q == qBEGIN && be && PosIsResize(g, be->x, be->y,
|
|
&resizeRow, &resizeCol, &isVert))
|
|
{
|
|
g->grid.resizeIsVert = isVert;
|
|
g->grid.inMode = InResize;
|
|
g->grid.resizeLineXY = -1;
|
|
g->grid.resizeRow = resizeRow;
|
|
g->grid.resizeCol = resizeCol;
|
|
if (isVert)
|
|
{
|
|
DrawResizeLine(g, be->y, 0);
|
|
DefineCursor(g, CursorVResize);
|
|
}
|
|
else
|
|
{
|
|
DrawResizeLine(g, be->x, 0);
|
|
DefineCursor(g, CursorHResize);
|
|
}
|
|
}
|
|
else if (q == qBEGIN || q == qEXTEND || q == qTOGGLE)
|
|
{
|
|
if (g->grid.inMode != InNormal)
|
|
return;
|
|
if (row == -1 || col == -1)
|
|
return;
|
|
if (RowPosToType(g, row) == XmCONTENT &&
|
|
ColPosToType(g, col) == XmCONTENT)
|
|
{
|
|
TextAction(g, TEXT_EDIT_COMPLETE);
|
|
if (q != qEXTEND)
|
|
{
|
|
SetFocus(g, row, col, 0, 1);
|
|
ExtendSelect(g, event, False, -1, -1);
|
|
}
|
|
XmProcessTraversal(g->grid.text, XmTRAVERSE_CURRENT);
|
|
}
|
|
if (g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
|
|
RowPosToType(g, row) == XmCONTENT)
|
|
{
|
|
flag = True;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
#if 0
|
|
/* Don't want single click to unselect something. -slamm */
|
|
if (q == qBEGIN && rowp && XmLGridRowIsSelected(rowp) == True)
|
|
flag = False;
|
|
#endif /* 0 -slamm */
|
|
if (q == qTOGGLE && rowp && XmLGridRowIsSelected(rowp) == True)
|
|
flag = False;
|
|
if (q == qBEGIN)
|
|
SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
|
|
if (be && q == qEXTEND)
|
|
ExtendSelect(g, event, False, row, col);
|
|
else
|
|
SelectTypeArea(g, SelectRow, event,
|
|
RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
|
|
}
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL)
|
|
{
|
|
if (q == qBEGIN)
|
|
{
|
|
SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
|
|
SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
|
|
SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
|
|
}
|
|
else if (q == qTOGGLE)
|
|
ExtendSelect(g, event, False, -1, -1);
|
|
if (RowPosToType(g, row) == XmFOOTER ||
|
|
ColPosToType(g, col) == XmFOOTER)
|
|
ExtendSelect(g, event, False, -1, -1);
|
|
if (be && q == qEXTEND)
|
|
ExtendSelect(g, event, False, row, col);
|
|
else if (RowPosToType(g, row) == XmCONTENT &&
|
|
ColPosToType(g, col) == XmCONTENT)
|
|
{
|
|
flag = True;
|
|
cellp = GetCell(g, row, col);
|
|
if (q == qTOGGLE && cellp &&
|
|
XmLGridCellIsSelected(cellp) == True)
|
|
flag = False;
|
|
SelectTypeArea(g, SelectCell, event,
|
|
RowPosToTypePos(g, XmCONTENT, row),
|
|
ColPosToTypePos(g, XmCONTENT, col), flag, True);
|
|
}
|
|
else if (RowPosToType(g, row) == XmHEADING &&
|
|
ColPosToType(g, col) == XmCONTENT)
|
|
{
|
|
if (q == qTOGGLE)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, col);
|
|
if (colp && XmLGridColumnIsSelected(colp) == True)
|
|
g->grid.extendSelect = False;
|
|
}
|
|
ExtendSelect(g, event, True, row, col);
|
|
}
|
|
else if (ColPosToType(g, col) == XmHEADING &&
|
|
RowPosToType(g, row) == XmCONTENT)
|
|
{
|
|
if (q == qTOGGLE)
|
|
{
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (rowp && XmLGridRowIsSelected(rowp) == True)
|
|
g->grid.extendSelect = False;
|
|
}
|
|
ExtendSelect(g, event, True, row, col);
|
|
}
|
|
}
|
|
if (g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
|
|
RowPosToType(g, row) == XmCONTENT)
|
|
{
|
|
flag = True;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (rowp && XmLGridRowIsSelected(rowp) == True)
|
|
flag = False;
|
|
SelectTypeArea(g, SelectRow, event,
|
|
RowPosToTypePos(g, XmCONTENT, row), 0, flag, True);
|
|
}
|
|
if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
|
|
RowPosToType(g, row) == XmCONTENT)
|
|
SelectTypeArea(g, SelectRow, event,
|
|
RowPosToTypePos(g, XmCONTENT, row), 0, True, True);
|
|
if (g->grid.selectionPolicy == XmSELECT_NONE ||
|
|
(g->grid.selectionPolicy == XmSELECT_BROWSE_ROW &&
|
|
RowPosToType(g, row) != XmCONTENT) ||
|
|
(g->grid.selectionPolicy == XmSELECT_SINGLE_ROW &&
|
|
RowPosToType(g, row) != XmCONTENT) ||
|
|
(g->grid.selectionPolicy == XmSELECT_MULTIPLE_ROW &&
|
|
RowPosToType(g, row) != XmCONTENT) )
|
|
{
|
|
cbs.reason = XmCR_SELECT_CELL;
|
|
cbs.event = event;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XtCallCallbackList((Widget)g, g->grid.selectCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
g->grid.inMode = InSelect;
|
|
}
|
|
else if (q == qEND && g->grid.inMode == InResize)
|
|
{
|
|
int r, c, width, height;
|
|
r = g->grid.resizeRow;
|
|
c = g->grid.resizeCol;
|
|
g->grid.resizeRow = -1;
|
|
g->grid.resizeCol = -1;
|
|
if (!RowColToXY(g, r, c, False, &rect))
|
|
{
|
|
if (g->grid.resizeIsVert)
|
|
{
|
|
cbs.rowType = RowPosToType(g, r);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, r);
|
|
height = 0;
|
|
if (g->grid.resizeLineXY > rect.y)
|
|
height = g->grid.resizeLineXY - rect.y -
|
|
(rect.height - GetRowHeight(g, r));
|
|
if (height < 6 && g->grid.allowRowHide == False)
|
|
height = 6;
|
|
XtVaSetValues((Widget)g,
|
|
XmNrowType, cbs.rowType,
|
|
XmNrow, cbs.row,
|
|
XmNrowHeight, height,
|
|
XmNrowSizePolicy, XmCONSTANT,
|
|
NULL);
|
|
cbs.reason = XmCR_RESIZE_ROW;
|
|
}
|
|
else
|
|
{
|
|
cbs.columnType = ColPosToType(g, c);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, c);
|
|
width = 0;
|
|
if (g->grid.resizeLineXY > rect.x)
|
|
width = g->grid.resizeLineXY - rect.x -
|
|
(rect.width - GetColWidth(g, c));
|
|
if (width < 6 && g->grid.allowColHide == False)
|
|
width = 6;
|
|
XtVaSetValues((Widget)g,
|
|
XmNcolumnType, cbs.columnType,
|
|
XmNcolumn, cbs.column,
|
|
XmNcolumnWidth, width,
|
|
XmNcolumnSizePolicy, XmCONSTANT,
|
|
NULL);
|
|
cbs.reason = XmCR_RESIZE_COLUMN;
|
|
|
|
}
|
|
XtCallCallbackList((Widget)g, g->grid.resizeCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
DrawResizeLine(g, 0, 2);
|
|
DefineCursor(g, CursorNormal);
|
|
g->grid.inMode = InNormal;
|
|
}
|
|
else if (q == qEND)
|
|
{
|
|
g->grid.inMode = InNormal;
|
|
if (g->grid.dragTimerSet)
|
|
XtRemoveTimeOut(g->grid.dragTimerId);
|
|
g->grid.dragTimerSet = 0;
|
|
|
|
/* XFE Additions to handle button up events in menus - they generate activate events */
|
|
{
|
|
if (XmIsMenuShell(XmLShellOfWidget((Widget)g)))
|
|
{
|
|
cbs.reason = XmCR_ACTIVATE;
|
|
cbs.event = event;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XtCallCallbackList((Widget)g, g->grid.activateCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
}
|
|
if (q == qBEGIN && g->grid.singleClickActivation) {
|
|
cbs.reason = XmCR_ACTIVATE;
|
|
cbs.event = event;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XtCallCallbackList((Widget)g, g->grid.activateCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
if (q == qACTIVATE)
|
|
{
|
|
cbs.reason = XmCR_ACTIVATE;
|
|
cbs.event = event;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XtCallCallbackList((Widget)g, g->grid.activateCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Selection policy when posting a context menu.
|
|
* If over a current selection, leave the selection alone.
|
|
* Otherwise, change the selection the same as Select(),
|
|
* except do not allow dragging to extend the selection.
|
|
*/
|
|
static void
|
|
PopupSelect(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
int row, col;
|
|
XButtonEvent *be;
|
|
XmLGridRow rowp;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
if (*nparam != 1)
|
|
return;
|
|
|
|
if (XmLIsGrid(w))
|
|
g = (XmLGridWidget)w;
|
|
else
|
|
g = (XmLGridWidget)XtParent(w);
|
|
|
|
be = 0;
|
|
if (event->type == KeyPress || event->type == KeyRelease)
|
|
{
|
|
row = g->grid.focusRow;
|
|
col = g->grid.focusCol;
|
|
}
|
|
else /* Button */
|
|
{
|
|
be = (XButtonEvent *)event;
|
|
if (XYToRowCol(g, be->x, be->y, &row, &col) == -1)
|
|
{
|
|
row = -1;
|
|
col = -1;
|
|
}
|
|
}
|
|
if (RowPosToType(g, row) == XmCONTENT)
|
|
{
|
|
XmLGridRow rowp;
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, row);
|
|
if (rowp && !XmLGridRowIsSelected(rowp))
|
|
{
|
|
String end_params[1];
|
|
end_params[0] = "END";
|
|
Select(w, event, params, nparam);
|
|
Select(w, event, end_params, nparam);
|
|
}
|
|
}
|
|
if (XtHasCallbacks(w, XmNpopupCallback) == XtCallbackHasSome)
|
|
{
|
|
cbs.reason = XmCR_SHOW_POPUP;
|
|
cbs.event = event;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
XtCallCallbackList((Widget)g, g->grid.popupCallback,
|
|
(XtPointer)&cbs);
|
|
}
|
|
}
|
|
|
|
static void
|
|
Traverse(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLGridWidget g;
|
|
static XrmQuark qDOWN, qEXTEND_DOWN, qEXTEND_LEFT;
|
|
static XrmQuark qEXTEND_PAGE_DOWN, qEXTEND_PAGE_LEFT;
|
|
static XrmQuark qEXTEND_PAGE_RIGHT, qEXTEND_PAGE_UP;
|
|
static XrmQuark qEXTEND_RIGHT, qEXTEND_UP, qLEFT, qPAGE_DOWN;
|
|
static XrmQuark qPAGE_LEFT, qPAGE_RIGHT, qPAGE_UP, qRIGHT;
|
|
static XrmQuark qTO_BOTTOM, qTO_BOTTOM_RIGHT, qTO_LEFT;
|
|
static XrmQuark qTO_RIGHT, qTO_TOP, qTO_TOP_LEFT, qUP;
|
|
static int quarksValid = 0;
|
|
int extend, focusRow, focusCol, rowDir, colDir;
|
|
int rowLoc, colLoc, prevRowLoc, prevColLoc;
|
|
int scrollRow, scrollCol, prevScrollRow, prevScrollCol;
|
|
XrmQuark q;
|
|
|
|
g = (XmLGridWidget)XtParent(w);
|
|
if (*nparam != 1)
|
|
return;
|
|
if (!quarksValid)
|
|
{
|
|
qDOWN = XrmStringToQuark("DOWN");
|
|
qEXTEND_DOWN = XrmStringToQuark("EXTEND_DOWN");
|
|
qEXTEND_LEFT = XrmStringToQuark("EXTEND_LEFT");
|
|
qEXTEND_PAGE_DOWN = XrmStringToQuark("EXTEND_PAGE_DOWN");
|
|
qEXTEND_PAGE_LEFT = XrmStringToQuark("EXTEND_PAGE_LEFT");
|
|
qEXTEND_PAGE_RIGHT = XrmStringToQuark("EXTEND_PAGE_RIGHT");
|
|
qEXTEND_PAGE_UP = XrmStringToQuark("EXTEND_PAGE_UP");
|
|
qEXTEND_RIGHT = XrmStringToQuark("EXTEND_RIGHT");
|
|
qEXTEND_UP = XrmStringToQuark("EXTEND_UP");
|
|
qLEFT = XrmStringToQuark("LEFT");
|
|
qPAGE_DOWN = XrmStringToQuark("PAGE_DOWN");
|
|
qPAGE_LEFT = XrmStringToQuark("PAGE_LEFT");
|
|
qPAGE_RIGHT = XrmStringToQuark("PAGE_RIGHT");
|
|
qPAGE_UP = XrmStringToQuark("PAGE_UP");
|
|
qRIGHT = XrmStringToQuark("RIGHT");
|
|
qTO_BOTTOM = XrmStringToQuark("TO_BOTTOM");
|
|
qTO_BOTTOM_RIGHT = XrmStringToQuark("TO_BOTTOM_RIGHT");
|
|
qTO_LEFT = XrmStringToQuark("TO_LEFT");
|
|
qTO_RIGHT = XrmStringToQuark("TO_RIGHT");
|
|
qTO_TOP = XrmStringToQuark("TO_TOP");
|
|
qTO_TOP_LEFT = XrmStringToQuark("TO_TOP_LEFT");
|
|
qUP = XrmStringToQuark("UP");
|
|
quarksValid = 1;
|
|
}
|
|
q = XrmStringToQuark(params[0]);
|
|
extend = 0;
|
|
/* map the extends to their counterparts and set extend flag */
|
|
if (q == qEXTEND_DOWN)
|
|
{
|
|
q = qDOWN;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_LEFT)
|
|
{
|
|
q = qLEFT;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_PAGE_DOWN)
|
|
{
|
|
q = qPAGE_DOWN;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_PAGE_LEFT)
|
|
{
|
|
q = qPAGE_LEFT;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_PAGE_RIGHT)
|
|
{
|
|
q = qPAGE_RIGHT;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_PAGE_UP)
|
|
{
|
|
q = qPAGE_UP;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_RIGHT)
|
|
{
|
|
q = qRIGHT;
|
|
extend = 1;
|
|
}
|
|
else if (q == qEXTEND_UP)
|
|
{
|
|
q = qUP;
|
|
extend = 1;
|
|
}
|
|
if (extend && g->grid.selectionPolicy != XmSELECT_MULTIPLE_ROW &&
|
|
g->grid.selectionPolicy != XmSELECT_CELL)
|
|
return;
|
|
if (extend && g->grid.extendRow != -1 && g->grid.extendCol != -1)
|
|
{
|
|
focusRow = g->grid.extendToRow;
|
|
focusCol = g->grid.extendToCol;
|
|
}
|
|
else
|
|
{
|
|
focusRow = g->grid.focusRow;
|
|
focusCol = g->grid.focusCol;
|
|
}
|
|
rowDir = 0;
|
|
colDir = 0;
|
|
if (focusRow < g->grid.topFixedCount)
|
|
prevRowLoc = 0;
|
|
else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
|
|
g->grid.bottomFixedCount)
|
|
prevRowLoc = 2;
|
|
else
|
|
prevRowLoc = 1;
|
|
if (focusCol < g->grid.leftFixedCount)
|
|
prevColLoc = 0;
|
|
else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
|
|
g->grid.rightFixedCount)
|
|
prevColLoc = 2;
|
|
else
|
|
prevColLoc = 1;
|
|
/* calculate new focus row, col and walk direction */
|
|
if (q == qDOWN)
|
|
{
|
|
focusRow++;
|
|
rowDir = 1;
|
|
}
|
|
else if (q == qLEFT)
|
|
{
|
|
focusCol--;
|
|
colDir = -1;
|
|
}
|
|
else if (q == qPAGE_DOWN)
|
|
{
|
|
if (prevRowLoc == 1)
|
|
focusRow = g->grid.reg[4].row + g->grid.reg[4].nrow - 1;
|
|
if (focusRow == g->grid.focusRow)
|
|
focusRow += 4;
|
|
rowDir = 1;
|
|
}
|
|
else if (q == qPAGE_LEFT)
|
|
{
|
|
if (prevColLoc == 1)
|
|
focusCol = g->grid.reg[4].col - 1;
|
|
if (focusCol == g->grid.focusCol)
|
|
focusCol -= 4;
|
|
colDir = -1;
|
|
}
|
|
else if (q == qPAGE_RIGHT)
|
|
{
|
|
if (prevColLoc == 1)
|
|
focusCol = g->grid.reg[4].col + g->grid.reg[4].ncol - 1;
|
|
if (focusCol == g->grid.focusCol)
|
|
focusCol += 4;
|
|
colDir = 1;
|
|
}
|
|
else if (q == qPAGE_UP)
|
|
{
|
|
if (prevRowLoc == 1)
|
|
focusRow = g->grid.reg[4].row - 1;
|
|
if (focusRow == g->grid.focusRow)
|
|
focusRow -= 4;
|
|
rowDir = -1;
|
|
}
|
|
else if (q == qRIGHT)
|
|
{
|
|
focusCol++;
|
|
colDir = 1;
|
|
}
|
|
else if (q == qTO_BOTTOM)
|
|
{
|
|
focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
|
|
rowDir = -1;
|
|
}
|
|
else if (q == qTO_BOTTOM_RIGHT)
|
|
{
|
|
focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
|
|
focusRow = XmLArrayGetCount(g->grid.rowArray) - 1;
|
|
rowDir = -1;
|
|
colDir = -1;
|
|
}
|
|
else if (q == qTO_LEFT)
|
|
{
|
|
focusCol = 0;
|
|
colDir = 1;
|
|
}
|
|
else if (q == qTO_RIGHT)
|
|
{
|
|
focusCol = XmLArrayGetCount(g->grid.colArray) - 1;
|
|
colDir = -1;
|
|
}
|
|
else if (q == qTO_TOP)
|
|
{
|
|
focusRow = 0;
|
|
rowDir = 1;
|
|
}
|
|
else if (q == qTO_TOP_LEFT)
|
|
{
|
|
focusCol = 0;
|
|
focusRow = 0;
|
|
rowDir = 1;
|
|
colDir = 1;
|
|
}
|
|
else if (q == qUP)
|
|
{
|
|
focusRow -= 1;
|
|
rowDir = -1;
|
|
}
|
|
if (!rowDir && !colDir)
|
|
return;
|
|
if (extend)
|
|
{
|
|
if (FindNextFocus(g, focusRow, focusCol, rowDir, colDir,
|
|
&focusRow, &focusCol) == -1)
|
|
return;
|
|
ExtendSelect(g, event, False, focusRow, focusCol);
|
|
}
|
|
else
|
|
{
|
|
if (SetFocus(g, focusRow, focusCol, rowDir, colDir) == -1)
|
|
return;
|
|
ExtendSelect(g, event, False, -1, -1);
|
|
focusRow = g->grid.focusRow;
|
|
focusCol = g->grid.focusCol;
|
|
if (g->grid.selectionPolicy == XmSELECT_CELL)
|
|
{
|
|
SelectTypeArea(g, SelectRow, event, -1, 0, False, True);
|
|
SelectTypeArea(g, SelectCol, event, 0, -1, False, True);
|
|
SelectTypeArea(g, SelectCell, event, -1, -1, False, True);
|
|
SelectTypeArea(g, SelectCell, event,
|
|
RowPosToTypePos(g, XmCONTENT, focusRow),
|
|
ColPosToTypePos(g, XmCONTENT, focusCol),
|
|
True, True);
|
|
}
|
|
else if (g->grid.selectionPolicy == XmSELECT_BROWSE_ROW)
|
|
SelectTypeArea(g, SelectRow, event,
|
|
RowPosToTypePos(g, XmCONTENT, focusRow), 0, True, True);
|
|
}
|
|
scrollRow = -1;
|
|
scrollCol = -1;
|
|
if (q == qPAGE_UP)
|
|
scrollRow = ScrollRowBottomPos(g, focusRow);
|
|
else if (q == qPAGE_DOWN)
|
|
scrollRow = focusRow;
|
|
else if (q == qPAGE_LEFT)
|
|
scrollCol = ScrollColRightPos(g, focusCol);
|
|
else if (q == qPAGE_RIGHT)
|
|
scrollCol = focusCol;
|
|
else
|
|
{
|
|
if (focusRow < g->grid.topFixedCount)
|
|
rowLoc = 0;
|
|
else if (focusRow >= XmLArrayGetCount(g->grid.rowArray) -
|
|
g->grid.bottomFixedCount)
|
|
rowLoc = 2;
|
|
else
|
|
rowLoc = 1;
|
|
if (prevRowLoc != 0 && rowLoc == 0)
|
|
scrollRow = g->grid.reg[0].nrow;
|
|
else if (prevRowLoc != 2 && rowLoc == 2)
|
|
scrollRow = g->grid.reg[6].row - 1;
|
|
|
|
if (focusCol < g->grid.leftFixedCount)
|
|
colLoc = 0;
|
|
else if (focusCol >= XmLArrayGetCount(g->grid.colArray) -
|
|
g->grid.rightFixedCount)
|
|
colLoc = 2;
|
|
else
|
|
colLoc = 1;
|
|
if (prevColLoc != 0 && colLoc == 0)
|
|
scrollCol = g->grid.reg[0].ncol;
|
|
else if (prevColLoc != 2 && colLoc == 2)
|
|
scrollCol = g->grid.reg[2].col - 1;
|
|
}
|
|
if (g->grid.vsPolicy == XmVARIABLE)
|
|
;
|
|
else if (scrollRow != -1)
|
|
{
|
|
prevScrollRow = g->grid.scrollRow;
|
|
g->grid.scrollRow = scrollRow;
|
|
VertLayout(g, 0);
|
|
if (g->grid.scrollRow != prevScrollRow)
|
|
DrawArea(g, DrawVScroll, 0, 0);
|
|
}
|
|
else
|
|
MakeRowVisible(g, focusRow);
|
|
if (g->grid.hsPolicy == XmVARIABLE)
|
|
;
|
|
else if (scrollCol != -1)
|
|
{
|
|
prevScrollCol = g->grid.scrollCol;
|
|
g->grid.scrollCol = scrollCol;
|
|
HorizLayout(g, 0);
|
|
if (g->grid.scrollCol != prevScrollCol)
|
|
DrawArea(g, DrawHScroll, 0, 0);
|
|
}
|
|
else
|
|
MakeColVisible(g, focusCol);
|
|
}
|
|
|
|
static void
|
|
TextActivate(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
XmLGridWidget g;
|
|
XmAnyCallbackStruct *cbs;
|
|
String params[1];
|
|
Cardinal nparam;
|
|
|
|
cbs = (XmAnyCallbackStruct *)callData;
|
|
g = (XmLGridWidget)XtParent(w);
|
|
if (g->grid.inEdit)
|
|
{
|
|
nparam = 0;
|
|
EditComplete(w, cbs->event, params, &nparam);
|
|
}
|
|
else
|
|
{
|
|
params[0] = "ACTIVATE";
|
|
nparam = 1;
|
|
Select(XtParent(w), cbs->event, params, &nparam);
|
|
}
|
|
}
|
|
|
|
static void
|
|
TextFocus(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
XmLGridWidget g;
|
|
XmAnyCallbackStruct *cbs;
|
|
int focusRow, focusCol;
|
|
|
|
cbs = (XmAnyCallbackStruct *)callData;
|
|
g = (XmLGridWidget)XtParent(w);
|
|
if (cbs->reason == XmCR_FOCUS)
|
|
g->grid.focusIn = 1;
|
|
else
|
|
g->grid.focusIn = 0;
|
|
focusRow = g->grid.focusRow;
|
|
focusCol = g->grid.focusCol;
|
|
if (focusRow != -1 && focusCol != -1)
|
|
{
|
|
if (g->grid.highlightRowMode == True)
|
|
DrawArea(g, DrawRow, focusRow, 0);
|
|
else
|
|
DrawArea(g, DrawCell, focusRow, focusCol);
|
|
}
|
|
}
|
|
|
|
static void
|
|
TextMapped(Widget w,
|
|
XtPointer clientData,
|
|
XEvent *event,
|
|
Boolean *con)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)(XtParent(w));
|
|
if (event->type != MapNotify)
|
|
return;
|
|
if (g->grid.textHidden)
|
|
XtUnmapWidget(g->grid.text);
|
|
}
|
|
|
|
static void
|
|
TextModifyVerify(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
XmLGridWidget g;
|
|
XmTextVerifyCallbackStruct *cbs;
|
|
|
|
g = (XmLGridWidget)XtParent(w);
|
|
cbs = (XmTextVerifyCallbackStruct *)callData;
|
|
if (!cbs->event || g->grid.ignoreModifyVerify || g->grid.inEdit)
|
|
return;
|
|
TextAction(g, TEXT_EDIT);
|
|
if (!g->grid.inEdit)
|
|
cbs->doit = False;
|
|
}
|
|
|
|
/*
|
|
XmLGridRow
|
|
*/
|
|
|
|
static
|
|
XmLGridRow XmLGridRowNew(Widget grid)
|
|
{
|
|
return XmLGridClassPartOfWidget(grid).rowNewProc(grid);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static XmLGridRow
|
|
_GridRowNew(Widget grid)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
int size;
|
|
|
|
g = (XmLGridWidget)grid;
|
|
size = XmLGridClassPartOfWidget(grid).rowRecSize;
|
|
row = (XmLGridRow)malloc(size);
|
|
row->grid.grid = grid;
|
|
row->grid.heightInPixels = 0;
|
|
row->grid.heightInPixelsValid = 0;
|
|
row->grid.height = 1;
|
|
row->grid.selected = False;
|
|
row->grid.sizePolicy = XmVARIABLE;
|
|
row->grid.userData = 0;
|
|
row->grid.cellArray = XmLArrayNew(0, 0);
|
|
return row;
|
|
}
|
|
|
|
static void
|
|
XmLGridRowFree(Widget grid,
|
|
XmLGridRow row)
|
|
{
|
|
XmLGridClassPartOfWidget(grid).rowFreeProc(row);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GridRowFree(XmLGridRow row)
|
|
{
|
|
int i, count;
|
|
|
|
count = XmLArrayGetCount(row->grid.cellArray);
|
|
for (i = 0; i < count; i++)
|
|
XmLGridCellFree(row->grid.grid,
|
|
(XmLGridCell)XmLArrayGet(row->grid.cellArray, i));
|
|
XmLArrayFree(row->grid.cellArray);
|
|
free ((char *)row);
|
|
}
|
|
|
|
static
|
|
XmLArray XmLGridRowCells(XmLGridRow row)
|
|
{
|
|
return row->grid.cellArray;
|
|
}
|
|
|
|
static int
|
|
XmLGridRowGetPos(XmLGridRow row)
|
|
{
|
|
return row->grid.pos;
|
|
}
|
|
|
|
static int
|
|
XmLGridRowGetVisPos(XmLGridRow row)
|
|
{
|
|
return row->grid.visPos;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridRowIsHidden(XmLGridRow row)
|
|
{
|
|
if (!row->grid.height)
|
|
return True;
|
|
return False;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridRowIsSelected(XmLGridRow row)
|
|
{
|
|
return row->grid.selected;
|
|
}
|
|
|
|
static void
|
|
XmLGridRowSetSelected(XmLGridRow row,
|
|
Boolean selected)
|
|
{
|
|
row->grid.selected = selected;
|
|
}
|
|
|
|
static void
|
|
XmLGridRowSetVisPos(XmLGridRow row,
|
|
int visPos)
|
|
{
|
|
row->grid.visPos = visPos;
|
|
}
|
|
|
|
static int
|
|
XmLGridRowHeightInPixels(XmLGridRow row)
|
|
{
|
|
int i, count;
|
|
Dimension height, maxHeight;
|
|
XmLGridWidget g;
|
|
XmLGridCell cell;
|
|
XmLGridCallbackStruct cbs;
|
|
XmLGridCellRefValues *cellValues;
|
|
|
|
if (row->grid.sizePolicy == XmCONSTANT)
|
|
return row->grid.height;
|
|
if (!row->grid.height)
|
|
return 0;
|
|
if (!row->grid.heightInPixelsValid)
|
|
{
|
|
g = (XmLGridWidget)row->grid.grid;
|
|
count = XmLArrayGetCount(row->grid.cellArray);
|
|
if (!count)
|
|
{
|
|
cellValues = g->grid.defCellValues;
|
|
maxHeight = 4 + row->grid.height * cellValues->fontHeight +
|
|
cellValues->topMargin + cellValues->bottomMargin;
|
|
}
|
|
else
|
|
maxHeight = 0;
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
cell = (XmLGridCell)XmLArrayGet(row->grid.cellArray, i);
|
|
cbs.reason = XmCR_PREF_HEIGHT;
|
|
cbs.rowType = RowPosToType(g, row->grid.pos);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row->grid.pos);
|
|
cbs.columnType = ColPosToType(g, i);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, i);
|
|
cbs.object = (void *)row;
|
|
height = XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
if (height > maxHeight)
|
|
maxHeight = height;
|
|
}
|
|
row->grid.heightInPixels = maxHeight;
|
|
row->grid.heightInPixelsValid = 1;
|
|
}
|
|
return row->grid.heightInPixels;
|
|
}
|
|
|
|
static void
|
|
XmLGridRowHeightChanged(XmLGridRow row)
|
|
{
|
|
row->grid.heightInPixelsValid = 0;
|
|
}
|
|
|
|
/*
|
|
XmLGridColumn
|
|
*/
|
|
|
|
static XmLGridColumn
|
|
XmLGridColumnNew(Widget grid)
|
|
{
|
|
return XmLGridClassPartOfWidget(grid).columnNewProc(grid);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static XmLGridColumn
|
|
_GridColumnNew(Widget grid)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridColumn column;
|
|
int size;
|
|
|
|
g = (XmLGridWidget)grid;
|
|
size = XmLGridClassPartOfWidget(grid).columnRecSize;
|
|
column = (XmLGridColumn)malloc(size);
|
|
column->grid.grid = grid;
|
|
column->grid.widthInPixels = 0;
|
|
column->grid.widthInPixelsValid = 0;
|
|
column->grid.defCellValues = 0;
|
|
column->grid.selected = False;
|
|
column->grid.sizePolicy = XmVARIABLE;
|
|
column->grid.width = 8;
|
|
column->grid.userData = 0;
|
|
column->grid.resizable = True;
|
|
column->grid.hidden = 0;
|
|
return column;
|
|
}
|
|
|
|
static void
|
|
XmLGridColumnFree(Widget grid,
|
|
XmLGridColumn column)
|
|
{
|
|
XmLGridClassPartOfWidget(grid).columnFreeProc(column);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static void
|
|
_GridColumnFree(XmLGridColumn column)
|
|
{
|
|
if (column->grid.defCellValues)
|
|
XmLGridCellDerefValues(column->grid.defCellValues);
|
|
free((char *)column);
|
|
}
|
|
|
|
static int
|
|
XmLGridColumnGetPos(XmLGridColumn column)
|
|
{
|
|
return column->grid.pos;
|
|
}
|
|
|
|
static int
|
|
XmLGridColumnGetVisPos(XmLGridColumn column)
|
|
{
|
|
return column->grid.visPos;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridColumnIsHidden(XmLGridColumn column)
|
|
{
|
|
return column->grid.width == 0
|
|
|| column->grid.hidden;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridColumnIsSelected(XmLGridColumn column)
|
|
{
|
|
return column->grid.selected;
|
|
}
|
|
|
|
static void
|
|
XmLGridColumnSetSelected(XmLGridColumn column,
|
|
Boolean selected)
|
|
{
|
|
column->grid.selected = selected;
|
|
}
|
|
|
|
static void
|
|
XmLGridColumnSetVisPos(XmLGridColumn column,
|
|
int visPos)
|
|
{
|
|
column->grid.visPos = visPos;
|
|
}
|
|
|
|
static int
|
|
XmLGridColumnWidthInPixels(XmLGridColumn column)
|
|
{
|
|
int i, count;
|
|
Dimension width, maxWidth;
|
|
XmLGridCell cell;
|
|
XmLGridWidget g;
|
|
XmLGridCallbackStruct cbs;
|
|
XmLGridCellRefValues *cellValues;
|
|
|
|
if (column->grid.sizePolicy == XmCONSTANT)
|
|
return column->grid.width;
|
|
if (!column->grid.width)
|
|
return 0;
|
|
if (!column->grid.widthInPixelsValid)
|
|
{
|
|
g = (XmLGridWidget)column->grid.grid;
|
|
count = XmLArrayGetCount(g->grid.rowArray);
|
|
if (!count)
|
|
{
|
|
cellValues = g->grid.defCellValues;
|
|
maxWidth = 4 + column->grid.width * cellValues->fontWidth +
|
|
cellValues->leftMargin + cellValues->rightMargin;
|
|
}
|
|
else
|
|
maxWidth = 0;
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
cell = GetCell(g, i, column->grid.pos);
|
|
cbs.reason = XmCR_PREF_WIDTH;
|
|
cbs.rowType = RowPosToType(g, i);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, i);
|
|
cbs.columnType = ColPosToType(g, column->grid.pos);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, column->grid.pos);
|
|
cbs.object = (void *)column;
|
|
width = XmLGridCellAction(cell, (Widget)g, &cbs);
|
|
if (width > maxWidth)
|
|
maxWidth = width;
|
|
}
|
|
column->grid.widthInPixels = maxWidth;
|
|
column->grid.widthInPixelsValid = 1;
|
|
}
|
|
return column->grid.widthInPixels;
|
|
}
|
|
|
|
static void
|
|
XmLGridColumnWidthChanged(XmLGridColumn column)
|
|
{
|
|
column->grid.widthInPixelsValid = 0;
|
|
}
|
|
|
|
/*
|
|
XmLGridCell
|
|
*/
|
|
|
|
static XmLGridCell
|
|
XmLGridCellNew(void)
|
|
{
|
|
XmLGridCell c;
|
|
|
|
c = (XmLGridCell)malloc(sizeof(struct _XmLGridCellRec));
|
|
c->cell.refValues = 0;
|
|
c->cell.flags = 0;
|
|
return c;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellFree(Widget grid,
|
|
XmLGridCell cell)
|
|
{
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
cbs.reason = XmCR_FREE_VALUE;
|
|
XmLGridCellAction(cell, grid, &cbs);
|
|
XmLGridCellDerefValues(cell->cell.refValues);
|
|
free((char *)cell);
|
|
}
|
|
|
|
static int
|
|
XmLGridCellAction(XmLGridCell cell,
|
|
Widget w,
|
|
XmLGridCallbackStruct *cbs)
|
|
{
|
|
return XmLGridClassPartOfWidget(w).cellActionProc(cell, w, cbs);
|
|
}
|
|
|
|
/* Only to be called through Grid class */
|
|
static int
|
|
_GridCellAction(XmLGridCell cell,
|
|
Widget w,
|
|
XmLGridCallbackStruct *cbs)
|
|
{
|
|
int ret;
|
|
|
|
ret = 0;
|
|
switch (cbs->reason)
|
|
{
|
|
case XmCR_CELL_DRAW:
|
|
_XmLGridCellDrawBackground(cell, w, cbs->clipRect, cbs->drawInfo);
|
|
_XmLGridCellDrawValue(cell, w, cbs->clipRect, cbs->drawInfo);
|
|
_XmLGridCellDrawBorders(cell, w, cbs->clipRect, cbs->drawInfo);
|
|
break;
|
|
case XmCR_CELL_FOCUS_IN:
|
|
break;
|
|
case XmCR_CELL_FOCUS_OUT:
|
|
break;
|
|
case XmCR_CONF_TEXT:
|
|
_XmLGridCellConfigureText(cell, w, cbs->clipRect);
|
|
break;
|
|
case XmCR_EDIT_BEGIN:
|
|
ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
|
|
break;
|
|
case XmCR_EDIT_CANCEL:
|
|
break;
|
|
case XmCR_EDIT_COMPLETE:
|
|
_XmLGridCellCompleteTextEdit(cell, w);
|
|
break;
|
|
case XmCR_EDIT_INSERT:
|
|
ret = _XmLGridCellBeginTextEdit(cell, w, cbs->clipRect);
|
|
if (ret)
|
|
_XmLGridCellInsertText(cell, w);
|
|
break;
|
|
case XmCR_FREE_VALUE:
|
|
_XmLGridCellFreeValue(cell);
|
|
break;
|
|
case XmCR_PREF_HEIGHT:
|
|
ret = _XmLGridCellGetHeight(cell, w,(XmLGridRow)cbs->object);
|
|
break;
|
|
case XmCR_PREF_WIDTH:
|
|
ret = _XmLGridCellGetWidth(cell, w,(XmLGridColumn)cbs->object);
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static XmLGridCellRefValues *
|
|
XmLGridCellGetRefValues(XmLGridCell cell)
|
|
{
|
|
return cell->cell.refValues;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetRefValues(XmLGridCell cell,
|
|
XmLGridCellRefValues *values)
|
|
{
|
|
values->refCount++;
|
|
XmLGridCellDerefValues(cell->cell.refValues);
|
|
cell->cell.refValues = values;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellDerefValues(XmLGridCellRefValues *values)
|
|
{
|
|
if (!values)
|
|
return;
|
|
values->refCount--;
|
|
if (!values->refCount)
|
|
{
|
|
XmFontListFree(values->fontList);
|
|
free((char *)values);
|
|
}
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridCellInRowSpan(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellInRowSpanFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridCellInColumnSpan(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellInColumnSpanFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridCellIsSelected(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellSelectedFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridCellIsValueSet(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellValueSetFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetValueSet(XmLGridCell cell,
|
|
Boolean set)
|
|
{
|
|
cell->cell.flags |= XmLGridCellValueSetFlag;
|
|
if (set != True)
|
|
cell->cell.flags ^= XmLGridCellValueSetFlag;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetInRowSpan(XmLGridCell cell,
|
|
Boolean set)
|
|
{
|
|
cell->cell.flags |= XmLGridCellInRowSpanFlag;
|
|
if (set != True)
|
|
cell->cell.flags ^= XmLGridCellInRowSpanFlag;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetInColumnSpan(XmLGridCell cell,
|
|
Boolean set)
|
|
{
|
|
cell->cell.flags |= XmLGridCellInColumnSpanFlag;
|
|
if (set != True)
|
|
cell->cell.flags ^= XmLGridCellInColumnSpanFlag;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetSelected(XmLGridCell cell,
|
|
Boolean selected)
|
|
{
|
|
cell->cell.flags |= XmLGridCellSelectedFlag;
|
|
if (selected != True)
|
|
cell->cell.flags ^= XmLGridCellSelectedFlag;
|
|
}
|
|
|
|
/*Xfe Additions*/
|
|
static Boolean
|
|
XmLGridCellDrawSort(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellDrawSortFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
static Boolean
|
|
XmLGridCellSortAscending(XmLGridCell cell)
|
|
{
|
|
if (cell->cell.flags & XmLGridCellSortAscendingFlag)
|
|
return True;
|
|
return False;
|
|
}
|
|
static void
|
|
XmLGridCellSetDrawSort(XmLGridCell cell, Boolean drawSort)
|
|
{
|
|
cell->cell.flags |= XmLGridCellDrawSortFlag;
|
|
if (drawSort != True)
|
|
cell->cell.flags ^= XmLGridCellDrawSortFlag;
|
|
}
|
|
static void
|
|
XmLGridCellSetSortAscending(XmLGridCell cell, Boolean ascending)
|
|
{
|
|
cell->cell.flags |= XmLGridCellSortAscendingFlag;
|
|
if (ascending != True)
|
|
cell->cell.flags ^= XmLGridCellSortAscendingFlag;
|
|
}
|
|
|
|
|
|
static void
|
|
XmLGridCellAllocIcon(XmLGridCell cell)
|
|
{
|
|
XmLGridCellIcon *icon;
|
|
|
|
icon = (XmLGridCellIcon *)malloc(sizeof(XmLGridCellIcon));
|
|
icon->pix.pixmap = XmUNSPECIFIED_PIXMAP;
|
|
icon->pix.pixmask = XmUNSPECIFIED_PIXMAP;
|
|
icon->pix.width = 0;
|
|
icon->pix.height = 0;
|
|
icon->string = 0;
|
|
cell->cell.value = (void *)icon;
|
|
XmLGridCellSetValueSet(cell, True);
|
|
}
|
|
|
|
static void
|
|
XmLGridCellAllocPixmap(XmLGridCell cell)
|
|
{
|
|
XmLGridCellPixmap *pix;
|
|
|
|
pix = (XmLGridCellPixmap *)malloc(sizeof(XmLGridCellPixmap));
|
|
pix->width = 0;
|
|
pix->height = 0;
|
|
pix->pixmap = XmUNSPECIFIED_PIXMAP;
|
|
pix->pixmask = XmUNSPECIFIED_PIXMAP;
|
|
cell->cell.value = (void *)pix;
|
|
XmLGridCellSetValueSet(cell, True);
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetString(XmLGridCell cell,
|
|
XmString string,
|
|
Boolean copy)
|
|
{
|
|
XmLGridCellIcon *icon;
|
|
|
|
if (cell->cell.refValues->type == XmSTRING_CELL)
|
|
{
|
|
_XmLGridCellFreeValue(cell);
|
|
if (string)
|
|
{
|
|
if (copy == True)
|
|
cell->cell.value = (void *)XmStringCopy(string);
|
|
else
|
|
cell->cell.value = (void *)string;
|
|
XmLGridCellSetValueSet(cell, True);
|
|
}
|
|
else
|
|
XmLGridCellSetValueSet(cell, False);
|
|
}
|
|
else if (cell->cell.refValues->type == XmICON_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == False)
|
|
XmLGridCellAllocIcon(cell);
|
|
icon = (XmLGridCellIcon *)cell->cell.value;
|
|
if (icon->string)
|
|
XmStringFree(icon->string);
|
|
if (string && copy == True)
|
|
icon->string = XmStringCopy(string);
|
|
else
|
|
icon->string = string;
|
|
}
|
|
else if (string && copy == False)
|
|
XmStringFree(string);
|
|
}
|
|
|
|
static XmString
|
|
XmLGridCellGetString(XmLGridCell cell)
|
|
{
|
|
XmString str;
|
|
|
|
str = 0;
|
|
if (cell->cell.refValues->type == XmSTRING_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
str = (XmString)cell->cell.value;
|
|
}
|
|
else if (cell->cell.refValues->type == XmICON_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
str = ((XmLGridCellIcon *)cell->cell.value)->string;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetToggle(XmLGridCell cell,
|
|
Boolean state)
|
|
{
|
|
if (cell->cell.refValues->type == XmTOGGLE_CELL)
|
|
{
|
|
if (state)
|
|
cell->cell.value = (void *)1;
|
|
else
|
|
cell->cell.value = (void *)0;
|
|
XmLGridCellSetValueSet(cell, True);
|
|
}
|
|
}
|
|
|
|
static Boolean
|
|
XmLGridCellGetToggle(XmLGridCell cell)
|
|
{
|
|
Boolean toggled;
|
|
|
|
toggled = False;
|
|
if (cell->cell.refValues->type == XmTOGGLE_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True &&
|
|
cell->cell.value == (void *)1)
|
|
toggled = True;
|
|
}
|
|
return toggled;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetPixmap(XmLGridCell cell,
|
|
Pixmap pixmap,
|
|
Dimension width,
|
|
Dimension height)
|
|
{
|
|
XmLGridCellPixmap *pix;
|
|
|
|
pix = 0;
|
|
if (cell->cell.refValues->type == XmPIXMAP_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == False)
|
|
XmLGridCellAllocPixmap(cell);
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
}
|
|
else if (cell->cell.refValues->type == XmICON_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == False)
|
|
XmLGridCellAllocIcon(cell);
|
|
pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
|
|
}
|
|
if (!pix)
|
|
return;
|
|
pix->pixmap = pixmap;
|
|
pix->height = height;
|
|
pix->width = width;
|
|
}
|
|
|
|
static void
|
|
XmLGridCellSetPixmask(XmLGridCell cell,
|
|
Pixmap pixmask)
|
|
{
|
|
XmLGridCellPixmap *pix;
|
|
|
|
if (XmLGridCellIsValueSet(cell) == False)
|
|
{
|
|
fprintf(stderr, "XmLGridCellSetPixmask: pixmap must be set ");
|
|
fprintf(stderr, "before pixmask\n");
|
|
return;
|
|
}
|
|
pix = 0;
|
|
if (cell->cell.refValues->type == XmPIXMAP_CELL)
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
else if (cell->cell.refValues->type == XmICON_CELL)
|
|
pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
|
|
if (!pix)
|
|
return;
|
|
pix->pixmask = pixmask;
|
|
}
|
|
|
|
static XmLGridCellPixmap *
|
|
XmLGridCellGetPixmap(XmLGridCell cell)
|
|
{
|
|
XmLGridCellPixmap *pix;
|
|
|
|
pix = 0;
|
|
if (cell->cell.refValues->type == XmPIXMAP_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
}
|
|
else if (cell->cell.refValues->type == XmICON_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
pix = &((XmLGridCellIcon *)cell->cell.value)->pix;
|
|
}
|
|
return pix;
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
void
|
|
_XmLGridCellDrawBackground(XmLGridCell cell,
|
|
Widget w,
|
|
XRectangle *clipRect,
|
|
XmLGridDrawStruct *ds)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
|
|
dpy = XtDisplay(w);
|
|
win = XtWindow(w);
|
|
if (ds->drawSelected == True)
|
|
XSetForeground(dpy, ds->gc, ds->selectBackground);
|
|
else
|
|
XSetForeground(dpy, ds->gc, ds->background);
|
|
XFillRectangle(dpy, win, ds->gc, clipRect->x, clipRect->y,
|
|
clipRect->width, clipRect->height);
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
void
|
|
_XmLGridCellDrawBorders(XmLGridCell cell,
|
|
Widget w,
|
|
XRectangle *clipRect,
|
|
XmLGridDrawStruct *ds)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
Window win;
|
|
GC gc;
|
|
Pixel black, white;
|
|
int x1, x2, y1, y2, loff, roff;
|
|
int drawLeft, drawRight, drawBot, drawTop;
|
|
XRectangle *cellRect;
|
|
unsigned char borderType;
|
|
|
|
g = (XmLGridWidget)w;
|
|
dpy = XtDisplay(w);
|
|
win = XtWindow(w);
|
|
gc = ds->gc;
|
|
cellRect = ds->cellRect;
|
|
black = BlackPixelOfScreen(XtScreen(w));
|
|
white = WhitePixelOfScreen(XtScreen(w));
|
|
x1 = clipRect->x;
|
|
x2 = clipRect->x + clipRect->width - 1;
|
|
y1 = clipRect->y;
|
|
y2 = clipRect->y + clipRect->height - 1;
|
|
drawLeft = 1;
|
|
drawRight = 1;
|
|
drawBot = 1;
|
|
drawTop = 1;
|
|
if (cellRect->x != clipRect->x)
|
|
drawLeft = 0;
|
|
if (cellRect->x + cellRect->width != clipRect->x + clipRect->width)
|
|
drawRight = 0;
|
|
if (cellRect->y != clipRect->y)
|
|
drawTop = 0;
|
|
if (cellRect->y + cellRect->height != clipRect->y + clipRect->height)
|
|
drawBot = 0;
|
|
borderType = cell->cell.refValues->rightBorderType;
|
|
if (borderType != XmBORDER_NONE && drawRight)
|
|
{
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
|
XSetForeground(dpy, gc, cell->cell.refValues->rightBorderColor);
|
|
XDrawLine(dpy, win, gc, x2, y1, x2, y2);
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
|
|
}
|
|
borderType = cell->cell.refValues->bottomBorderType;
|
|
if (borderType != XmBORDER_NONE && drawBot)
|
|
{
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
|
XSetForeground(dpy, gc, cell->cell.refValues->bottomBorderColor);
|
|
XDrawLine(dpy, win, gc, x1, y2, x2, y2);
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
|
|
}
|
|
borderType = cell->cell.refValues->topBorderType;
|
|
if (borderType != XmBORDER_NONE && drawTop)
|
|
{
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
|
XSetForeground(dpy, gc, cell->cell.refValues->topBorderColor);
|
|
XDrawLine(dpy, win, gc, x1, y1, x2, y1);
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
|
|
}
|
|
borderType = cell->cell.refValues->leftBorderType;
|
|
if (borderType != XmBORDER_NONE && drawLeft)
|
|
{
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinMiter);
|
|
XSetForeground(dpy, gc, cell->cell.refValues->leftBorderColor);
|
|
XDrawLine(dpy, win, gc, x1, y1, x1, y2);
|
|
if (borderType == XmBORDER_DASH)
|
|
XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinMiter);
|
|
}
|
|
if (ds->drawFocusType == XmDRAW_FOCUS_NONE)
|
|
return;
|
|
if (ds->drawFocusType == XmDRAW_FOCUS_LEFT)
|
|
drawRight = 0;
|
|
else if (ds->drawFocusType == XmDRAW_FOCUS_RIGHT)
|
|
drawLeft = 0;
|
|
else if (ds->drawFocusType == XmDRAW_FOCUS_MID)
|
|
{
|
|
drawLeft = 0;
|
|
drawRight = 0;
|
|
}
|
|
if (!drawLeft)
|
|
loff = 0;
|
|
else
|
|
loff = 2;
|
|
if (!drawRight)
|
|
roff = 0;
|
|
else
|
|
roff = 2;
|
|
if (g->grid.highlightThickness < 2)
|
|
return;
|
|
XSetForeground(dpy, gc, g->manager.highlight_color);
|
|
if (drawTop)
|
|
XDrawLine(dpy, win, gc, x1, y1, x2, y1);
|
|
if (drawLeft)
|
|
XDrawLine(dpy, win, gc, x1, y1 + 2, x1, y2);
|
|
if (drawRight)
|
|
XDrawLine(dpy, win, gc, x2, y1 + 2, x2, y2);
|
|
if (drawBot)
|
|
XDrawLine(dpy, win, gc, x1 + loff, y2, x2 - roff, y2);
|
|
if (drawTop && clipRect->height > 1)
|
|
XDrawLine(dpy, win, gc, x1, y1 + 1, x2, y1 + 1);
|
|
if (drawBot && (int)clipRect->height > 1 &&
|
|
(int)clipRect->width > roff &&
|
|
(int)clipRect->width > loff)
|
|
XDrawLine(dpy, win, gc, x1 + loff, y2 - 1, x2 - roff, y2 - 1);
|
|
if (clipRect->width > 1 && clipRect->height > 2)
|
|
{
|
|
if (drawLeft)
|
|
XDrawLine(dpy, win, gc, x1 + 1, y1 + 2, x1 + 1, y2);
|
|
if (drawRight)
|
|
XDrawLine(dpy, win, gc, x2 - 1, y1 + 2, x2 - 1, y2);
|
|
}
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
void
|
|
_XmLGridCellDrawValue(XmLGridCell cell,
|
|
Widget w,
|
|
XRectangle *clipRect,
|
|
XmLGridDrawStruct *ds)
|
|
{
|
|
XmLGridWidget g;
|
|
Display *dpy;
|
|
XmLGridCellPixmap *pix;
|
|
XmLGridCellIcon *icon;
|
|
XRectangle cellRect;
|
|
XmLGridCellRefValues *cellValues;
|
|
int type, horizMargin, vertMargin, xoff;
|
|
|
|
g = (XmLGridWidget)w;
|
|
cellRect = *ds->cellRect;
|
|
cellValues = cell->cell.refValues;
|
|
horizMargin = ds->leftMargin + ds->rightMargin;
|
|
vertMargin = ds->topMargin + ds->bottomMargin;
|
|
if (horizMargin >= (int)cellRect.width ||
|
|
vertMargin >= (int)cellRect.height)
|
|
return;
|
|
type = cellValues->type;
|
|
cellRect.x += ds->leftMargin;
|
|
cellRect.y += ds->topMargin;
|
|
cellRect.width -= horizMargin;
|
|
cellRect.height -= vertMargin;
|
|
dpy = XtDisplay(w);
|
|
if (type == XmSTRING_CELL && XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
if (ds->drawSelected == True)
|
|
XSetForeground(dpy, ds->gc, ds->selectForeground);
|
|
else
|
|
XSetForeground(dpy, ds->gc, ds->foreground);
|
|
XmLStringDraw(w, (XmString)cell->cell.value, ds->stringDirection,
|
|
ds->fontList, ds->alignment, ds->gc,
|
|
&cellRect, clipRect);
|
|
}
|
|
if (type == XmPIXMAP_CELL && XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
XmLPixmapDraw(w, pix->pixmap, pix->pixmask,
|
|
pix->width, pix->height, ds->alignment,
|
|
ds->gc, &cellRect, clipRect);
|
|
}
|
|
if (type == XmICON_CELL && XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
icon = (XmLGridCellIcon *)cell->cell.value;
|
|
if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
XmLPixmapDraw(w, icon->pix.pixmap, icon->pix.pixmask,
|
|
icon->pix.width, icon->pix.height, ds->alignment,
|
|
ds->gc, &cellRect, clipRect);
|
|
xoff = icon->pix.width + g->grid.iconSpacing;
|
|
cellRect.x += xoff;
|
|
if (xoff < (int)cellRect.width)
|
|
cellRect.width -= xoff;
|
|
else
|
|
cellRect.width = 0;
|
|
}
|
|
if (cellRect.width && icon->string)
|
|
{
|
|
if (ds->drawSelected == True)
|
|
XSetForeground(dpy, ds->gc, ds->selectForeground);
|
|
else
|
|
XSetForeground(dpy, ds->gc, ds->foreground);
|
|
XmLStringDraw(w, icon->string, ds->stringDirection,
|
|
ds->fontList, ds->alignment, ds->gc,
|
|
&cellRect, clipRect);
|
|
}
|
|
}
|
|
if (type == XmTOGGLE_CELL)
|
|
XmLDrawToggle(w, XmLGridCellGetToggle(cell),
|
|
g->grid.toggleSize, ds->alignment, ds->gc,
|
|
ds->background, g->grid.toggleTopColor,
|
|
g->grid.toggleBotColor, ds->foreground,
|
|
&cellRect, clipRect);
|
|
|
|
if (cellRect.width > cellRect.height - 4 && XmLGridCellDrawSort(cell))
|
|
{
|
|
int arrow_direction = XmLGridCellSortAscending(cell);
|
|
int arrow_size = cellRect.height * 0.75;
|
|
|
|
if (arrow_size > 0)
|
|
{
|
|
XSetForeground(dpy, ds->gc, ds->background);
|
|
|
|
_XmDrawArrow(dpy, XtWindow(w),
|
|
((XmManagerWidget)g)->manager.bottom_shadow_GC,
|
|
((XmManagerWidget)g)->manager.top_shadow_GC,
|
|
ds->gc,
|
|
cellRect.x + cellRect.width - arrow_size - 2,
|
|
cellRect.y + (cellRect.height / 2 - arrow_size / 2),
|
|
arrow_size,
|
|
arrow_size,
|
|
2,
|
|
arrow_direction);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static int
|
|
_XmLGridCellConfigureText(XmLGridCell cell, Widget w, XRectangle *rect)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)w;
|
|
XtConfigureWidget(g->grid.text, rect->x, rect->y,
|
|
rect->width, rect->height, 0);
|
|
return(0);
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static int
|
|
_XmLGridCellBeginTextEdit(XmLGridCell cell,
|
|
Widget w,
|
|
XRectangle *clipRect)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
Widget text;
|
|
|
|
if ((cell->cell.refValues->type != XmSTRING_CELL &&
|
|
cell->cell.refValues->type != XmICON_CELL)
|
|
|| cell->cell.refValues->editable != True
|
|
|| g->grid.useTextWidget != True)
|
|
return 0;
|
|
XtVaGetValues(w,
|
|
XmNtextWidget, &text,
|
|
NULL);
|
|
XtVaSetValues(text,
|
|
XmNfontList, cell->cell.refValues->fontList,
|
|
NULL);
|
|
return 1;
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static void
|
|
_XmLGridCellCompleteTextEdit(XmLGridCell cell,
|
|
Widget w)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
Widget text;
|
|
char *s;
|
|
int i, len;
|
|
|
|
if ((cell->cell.refValues->type != XmSTRING_CELL &&
|
|
cell->cell.refValues->type != XmICON_CELL)
|
|
|| cell->cell.refValues->editable != True
|
|
|| g->grid.useTextWidget != True)
|
|
return;
|
|
XtVaGetValues(w,
|
|
XmNtextWidget, &text,
|
|
NULL);
|
|
s = XmTextGetString(text);
|
|
len = strlen(s);
|
|
for (i = 0; i < len - 1; i++)
|
|
if (s[i] == '\\' && s[i + 1] == 'n')
|
|
{
|
|
s[i] = '\n';
|
|
strcpy(&s[i + 1], &s[i + 2]);
|
|
}
|
|
XmLGridCellSetString(cell,
|
|
XmStringCreateLtoR(s, XmSTRING_DEFAULT_CHARSET),
|
|
False);
|
|
#if 0
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
XmStringFree((XmString)cell->cell.value);
|
|
if (strlen(s))
|
|
{
|
|
cell->cell.value = (void *)XmStringCreateLtoR(s,
|
|
XmSTRING_DEFAULT_CHARSET);
|
|
XmLGridCellSetValueSet(cell, True);
|
|
}
|
|
else
|
|
XmLGridCellSetValueSet(cell, False);
|
|
#endif /*0*/
|
|
XtFree(s);
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static void
|
|
_XmLGridCellInsertText(XmLGridCell cell,
|
|
Widget w)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
char *s;
|
|
Widget text = NULL;
|
|
|
|
if ((cell->cell.refValues->type != XmSTRING_CELL &&
|
|
cell->cell.refValues->type != XmICON_CELL)
|
|
|| cell->cell.refValues->editable != True
|
|
|| g->grid.useTextWidget != True)
|
|
return;
|
|
XtVaGetValues(w,
|
|
XmNtextWidget, &text,
|
|
NULL);
|
|
s = 0;
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
s = CvtXmStringToStr(XmLGridCellGetString(cell));
|
|
if (s)
|
|
{
|
|
XmTextSetString(text, s);
|
|
free(s);
|
|
}
|
|
else
|
|
XmTextSetString(text, "");
|
|
XmTextSetInsertionPosition(text, XmTextGetLastPosition(text));
|
|
XmProcessTraversal(text, XmTRAVERSE_CURRENT);
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static int
|
|
_XmLGridCellGetHeight(XmLGridCell cell,
|
|
Widget w,
|
|
XmLGridRow row)
|
|
{
|
|
XmLGridCellPixmap *pix;
|
|
XmLGridCellIcon *icon;
|
|
XmLGridCellRefValues *cellValues;
|
|
int height, pixHeight;
|
|
|
|
cellValues = cell->cell.refValues;
|
|
height = -1;
|
|
if (cellValues->type == XmPIXMAP_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
if (pix->height)
|
|
height = 4 + pix->height + cellValues->topMargin +
|
|
cellValues->bottomMargin;
|
|
}
|
|
}
|
|
else if (cellValues->type == XmICON_CELL)
|
|
{
|
|
pixHeight = 0;
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
icon = (XmLGridCellIcon *)cell->cell.value;
|
|
if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.height)
|
|
pixHeight = 4 + icon->pix.height +
|
|
cellValues->topMargin + cellValues->bottomMargin;
|
|
}
|
|
height = 4 + row->grid.height * cellValues->fontHeight +
|
|
cellValues->topMargin + cellValues->bottomMargin;
|
|
if (pixHeight > height)
|
|
height = pixHeight;
|
|
}
|
|
else if (cellValues->type == XmTOGGLE_CELL)
|
|
height = 4 + 16 + cellValues->topMargin +
|
|
cellValues->bottomMargin;
|
|
else if (cellValues->type == XmSTRING_CELL)
|
|
{
|
|
height = 4 + row->grid.height * cellValues->fontHeight +
|
|
cellValues->topMargin + cellValues->bottomMargin;
|
|
}
|
|
if (height < 0 || cellValues->rowSpan)
|
|
height = 4;
|
|
return height;
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static int
|
|
_XmLGridCellGetWidth(XmLGridCell cell,
|
|
Widget w,
|
|
XmLGridColumn col)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
XmLGridCellPixmap *pix;
|
|
XmLGridCellIcon *icon;
|
|
XmLGridCellRefValues *cellValues;
|
|
int width;
|
|
|
|
cellValues = cell->cell.refValues;
|
|
width = -1;
|
|
if (cellValues->type == XmPIXMAP_CELL)
|
|
{
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
pix = (XmLGridCellPixmap *)cell->cell.value;
|
|
if (pix->width)
|
|
width = 4 + pix->width + cellValues->leftMargin +
|
|
cellValues->rightMargin;
|
|
}
|
|
}
|
|
else if (cellValues->type == XmICON_CELL)
|
|
{
|
|
width = 4 + col->grid.width * cellValues->fontWidth +
|
|
cellValues->leftMargin + cellValues->rightMargin;
|
|
if (XmLGridCellIsValueSet(cell) == True)
|
|
{
|
|
icon = (XmLGridCellIcon *)cell->cell.value;
|
|
if (icon->pix.pixmap != XmUNSPECIFIED_PIXMAP && icon->pix.width)
|
|
width += icon->pix.width + g->grid.iconSpacing;
|
|
}
|
|
}
|
|
else if (cellValues->type == XmTOGGLE_CELL)
|
|
width = 4 + 16 + cellValues->leftMargin +
|
|
cellValues->rightMargin;
|
|
else if (cellValues->type == XmSTRING_CELL)
|
|
width = 4 + col->grid.width * cellValues->fontWidth +
|
|
cellValues->leftMargin + cellValues->rightMargin;
|
|
if (width < 0 || cellValues->columnSpan)
|
|
width = 4;
|
|
return width;
|
|
}
|
|
|
|
/* Only to be called by XmLGridCellAction() */
|
|
static void
|
|
_XmLGridCellFreeValue(XmLGridCell cell)
|
|
{
|
|
int type;
|
|
XmLGridCellIcon *icon;
|
|
|
|
if (XmLGridCellIsValueSet(cell) == False)
|
|
return;
|
|
type = cell->cell.refValues->type;
|
|
if (type == XmSTRING_CELL)
|
|
XmStringFree((XmString)cell->cell.value);
|
|
else if (type == XmPIXMAP_CELL)
|
|
free((char *)cell->cell.value);
|
|
else if (type == XmICON_CELL)
|
|
{
|
|
icon = (XmLGridCellIcon *)cell->cell.value;
|
|
if (icon->string)
|
|
XmStringFree(icon->string);
|
|
free((char *)icon);
|
|
}
|
|
XmLGridCellSetValueSet(cell, False);
|
|
}
|
|
|
|
/*
|
|
Public Functions
|
|
*/
|
|
|
|
Widget
|
|
XmLCreateGrid(Widget parent,
|
|
char *name,
|
|
ArgList arglist,
|
|
Cardinal argcount)
|
|
{
|
|
return XtCreateWidget(name, xmlGridWidgetClass, parent,
|
|
arglist, argcount);
|
|
}
|
|
|
|
void
|
|
XmLGridAddColumns(Widget w,
|
|
unsigned char type,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridColumn col;
|
|
XmLGridRow row;
|
|
XmLGridCell cell;
|
|
XmLGridCallbackStruct cbs;
|
|
int i, j, rowCount, hasAddCB, redraw;
|
|
|
|
g = WidgetToGrid(w, "AddColumns()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
redraw = 0;
|
|
position = ColTypePosToPos(g, type, position, 1);
|
|
if (position < 0)
|
|
position = ColTypePosToPos(g, type, -1, 1);
|
|
/* adjust count */
|
|
if (type == XmHEADING)
|
|
{
|
|
g->grid.headingColCount += count;
|
|
g->grid.leftFixedCount += count;
|
|
redraw = 1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
g->grid.footerColCount += count;
|
|
g->grid.rightFixedCount += count;
|
|
redraw = 1;
|
|
}
|
|
else /* XmCONTENT */
|
|
g->grid.colCount += count;
|
|
|
|
hasAddCB = 0;
|
|
if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
|
|
hasAddCB = 1;
|
|
/* add columns */
|
|
XmLArrayAdd(g->grid.colArray, position, count);
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
col = 0;
|
|
if (hasAddCB)
|
|
{
|
|
cbs.reason = XmCR_ADD_COLUMN;
|
|
cbs.columnType = type;
|
|
cbs.object = 0;
|
|
XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
|
|
col = (XmLGridColumn)cbs.object;
|
|
}
|
|
if (!col)
|
|
col = XmLGridColumnNew(w);
|
|
XmLArraySet(g->grid.colArray, position + i, col);
|
|
}
|
|
/* add cells */
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
for (j = 0; j < rowCount; j++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
|
|
XmLArrayAdd(XmLGridRowCells(row), position, count);
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
cell = 0;
|
|
if (hasAddCB)
|
|
{
|
|
cbs.reason = XmCR_ADD_CELL;
|
|
cbs.rowType = RowPosToType(g, j);
|
|
cbs.columnType = type;
|
|
cbs.object = 0;
|
|
XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
|
|
cell = (XmLGridCell)cbs.object;
|
|
}
|
|
if (!cell)
|
|
cell = XmLGridCellNew();
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
if (col->grid.defCellValues)
|
|
XmLGridCellSetRefValues(cell, col->grid.defCellValues);
|
|
else
|
|
XmLGridCellSetRefValues(cell, g->grid.defCellValues);
|
|
XmLArraySet(XmLGridRowCells(row), i, cell);
|
|
}
|
|
XmLGridRowHeightChanged(row);
|
|
}
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
XmLGridColumnWidthChanged(col);
|
|
}
|
|
/* sanity check */
|
|
if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
|
|
g->grid.colCount + g->grid.footerColCount)
|
|
XmLWarning(w, "AddColumns() - count sanity check failed");
|
|
|
|
/* maintain scroll and focus position */
|
|
if (g->grid.hsPolicy == XmCONSTANT)
|
|
{
|
|
if (type == XmCONTENT && g->grid.colCount == count)
|
|
g->grid.scrollCol = 0;
|
|
else if (position <= g->grid.scrollCol)
|
|
g->grid.scrollCol += count;
|
|
}
|
|
if (position <= g->grid.focusCol)
|
|
g->grid.focusCol += count;
|
|
VisPosChanged(g, 0);
|
|
HorizLayout(g, 1);
|
|
VertLayout(g, 1);
|
|
if (g->grid.focusCol == -1 && type == XmCONTENT)
|
|
{
|
|
if (g->grid.focusRow != -1)
|
|
SetFocus(g, g->grid.focusRow, position, 0, 0);
|
|
else
|
|
g->grid.focusCol = position;
|
|
}
|
|
for (i = position; i < position + count; i++)
|
|
redraw |= ColIsVisible(g, i);
|
|
if (redraw)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridAddRows(Widget w,
|
|
unsigned char type,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCell cell;
|
|
XmLGridCallbackStruct cbs;
|
|
int i, j, hasAddCB, redraw, colCount;
|
|
|
|
g = WidgetToGrid(w, "AddRows()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
redraw = 0;
|
|
position = RowTypePosToPos(g, type, position, 1);
|
|
if (position < 0)
|
|
position = RowTypePosToPos(g, type, -1, 1);
|
|
/* adjust count */
|
|
if (type == XmHEADING)
|
|
{
|
|
g->grid.headingRowCount += count;
|
|
g->grid.topFixedCount += count;
|
|
redraw = 1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
g->grid.footerRowCount += count;
|
|
g->grid.bottomFixedCount += count;
|
|
redraw = 1;
|
|
}
|
|
else /* XmCONTENT */
|
|
g->grid.rowCount += count;
|
|
|
|
/* add rows and cells */
|
|
XmLArrayAdd(g->grid.rowArray, position, count);
|
|
colCount = XmLArrayGetCount(g->grid.colArray);
|
|
hasAddCB = 0;
|
|
if (XtHasCallbacks(w, XmNaddCallback) == XtCallbackHasSome)
|
|
hasAddCB = 1;
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
row = 0;
|
|
if (hasAddCB)
|
|
{
|
|
cbs.reason = XmCR_ADD_ROW;
|
|
cbs.rowType = type;
|
|
cbs.object = 0;
|
|
XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
|
|
row = (XmLGridRow)cbs.object;
|
|
}
|
|
if (!row)
|
|
row = XmLGridRowNew(w);
|
|
XmLArraySet(g->grid.rowArray, position + i, row);
|
|
XmLArrayAdd(XmLGridRowCells(row), 0, colCount);
|
|
for (j = 0; j < colCount; j++)
|
|
{
|
|
cell = 0;
|
|
if (hasAddCB)
|
|
{
|
|
cbs.reason = XmCR_ADD_CELL;
|
|
cbs.rowType = type;
|
|
cbs.columnType = ColPosToType(g, j);
|
|
cbs.object = 0;
|
|
XtCallCallbackList(w, g->grid.addCallback, (XtPointer)&cbs);
|
|
cell = (XmLGridCell)cbs.object;
|
|
}
|
|
if (!cell)
|
|
cell = XmLGridCellNew();
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
|
|
if (col->grid.defCellValues)
|
|
XmLGridCellSetRefValues(cell, col->grid.defCellValues);
|
|
else
|
|
XmLGridCellSetRefValues(cell, g->grid.defCellValues);
|
|
XmLArraySet(XmLGridRowCells(row), j, cell);
|
|
}
|
|
XmLGridRowHeightChanged(row);
|
|
}
|
|
for (j = 0; j < colCount; j++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, j);
|
|
XmLGridColumnWidthChanged(col);
|
|
}
|
|
/* sanity check */
|
|
if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
|
|
g->grid.rowCount + g->grid.footerRowCount)
|
|
XmLWarning(w, "AddRows() - count sanity check failed");
|
|
|
|
/* maintain scroll and focus position */
|
|
if (g->grid.vsPolicy == XmCONSTANT)
|
|
{
|
|
if (type == XmCONTENT && g->grid.rowCount == count)
|
|
g->grid.scrollRow = 0;
|
|
else if (position <= g->grid.scrollRow)
|
|
g->grid.scrollRow += count;
|
|
}
|
|
if (position <= g->grid.focusRow)
|
|
g->grid.focusRow += count;
|
|
VisPosChanged(g, 1);
|
|
HorizLayout(g, 1);
|
|
VertLayout(g, 1);
|
|
if (g->grid.focusRow == -1 && type == XmCONTENT)
|
|
{
|
|
if (g->grid.focusCol != -1)
|
|
SetFocus(g, position, g->grid.focusCol, 0, 0);
|
|
else
|
|
g->grid.focusRow = position;
|
|
}
|
|
for (i = position; i < position + count; i++)
|
|
redraw |= RowIsVisible(g, i);
|
|
if (redraw)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
|
|
#ifdef XmLEVAL
|
|
if (g->grid.rowCount > 100)
|
|
{
|
|
fprintf(stderr, "XmL: evaluation version only supports <= 100 rows\n");
|
|
exit(0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
XmLGridDeleteAllColumns(Widget w,
|
|
unsigned char type)
|
|
{
|
|
XmLGridWidget g;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "DeleteAllColumns()");
|
|
if (!g)
|
|
return;
|
|
if (type == XmHEADING)
|
|
n = g->grid.headingColCount;
|
|
else if (type == XmCONTENT)
|
|
n = g->grid.colCount;
|
|
else if (type == XmFOOTER)
|
|
n = g->grid.footerColCount;
|
|
else
|
|
{
|
|
XmLWarning(w, "DeleteAllColumns() - invalid type");
|
|
return;
|
|
}
|
|
if (!n)
|
|
return;
|
|
XmLGridDeleteColumns(w, type, 0, n);
|
|
}
|
|
|
|
void
|
|
XmLGridDeleteAllRows(Widget w,
|
|
unsigned char type)
|
|
{
|
|
XmLGridWidget g;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "DeleteAllRows()");
|
|
if (!g)
|
|
return;
|
|
if (type == XmHEADING)
|
|
n = g->grid.headingRowCount;
|
|
else if (type == XmCONTENT)
|
|
n = g->grid.rowCount;
|
|
else if (type == XmFOOTER)
|
|
n = g->grid.footerRowCount;
|
|
else
|
|
{
|
|
XmLWarning(w, "DeleteAllRows() - invalid type");
|
|
return;
|
|
}
|
|
if (!n)
|
|
return;
|
|
XmLGridDeleteRows(w, type, 0, n);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectAllRows(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectAllRows()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectAllColumns(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectAllColumns()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectAllCells(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectAllCells()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectCell(Widget w,
|
|
int row,
|
|
int column,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectCell()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectColumn(Widget w,
|
|
int column,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectColumn()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeselectRow(Widget w,
|
|
int row,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "DeselectRow()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, False, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridDeleteColumns(Widget w,
|
|
unsigned char type,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCallbackStruct cbs;
|
|
int changeFocus, i, j, rowCount, lastPos, redraw;
|
|
|
|
g = WidgetToGrid(w, "DeleteColumns()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
lastPos = ColTypePosToPos(g, type, position + count - 1, 0);
|
|
position = ColTypePosToPos(g, type, position, 0);
|
|
if (position < 0 || lastPos < 0)
|
|
{
|
|
XmLWarning(w, "DeleteColumns() - invalid position");
|
|
return;
|
|
}
|
|
changeFocus = 0;
|
|
if (position <= g->grid.focusCol && lastPos >= g->grid.focusCol)
|
|
{
|
|
/* deleting focus col */
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
ChangeFocus(g, g->grid.focusRow, -1);
|
|
changeFocus = 1;
|
|
}
|
|
redraw = 0;
|
|
|
|
if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
for (j = 0; j < rowCount; j++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, j);
|
|
cbs.reason = XmCR_DELETE_CELL;
|
|
cbs.rowType = RowPosToType(g, j);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, i);
|
|
cbs.columnType = type;
|
|
cbs.column = RowPosToTypePos(g, cbs.columnType, j);
|
|
cbs.object = XmLArrayGet(XmLGridRowCells(row), i);
|
|
XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
|
|
}
|
|
cbs.reason = XmCR_DELETE_COLUMN;
|
|
cbs.columnType = type;
|
|
cbs.column = RowPosToTypePos(g, cbs.columnType, i);
|
|
cbs.object = XmLArrayGet(g->grid.colArray, i);
|
|
XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
|
|
}
|
|
|
|
/* adjust count */
|
|
if (type == XmHEADING)
|
|
{
|
|
g->grid.headingColCount -= count;
|
|
g->grid.leftFixedCount -= count;
|
|
redraw = 1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
g->grid.footerColCount -= count;
|
|
g->grid.rightFixedCount -= count;
|
|
redraw = 1;
|
|
}
|
|
else /* XmCONTENT */
|
|
g->grid.colCount -= count;
|
|
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
if (XmLGridColumnIsHidden(col) == True)
|
|
g->grid.hiddenColCount--;
|
|
redraw |= ColIsVisible(g, i);
|
|
}
|
|
|
|
/* delete columns */
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
XmLGridColumnFree(w, col);
|
|
}
|
|
XmLArrayDel(g->grid.colArray, position, count);
|
|
/* delete cells */
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
for (i = 0; i < rowCount; i++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
|
|
for (j = position; j < position + count; j++)
|
|
XmLGridCellFree(w,
|
|
(XmLGridCell)XmLArrayGet(XmLGridRowCells(row), j));
|
|
XmLArrayDel(XmLGridRowCells(row), position, count);
|
|
XmLGridRowHeightChanged(row);
|
|
}
|
|
/* sanity check */
|
|
if (XmLArrayGetCount(g->grid.colArray) != g->grid.headingColCount +
|
|
g->grid.colCount + g->grid.footerColCount)
|
|
XmLWarning(w, "DeleteColumns() - count sanity check failed");
|
|
|
|
/* maintain scroll and focus position */
|
|
if (g->grid.hsPolicy == XmCONSTANT)
|
|
{
|
|
if (lastPos < g->grid.scrollCol)
|
|
g->grid.scrollCol -= count;
|
|
else if (position <= g->grid.scrollCol)
|
|
g->grid.scrollCol = position;
|
|
}
|
|
if (lastPos < g->grid.focusCol)
|
|
g->grid.focusCol -= count;
|
|
VisPosChanged(g, 0);
|
|
HorizLayout(g, 1);
|
|
VertLayout(g, 1);
|
|
if (changeFocus)
|
|
{
|
|
SetFocus(g, g->grid.focusRow, position, 0, 1);
|
|
if (g->grid.focusCol == -1)
|
|
SetFocus(g, g->grid.focusRow, position, 0, -1);
|
|
}
|
|
if (redraw)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridDeleteRows(Widget w,
|
|
unsigned char type,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
XmLGridColumn col;
|
|
XmLGridCallbackStruct cbs;
|
|
int changeFocus, i, j, colCount, lastPos, redraw;
|
|
|
|
g = WidgetToGrid(w, "DeleteRows()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
lastPos = RowTypePosToPos(g, type, position + count - 1, 0);
|
|
position = RowTypePosToPos(g, type, position, 0);
|
|
if (position < 0 || lastPos < 0)
|
|
{
|
|
XmLWarning(w, "DeleteRows() - invalid position");
|
|
return;
|
|
}
|
|
changeFocus = 0;
|
|
if (position <= g->grid.focusRow && lastPos >= g->grid.focusRow)
|
|
{
|
|
/* deleting focus row */
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
ChangeFocus(g, -1, g->grid.focusCol);
|
|
changeFocus = 1;
|
|
}
|
|
redraw = 0;
|
|
|
|
if (XtHasCallbacks(w, XmNdeleteCallback) == XtCallbackHasSome)
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
|
|
colCount = XmLArrayGetCount(g->grid.colArray);
|
|
for (j = 0; j < colCount; j++)
|
|
{
|
|
cbs.reason = XmCR_DELETE_CELL;
|
|
cbs.rowType = type;
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, i);
|
|
cbs.columnType = ColPosToType(g, j);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, j);
|
|
cbs.object = XmLArrayGet(XmLGridRowCells(row), j);
|
|
XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
|
|
}
|
|
cbs.reason = XmCR_DELETE_ROW;
|
|
cbs.rowType = type;
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, i);
|
|
cbs.object = (void *)row;
|
|
XtCallCallbackList(w, g->grid.deleteCallback, (XtPointer)&cbs);
|
|
}
|
|
|
|
/* adjust count */
|
|
if (type == XmHEADING)
|
|
{
|
|
g->grid.headingRowCount -= count;
|
|
g->grid.topFixedCount -= count;
|
|
redraw = 1;
|
|
}
|
|
else if (type == XmFOOTER)
|
|
{
|
|
g->grid.footerRowCount -= count;
|
|
g->grid.bottomFixedCount -= count;
|
|
redraw = 1;
|
|
}
|
|
else /* XmCONTENT */
|
|
g->grid.rowCount -= count;
|
|
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
|
|
if (XmLGridRowIsHidden(row) == True)
|
|
g->grid.hiddenRowCount--;
|
|
redraw |= RowIsVisible(g, i);
|
|
}
|
|
|
|
/* delete rows and cells */
|
|
for (i = position; i < position + count; i++)
|
|
{
|
|
row = (XmLGridRow)XmLArrayGet(g->grid.rowArray, i);
|
|
XmLGridRowFree(w, row);
|
|
}
|
|
XmLArrayDel(g->grid.rowArray, position, count);
|
|
colCount = XmLArrayGetCount(g->grid.colArray);
|
|
for (i = 0; i < colCount; i++)
|
|
{
|
|
col = (XmLGridColumn)XmLArrayGet(g->grid.colArray, i);
|
|
XmLGridColumnWidthChanged(col);
|
|
}
|
|
/* sanity check */
|
|
if (XmLArrayGetCount(g->grid.rowArray) != g->grid.headingRowCount +
|
|
g->grid.rowCount + g->grid.footerRowCount)
|
|
XmLWarning(w, "DeleteRows() - count sanity check failed");
|
|
|
|
/* maintain scroll and focus position */
|
|
if (g->grid.vsPolicy == XmCONSTANT)
|
|
{
|
|
if (lastPos < g->grid.scrollRow)
|
|
g->grid.scrollRow -= count;
|
|
else if (position <= g->grid.scrollRow)
|
|
g->grid.scrollRow = position;
|
|
}
|
|
if (lastPos < g->grid.focusRow)
|
|
g->grid.focusRow -= count;
|
|
VisPosChanged(g, 1);
|
|
HorizLayout(g, 1);
|
|
VertLayout(g, 1);
|
|
if (changeFocus)
|
|
{
|
|
SetFocus(g, position, g->grid.focusCol, 1, 0);
|
|
if (g->grid.focusRow == -1)
|
|
SetFocus(g, position, g->grid.focusCol, -1, 0);
|
|
}
|
|
if (redraw)
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridGetFocus(Widget w,
|
|
int *row,
|
|
int *column,
|
|
Boolean *focusIn)
|
|
{
|
|
XmLGridWidget g;
|
|
unsigned char rowType, colType;
|
|
|
|
g = WidgetToGrid(w, "GetFocus()");
|
|
if (!g)
|
|
return;
|
|
if (g->grid.focusIn)
|
|
*focusIn = True;
|
|
else
|
|
*focusIn = False;
|
|
if (g->grid.focusRow < 0 || g->grid.focusCol < 0)
|
|
{
|
|
*row = -1;
|
|
*column = -1;
|
|
return;
|
|
}
|
|
rowType = RowPosToType(g, g->grid.focusRow);
|
|
colType = ColPosToType(g, g->grid.focusCol);
|
|
if (rowType != XmCONTENT || colType != XmCONTENT)
|
|
{
|
|
*row = -1;
|
|
*column = -1;
|
|
XmLWarning(w, "GetFocus() - focus row/column invalid\n");
|
|
return;
|
|
}
|
|
*row = RowPosToTypePos(g, XmCONTENT, g->grid.focusRow);
|
|
*column = ColPosToTypePos(g, XmCONTENT, g->grid.focusCol);
|
|
}
|
|
|
|
XmLGridRow
|
|
XmLGridGetRow(Widget w,
|
|
unsigned char rowType,
|
|
int row)
|
|
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow r;
|
|
int pos;
|
|
|
|
g = WidgetToGrid(w, "GetRow()");
|
|
if (!g)
|
|
return 0;
|
|
pos = RowTypePosToPos(g, rowType, row, 0);
|
|
r = (XmLGridRow)XmLArrayGet(g->grid.rowArray, pos);
|
|
if (!r)
|
|
XmLWarning(w, "GetRow() - invalid row");
|
|
return r;
|
|
}
|
|
|
|
int
|
|
XmLGridEditBegin(Widget w,
|
|
Boolean insert,
|
|
int row,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
XRectangle rect;
|
|
|
|
g = WidgetToGrid(w, "EditBegin()");
|
|
if (!g)
|
|
return -1;
|
|
if (column < 0 || column >= g->grid.colCount)
|
|
{
|
|
XmLWarning(w, "EditBegin() - invalid column");
|
|
return -1;
|
|
}
|
|
if (row < 0 || row >= g->grid.rowCount)
|
|
{
|
|
XmLWarning(w, "EditBegin() - invalid row");
|
|
return -1;
|
|
}
|
|
r = RowTypePosToPos(g, XmCONTENT, row, 0);
|
|
c = ColTypePosToPos(g, XmCONTENT, column, 0);
|
|
if (RowColToXY(g, r, c, True, &rect) == -1)
|
|
{
|
|
XmLWarning(w, "EditBegin() - cell must be visible to begin edit");
|
|
return -1;
|
|
}
|
|
if (SetFocus(g, r, c, 0, 0) == -1)
|
|
{
|
|
XmLWarning(w, "EditBegin() - can't set focus to cell");
|
|
return -1;
|
|
}
|
|
if (insert == False)
|
|
TextAction(g, TEXT_EDIT);
|
|
else
|
|
TextAction(g, TEXT_EDIT_INSERT);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
XmLGridEditCancel(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "EditCancel()");
|
|
if (!g)
|
|
return;
|
|
TextAction(g, TEXT_EDIT_CANCEL);
|
|
}
|
|
|
|
void
|
|
XmLGridEditComplete(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "EditComplete()");
|
|
if (!g)
|
|
return;
|
|
TextAction(g, TEXT_EDIT_COMPLETE);
|
|
}
|
|
|
|
XmLGridColumn
|
|
XmLGridGetColumn(Widget w,
|
|
unsigned char columnType,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridColumn c;
|
|
int pos;
|
|
|
|
g = WidgetToGrid(w, "GetColumn()");
|
|
if (!g)
|
|
return 0;
|
|
pos = ColTypePosToPos(g, columnType, column, 0);
|
|
c = (XmLGridColumn)XmLArrayGet(g->grid.colArray, pos);
|
|
if (!c)
|
|
XmLWarning(w, "GetColumn() - invalid column");
|
|
return c;
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedCellCount(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedCellCount()");
|
|
if (!g)
|
|
return -1;
|
|
return GetSelectedArea(g, SelectCell, 0, 0, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedCells(Widget w,
|
|
int *rowPositions,
|
|
int *columnPositions,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedCells()");
|
|
if (!g)
|
|
return -1;
|
|
n = GetSelectedArea(g, SelectCell, rowPositions, columnPositions, count);
|
|
if (count != n)
|
|
{
|
|
XmLWarning(w, "GetSelectedCells() - count is incorrect");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedColumnCount(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedColumnCount()");
|
|
if (!g)
|
|
return -1;
|
|
return GetSelectedArea(g, SelectCol, 0, 0, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedColumns(Widget w,
|
|
int *positions,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedColumns()");
|
|
if (!g)
|
|
return -1;
|
|
n = GetSelectedArea(g, SelectCol, 0, positions, count);
|
|
if (count != n)
|
|
{
|
|
XmLWarning(w, "GetSelectedColumns() - count is incorrect");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedRow(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
int n, pos;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedRow()");
|
|
if (!g)
|
|
return -1;
|
|
n = GetSelectedArea(g, SelectRow, &pos, 0, 1);
|
|
if (n != 1)
|
|
return -1;
|
|
return pos;
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedRowCount(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedRowCount()");
|
|
if (!g)
|
|
return -1;
|
|
return GetSelectedArea(g, SelectRow, 0, 0, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridGetSelectedRows(Widget w,
|
|
int *positions,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "GetSelectedRows()");
|
|
if (!g)
|
|
return -1;
|
|
n = GetSelectedArea(g, SelectRow, positions, 0, count);
|
|
if (count != n)
|
|
{
|
|
XmLWarning(w, "GetSelectedRows() - count is incorrect");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Boolean
|
|
XmLGridColumnIsVisible(Widget w,
|
|
int col)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "ColumnIsVisible()");
|
|
if (!g)
|
|
return -1;
|
|
if (!ColIsVisible(g, g->grid.headingColCount + col))
|
|
return False;
|
|
return True;
|
|
}
|
|
|
|
void
|
|
XmLGridMoveColumns(Widget w,
|
|
int newPosition,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
int i, np, p, rowCount;
|
|
|
|
g = WidgetToGrid(w, "MoveColumns()");
|
|
if (!g)
|
|
return;
|
|
np = ColTypePosToPos(g, XmCONTENT, newPosition, 0);
|
|
p = ColTypePosToPos(g, XmCONTENT, position, 0);
|
|
if (XmLArrayMove(g->grid.colArray, np, p, count) == -1)
|
|
{
|
|
XmLWarning(w, "MoveColumns() - invalid position");
|
|
return;
|
|
}
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
for (i = 0; i < rowCount; i++)
|
|
{
|
|
row = XmLArrayGet(g->grid.rowArray, i);
|
|
XmLArrayMove(XmLGridRowCells(row), np, p, count);
|
|
}
|
|
VisPosChanged(g, 0);
|
|
HorizLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridMoveRows(Widget w,
|
|
int newPosition,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
int np, p;
|
|
|
|
g = WidgetToGrid(w, "MoveRows()");
|
|
if (!g)
|
|
return;
|
|
np = RowTypePosToPos(g, XmCONTENT, newPosition, 0);
|
|
p = RowTypePosToPos(g, XmCONTENT, position, 0);
|
|
if (XmLArrayMove(g->grid.rowArray, np, p, count) == -1)
|
|
{
|
|
XmLWarning(w, "MoveRows() - invalid position/count");
|
|
return;
|
|
}
|
|
VisPosChanged(g, 1);
|
|
VertLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridReorderColumns(Widget w,
|
|
int *newPositions,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
XmLGridRow row;
|
|
int i, *np, p, rowCount, status;
|
|
|
|
g = WidgetToGrid(w, "ReorderColumns()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
p = ColTypePosToPos(g, XmCONTENT, position, 0);
|
|
np = (int *)malloc(sizeof(int) * count);
|
|
for (i = 0; i < count; i++)
|
|
np[i] = ColTypePosToPos(g, XmCONTENT, newPositions[i], 0);
|
|
status = XmLArrayReorder(g->grid.colArray, np, p, count);
|
|
if (status < 0)
|
|
{
|
|
free((char *)np);
|
|
XmLWarning(w, "ReorderColumns() - invalid position/count");
|
|
return;
|
|
}
|
|
rowCount = XmLArrayGetCount(g->grid.rowArray);
|
|
for (i = 0; i < rowCount; i++)
|
|
{
|
|
row = XmLArrayGet(g->grid.rowArray, i);
|
|
XmLArrayReorder(XmLGridRowCells(row), np, p, count);
|
|
}
|
|
free((char *)np);
|
|
VisPosChanged(g, 0);
|
|
HorizLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridReorderRows(Widget w,
|
|
int *newPositions,
|
|
int position,
|
|
int count)
|
|
{
|
|
XmLGridWidget g;
|
|
int i, *np, p, status;
|
|
|
|
g = WidgetToGrid(w, "ReorderRows()");
|
|
if (!g)
|
|
return;
|
|
if (count <= 0)
|
|
return;
|
|
p = RowTypePosToPos(g, XmCONTENT, position, 0);
|
|
np = (int *)malloc(sizeof(int) * count);
|
|
for (i = 0; i < count; i++)
|
|
np[i] = RowTypePosToPos(g, XmCONTENT, newPositions[i], 0);
|
|
status = XmLArrayReorder(g->grid.rowArray, np, p, count);
|
|
free((char *)np);
|
|
if (status == -1)
|
|
{
|
|
XmLWarning(w, "ReorderRows() - invalid position/count");
|
|
return;
|
|
}
|
|
VisPosChanged(g, 1);
|
|
VertLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridRowColumnToXY(Widget w,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column,
|
|
Boolean clipped,
|
|
XRectangle *rect)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "RowColumnToXY()");
|
|
if (!g)
|
|
return -1;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
if (r < 0 || r >= XmLArrayGetCount(g->grid.rowArray) ||
|
|
c < 0 || c >= XmLArrayGetCount(g->grid.colArray))
|
|
{
|
|
/* XmLWarning(w, "RowColumnToXY() - invalid position");*/
|
|
return -1;
|
|
}
|
|
return RowColToXY(g, r, c, clipped, rect);
|
|
}
|
|
|
|
Boolean
|
|
XmLGridRowIsVisible(Widget w, int row)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "RowIsVisible()");
|
|
if (!g)
|
|
return -1;
|
|
if (!RowIsVisible(g, g->grid.headingRowCount + row))
|
|
return False;
|
|
return True;
|
|
}
|
|
|
|
void
|
|
XmLGridSelectAllRows(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectAllRows()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0, -1, 0, True, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridSelectAllColumns(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectAllColumns()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCol, (XEvent *)0, 0, -1, True, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridSelectAllCells(Widget w,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectAllCells()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCell, (XEvent *)0, -1, -1, True, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridSelectCell(Widget w,
|
|
int row,
|
|
int column,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectCell()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCell, (XEvent *)0, row, column, True, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridSelectColumn(Widget w,
|
|
int column,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectColumn()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectCol, (XEvent *)0, 0, column, True, notify);
|
|
}
|
|
|
|
void
|
|
XmLGridSelectRow(Widget w,
|
|
int row,
|
|
Boolean notify)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SelectRow()");
|
|
if (!g)
|
|
return;
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0, row, 0, True, notify);
|
|
}
|
|
|
|
int
|
|
XmLGridSetFocus(Widget w,
|
|
int row,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "SetFocus()");
|
|
if (!g)
|
|
return -1;
|
|
if (row < 0 || row >= g->grid.rowCount)
|
|
{
|
|
XmLWarning(w, "SetFocus() - invalid row");
|
|
return -1;
|
|
}
|
|
if (column < 0 || column >= g->grid.colCount)
|
|
{
|
|
XmLWarning(w, "SetFocus() - invalid column");
|
|
return -1;
|
|
}
|
|
r = RowTypePosToPos(g, XmCONTENT, row, 0);
|
|
c = ColTypePosToPos(g, XmCONTENT, column, 0);
|
|
return SetFocus(g, r, c, 0, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridXYToRowColumn(Widget w,
|
|
int x,
|
|
int y,
|
|
unsigned char *rowType,
|
|
int *row,
|
|
unsigned char *columnType,
|
|
int *column)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "XYToRowColumn()");
|
|
if (!g)
|
|
return -1;
|
|
if (XYToRowCol(g, x, y, &r, &c) == -1)
|
|
return -1;
|
|
*rowType = RowPosToType(g, r);
|
|
*row = RowPosToTypePos(g, *rowType, r);
|
|
*columnType = ColPosToType(g, c);
|
|
*column = ColPosToTypePos(g, *columnType, c);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
XmLGridRedrawAll(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "RedrawAll()");
|
|
if (!g)
|
|
return;
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
void
|
|
XmLGridRedrawCell(Widget w,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "RedrawCell()");
|
|
if (!g)
|
|
return;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
DrawArea(g, DrawCell, r, c);
|
|
}
|
|
|
|
void
|
|
XmLGridRedrawColumn(Widget w,
|
|
unsigned char type,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
int c;
|
|
|
|
g = WidgetToGrid(w, "RedrawColumn()");
|
|
if (!g)
|
|
return;
|
|
c = ColTypePosToPos(g, type, column, 0);
|
|
DrawArea(g, DrawCol, 0, c);
|
|
}
|
|
|
|
void
|
|
XmLGridRedrawRow(Widget w,
|
|
unsigned char type,
|
|
int row)
|
|
{
|
|
XmLGridWidget g;
|
|
int r;
|
|
|
|
g = WidgetToGrid(w, "RedrawRow()");
|
|
if (!g)
|
|
return;
|
|
r = RowTypePosToPos(g, type, row, 0);
|
|
DrawArea(g, DrawRow, r, 0);
|
|
}
|
|
|
|
int
|
|
XmLGridRead(Widget w,
|
|
FILE *file,
|
|
int format,
|
|
char delimiter)
|
|
{
|
|
XmLGridWidget g;
|
|
char *data;
|
|
int n;
|
|
|
|
g = WidgetToGrid(w, "Read()");
|
|
if (!g)
|
|
return 0;
|
|
if (!file)
|
|
{
|
|
XmLWarning(w, "Read() - file is NULL");
|
|
return 0;
|
|
}
|
|
data = FileToString(file);
|
|
if (!data)
|
|
{
|
|
XmLWarning(w, "Read() - error loading file");
|
|
return 0;
|
|
}
|
|
n = Read(g, format, delimiter, 0, 0, data);
|
|
free((char *)data);
|
|
return n;
|
|
}
|
|
|
|
int
|
|
XmLGridReadPos(Widget w,
|
|
FILE *file,
|
|
int format,
|
|
char delimiter,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
char *data;
|
|
int r, c, n;
|
|
|
|
g = WidgetToGrid(w, "ReadPos()");
|
|
if (!g)
|
|
return 0;
|
|
if (!file)
|
|
{
|
|
XmLWarning(w, "ReadPos() - file is NULL");
|
|
return 0;
|
|
}
|
|
data = FileToString(file);
|
|
if (!data)
|
|
{
|
|
XmLWarning(w, "ReadPos() - error loading file");
|
|
return 0;
|
|
}
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
n = Read(g, format, delimiter, r, c, data);
|
|
free((char *)data);
|
|
return n;
|
|
}
|
|
|
|
int
|
|
XmLGridSetStrings(Widget w,
|
|
char *data)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "SetStrings()");
|
|
if (!g)
|
|
return 0;
|
|
return Read(g, XmFORMAT_DELIMITED, '|', 0, 0, data);
|
|
}
|
|
|
|
int
|
|
XmLGridSetStringsPos(Widget w,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column,
|
|
char *data)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "SetStringsPos()");
|
|
if (!g)
|
|
return 0;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
return Read(g, XmFORMAT_DELIMITED, '|', r, c, data);
|
|
}
|
|
|
|
int
|
|
XmLGridWrite(Widget w,
|
|
FILE *file,
|
|
int format,
|
|
char delimiter,
|
|
Boolean skipHidden)
|
|
{
|
|
XmLGridWidget g;
|
|
int nrow, ncol;
|
|
|
|
g = WidgetToGrid(w, "Write()");
|
|
if (!g)
|
|
return 0;
|
|
nrow = XmLArrayGetCount(g->grid.rowArray);
|
|
ncol = XmLArrayGetCount(g->grid.colArray);
|
|
Write(g, file, format, delimiter, skipHidden, 0, 0, nrow, ncol);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
XmLGridWritePos(Widget w,
|
|
FILE *file,
|
|
int format,
|
|
char delimiter,
|
|
Boolean skipHidden,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column,
|
|
int nrow,
|
|
int ncolumn)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "WritePos()");
|
|
if (!g)
|
|
return 0;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
Write(g, file, format, delimiter, skipHidden, r, c, nrow, ncolumn);
|
|
return 0;
|
|
}
|
|
|
|
Boolean
|
|
XmLGridCopyPos(Widget w,
|
|
Time time,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column,
|
|
int nrow,
|
|
int ncolumn)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "CopyPos()");
|
|
if (!g)
|
|
return False;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
return Copy(g, time, 0, r, c, nrow, ncolumn);
|
|
}
|
|
|
|
Boolean
|
|
XmLGridCopySelected(Widget w,
|
|
Time time)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = WidgetToGrid(w, "CopySelected()");
|
|
if (!g)
|
|
return False;
|
|
return Copy(g, time, 1, 0, 0, 0, 0);
|
|
}
|
|
|
|
Boolean
|
|
XmLGridPaste(Widget w)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "Paste()");
|
|
if (!g)
|
|
return False;
|
|
r = g->grid.focusRow;
|
|
c = g->grid.focusCol;
|
|
if (r < 0 || c < 0)
|
|
{
|
|
XmLWarning(w, "Paste() - no cell has focus");
|
|
return False;
|
|
}
|
|
return Paste(g, r, c);
|
|
}
|
|
|
|
Boolean
|
|
XmLGridPastePos(Widget w,
|
|
unsigned char rowType,
|
|
int row,
|
|
unsigned char columnType,
|
|
int column)
|
|
{
|
|
XmLGridWidget g;
|
|
int r, c;
|
|
|
|
g = WidgetToGrid(w, "PastePos()");
|
|
if (!g)
|
|
return False;
|
|
r = RowTypePosToPos(g, rowType, row, 0);
|
|
c = ColTypePosToPos(g, columnType, column, 0);
|
|
return Paste(g, r, c);
|
|
}
|
|
|
|
/* XFE Additions below here */
|
|
static void
|
|
EditTimer(XtPointer clientData,
|
|
XtIntervalId *intervalId)
|
|
{
|
|
XmLGridWidget g;
|
|
|
|
g = (XmLGridWidget)clientData;
|
|
|
|
g->grid.editTimerSet = 0;
|
|
g->grid.lastSelectTime = 0;
|
|
TextAction(g,TEXT_EDIT_INSERT);
|
|
}
|
|
|
|
void
|
|
XmLGridSetVisibleColumnCount(Widget w, int new_num_visible)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
int ii, num_columns, visible_count;
|
|
XmLGridColumn colp;
|
|
|
|
|
|
visible_count = 0;
|
|
num_columns = XmLArrayGetCount(g->grid.colArray);
|
|
|
|
if (new_num_visible == 0)
|
|
return;
|
|
for (ii = 0; ii < num_columns; ii ++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
|
|
|
|
if (colp->grid.hidden && visible_count < new_num_visible)
|
|
{
|
|
colp->grid.hidden = False;
|
|
}
|
|
else if (!colp->grid.hidden && visible_count >= new_num_visible)
|
|
{
|
|
colp->grid.hidden = True;
|
|
}
|
|
if (!colp->grid.hidden)
|
|
visible_count++;
|
|
}
|
|
if (visible_count < num_columns)
|
|
g->grid.visibleCols = visible_count;
|
|
else
|
|
g->grid.visibleCols = 0;
|
|
|
|
setHideUnhideSensitivity(w);
|
|
|
|
HorizLayout(g, 1);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
}
|
|
|
|
static void
|
|
HideColumn(Widget w, XtPointer clientData, XtPointer callData)
|
|
{
|
|
Widget g = (Widget) clientData;
|
|
|
|
XmLGridHideRightColumn(g);
|
|
}
|
|
static void
|
|
UnhideColumn(Widget w, XtPointer clientData, XtPointer callData)
|
|
{
|
|
Widget g = (Widget) clientData;
|
|
|
|
XmLGridUnhideRightColumn(g);
|
|
}
|
|
|
|
static void
|
|
CreateHideUnhideButtons(XmLGridWidget g)
|
|
{
|
|
if (!g->grid.hideUnhideButtons)
|
|
{
|
|
XmLWarning((Widget)g,"CreateHideUnhideButtons - Creating buttons when XmNhideUnhideButtons is False.");
|
|
return;
|
|
}
|
|
|
|
g->grid.hideButton = XtVaCreateWidget(
|
|
"hide", xmDrawnButtonWidgetClass,
|
|
(Widget)g, XmNhighlightThickness, 0,
|
|
XmNshadowThickness, 1,
|
|
XmNtraversalOn, False,
|
|
XmNbackground, g->core.background_pixel,
|
|
XmNforeground, g->manager.foreground,
|
|
XmNtopShadowColor, g->manager.top_shadow_color,
|
|
XmNbottomShadowColor, g->manager.bottom_shadow_color,
|
|
NULL);
|
|
|
|
g->grid.unhideButton = XtVaCreateWidget(
|
|
"unhide", xmDrawnButtonWidgetClass,
|
|
(Widget)g, XmNhighlightThickness, 0,
|
|
XmNshadowThickness, 1,
|
|
XmNtraversalOn, False,
|
|
XmNbackground, g->core.background_pixel,
|
|
XmNforeground, g->manager.foreground,
|
|
XmNtopShadowColor, g->manager.top_shadow_color,
|
|
XmNbottomShadowColor, g->manager.bottom_shadow_color,
|
|
NULL);
|
|
|
|
XmLDrawnButtonSetType(g->grid.hideButton, XmDRAWNB_SMALLARROW,
|
|
XmDRAWNB_RIGHT);
|
|
XmLDrawnButtonSetType(g->grid.unhideButton, XmDRAWNB_SMALLARROW,
|
|
XmDRAWNB_LEFT);
|
|
|
|
|
|
XtAddCallback(g->grid.hideButton, XmNactivateCallback,
|
|
HideColumn, (XtPointer)g);
|
|
XtAddCallback(g->grid.unhideButton, XmNactivateCallback,
|
|
UnhideColumn, (XtPointer)g);
|
|
#if 0
|
|
XtOverrideTranslations(g->grid.unhideButton,
|
|
g->grid.unhideButtonTrans);
|
|
XtOverrideTranslations(g->grid.hideButton,
|
|
g->grid.hideButtonTrans);
|
|
#endif /*0*/
|
|
}
|
|
|
|
static void
|
|
HideAction(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *num_params)
|
|
{
|
|
XmLGridHideRightColumn(w);
|
|
}
|
|
|
|
static void
|
|
UnhideAction(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *num_params)
|
|
{
|
|
XmLGridUnhideRightColumn(w);
|
|
}
|
|
|
|
static void
|
|
setHideUnhideSensitivity(Widget w)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
int total_columns = XmLArrayGetCount(g->grid.colArray);
|
|
Boolean can_unhide, can_hide;
|
|
|
|
if (!g->grid.hideUnhideButtons) return;
|
|
|
|
/* If visibleCols is zero, that means all the columns are visible. */
|
|
if (g->grid.visibleCols == 0) {
|
|
can_unhide = 0;
|
|
can_hide = (total_columns > 1);
|
|
} else {
|
|
can_unhide = (g->grid.visibleCols < total_columns);
|
|
can_hide = (g->grid.visibleCols > 1);
|
|
}
|
|
XtSetSensitive(g->grid.unhideButton, can_unhide);
|
|
XtSetSensitive(g->grid.hideButton, can_hide);
|
|
}
|
|
|
|
void
|
|
XmLGridHideRightColumn(Widget w)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
int total_columns = XmLArrayGetCount(g->grid.colArray);
|
|
if (total_columns <= 1)
|
|
return;
|
|
|
|
/* If visibleCols is zero, that means all the columns are visible. */
|
|
if (g->grid.visibleCols == 0 || g->grid.visibleCols > total_columns)
|
|
XmLGridSetVisibleColumnCount(w, total_columns - 1);
|
|
else
|
|
XmLGridSetVisibleColumnCount(w, g->grid.visibleCols - 1);
|
|
}
|
|
|
|
void
|
|
XmLGridUnhideRightColumn(Widget w)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
int total_columns = XmLArrayGetCount(g->grid.colArray);
|
|
|
|
/* If visibleCols is zero, that means all the columns are visible. */
|
|
if ( g->grid.visibleCols != 0 && g->grid.visibleCols < total_columns)
|
|
XmLGridSetVisibleColumnCount(w, g->grid.visibleCols + 1);
|
|
}
|
|
|
|
static void
|
|
MenuArm(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *num_params)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
|
|
SelectTypeArea(g, SelectRow, (XEvent *)0, g->grid.lastSelectRow, 0, False, False);
|
|
|
|
g->grid.inMode = InSelect;
|
|
}
|
|
|
|
static void
|
|
MenuDisarm(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *num_params)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
|
|
g->grid.inMode = InNormal;
|
|
}
|
|
|
|
static void
|
|
ResizeColumnToFit(XmLGridWidget g, int new_x)
|
|
{
|
|
XmLGridColumn colp;
|
|
int width = 0;
|
|
XRectangle rect;
|
|
if (!RowColToXY(g, 0, g->grid.resizeCol, False, &rect))
|
|
{
|
|
if (new_x > rect.x)
|
|
width = (new_x - rect.x) -
|
|
(rect.width - GetColWidth(g, g->grid.resizeCol));
|
|
if (width < g->grid.minColWidth)
|
|
width = g->grid.minColWidth;
|
|
|
|
/*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);*/
|
|
|
|
/* Resize all columns to the right */
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray,
|
|
g->grid.resizeCol);
|
|
colp->grid.width = width;
|
|
SizeColumnsToFit(g, g->grid.resizeCol + 1);
|
|
HorizLayout(g, 0);
|
|
DrawArea(g, DrawAll, 0, 0);
|
|
g->grid.resizeLineXY = rect.x + width;
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
SizeColumnsToFit(XmLGridWidget g, int starting_at)
|
|
{
|
|
int resizable_width = 0;
|
|
int delta = 0;
|
|
float hidden_col_adjust;
|
|
int ii, num_columns;
|
|
XmLGridColumn colp;
|
|
|
|
/* Total the width of the columns and
|
|
also total how much of that can be resized */
|
|
delta = g->core.width;
|
|
delta -= g->manager.shadow_thickness * 2;
|
|
|
|
if (g->grid.hideUnhideButtons)
|
|
{
|
|
delta -= g->grid.unhideButton->core.width;
|
|
delta -= g->grid.hideButton->core.width;
|
|
}
|
|
else if (XtIsManaged(g->grid.vsb))
|
|
{
|
|
delta -= g->grid.vsb->core.width;
|
|
}
|
|
|
|
num_columns = g->grid.colCount + g->grid.headingColCount
|
|
+ g->grid.footerColCount;
|
|
for (ii = 0; ii < num_columns; ii ++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
|
|
|
|
if (colp->grid.sizePolicy != XmCONSTANT)
|
|
{
|
|
if (g->grid.debugLevel)
|
|
XmLWarning((Widget)g, "SizeColumnsToFit() - only valid for XmNcolumnSizePolicy == XmCONSTANT");
|
|
colp->grid.sizePolicy = XmCONSTANT;
|
|
}
|
|
if (!g->grid.visibleCols || ii < g->grid.visibleCols)
|
|
{
|
|
delta -= colp->grid.width;
|
|
|
|
if (ii >= starting_at && colp->grid.resizable)
|
|
resizable_width += colp->grid.width;
|
|
}
|
|
}
|
|
if (delta == 0 || resizable_width <= 0)
|
|
return delta;
|
|
|
|
if (g->grid.debugLevel)
|
|
{
|
|
fprintf(stderr,"Applying delta(%d) from %d to %d (%d resizable)\n",
|
|
delta, starting_at, num_columns - 1, resizable_width);
|
|
}
|
|
|
|
hidden_col_adjust = (float)delta / resizable_width;
|
|
|
|
/* Adjust each column to fit based on its percentage of the total width */
|
|
for (ii = starting_at; ii < num_columns ; ii ++)
|
|
{
|
|
int col_width;
|
|
int col_delta;
|
|
int new_col_width;
|
|
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
|
|
col_width = colp->grid.width;
|
|
|
|
if (!colp->grid.resizable || col_width == 0)
|
|
continue;
|
|
|
|
if (colp->grid.hidden)
|
|
col_delta = (int)(hidden_col_adjust * col_width);
|
|
else
|
|
if (col_width < resizable_width && resizable_width > 0)
|
|
col_delta = delta * ((float)col_width / resizable_width);
|
|
else
|
|
col_delta = delta;
|
|
|
|
new_col_width = col_width + col_delta;
|
|
|
|
if (new_col_width < g->grid.minColWidth)
|
|
{
|
|
new_col_width = g->grid.minColWidth;
|
|
col_delta = col_width - new_col_width;
|
|
}
|
|
|
|
if (!colp->grid.hidden)
|
|
{
|
|
delta -= col_delta;
|
|
resizable_width -= col_width;
|
|
}
|
|
|
|
colp->grid.width = new_col_width;
|
|
|
|
if (g->grid.debugLevel)
|
|
fprintf (stderr, "Column %d, width %d -> %d, new delta %d, new resizable width %d\n",
|
|
ii, col_width, new_col_width,
|
|
delta, resizable_width);
|
|
}
|
|
|
|
return delta;
|
|
}
|
|
|
|
|
|
void
|
|
XmLGridGetSort(Widget w, int *column, unsigned char *sortType)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
XmLGridColumn colp;
|
|
int num_columns = XmLArrayGetCount(g->grid.colArray);
|
|
int ii;
|
|
|
|
*column = 0;
|
|
*sortType = XmSORT_NONE;
|
|
|
|
for (ii = 0; ii < num_columns; ii ++)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, ii);
|
|
|
|
if (colp && colp->grid.sort != XmSORT_NONE)
|
|
{
|
|
*column = ii;
|
|
*sortType = colp->grid.sort;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
XmLGridSetSort(Widget w, int column, unsigned char sortType)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
XmLGridRow rowp;
|
|
XmLGridColumn colp;
|
|
XmLGridCell cellp;
|
|
int old_sort_column;
|
|
unsigned char old_sort_type;
|
|
|
|
/*printf("XmLGridSetSort: (%d,%s)\n", column,
|
|
sortType == XmSORT_NONE ? "none" :
|
|
sortType == XmSORT_ASCENDING ? "ascending" : "descending");
|
|
*/
|
|
|
|
/* Clear old sort resource */
|
|
XmLGridGetSort(w, &old_sort_column, &old_sort_type);
|
|
if (old_sort_type != XmSORT_NONE)
|
|
{
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, old_sort_column);
|
|
if (colp)
|
|
colp->grid.sort = XmSORT_NONE;
|
|
}
|
|
|
|
colp = (XmLGridColumn)XmLArrayGet(g->grid.colArray, column);
|
|
colp->grid.sort = sortType;
|
|
|
|
/* Clear any existing cell sort masks. */
|
|
rowp = (XmLGridRow)XmLArrayGet(g->grid.rowArray, 0);
|
|
if (rowp)
|
|
{
|
|
int ii, count;
|
|
|
|
count = XmLArrayGetCount(rowp->grid.cellArray);
|
|
for (ii = 0; ii < count; ii++)
|
|
{
|
|
cellp = (XmLGridCell)XmLArrayGet(rowp->grid.cellArray, ii);
|
|
|
|
if (XmLGridCellDrawSort(cellp))
|
|
{
|
|
DrawArea(g, DrawCell, 0, ii);
|
|
XmLGridCellSetDrawSort(cellp, False);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set the cell mask of the heading cell. */
|
|
cellp = GetCell(g, 0, column);
|
|
|
|
if (cellp)
|
|
{
|
|
XmLGridCellSetDrawSort(cellp, True);
|
|
if (sortType == XmSORT_NONE)
|
|
XmLGridCellSetDrawSort(cellp, False);
|
|
else if (sortType == XmSORT_ASCENDING)
|
|
XmLGridCellSetSortAscending(cellp, True);
|
|
else if (sortType == XmSORT_DESCENDING)
|
|
XmLGridCellSetSortAscending(cellp, False);
|
|
|
|
DrawArea(g, DrawCell, 0, column);
|
|
}
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
GridInvokeCallbacks(Widget w,
|
|
XtCallbackList list,
|
|
int reason,
|
|
XEvent * event)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
|
|
/* Make sure widget is alive and callback list is not NULL */
|
|
if (!g->core.being_destroyed && list)
|
|
{
|
|
XmAnyCallbackStruct cbs;
|
|
|
|
cbs.event = event;
|
|
cbs.reason = reason;
|
|
|
|
/* Invoke the Callback List */
|
|
XtCallCallbackList(w,list,&cbs);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
GridInvokeCellCrossingCallbacks(Widget w,
|
|
XtCallbackList list,
|
|
int reason,
|
|
XEvent * event,
|
|
int row,
|
|
int col)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
|
|
/* Make sure widget is alive and callback list is not NULL */
|
|
if (!g->core.being_destroyed && list)
|
|
{
|
|
if (row != -1 && col != -1)
|
|
{
|
|
XmLGridCell cell;
|
|
XmLGridCallbackStruct cbs;
|
|
|
|
cell = GetCell(g, row, col);
|
|
|
|
if (cell)
|
|
{
|
|
cbs.reason = XmCR_CELL_FOCUS_OUT;
|
|
cbs.columnType = ColPosToType(g, col);
|
|
cbs.column = ColPosToTypePos(g, cbs.columnType, col);
|
|
cbs.rowType = RowPosToType(g, row);
|
|
cbs.row = RowPosToTypePos(g, cbs.rowType, row);
|
|
|
|
/* XmLGridCellAction(cell, (Widget)g, &cbs); */
|
|
|
|
/* Invoke the Callback List */
|
|
XtCallCallbackList(w,list,&cbs);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
GridCrossingEH(Widget w,
|
|
XtPointer closure,
|
|
XEvent * event,
|
|
Boolean * ctd)
|
|
{
|
|
XmLGridWidget g = (XmLGridWidget)w;
|
|
|
|
if (event)
|
|
{
|
|
if (event->type == EnterNotify)
|
|
{
|
|
/* Invoke XmNenterGridCallback */
|
|
GridInvokeCallbacks(w,
|
|
g->grid.enterGridCallback,
|
|
XmCR_ENTER_GRID,
|
|
event);
|
|
|
|
/* printf("Enter(%s)\n",XtName(w)); */
|
|
}
|
|
else if (event->type == LeaveNotify)
|
|
{
|
|
g->grid.lastCursorMotionRow = -1;
|
|
g->grid.lastCursorMotionCol = -1;
|
|
|
|
/* Invoke XmNleaveGridCallback */
|
|
GridInvokeCallbacks(w,
|
|
g->grid.leaveGridCallback,
|
|
XmCR_LEAVE_GRID,
|
|
event);
|
|
|
|
/* printf("Leave(%s)\n",XtName(w)); */
|
|
}
|
|
}
|
|
|
|
*ctd = True;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|