PromptDialog, SelectionDialog, FileSelectionDialog

Dernière modification : 9/12/96

Table des matières

Le widget de type PromptDialog

Le PromptDialog widget invite l'utilisateur à entrer des données au clavier.

Pour créer un PromptDialog, on utilise la fonction XmCreatePromptDialog()

Ce widget possède deux ressources importantes :

Remarque : le PromptDialog est basé sur la classe SelectionBox, pour compiler sans erreur il faut donc inclure le fichier <Xm/SelectionB.h>.

Nous allons ensemble étudier le petit programme prompt.c, extension du programme dialog2.c étudié précédemment.

L'exécutable se trouve dans :

    /home/profs/cours/minfo/motif/dialogs/prompt

Exemple de PromptDialog : celui créé par le programme prompt.c :

Le programme prompt.c

Nous ajoutons un nouveau menu "Prompt" à l'exemple précédent (dialog2.c). Ce menu ne contient qu'un CascadeButton qui décenche l'affichage du PromptWidget.

Le texte saisi par l'utilisateur sera affiché dans un InformationDialog créé par la fonction de callback du PromptDialog, la fonction prompt_activate().

Une fonction de callback d'un PromptDialog possède la structure suivante :



void prompt_callback(Widget widget, 
                     XtPointer client_data,
                     XmSelectionBoxCallbackStruct *selection)


En général, nous sommes surtout intéressés par la chaîne de caractères qui a été saisie dans le PromptDialog. Cette information est située dans le champ value (type XmString) de la structure XmSelectionBoxCallbackStruct.

Dans la fonction de callback du PromptDialog, prompt_activate() (voir ci-dessus l'exemple de code), cette valeur se trouve dans selection->value. La fonction utilise cette valeur pour mettre à jour la ressource XmNmessageString de l'InformationDialog.



#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/CascadeB.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/SelectioB.h>
#include <Xm/RowColumn.h>

void ScrubDial(Widget, int);

Widget top_wid;

/*--------------------------*/
main(int argc, char *argv[])
/*--------------------------*/
{   

  XtAppContext app;
  Widget main_w, menu_bar, info, prompt, quit;
  void info_pop_up(), quit_pop_up(), prompt_pop_up();

    
  top_wid = XtVaAppInitialize(&app, "Demos", NULL, 0,
                              &argc, argv, NULL, NULL);

  main_w = XtVaCreateManagedWidget("main_window",
                                   xmMainWindowWidgetClass, top_wid, 
                                   XmNheight, 300,
                                   XmNwidth,300,
                                   NULL);

        
  menu_bar = XmCreateMenuBar(main_w, "main_list", 
                             NULL, 0);        
  XtManageChild(menu_bar);
       
  /* create prompt widget + callback */       
  prompt = XtVaCreateManagedWidget( "Prompt",
                                    xmCascadeButtonWidgetClass, menu_bar,
                                    XmNmnemonic, 'P',
                                    NULL);
                
  /* Callback has data passed to */   
  XtAddCallback(prompt, XmNactivateCallback, 
                prompt_pop_up, NULL);

    
    
  /* create quit widget + callback */
  quit = XtVaCreateManagedWidget( "Quit",
                                  xmCascadeButtonWidgetClass, menu_bar,
                                  XmNmnemonic, 'Q',
                                  NULL);
        
        
  /* Callback has data passed to */
  XtAddCallback(quit, XmNactivateCallback, quit_pop_up, 
                "Are you sure you want to quit?");


    
  /* create help widget + callback */
        
  info = XtVaCreateManagedWidget( "Info",
                                  xmCascadeButtonWidgetClass, menu_bar,
                                  XmNmnemonic, 'I',
                                  NULL);    

  XtAddCallback(info, XmNactivateCallback, info_pop_up, 
                "Select Prompt Option To Get Program Going."); 
    
  XtRealizeWidget(top_wid);
  XtAppMainLoop(app);
}

/*----------------------------------------------------*/
void prompt_pop_up(Widget cascade_button, char *text, 
                   XmPushButtonCallbackStruct *cbs)
/*----------------------------------------------------*/
{   
  Widget dialog, remove;
  XmString xm_string1, xm_string2;
  void prompt_activate();
  Arg args[3];
  int n;

  /* label the dialog */
  xm_string1 = XmStringCreateSimple("Enter Text Here:");
  /* default text string  */
  xm_string2 = XmStringCreateSimple("Default String");

  n=0;
  XtSetArg(args[n], XmNselectionLabelString, xm_string1); n++;
  XtSetArg(args[n], XmNtextString, xm_string2); n++;
   /* set up default button for cancel callback */
  XtSetArg(args[n], XmNdefaultButtonType, 
           XmDIALOG_CANCEL_BUTTON);  n++;

  /* Create the WarningDialog */
  dialog = XmCreatePromptDialog(cascade_button, "prompt", 
                                args, n);
    
  XmStringFree(xm_string1);
  XmStringFree(xm_string2);

   
  XtAddCallback(dialog, XmNokCallback, prompt_activate, 
                NULL);
  /* Scrub Prompt Help Button */
  remove = XmSelectionBoxGetChild(dialog, 
                                  XmDIALOG_HELP_BUTTON);
   
  XtUnmanageChild(remove);  /* scrub HELP button */ 
    
  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);
}

/*----------------------------------------------------*/
void info_pop_up(Widget cascade_button, char *text, 
                 XmPushButtonCallbackStruct *cbs)
/*----------------------------------------------------*/
{   
  Widget dialog;
  XmString xm_string;
  extern void info_activate();
  Arg args[2];
  int n;

  /* label the dialog */
  xm_string = XmStringCreateSimple(text);

  n=0;
  XtSetArg(args[n], XmNmessageString, xm_string); n++;
  /* set up default button for OK callback */
  XtSetArg(args[n], XmNdefaultButtonType, 
           XmDIALOG_OK_BUTTON); n++;

   
  /* Create the InformationDialog as child of 
       cascade_button passed in */
  dialog = XmCreateInformationDialog(cascade_button, 
                                     "info", args, n);
    
  ScrubDial(dialog, XmDIALOG_CANCEL_BUTTON);
  ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

  XmStringFree(xm_string);

  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);
}

/*-------------------------------------------------*/
void quit_pop_up(Widget cascade_button, char *text, 
                 XmPushButtonCallbackStruct *cbs)
/*-------------------------------------------------*/
{   
  Widget dialog;
  XmString xm_string;
  void quit_activate();
  Arg args[1];
  int n;

  /* label the dialog */
  xm_string = XmStringCreateSimple(text);

  n=0;
  XtSetArg(args[n], XmNmessageString, xm_string); n++;
  /* set up default button for cancel callback */
  XtSetArg(args[n], XmNdefaultButtonType, 
           XmDIALOG_CANCEL_BUTTON); n++;
  /* Create the WarningDialog */
  dialog = XmCreateWarningDialog(cascade_button, "quit", 
                                 args, n);
    
  ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

  XmStringFree(xm_string);

  XtAddCallback(dialog, XmNokCallback, quit_activate, 
                NULL);

  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);
}

/*-----------------------------------*/
void ScrubDial(Widget wid, int dial)
/*-----------------------------------*/
/* routine to remove a DialButton from a Dialog */
{  
  Widget remove;

  remove = XmMessageBoxGetChild(wid, dial);
  XtUnmanageChild(remove);
}

/*---------------------------------------------------------*/
void prompt_activate(Widget widget, XtPointer client_data,
                     XmSelectionBoxCallbackStruct *selection)
/*---------------------------------------------------------*/
/* callback function for Prompt activate */
{   
  Widget dialog;
  Arg args[2];
  XmString xm_string;
  int n;

  /* compose InformationDialog output string */
  /* selection->value holds XmString entered to prompt */
    
  xm_string = XmStringCreateSimple("You typed: ");
  xm_string = XmStringConcat(xm_string,selection->value);

  n=0;
  XtSetArg(args[n], XmNmessageString, xm_string); n++;
  /* set up default button for OK callback */
  XtSetArg(args[n], XmNdefaultButtonType, 
           XmDIALOG_OK_BUTTON);  n++;
  /* Create the InformationDialog to echo 
       string grabbed from prompt */
  dialog = XmCreateInformationDialog(top_wid, 
                                     "prompt_message", args, n);
    
  ScrubDial(dialog, XmDIALOG_CANCEL_BUTTON);
  ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);
}

/*---------------------------------*/
void quit_activate(Widget dialog)
/*---------------------------------*/
/* callback routines for quit ok dialog */
{
  printf("Quit Ok was pressed.\n");
  exit(0);
}


SelectionDialog et FileSelectionDialog

Ces deux widgets permettent à l'utilisateur d'effectuer un ou plusieurs choix dans une liste d'items.

Nous allons étudier le FileSelectionDialog car bien que plus complexe à utiliser que le SelectionDialog son usage est plus fréquent.

Le FileSelectionDialog est spécialisé dans la séléction de fichier(s) dans un répertoire. On le rencontre dans toutes les applications qui nécessitent la lecture/écriture de fichiers.

Le widget de type SelectionDialog est moins spécialisé et permet de séléctionner des objets moins spécifiques que des fichiers.

Exemple de FileSelectionDialog :

Pour créer un FileSelectionDialog, on utilise la fonction XmCreateFileSelectionDialog(). Pour compiler sans erreur, il faut inclure le fichier <Xm/FileSB.h> car le widget de type FileSelectionDialog est basé sur la classe FileSelectionBox.

Remarque : si on utilise des fonctions de manipulation des SelectionDialog telles que XmSelectionBoxGetChild() nécessaire si on veut enlever un des boutons par défaut d'un FileSelectionDialog (voir programme file_select.c), nous devons aussi inclure <Xm/SelectioB.h> pour ne pas qu'il y ait d'erreur de compilation .

Ressources des FileSelectionDialog

Un FileSelectionDialog possède de nombreuses ressources que l'on peut positionner pour contrôler la recherche de fichiers, utiliser des méta-caractères tels que '*' pour ne proposer que les fichiers ayant un suffixe donné, etc... En général ces ressources sont du type XmString.

XmNdirectory
Le répertoire oú se trouvent les fichier que l'on va proposer à l'utilisateur. Par défault : le répertoire courant.
XmNdirLabelString
Texte affiché au-dessus de la boîte du FileSelectionDialog contenant la liste des noms de répertoires.
XmNdirMask
Masque utilisé pour filtrer certains noms de fichiers. Par exemple, dans le programme file_select.c ce masque vaut *.c afin de ne proposer que des fichiers sources C dans le FileSelctionDialog.
XmNdirSpec
Le nom du fichier choisi par défaut.
XmNfileListLabelString
Texte affiché au-dessus de la boîte du FileSelectionDialog contenant la liste des noms de fichiers.
XmNfileTypeMask
Type des fichiers devant être listés. Valeurs possibles : XmFILE_REGULAR, XmFILE_DIRECTORY, XmFILE_TYPE_ANY.
XmNfilterLabelString
Texte affiché au-dessus de la boîte du FileSelectionDialog contenant le filtre sur les noms de fichiers.

Certaines de ces resssources peuvent être modifiées pendant l'exécution du programme par l'utilisateur, en saisissant du texte directement dans les fenêtres correspondantes du FileSelectionDialog.

Le programme file_select.c

Ce petit programme ouvre un FileSelectionDialog avec un filtre pour ne proposer que des fichiers sources C (valeur du filtre XmNdirMask : *.c). Lorsqu'un fichier est séléctionné son listing est imprimé sur stdout.

L'exécutable se trouve dans :

    /home/profs/cours/minfo/motif/dialogs/file_select



#include <stdio.h>

#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/CascadeB.h>
#include <Xm/MessageB.h>
#include <Xm/SelectioB.h>
#include <Xm/PushB.h>
#include <Xm/FileSB.h>
#include <Xm/RowColumn.h>

void ScrubDial(Widget, int);

Widget top_wid;

/*---------------------------*/
main(int argc, char *argv[])
/*---------------------------*/
{
XtAppContext app;
Widget main_w, menu_bar, file_select, quit;
void quit_pop_up(), select_pop_up(); /* callbacks */

top_wid = XtVaAppInitialize(&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);

main_w = XtVaCreateManagedWidget("main_window",
xmMainWindowWidgetClass, top_wid,
XmNheight, 300,
XmNwidth,300,
NULL);


menu_bar = XmCreateMenuBar(main_w, "main_list",
NULL, 0);
XtManageChild(menu_bar);


/* create prompt widget + callback */

file_select = XtVaCreateManagedWidget( "Select",
xmCascadeButtonWidgetClass, menu_bar,
XmNmnemonic, 'S',
NULL);


/* Callback has data passed to */
XtAddCallback(file_select, XmNactivateCallback,
select_pop_up, NULL);

/* create quit widget + callback */
quit = XtVaCreateManagedWidget( "Quit",
xmCascadeButtonWidgetClass, menu_bar,
XmNmnemonic, 'Q',
NULL);


/* Callback has data passed to */
XtAddCallback(quit, XmNactivateCallback, quit_pop_up,
"Are you sure you want to quit?");

XtRealizeWidget(top_wid);
XtAppMainLoop(app);
}

/*----------------------------------------------------*/
void select_pop_up(Widget cascade_button, char *text,
XmPushButtonCallbackStruct *cbs)
/*----------------------------------------------------*/
{
Widget dialog, remove;
void select_activate(), cancel();
XmString mask;
Arg args[1];
int n;

/* Create the FileSelectionDialog */

mask = XmStringCreateSimple("*.c");

n=0;
XtSetArg(args[n], XmNdirMask, mask); n++;
dialog = XmCreateFileSelectionDialog(cascade_button,
"select", args, n);

XtAddCallback(dialog, XmNokCallback, select_activate,
NULL);
XtAddCallback(dialog, XmNcancelCallback, cancel, NULL);

remove = XmSelectionBoxGetChild(dialog,
XmDIALOG_HELP_BUTTON);

XtUnmanageChild(remove); /* delete HELP BUTTON */


XtManageChild(dialog);
XtPopup(XtParent(dialog), XtGrabNone);
}

/*-------------------------------------------------*/
void quit_pop_up(Widget cascade_button, char *text,
XmPushButtonCallbackStruct *cbs)
/*-------------------------------------------------*/
{
Widget dialog;
XmString xm_string;
void quit_activate();
Arg args[2];
int n;

/* label the dialog */
xm_string = XmStringCreateSimple(text);

n = 0;
XtSetArg(args[n], XmNmessageString, xm_string); n++;
/* set up default button for cancel callback */
XtSetArg(args[n], XmNdefaultButtonType,
XmDIALOG_CANCEL_BUTTON); n++;
/* Create the WarningDialog */
dialog = XmCreateWarningDialog(cascade_button, "quit",
args, n);

ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

XmStringFree(xm_string);

XtAddCallback(dialog, XmNokCallback, quit_activate,
NULL);

XtManageChild(dialog);
XtPopup(XtParent(dialog), XtGrabNone);
}

/*----------------------------------*/
void ScrubDial(Widget wid, int dial)
/*----------------------------------*/
/* routine to remove a DialButton from a Dialog */
{
Widget remove;

remove = XmMessageBoxGetChild(wid, dial);
XtUnmanageChild(remove);
}

/*-------------------------------------------------------*/
void select_activate(Widget widget, caddr_t client_data,
XmFileSelectionBoxCallbackStruct *selection)
/*-------------------------------------------------------*/
/* callback function for Prompt activate */
/* function opens file (text) and prints to stdout */
{
FILE *fp, *fopen();
char *filename, line[200];
void error();

XmStringGetLtoR(selection->value,
XmSTRING_DEFAULT_CHARSET, &filename);


if ((fp = fopen(filename,"r")) == NULL)
error("CANNOT OPEN FILE", filename);
else {
while (!feof(fp)) {
fgets(line,200,fp);
printf("%s\n",line);
}
fclose(fp);
}
}

/*----------------------------------------------*/
void cancel(Widget widget, caddr_t client_data,
XmFileSelectionBoxCallbackStruct *selection)
/*----------------------------------------------*/
{
XtUnmanageChild(widget); /* undisplay widget */
}

/*-----------------------------*/
void error(char *s1, char *s2)
/*-----------------------------*/
/* prints error to stdout */
{
/* EXERCICE:

REECRIRE CETTE ROUTINE POUR AFFICHER LE TEXTE DANS UN
ErrorDialog widget. */

printf("%s: %s\n", s1, s2);
exit(-1);
}

/*-------------------------------*/
void quit_activate(Widget dialog)
/*-------------------------------*/
{
/* callback routines for quit ok dialog */
printf("Quit Ok was pressed.\n");
exit(0);
}



Copyright Michel Buffa 1996 (michel.buffa@unice.fr)