
/*
 *    File editlist.cpp
 */
#include <stdio.h>
#include <string.h>

#include "mguipp.h"

#include "mguitest.hpp"

static EL_TEMPLATE elt[] =
{
    {"Nome", 10, 10, True, NULL, NULL},
    {"Cognome", 20, 10, True, NULL, NULL},
    {"Indirizzo\nsu due righe", 10, 10, False, NULL, NULL},
    {"Numero civico", 3, 10, False, NULL, NULL},
    {"Citta'", 10, 10, True, NULL, NULL}
};

#define N_FIELDS	(int)(sizeof(elt)/sizeof(EL_TEMPLATE))


class EditListDialog : public CmCallback {
    CmShell *shell;
    CmEditList *elist;
public:
    EditListDialog();
    void onActivate(LIST_ACT * la);
    void onAdd(void);
    void onDelete(void);
    void onChange(void);
    void closeDialog(void) { delete shell; delete this; };
};

/******************************************************************
 *	This Callback is invoked by the EDITLIST Object
 *	when the user double-clicks on an item or presses the
 *	'Enter' key on a highlighted item.
 *******************************************************************/
void
EditListDialog::onActivate(LIST_ACT * pla)
{
    char str[256];
    char s1[32];
    char s2[32];
    char s3[32];
    char s4[32];
    char s5[32];
/*
 * Get the fields of the selected item
 */
    elist->getItemField(pla->item, 0, s1);
    elist->getItemField(pla->item, 1, s2);
    elist->getItemField(pla->item, 2, s3);
    elist->getItemField(pla->item, 3, s4);
    elist->getItemField(pla->item, 4, s5);
/*
 * Format and show the selected item one field per line
 */
    sprintf(str, "Item <%s>\n\n<%s>\n<%s>\n<%s>\n<%s>\n<%s>\n",
	    pla->item, s1, s2, s3, s4, s5);
    elist->setUserData((void *) pla->pos);
    MMessageDialog("MEditListGetItemField()", str, " Ok ", 0);
}

/******************************************************************
 *	This Callback is invoked by a PUSH BUTTON
 *	to add a new item in the EDITLIST.
 *******************************************************************/
void
EditListDialog::onAdd(void)
{
    elist->addItemFromEdits(0L);
}

/******************************************************************
 *	This Callback is invoked by a PUSH BUTTON
 *	to delete the item currently loaded in the EDITs of the
 *	EDITLIST.
 *******************************************************************/
void
EditListDialog::onDelete(void)
{
    char *pl[3];
    char strs[2][32];
    long pos;
    void *u_data;
/*
 * Use only the first two fields as a key to find
 * the item to delete
 */
    elist->getEditText(0, strs[0]);
    elist->getEditText(1, strs[1]);
    pl[0] = strs[0];
    pl[1] = strs[1];
    pl[2] = 0;
    elist->seekItem(pl, &pos, &u_data);
/*
 * Delete the item (if found)
 */
    if (pos != -1)
	elist->delElement(pos);
    else
	MBeep();
}

/******************************************************************
 *	This Callback is invoked by a PUSH BUTTON
 *	to change the item currently loaded in the EDITs of the
 *	EDITLIST.
 *******************************************************************/
void
EditListDialog::onChange(void)
{
    char *pl[N_FIELDS];
    char strs[N_FIELDS][32];
    long pos;
    void *u_data;
    int i;
/*
 * Use only the first two fields as a key to find
 * the item to delete
 */
    elist->getEditText(0, strs[0]);
    elist->getEditText(1, strs[1]);
    pl[0] = strs[0];
    pl[1] = strs[1];
    pl[2] = 0;
    elist->seekItem(pl, &pos, &u_data);
    if (pos != -1)
    {
/*
 * Get the field values from the EDITs and replace the item
 * at position 'pos'
 */
 	for (i = 2; i < N_FIELDS; i++)
	{
	    elist->getEditText(i, strs[i]);
	    pl[i] = strs[i];
	}
	elist->changeElement(pos, pl, 0L);
    }
    else
	MBeep();
}

EditListDialog::EditListDialog()
{
    CmContainer *form0, *form;
    CmSFile *sfile;
    CmPushButton *pbutton;
    int i;
    char s1[32];
    char s2[32];
    char s3[32];
    char s4[32];
    char s5[32];
    char *argl[6];

    shell = new CmShell("Edit List", SF_MODAL);

    form0 = new CmColForm(shell);

    form = new CmRowForm(form0);

    elist = new CmEditList(form, FIXED_MEDIUM, elt, N_FIELDS, 10, 28);

    elist->setColor(cadetblue, black);
    elist->setHeadColor(darkblue, white);
    elist->setCallback(this, (LISTACT_CB)&EditListDialog::onActivate);
    elist->setSortCallback(strcmp);

/*
 * Create Push buttons and set the callbacks to add, delete and change
 * item values
 */
    form = new CmColForm(form);
    pbutton = new CmPushButton(form, "Add", TIMES_N_FONT);
    pbutton->setCallback(this, (VOID_CB)&EditListDialog::onAdd);
    pbutton = new CmPushButton(form, "Del", TIMES_N_FONT);
    pbutton->setCallback(this, (VOID_CB)&EditListDialog::onDelete);
    pbutton = new CmPushButton(form, "Change", TIMES_N_FONT);
    pbutton->setCallback(this, (VOID_CB)&EditListDialog::onChange);

/*
 * Insert 50 items in the EDITLIST
 */
    argl[0] = s1;
    argl[1] = s2;
    argl[2] = s3;
    argl[3] = s4;
    argl[4] = s5;
    argl[5] = 0;
    for (i = 0; i < 50; i++)
    {
	sprintf(s1, "Nome_%d___", i);
	sprintf(s2, "Cognome_%d___", i);
	sprintf(s3, "Indirizzo_%d___", i);
	sprintf(s4, "%03d", i);
	sprintf(s5, "citta'_%d___", i);
	elist->addItem(argl, (void *) i);
    }
/*
 * Create a SFile to view this source file
 */
    sfile = new CmSFile(form0, __FILE__, FIXED_MEDIUM, 15, 46);
    sfile->setColor(darkblue, white);

    pbutton = new CmPushButton(shell, "Close", TIMES_MEDIUM);
    pbutton->setCallback(this, (VOID_CB)&EditListDialog::closeDialog);

    shell->realize();
}

/*****************************************************
 *	This callback opens the dialog when the
 *	corresponding menu item is selected
 *****************************************************/
void
EditListDemo(void)
{
	new EditListDialog;
}

