When I add a row to a matrix using XbaeMatrixAddRows() with the
following lines:

   XbaeMatrixGetCurrentCell(MyMatrix, &RowNum, &ColNum);
   XbaeMatrixAddRows(MyMatrix, RowNum, NULL, NULL, NULL, 1);

the data in the cells of the selected row is copied to all the rows
below it.
Could you please help?

I am attaching two samples of code in which I have found this problem.

My info:
Motif 1.2
Xbae 4.9.0 built from source
g++ 2.95.2 for TestMatrix.cpp and
gcc 2.95.2 for add.c
Solaris 2.7
Sun Ultra 10


In TestMatrix.cpp just select any row (maybe not the last one) and press
the button.

add.c is the example which comes with Xbae with minor changes. Instead
of adding a 
new row to the end of the matrix, it is added before the selected row.

Thanks for your help

Matt Sneed
[EMAIL PROTECTED]

#include <iostream>

#ifdef __cplusplus
extern "C" {
#endif

#include <Xm/Form.h>
#include <Xm/MainW.h>
#include <Xm/PushB.h>
#include <Xbae/Matrix.h>

#ifdef __cplusplus
}
#endif

void AddRowCB(Widget pb, XtPointer ClientData, XtPointer CallData);
void LoadMatrix();
Widget MyMatrix;

int main()
{
   XtAppContext appContext;
   Widget TopLevel, MainWindow, form, button;

   short ColumnWidths[4] = {10, 10, 10, 10};

   XtSetLanguageProc(NULL, NULL, NULL);

   int temp = 1;
   char *TempArgs[1] = {"MatrixTest"};

   TopLevel = XtAppInitialize(&appContext, "Top", NULL, 0, &temp, TempArgs, NULL, 
NULL, 0);

   MainWindow = XtVaCreateWidget("MainWindow", 
      xmMainWindowWidgetClass, TopLevel, 
      XmNwidth, 400,
      XmNheight, 350,
      NULL);

   form = XmCreateForm(MainWindow, "form", NULL, 0);
   XtManageChild(form);

   MyMatrix = XtVaCreateManagedWidget("MyMatrix", xbaeMatrixWidgetClass, form,
      XmNtopAttachment, XmATTACH_FORM,
      XmNtopOffset, 10, 
      XmNleftAttachment, XmATTACH_FORM,
      XmNleftOffset, 10, 
      XmNcolumns, 5,
      XmNcolumnWidths, ColumnWidths,
      XmNverticalScrollBarDisplayPolicy, XmDISPLAY_STATIC,
      XmNhorizontalScrollBarDisplayPolicy, XmDISPLAY_STATIC,
      XmNrows, 10,
      XmNcolumns, 4,
      XmNallowColumnResize, False,
      NULL);

   button = XtVaCreateManagedWidget ("Add Row",
      xmPushButtonWidgetClass, form, 
      XmNtopAttachment, XmATTACH_FORM,
      XmNtopOffset, 10,
      XmNleftAttachment, XmATTACH_WIDGET,
      XmNleftWidget, MyMatrix,
      XmNleftOffset, 10,
      NULL);
   XtAddCallback(button, XmNactivateCallback, 
      (XtCallbackProc) AddRowCB, (XtPointer) 0);

   LoadMatrix();

   XtManageChild(MainWindow);
   XtRealizeWidget(TopLevel);

   XtAppMainLoop(appContext);

   return 0;
}

void AddRowCB(Widget pb, XtPointer ClientData, XtPointer CallData)
{
   int RowNum, ColNum;

   XbaeMatrixGetCurrentCell(MyMatrix, &RowNum, &ColNum);
   XbaeMatrixAddRows(MyMatrix, RowNum, NULL, NULL, NULL, 1);

   return;
}

void LoadMatrix()
{
   int i = 0;
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 0, i, "AAAAAAA");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 1, i, "BBBBBBB");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 2, i, "CCCCCCC");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 3, i, "DDDDDDD");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 4, i, "EEEEEEE");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 5, i, "FFFFFFF");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 6, i, "GGGGGGG");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 7, i, "HHHHHHH");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 8, i, "JJJJJJJ");
   for(i = 0; i < 4; ++i) 
      XbaeMatrixSetCell(MyMatrix, 9, i, "KKKKKKK");

   return;
}
/*
 * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
 *                        All rights reserved
 *
 * Copyright � 1999,2001 by the LessTif Developers.
 *
 * Permission to use, copy, modify and distribute this material for
 * any purpose and without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies, and that the name of Bellcore not be used in advertising
 * or publicity pertaining to this material without the specific,
 * prior written permission of an authorized representative of
 * Bellcore.
 *
 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
 * ING TO THE SOFTWARE.
 *
 * $Id: add.c,v 1.7 2001/03/30 07:52:02 dannybackx Exp $
*/

#ifdef HAVE_CONFIG_H
#include <XbaeConfig.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#ifdef USE_EDITRES
#include <X11/Intrinsic.h>
#include <X11/Xmu/Editres.h>
#endif
#include <Xm/Form.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
#include <Xm/Scale.h>
#include <Xm/MessageB.h>
#include <Xbae/Matrix.h>

/*
 * Add multiple rows or columns at a time.
 * Use option menu to choose whether to add rows or columns.
 * Use the scale to choose how many to add.
 * Select a cell with Shift-Button1 to select the row or column to add after.
 */

typedef enum {
    RowOrientation,
    ColumnOrientation
} Orientation;

typedef struct {
    Widget matrix;
    Orientation orientation;
    int number;
    int row, column;
    int num_rows, num_columns;
    Dimension fixed_rows, fixed_columns;
    Dimension trailing_fixed_rows, trailing_fixed_columns;    
} AddDataRec, *AddData;

void LoadMatrix(AddData addData);
void RowOrientationCB(Widget w, AddData addData, XtPointer call_data);
void ColumnOrientationCB(Widget w, AddData addData, XtPointer call_data);
void AddCB(Widget w, AddData addData, XtPointer call_data);
void DelCB(Widget w, AddData addData, XtPointer call_data);
void SetNumberCB(Widget w, AddData addData, XmScaleCallbackStruct *call_data);
void SetPositionCB(Widget w, AddData addData, XbaeMatrixSelectCellCallbackStruct 
*call_data);
void defaultCB(Widget w, AddData addData, XbaeMatrixDefaultActionCallbackStruct *cbs);
void enterCB(Widget w, AddData addData, XbaeMatrixEnterCellCallbackStruct *cbs);


/* This used to be in the Add app-defaults file */
static String fallback[] = {
        "*rc.orientation:               horizontal",
        "*number.showValue:             True",
        "*number.orientation:   horizontal",
        "*number.maximum:               10",
        "*add.labelString:              Add",
        "*row.labelString:              Add rows",
        "*column.labelString:   Add columns",
        "*mw.rows:                      7",
        "*mw.columns:           5",
        "*mw.columnWidths:              15, 15, 15, 15, 15",
        "*mw.traverseFixedCells:        True",
        "*mw.translations:              #override\n"
        "       Shift <Btn1Down>:       SelectCell(row)",
        "*mw.allowColumnResize: True",
        "*mw.gridType:          grid_cell_shadow",
        "*mw.cellShadowType:            shadow_in",
        "*mw.cellHighlightThickness:    0",
        "*mw.cellShadowThickness:       3",
        "*mw.shadowThickness:   5",
        "*fixedRows:                    1",
        "*trailingFixedRows:            1",
        "*fixedColumns:         1",
        "*trailingFixedColumns: 1",
        "*mw.textShadowThickness:       2",
        NULL
};

int
main(int argc, char *argv[])
{
    Widget toplevel, form, rc, menu, row, column, option, number, add, del;
    AddDataRec addData;
    XtAppContext app;
    Arg args[8];
    int n;

    toplevel = XtVaAppInitialize(&app, "Add",
                                 NULL, 0,
                                 &argc, argv,
                                 fallback,
                                 NULL);
#ifdef USE_EDITRES
    XtAddEventHandler( toplevel, (EventMask)0, True,
                       _XEditResCheckMessages, NULL);
#endif
    /*
     * Create a Form to hold everything
     */
    form = XtCreateManagedWidget("form",
                                 xmFormWidgetClass, toplevel,
                                 NULL, 0);

    rc = XtCreateManagedWidget("rc",
                               xmRowColumnWidgetClass, form,
                               NULL, 0);

    /*
     * Create a menu for use in an OptionMenu
     */
    menu = XmCreatePulldownMenu(rc, "menu", NULL, 0);

    /*
     * Create a menu button to select row orientation
     */
    row = XtVaCreateManagedWidget("row",
                                  xmPushButtonWidgetClass, menu,
                                  NULL);
    XtAddCallback(row, XmNactivateCallback, (XtCallbackProc)RowOrientationCB,
                  (XtPointer)&addData);

    /*
     * Create a menu button to select column orientation
     */
    column = XtVaCreateManagedWidget("column",
                                     xmPushButtonWidgetClass, menu,
                                     NULL);
    XtAddCallback(column, XmNactivateCallback, (XtCallbackProc)ColumnOrientationCB,
                  (XtPointer)&addData);

    /*
     * Setup and create the option menu
     */
    n = 0;
    XtSetArg(args[n], XmNsubMenuId, menu); n++;
    XtSetArg(args[n], XmNmenuHistory, row); n++;
    option = XmCreateOptionMenu(rc, "option", args, n);
    XtManageChild(option);

    addData.orientation = RowOrientation;

    /*
     * Create a scale to determine how many to add
     */
    number = XtVaCreateManagedWidget(
        "number", xmScaleWidgetClass, rc,
        XmNvalue, 1,
        XmNleftAttachment, XmATTACH_WIDGET,
        XmNleftWidget, option,
        XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
        XmNbottomWidget, option,
        NULL);

    XtAddCallback(number, XmNvalueChangedCallback, (XtCallbackProc)SetNumberCB,
                  (XtPointer)&addData);
    addData.number = 1;

    /*
     * Create a button to do the adding
     */
    add = XtVaCreateManagedWidget(
        "add", xmPushButtonWidgetClass, rc,
        XmNleftAttachment, XmATTACH_WIDGET,
        XmNleftWidget, number,
        XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
        XmNbottomWidget, number,
        NULL);

    XtAddCallback(add, XmNactivateCallback, (XtCallbackProc)AddCB, 
(XtPointer)&addData);

    del = XtVaCreateManagedWidget(
        "Delete", xmPushButtonWidgetClass, rc,
        XmNleftAttachment, XmATTACH_WIDGET,
        XmNleftWidget, add,
        XmNbottomAttachment,XmATTACH_OPPOSITE_WIDGET,
        XmNbottomWidget, add,
        NULL);

    XtAddCallback(del, XmNactivateCallback, (XtCallbackProc)DelCB, 
(XtPointer)&addData);

    /*
     * Create a Matrix widget.
     */

    addData.matrix = XtVaCreateManagedWidget(
        "mw", xbaeMatrixWidgetClass, form,
        XmNleftAttachment, XmATTACH_FORM,
        XmNrightAttachment, XmATTACH_FORM,
        XmNbottomAttachment, XmATTACH_FORM,
        XmNtopAttachment, XmATTACH_WIDGET,
        XmNtopWidget, rc,
        NULL);

    XtAddCallback(addData.matrix, XmNselectCellCallback, (XtCallbackProc)SetPositionCB,
                  (XtPointer)&addData);
    XtAddCallback(addData.matrix, XmNdefaultActionCallback, (XtCallbackProc)defaultCB,
                  (XtPointer)&addData);
    XtAddCallback(addData.matrix, XmNenterCellCallback, (XtCallbackProc)enterCB,
                  (XtPointer)&addData);

    XtVaGetValues(addData.matrix,
                  XmNrows, &addData.num_rows,
                  XmNcolumns, &addData.num_columns,
                  XmNfixedRows, &addData.fixed_rows,
                  XmNfixedColumns, &addData.fixed_columns,
                  XmNtrailingFixedRows, &addData.trailing_fixed_rows,
                  XmNtrailingFixedColumns, &addData.trailing_fixed_columns,
                  NULL);

    addData.row = 0;
    addData.column = 0;
    /*
     * Load the matrix with default values
     */
    LoadMatrix(&addData);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);

    return 0;
}

/* ARGSUSED */
void
RowOrientationCB(Widget w, AddData addData, XtPointer call_data)
{
    if (addData->orientation != RowOrientation) {
        addData->orientation = RowOrientation;
        XbaeMatrixDeselectColumn(addData->matrix, addData->column);
    }
}

/* ARGSUSED */
void
ColumnOrientationCB(Widget w, AddData addData, XtPointer call_data)
{
    if (addData->orientation != ColumnOrientation)
    {
        addData->orientation = ColumnOrientation;
        XbaeMatrixDeselectRow(addData->matrix, addData->row);
    }
}

/* ARGSUSED */
void
enterCB(Widget w, AddData addData, XbaeMatrixEnterCellCallbackStruct *cbs)
{
#if 0
    int rows, cols;
    char str[16];
#endif

    if( cbs->row == 1 || cbs->row == 4 || cbs->column == 1 )
    {
        cbs->doit = True;
#if 0
        XtVaGetValues(w, XmNrows, &rows, XmNcolumns, &cols, NULL);
        (void)sprintf(str, "%d", rand() % 16381);
        XbaeMatrixSetCell(w, rows - 1, cols / 2, str);
        printf("set cell to %s\n", str);
#endif
    }
    else
        cbs->doit = False;
}

/* ARGSUSED */
void
defaultCB(Widget w, AddData addData, XbaeMatrixDefaultActionCallbackStruct *cbs)
{
    static Widget dialog = NULL;
    XmString xm_string;
    Arg args[1];
    char buf[ 64 ];
    
    /* set the label for the dialog */
    sprintf( buf, "Double click in row %d, column %d", cbs->row, cbs->column );
    xm_string = XmStringCreateSimple( buf );
    XtSetArg(args[0], XmNmessageString, xm_string);

    /* Create the InformationDialog as child of w */
    if( !dialog )
        dialog = XmCreateInformationDialog(w, "info", args, 1);
    else
        XtSetValues(dialog, args, 1);

    /* no longer need the compound string, free it */
    XmStringFree(xm_string);

    /* manage the dialog */
    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone);
   
}

/* ARGSUSED */
void
AddCB(Widget w, AddData addData, XtPointer call_data)
{
    String *rows, *columns;
    short *widths;
    char buf[BUFSIZ];
    int i, j, length;
    int row_num = 0, col_num = 0;

    /*
     * Add rows or columns
     */

    switch (addData->orientation) {

    case RowOrientation:
        rows = (String *) XtMalloc(addData->num_columns * addData->number *
                                   sizeof(String));
        for (i = 0; i < addData->number; i++)
            for (j = 0; j < addData->num_columns; j++) {
                sprintf(buf, "addrow %d, %d", i, j);
                rows[i * addData->num_columns + j] = XtNewString(buf);
            }

    XbaeMatrixGetCurrentCell(addData->matrix, &row_num, &col_num);

        XbaeMatrixAddRows(addData->matrix, row_num, rows, NULL, NULL, addData->number);

        length = addData->num_columns * addData->number;
        for (i = 0; i < length; i++)
            XtFree(rows[i]);
        XtFree((XtPointer)rows);

        addData->num_rows += addData->number;
        break;

    case ColumnOrientation:
        widths = (short *) XtMalloc(addData->number * sizeof(short));
        for (i = 0; i < addData->number; i++)
            widths[i] = 15;
        
        columns = (String *) XtMalloc(addData->num_rows * addData->number *
                                      sizeof(String));
        for (i = 0; i < addData->num_rows; i++)
            for (j = 0; j < addData->number; j++) {
                sprintf(buf, "addcol %d, %d", i, j);
                columns[i * addData->number + j] = XtNewString(buf);
            }

        XbaeMatrixAddColumns(addData->matrix, addData->num_columns - 1,
                             columns, NULL, widths, NULL, NULL, NULL, NULL,
                             addData->number);

        XtFree((XtPointer)widths);
        length = addData->num_rows * addData->number;
        for (i = 0; i < length; i++)
            XtFree(columns[i]);
        XtFree((XtPointer)columns);

        addData->num_columns += addData->number;
        break;
    }
}

/* ARGSUSED */
void
DelCB(Widget w, AddData addData, XtPointer call_data)
{
    /*
     * Delete rows or columns
     */

    switch (addData->orientation) {

    case RowOrientation:
        if( addData->num_rows - addData->fixed_rows -
            addData->trailing_fixed_rows - addData->number <= 0 )
            return;

        XbaeMatrixDeleteRows(addData->matrix, addData->num_rows -
                             addData->number, addData->number);

        addData->num_rows -= addData->number;
        break;

    case ColumnOrientation:
        if( addData->num_columns - addData->fixed_columns -
            addData->trailing_fixed_columns - addData->number <= 0 )
            return;
    
        XbaeMatrixDeleteColumns(addData->matrix, addData->num_columns -
                                addData->number, addData->number);

        addData->num_columns -= addData->number;
        break;
    }
}

/* ARGSUSED */
void
SetNumberCB(Widget w, AddData addData, XmScaleCallbackStruct *call_data)
{
    addData->number = call_data->value;
}

/* ARGSUSED */
void
SetPositionCB(Widget w, AddData addData, XbaeMatrixSelectCellCallbackStruct *call_data)
{
    switch (addData->orientation) {
    case RowOrientation:
        XbaeMatrixUnhighlightRow(addData->matrix, addData->row);
        addData->row = call_data->row;
        addData->column = call_data->column;
        XbaeMatrixHighlightRow(addData->matrix, addData->row);
        break;
    case ColumnOrientation:
        XbaeMatrixUnhighlightColumn(addData->matrix, addData->column);
        addData->row = call_data->row;
        addData->column = call_data->column;
        XbaeMatrixHighlightColumn(addData->matrix, addData->column);
        break;
    }

}

void
LoadMatrix(AddData addData)
{
    int i, j;
    char buf[BUFSIZ];
    String *rowArrays, **cells;

    cells = (String **)XtMalloc(addData->num_rows * sizeof(String *));
    rowArrays = (String *)XtMalloc(addData->num_rows * addData->num_columns *
                                   sizeof(String));

    for (i = 0; i < addData->num_rows; i++) {
        cells[i] = &rowArrays[i * addData->num_columns];
            for (j = 0; j < addData->num_columns; j++) {
                sprintf(buf, "%d, %d", i, j);
                rowArrays[i * addData->num_columns + j] = XtNewString(buf);
            }
    }

    XtVaSetValues(addData->matrix,
                  XmNcells,     cells,
                  NULL);

    for (i = 0; i < addData->num_rows; i++)
        for (j = 0; j < addData->num_columns; j++)
            XtFree(rowArrays[i * addData->num_columns + j]);

    XtFree((XtPointer) rowArrays);
    XtFree((XtPointer) cells);
}

Reply via email to