LCOV - code coverage report
Current view: top level - gdraw - gaskdlg.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 22 785 2.8 %
Date: 2017-08-04 Functions: 3 23 13.0 %

          Line data    Source code
       1             : /* Copyright (C) 2000-2012 by George Williams */
       2             : /*
       3             :  * Redistribution and use in source and binary forms, with or without
       4             :  * modification, are permitted provided that the following conditions are met:
       5             : 
       6             :  * Redistributions of source code must retain the above copyright notice, this
       7             :  * list of conditions and the following disclaimer.
       8             : 
       9             :  * Redistributions in binary form must reproduce the above copyright notice,
      10             :  * this list of conditions and the following disclaimer in the documentation
      11             :  * and/or other materials provided with the distribution.
      12             : 
      13             :  * The name of the author may not be used to endorse or promote products
      14             :  * derived from this software without specific prior written permission.
      15             : 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      17             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      18             :  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
      19             :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      20             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      22             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      23             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      24             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      25             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : #include <stdarg.h>
      28             : #include <stdlib.h>
      29             : #include <string.h>
      30             : #include "ustring.h"
      31             : #include "ffglib.h"
      32             : #include <glib/gprintf.h>
      33             : #include "gdraw.h"
      34             : #include "gwidget.h"
      35             : #include "ggadget.h"
      36             : #include "ggadgetP.h"
      37             : 
      38             : static GWindow last;
      39             : static const char *last_title;
      40             : 
      41             : struct dlg_info {
      42             :     int done;
      43             :     int ret;
      44             :     int multi;
      45             :     int exposed;
      46             :     int size_diff;
      47             :     int bcnt;
      48             : };
      49             : 
      50           0 : static int d_e_h(GWindow gw, GEvent *event) {
      51           0 :     struct dlg_info *d = GDrawGetUserData(gw);
      52             : 
      53           0 :     if ( event->type==et_close ) {
      54           0 :         d->done = true;
      55             :         /* d->ret is initialized to cancel */
      56           0 :     } else if ( event->type==et_controlevent &&
      57           0 :             event->u.control.subtype == et_buttonactivate ) {
      58           0 :         d->done = true;
      59           0 :         d->ret = GGadgetGetCid(event->u.control.g);
      60           0 :     } else if ( event->type == et_expose ) {
      61           0 :         d->exposed = true;
      62           0 :     } else if ( event->type == et_char ) {
      63           0 : return( false );
      64           0 :     } else if ( event->type == et_resize && !d->exposed ) {
      65             :         GRect pos,rootsize;
      66           0 :         GDrawGetSize(gw,&pos);
      67           0 :         GDrawGetSize(GDrawGetRoot(NULL),&rootsize);
      68           0 :         if ( pos.x+pos.width>=rootsize.width || pos.y+pos.height>=rootsize.height ) {
      69           0 :             if ( pos.x+pos.width>=rootsize.width )
      70           0 :                 if (( pos.x = rootsize.width - pos.width )<0 ) pos.x = 0;
      71           0 :             if ( pos.y+pos.height>=rootsize.height )
      72           0 :                 if (( pos.y = rootsize.height - pos.height )<0 ) pos.y = 0;
      73           0 :             GDrawMove(gw,pos.x,pos.y);
      74             :         }
      75           0 :     } else if ( event->type == et_map ) {
      76             :         /* Above palettes */
      77           0 :         GDrawRaise(gw);
      78             :     }
      79           0 : return( true );
      80             : }
      81             : 
      82           0 : static int w_e_h(GWindow gw, GEvent *event) {
      83             : 
      84           0 :     if ( event->type==et_close ||
      85           0 :             (event->type==et_controlevent &&
      86           0 :              event->u.control.subtype == et_buttonactivate ) ||
      87           0 :             event->type==et_timer )
      88           0 :         GDrawDestroyWindow(gw);
      89           0 :     else if ( event->type == et_map ) {
      90             :         /* Above palettes */
      91           0 :         GDrawRaise(gw);
      92           0 :     } else if ( event->type == et_char ) {
      93           0 : return( false );
      94           0 :     } else if ( event->type == et_destroy ) {
      95           0 :         if ( last==gw ) {
      96           0 :             last = NULL;
      97           0 :             last_title = NULL;
      98             :         }
      99             :     }
     100           0 : return( true );
     101             : }
     102             : 
     103             : #define GLINE_MAX       20
     104             : 
     105           0 : static int FindLineBreaks(const unichar_t *question, GTextInfo linebreaks[GLINE_MAX+1]) {
     106             :     int lb, i;
     107             :     const unichar_t *pt, *last;
     108             : 
     109             :     /* Find good places to break the question into bits */
     110           0 :     last = pt = question;
     111           0 :     linebreaks[0].text = (unichar_t *) question;
     112           0 :     lb=0;
     113           0 :     while ( *pt!='\0' && lb<GLINE_MAX-1 ) {
     114           0 :         last = pt;
     115             :         /* break lines around 60 characters (or if there are no spaces at 90 chars) */
     116           0 :         while ( pt-linebreaks[lb].text<60 ||
     117           0 :                 (pt-linebreaks[lb].text<90 && last==linebreaks[lb].text)) {
     118           0 :             if ( *pt=='\n' || *pt=='\0' ) {
     119           0 :                 last = pt;
     120           0 :         break;
     121             :             }
     122           0 :             if ( *pt==' ' )
     123           0 :                 last = pt;
     124           0 :             ++pt;
     125             :         }
     126           0 :         if ( last==linebreaks[lb].text )
     127           0 :             last = pt;
     128           0 :         if ( *last==' ' || *last=='\n' ) ++last;
     129           0 :         linebreaks[++lb].text = (unichar_t *) last;
     130           0 :         pt = last;
     131             :     }
     132           0 :     if ( *pt!='\0' )
     133           0 :         linebreaks[++lb].text = (unichar_t *) pt+u_strlen(pt);
     134           0 :     for ( i=0; i<lb; ++i ) {
     135           0 :         int temp = linebreaks[i+1].text - linebreaks[i].text;
     136           0 :         if ( linebreaks[i+1].text[-1]==' ' || linebreaks[i+1].text[-1]=='\n' )
     137           0 :             --temp;
     138           0 :         linebreaks[i].text = u_copyn(linebreaks[i].text,temp);
     139             :     }
     140             : 
     141           0 :     if ( question[u_strlen(question)-1]=='\n' )
     142           0 :         --lb;
     143           0 : return( lb );
     144             : }
     145             : 
     146           0 : static GWindow DlgCreate(const unichar_t *title,const unichar_t *question,va_list ap,
     147             :         const unichar_t **answers, const unichar_t *mn, int def, int cancel,
     148             :         struct dlg_info *d, int add_text, int restrict_input, int center) {
     149             :     GTextInfo qlabels[GLINE_MAX+1], *blabels;
     150             :     GGadgetCreateData *gcd;
     151           0 :     int lb, bcnt=0;
     152             :     GRect pos;
     153             :     GWindow gw;
     154             :     GWindowAttrs wattrs;
     155             :     extern FontInstance *_ggadget_default_font;
     156             :     int as, ds, ld, fh;
     157             :     int w, maxw, bw, bspace;
     158             :     int i, y;
     159             :     gchar *buf, *qbuf;
     160             :     unichar_t *ubuf;
     161             :     extern GBox _GGadget_defaultbutton_box;
     162             : 
     163           0 :     if ( d!=NULL )
     164           0 :         memset(d,0,sizeof(*d));
     165           0 :     GGadgetInit();
     166             :     /* u_vsnprintf(ubuf,sizeof(ubuf)/sizeof(ubuf[0]),question,ap);*/
     167             :     /* u_vsnprintf() also assumes UCS4 string is null terminated */
     168           0 :     qbuf = g_ucs4_to_utf8( (const gunichar *)question, -1, NULL, NULL, NULL );
     169           0 :     if( !qbuf ) {
     170           0 :         fprintf( stderr, "Failed to convert question string in DlgCreate()\n" );
     171           0 :         return( NULL );
     172             :     }
     173           0 :     g_vasprintf(&buf, qbuf, ap);
     174           0 :     g_free( qbuf );
     175           0 :     ubuf = (unichar_t *) g_utf8_to_ucs4( buf, -1, NULL, NULL, NULL );
     176           0 :     g_free( buf );
     177           0 :     if( !ubuf ) {
     178           0 :         fprintf( stderr, "Failed to convert formatted string in DlgCreate()\n" );
     179           0 :         return( NULL );
     180             :     }
     181           0 :     if ( screen_display==NULL ) {
     182           0 :         char *temp = u2def_copy(ubuf);
     183           0 :         fprintf(stderr, "%s\n", temp);
     184           0 :         free(temp);
     185           0 :         if ( d!=NULL ) d->done = true;
     186           0 : return( NULL );
     187             :     }
     188             : 
     189           0 :     GProgressPauseTimer();
     190           0 :     memset(qlabels,'\0',sizeof(qlabels));
     191           0 :     lb = FindLineBreaks(ubuf,qlabels);
     192           0 :     for ( bcnt=0; answers[bcnt]!=NULL; ++bcnt);
     193           0 :     blabels = calloc(bcnt+1,sizeof(GTextInfo));
     194           0 :     for ( bcnt=0; answers[bcnt]!=NULL; ++bcnt)
     195           0 :         blabels[bcnt].text = (unichar_t *) answers[bcnt];
     196             : 
     197           0 :     memset(&wattrs,0,sizeof(wattrs));
     198             :     /* If we have many questions in quick succession the dlg will jump around*/
     199             :     /*  as it tracks the cursor (which moves to the buttons). That's not good*/
     200             :     /*  So I don't do undercursor here */
     201           0 :     wattrs.mask = wam_events|wam_cursor|wam_wtitle|wam_isdlg;
     202           0 :     if ( restrict_input )
     203           0 :         wattrs.mask |= wam_restrict;
     204             :     else 
     205           0 :         wattrs.mask |= wam_notrestricted;
     206           0 :     if ( center )
     207           0 :         wattrs.mask |= wam_centered;
     208             :     else
     209           0 :         wattrs.mask |= wam_undercursor;
     210           0 :     wattrs.is_dlg = true;
     211           0 :     wattrs.not_restricted = true;
     212           0 :     wattrs.restrict_input_to_me = 1;
     213           0 :     wattrs.event_masks = ~(1<<et_charup);
     214           0 :     wattrs.undercursor = 1;
     215           0 :     wattrs.centered = 2;
     216           0 :     wattrs.cursor = ct_pointer;
     217           0 :     wattrs.window_title = (unichar_t *) title;
     218           0 :     pos.x = pos.y = 0;
     219           0 :     pos.width = 200; pos.height = 60;           /* We'll figure size later */
     220             :                 /* but if we get the size too small, the cursor isn't in dlg */
     221           0 :     gw = GDrawCreateTopWindow(NULL,&pos,restrict_input?d_e_h:w_e_h,d,&wattrs);
     222             : 
     223           0 :     GGadgetInit();
     224           0 :     GDrawSetFont(gw,_ggadget_default_font);
     225           0 :     GDrawWindowFontMetrics(gw,_ggadget_default_font,&as,&ds,&ld);
     226           0 :     fh = as+ds;
     227           0 :     maxw = 0;
     228           0 :     for ( i=0; i<lb; ++i ) {
     229           0 :         w = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     230           0 :         if ( w>maxw ) maxw = w;
     231             :     }
     232           0 :     bw = 0;
     233           0 :     for ( i=0; i<bcnt; ++i ) {
     234           0 :         w = GDrawGetTextWidth(gw,answers[i],-1);
     235           0 :         if ( w>bw ) bw = w;
     236             :     }
     237           0 :     bw += GDrawPointsToPixels(gw,20);
     238           0 :     bspace = GDrawPointsToPixels(gw,6);
     239           0 :     if ( (bw+bspace) * bcnt > maxw )
     240           0 :         maxw = (bw+bspace)*bcnt;
     241           0 :     if ( bcnt!=1 )
     242           0 :         bspace = (maxw-bcnt*bw)/(bcnt-1);
     243           0 :     maxw += GDrawPointsToPixels(gw,16);
     244             : 
     245           0 :     gcd = calloc(lb+bcnt+2,sizeof(GGadgetCreateData));
     246           0 :     if ( lb==1 ) {
     247           0 :         gcd[0].gd.pos.width = GDrawGetTextWidth(gw,qlabels[0].text,-1);
     248           0 :         gcd[0].gd.pos.x = (maxw-gcd[0].gd.pos.width)/2;
     249           0 :         gcd[0].gd.pos.y = GDrawPointsToPixels(gw,6);
     250           0 :         gcd[0].gd.pos.height = fh;
     251           0 :         gcd[0].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     252           0 :         gcd[0].gd.label = &qlabels[0];
     253           0 :         gcd[0].creator = GLabelCreate;
     254           0 :     } else for ( i=0; i<lb; ++i ) {
     255           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,8);
     256           0 :         gcd[i].gd.pos.y = GDrawPointsToPixels(gw,6)+i*fh;
     257           0 :         gcd[i].gd.pos.width = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     258           0 :         gcd[i].gd.pos.height = fh;
     259           0 :         gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     260           0 :         gcd[i].gd.label = &qlabels[i];
     261           0 :         gcd[i].creator = GLabelCreate;
     262             :     }
     263           0 :     y = GDrawPointsToPixels(gw,12)+lb*fh;
     264           0 :     if ( add_text ) {
     265           0 :         gcd[bcnt+lb].gd.pos.x = GDrawPointsToPixels(gw,8);
     266           0 :         gcd[bcnt+lb].gd.pos.y = y;
     267           0 :         gcd[bcnt+lb].gd.pos.width = maxw-2*GDrawPointsToPixels(gw,6);
     268           0 :         gcd[bcnt+lb].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0 | gg_text_xim;
     269           0 :         gcd[bcnt+lb].gd.cid = bcnt;
     270           0 :         gcd[bcnt+lb].creator = GTextFieldCreate;
     271           0 :         y += fh + GDrawPointsToPixels(gw,6) + GDrawPointsToPixels(gw,10);
     272             :     }
     273           0 :     y += GDrawPointsToPixels(gw,2);
     274           0 :     for ( i=0; i<bcnt; ++i ) {
     275           0 :         gcd[i+lb].gd.pos.x = GDrawPointsToPixels(gw,8) + i*(bw+bspace);
     276           0 :         gcd[i+lb].gd.pos.y = y;
     277           0 :         gcd[i+lb].gd.pos.width = bw;
     278           0 :         gcd[i+lb].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     279           0 :         if ( i==def ) {
     280           0 :             gcd[i+lb].gd.flags |= gg_but_default;
     281           0 :             if ( _GGadget_defaultbutton_box.flags&box_draw_default ) {
     282           0 :                 gcd[i+lb].gd.pos.x -= GDrawPointsToPixels(gw,3);
     283           0 :                 gcd[i+lb].gd.pos.y -= GDrawPointsToPixels(gw,3);
     284           0 :                 gcd[i+lb].gd.pos.width += 2*GDrawPointsToPixels(gw,3);
     285             :             }
     286             :         }
     287           0 :         if ( i==cancel )
     288           0 :             gcd[i+lb].gd.flags |= gg_but_cancel;
     289           0 :         gcd[i+lb].gd.cid = i;
     290           0 :         gcd[i+lb].gd.label = &blabels[i];
     291           0 :         if ( mn!=NULL ) {
     292           0 :             gcd[i+lb].gd.mnemonic = mn[i];
     293           0 :             if ( mn[i]=='\0' ) mn = NULL;
     294             :         }
     295           0 :         gcd[i+lb].creator = GButtonCreate;
     296             :     }
     297           0 :     if ( bcnt==1 )
     298           0 :         gcd[lb].gd.pos.x = (maxw-bw)/2;
     299           0 :     GGadgetsCreate(gw,gcd);
     300           0 :     pos.width = maxw;
     301           0 :     pos.height = (lb+1)*fh + GDrawPointsToPixels(gw,34);
     302           0 :     if ( add_text )
     303           0 :         pos.height += fh + GDrawPointsToPixels(gw,16);
     304           0 :     GDrawResize(gw,pos.width,pos.height);
     305           0 :     GWidgetHidePalettes();
     306           0 :     if ( d!=NULL ) {
     307           0 :         d->ret  = cancel;
     308           0 :         d->bcnt = bcnt;
     309             :     }
     310           0 :     GDrawSetVisible(gw,true);
     311           0 :     free(blabels);
     312           0 :     free(gcd);
     313           0 :     for ( i=0; i<lb; ++i )
     314           0 :         free(qlabels[i].text);
     315           0 :     GProgressResumeTimer();
     316           0 : return( gw );
     317             : }
     318             : 
     319           0 : int GWidgetAsk(const unichar_t *title,
     320             :         const unichar_t **answers, const unichar_t *mn, int def, int cancel,
     321             :         const unichar_t *question,...) {
     322             :     struct dlg_info d;
     323             :     GWindow gw;
     324             :     va_list ap;
     325             : 
     326           0 :     if ( screen_display==NULL )
     327           0 : return( def );
     328             : 
     329           0 :     va_start(ap,question);
     330           0 :     gw = DlgCreate(title,question,ap,answers,mn,def,cancel,&d,false,true,false);
     331           0 :     va_end(ap);
     332             : 
     333           0 :     while ( !d.done )
     334           0 :         GDrawProcessOneEvent(NULL);
     335           0 :     GDrawDestroyWindow(gw);
     336           0 :     GDrawSync(NULL);
     337           0 :     GDrawProcessPendingEvents(NULL);
     338           0 : return(d.ret);
     339             : }
     340             : 
     341           0 : unichar_t *GWidgetAskStringR(int title,const unichar_t *def,int question,...) {
     342             :     struct dlg_info d;
     343             :     GWindow gw;
     344           0 :     unichar_t *ret = NULL;
     345             :     const unichar_t *ocb[3]; unichar_t ocmn[2];
     346             :     va_list ap;
     347             : 
     348           0 :     if ( screen_display==NULL )
     349           0 : return( u_copy(def ));
     350             : 
     351           0 :     ocb[2]=NULL;
     352           0 :     ocb[0] = GStringGetResource( _STR_OK, &ocmn[0]);
     353           0 :     ocb[1] = GStringGetResource( _STR_Cancel, &ocmn[1]);
     354           0 :     va_start(ap,question);
     355           0 :     gw = DlgCreate(GStringGetResource( title,NULL),GStringGetResource( question,NULL),ap,
     356             :             ocb,ocmn,0,1,&d,true,true,false);
     357           0 :     va_end(ap);
     358           0 :     if ( def!=NULL && *def!='\0' )
     359           0 :         GGadgetSetTitle(GWidgetGetControl(gw,2),def);
     360           0 :     while ( !d.done )
     361           0 :         GDrawProcessOneEvent(NULL);
     362           0 :     if ( d.ret==0 )
     363           0 :         ret = GGadgetGetTitle(GWidgetGetControl(gw,2));
     364           0 :     GDrawDestroyWindow(gw);
     365           0 :     GDrawSync(NULL);
     366           0 :     GDrawProcessPendingEvents(NULL);
     367           0 : return(ret);
     368             : }
     369             : 
     370           0 : void GWidgetError(const unichar_t *title,const unichar_t *statement, ...) {
     371             :     struct dlg_info d;
     372             :     GWindow gw;
     373             :     const unichar_t *ob[2]; unichar_t omn[1];
     374             :     va_list ap;
     375             : 
     376           0 :     ob[1]=NULL;
     377           0 :     ob[0] = GStringGetResource( _STR_OK, &omn[0]);
     378           0 :     va_start(ap,statement);
     379           0 :     gw = DlgCreate(title,statement,ap,ob,omn,0,0,&d,false,true,true);
     380           0 :     va_end(ap);
     381           0 :     if ( gw!=NULL ) {
     382           0 :         while ( !d.done )
     383           0 :             GDrawProcessOneEvent(NULL);
     384           0 :         GDrawDestroyWindow(gw);
     385             :     }
     386           0 : }
     387             : 
     388             : /* ************************************************************************** */
     389             : 
     390             : #define CID_Cancel      0
     391             : #define CID_OK          1
     392             : #define CID_List        2
     393             : #define CID_SelectAll   3
     394             : #define CID_SelectNone  4
     395             : 
     396           0 : static int GCD_Select(GGadget *g, GEvent *e) {
     397             : 
     398           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     399           0 :         GWindow gw = GGadgetGetWindow(g);
     400           0 :         GGadget *list = GWidgetGetControl(gw,CID_List);
     401             : 
     402           0 :         GGadgetSelectListItem(list,-1,GGadgetGetCid(g)==CID_SelectAll?1:0 );
     403             :     }
     404           0 : return( true );
     405             : }
     406             : 
     407           0 : static int c_e_h(GWindow gw, GEvent *event) {
     408           0 :     struct dlg_info *d = GDrawGetUserData(gw);
     409             : 
     410           0 :     if ( event->type==et_close ) {
     411           0 :         d->done = true;
     412           0 :         d->ret = -1;
     413           0 :     } else if ( event->type==et_resize ) {
     414           0 :         GDrawRequestExpose(gw,NULL,false);
     415           0 :     } else if ( event->type==et_controlevent &&
     416           0 :             (event->u.control.subtype == et_buttonactivate ||
     417           0 :              event->u.control.subtype == et_listdoubleclick )) {
     418           0 :         d->done = true;
     419           0 :         if ( GGadgetGetCid(event->u.control.g)==CID_Cancel )
     420           0 :             d->ret = -1;
     421             :         else
     422           0 :             d->ret = GGadgetGetFirstListSelectedItem(GWidgetGetControl(gw,CID_List));
     423           0 :     } else if ( event->type == et_char ) {
     424           0 : return( false );
     425           0 :     } else if ( event->type == et_map ) {
     426             :         /* Above palettes */
     427           0 :         GDrawRaise(gw);
     428             :     }
     429           0 : return( true );
     430             : }
     431             : 
     432             : /* ************** Parallel routines using utf8 arguments ******************** */
     433             : 
     434          14 : static GWindow DlgCreate8(const char *title,const char *question,va_list ap,
     435             :         const char **answers, int def, int cancel,
     436             :         struct dlg_info *d, int add_text, const char *defstr,
     437             :         int restrict_input, int center) {
     438             :     GTextInfo qlabels[GLINE_MAX+1], *blabels;
     439             :     GGadgetCreateData *gcd, *array[2*(GLINE_MAX+5)+1], boxes[5], **barray, *labarray[4];
     440          14 :     int lb, bcnt=0, l;
     441             :     GRect pos;
     442             :     GWindow gw;
     443             :     GWindowAttrs wattrs;
     444             :     extern FontInstance *_ggadget_default_font;
     445             :     int as, ds, ld, fh;
     446             :     int w, maxw, bw, bspace;
     447             :     int i, y;
     448             :     gchar *buf;
     449             :     unichar_t *ubuf;
     450             :     extern GBox _GGadget_defaultbutton_box;
     451             : 
     452          14 :     if ( d!=NULL )
     453          14 :         memset(d,0,sizeof(*d));
     454             :     /*vsnprintf(buf,sizeof(buf)/sizeof(buf[0]),question,ap);*/
     455          14 :     g_vasprintf( &buf, (const gchar *) question, ap );
     456          14 :     if ( screen_display==NULL ) {
     457          14 :         fprintf(stderr, "%s\n", buf );
     458          14 :         if ( d!=NULL ) d->done = true;
     459          14 : return( NULL );
     460             :     }
     461             :     /*ubuf = utf82u_copy(buf);*/
     462           0 :     ubuf = (unichar_t *) g_utf8_to_ucs4( (const gchar *) buf, -1, NULL, NULL, NULL);
     463           0 :     g_free( buf );
     464           0 :     if( !ubuf ) {
     465           0 :         fprintf( stderr, "Failed to convert question string in DlgCreate8()\n" );
     466           0 :         return( NULL );
     467             :     }
     468             : 
     469           0 :     GGadgetInit();
     470           0 :     GProgressPauseTimer();
     471           0 :     memset(qlabels,'\0',sizeof(qlabels));
     472           0 :     lb = FindLineBreaks(ubuf,qlabels);
     473           0 :     for ( bcnt=0; answers[bcnt]!=NULL; ++bcnt);
     474           0 :     blabels = calloc(bcnt+1,sizeof(GTextInfo));
     475           0 :     barray = calloc(2*bcnt+3,sizeof(GGadgetCreateData *));
     476           0 :     for ( bcnt=0; answers[bcnt]!=NULL; ++bcnt) {
     477           0 :         blabels[bcnt].text = (unichar_t *) answers[bcnt];
     478           0 :         blabels[bcnt].text_is_1byte = true;
     479           0 :         blabels[bcnt].text_in_resource = true;  /* Look for mnemonics in the utf8 string (preceded by _) */
     480             :     }
     481             : 
     482           0 :     memset(&wattrs,0,sizeof(wattrs));
     483             :     /* If we have many questions in quick succession the dlg will jump around*/
     484             :     /*  as it tracks the cursor (which moves to the buttons). That's not good*/
     485             :     /*  So I don't do undercursor here */
     486           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_isdlg;
     487           0 :     if ( restrict_input )
     488           0 :         wattrs.mask |= wam_restrict;
     489             :     else 
     490           0 :         wattrs.mask |= wam_notrestricted;
     491           0 :     if ( center )
     492           0 :         wattrs.mask |= wam_centered;
     493             :     else
     494           0 :         wattrs.mask |= wam_undercursor;
     495           0 :     wattrs.not_restricted = true;
     496           0 :     wattrs.restrict_input_to_me = 1;
     497           0 :     wattrs.is_dlg = true;
     498           0 :     wattrs.event_masks = ~(1<<et_charup);
     499           0 :     wattrs.undercursor = 1;
     500           0 :     wattrs.centered = 2;
     501           0 :     wattrs.cursor = ct_pointer;
     502           0 :     wattrs.utf8_window_title = (char *) title;
     503           0 :     pos.x = pos.y = 0;
     504           0 :     pos.width = 200; pos.height = 60;           /* We'll figure size later */
     505             :                 /* but if we get the size too small, the cursor isn't in dlg */
     506           0 :     gw = GDrawCreateTopWindow(NULL,&pos,restrict_input?d_e_h:w_e_h,d,&wattrs);
     507             : 
     508           0 :     GGadgetInit();
     509           0 :     GDrawSetFont(gw,_ggadget_default_font);
     510           0 :     GDrawWindowFontMetrics(gw,_ggadget_default_font,&as,&ds,&ld);
     511           0 :     fh = as+ds;
     512           0 :     maxw = 0;
     513           0 :     for ( i=0; i<lb; ++i ) {
     514           0 :         w = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     515           0 :         if ( w>maxw ) maxw = w;
     516             :     }
     517           0 :     if ( add_text && defstr!=NULL ) {
     518             :         extern GFont *_gtextfield_font;
     519           0 :         if ( _gtextfield_font!=NULL ) {
     520           0 :             GDrawSetFont(gw,_gtextfield_font);
     521           0 :             w = GDrawGetText8Width(gw,defstr,-1);
     522           0 :             GDrawSetFont(gw,_ggadget_default_font);
     523             :         } else
     524           0 :             w = 8*GDrawGetText8Width(gw,defstr,-1)/5;
     525           0 :         w += GDrawPointsToPixels(gw,40);
     526           0 :         if ( w >1000 ) w = 1000;
     527           0 :         if ( w>maxw ) maxw = w;
     528             :     }
     529           0 :     bw = 0;
     530           0 :     for ( i=0; i<bcnt; ++i ) {
     531           0 :         w = GDrawGetText8Width(gw,answers[i],-1);
     532           0 :         if ( w>bw ) bw = w;
     533             :     }
     534           0 :     bw += GDrawPointsToPixels(gw,20);
     535           0 :     bspace = GDrawPointsToPixels(gw,6);
     536           0 :     if ( (bw+bspace) * bcnt > maxw )
     537           0 :         maxw = (bw+bspace)*bcnt;
     538           0 :     if ( bcnt!=1 )
     539           0 :         bspace = (maxw-bcnt*bw)/(bcnt-1);
     540           0 :     maxw += GDrawPointsToPixels(gw,16);
     541             : 
     542           0 :     gcd = calloc(lb+bcnt+2,sizeof(GGadgetCreateData));
     543           0 :     memset(boxes,0,sizeof(boxes));
     544           0 :     l = 0;
     545           0 :     if ( lb==1 ) {
     546           0 :         gcd[0].gd.pos.width = GDrawGetTextWidth(gw,qlabels[0].text,-1);
     547           0 :         gcd[0].gd.pos.x = (maxw-gcd[0].gd.pos.width)/2;
     548           0 :         gcd[0].gd.pos.y = GDrawPointsToPixels(gw,6);
     549           0 :         gcd[0].gd.pos.height = fh;
     550           0 :         gcd[0].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     551           0 :         gcd[0].gd.label = &qlabels[0];
     552           0 :         gcd[0].creator = GLabelCreate;
     553           0 :         labarray[0] = GCD_Glue; labarray[1] = &gcd[0]; labarray[2] = GCD_Glue; labarray[3] = NULL;
     554           0 :         boxes[2].gd.flags = gg_visible|gg_enabled;
     555           0 :         boxes[2].gd.u.boxelements = labarray;
     556           0 :         boxes[2].creator = GHBoxCreate;
     557           0 :         array[0] = &boxes[2]; array[1] = NULL;
     558           0 :         l = 1;
     559           0 :     } else for ( i=0; i<lb; ++i ) {
     560           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,8);
     561           0 :         gcd[i].gd.pos.y = GDrawPointsToPixels(gw,6)+i*fh;
     562           0 :         gcd[i].gd.pos.width = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     563           0 :         gcd[i].gd.pos.height = fh;
     564           0 :         gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     565           0 :         gcd[i].gd.label = &qlabels[i];
     566           0 :         gcd[i].creator = GLabelCreate;
     567           0 :         array[2*l] = &gcd[i]; array[2*l++ +1] = NULL;
     568             :     }
     569           0 :     y = GDrawPointsToPixels(gw,12)+lb*fh;
     570           0 :     if ( add_text ) {
     571           0 :         gcd[bcnt+lb].gd.pos.x = GDrawPointsToPixels(gw,8);
     572           0 :         gcd[bcnt+lb].gd.pos.y = y;
     573           0 :         gcd[bcnt+lb].gd.pos.width = maxw-2*GDrawPointsToPixels(gw,6);
     574           0 :         gcd[bcnt+lb].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0 | gg_text_xim;
     575           0 :         gcd[bcnt+lb].gd.cid = bcnt;
     576           0 :         gcd[bcnt+lb].creator = GTextFieldCreate;
     577           0 :         if ( add_text==2 )
     578           0 :             gcd[bcnt+lb].creator = GPasswordCreate;
     579           0 :         y += fh + GDrawPointsToPixels(gw,6) + GDrawPointsToPixels(gw,10);
     580           0 :         array[2*l] = &gcd[bcnt+lb]; array[2*l++ +1] = NULL;
     581             :     }
     582           0 :     y += GDrawPointsToPixels(gw,2);
     583           0 :     for ( i=0; i<bcnt; ++i ) {
     584           0 :         gcd[i+lb].gd.pos.x = GDrawPointsToPixels(gw,8) + i*(bw+bspace);
     585           0 :         gcd[i+lb].gd.pos.y = y;
     586           0 :         gcd[i+lb].gd.pos.width = bw;
     587           0 :         gcd[i+lb].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     588           0 :         if ( i==def ) {
     589           0 :             gcd[i+lb].gd.flags |= gg_but_default;
     590           0 :             if ( _GGadget_defaultbutton_box.flags&box_draw_default ) {
     591           0 :                 gcd[i+lb].gd.pos.x -= GDrawPointsToPixels(gw,3);
     592           0 :                 gcd[i+lb].gd.pos.y -= GDrawPointsToPixels(gw,3);
     593           0 :                 gcd[i+lb].gd.pos.width += 2*GDrawPointsToPixels(gw,3);
     594             :             }
     595             :         }
     596           0 :         if ( i==cancel )
     597           0 :             gcd[i+lb].gd.flags |= gg_but_cancel;
     598           0 :         gcd[i+lb].gd.cid = i;
     599           0 :         gcd[i+lb].gd.label = &blabels[i];
     600           0 :         gcd[i+lb].creator = GButtonCreate;
     601           0 :         barray[2*i] = GCD_Glue; barray[2*i+1] = &gcd[i+lb];
     602             :     }
     603           0 :     barray[2*i] = GCD_Glue; barray[2*i+1] = NULL;
     604           0 :     boxes[3].gd.flags = gg_visible|gg_enabled;
     605           0 :     boxes[3].gd.u.boxelements = barray;
     606           0 :     boxes[3].creator = GHBoxCreate;
     607           0 :     array[2*l] = &boxes[3]; array[2*l++ +1] = NULL;
     608           0 :     array[2*l] = NULL;
     609             : 
     610           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     611           0 :     boxes[0].gd.flags = gg_visible|gg_enabled;
     612           0 :     boxes[0].gd.u.boxelements = array;
     613           0 :     boxes[0].creator = GHVGroupCreate;
     614             : 
     615           0 :     GGadgetsCreate(gw,boxes);
     616           0 :     GHVBoxSetExpandableCol(boxes[3].ret,gb_expandgluesame);
     617           0 :     if ( boxes[2].ret!=NULL )
     618           0 :         GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
     619           0 :     GHVBoxFitWindow(boxes[0].ret);
     620             : 
     621           0 :     GWidgetHidePalettes();
     622           0 :     if ( d!=NULL ) {
     623           0 :         d->ret  = cancel;
     624           0 :         d->bcnt = bcnt;
     625             :     }
     626           0 :     GDrawSetVisible(gw,true);
     627           0 :     free(blabels);
     628           0 :     free(gcd);
     629           0 :     free(barray);
     630           0 :     for ( i=0; i<lb; ++i )
     631           0 :         free(qlabels[i].text);
     632           0 :     free(ubuf);
     633           0 :     GProgressResumeTimer();
     634           0 : return( gw );
     635             : }
     636             : 
     637           0 : int GWidgetAsk8(const char *title,
     638             :         const char **answers, int def, int cancel,
     639             :         const char *question,...) {
     640             :     struct dlg_info d;
     641             :     GWindow gw;
     642             :     va_list ap;
     643             : 
     644           0 :     if ( screen_display==NULL )
     645           0 : return( def );
     646             : 
     647           0 :     va_start(ap,question);
     648           0 :     gw = DlgCreate8(title,question,ap,answers,def,cancel,&d,false,NULL,true,false);
     649           0 :     va_end(ap);
     650             : 
     651           0 :     while ( !d.done )
     652           0 :         GDrawProcessOneEvent(NULL);
     653           0 :     GDrawDestroyWindow(gw);
     654           0 :     GDrawSync(NULL);
     655           0 :     GDrawProcessPendingEvents(NULL);
     656           0 : return(d.ret);
     657             : }
     658             : 
     659           1 : int GWidgetAskCentered8(const char *title,
     660             :         const char **answers, int def, int cancel,
     661             :         const char *question, ... ) {
     662             :     struct dlg_info d;
     663             :     GWindow gw;
     664             :     va_list ap;
     665             : 
     666           1 :     if ( screen_display==NULL )
     667           1 : return( def );
     668             : 
     669           0 :     va_start(ap,question);
     670           0 :     gw = DlgCreate8(title,question,ap,answers,def,cancel,&d,false,NULL,true,true);
     671           0 :     va_end(ap);
     672             : 
     673           0 :     while ( !d.done )
     674           0 :         GDrawProcessOneEvent(NULL);
     675           0 :     GDrawDestroyWindow(gw);
     676           0 :     GDrawSync(NULL);
     677           0 :     GDrawProcessPendingEvents(NULL);
     678           0 : return(d.ret);
     679             : }
     680             : 
     681           0 : char *GWidgetAskString8(const char *title,const char *def,
     682             :         const char *question,...) {
     683             :     struct dlg_info d;
     684             :     GWindow gw;
     685           0 :     char *ret = NULL;
     686             :     char *ocb[3];
     687             :     va_list ap;
     688             : 
     689           0 :     if ( screen_display==NULL )
     690           0 : return( copy(def ));
     691             : 
     692           0 :     ocb[2]=NULL;
     693           0 :     if ( _ggadget_use_gettext ) {
     694           0 :         ocb[0] = _("_OK");
     695           0 :         ocb[1] = _("_Cancel");
     696             :     } else {
     697           0 :         ocb[0] = u2utf8_copy(GStringGetResource( _STR_OK, NULL));
     698           0 :         ocb[1] = u2utf8_copy(GStringGetResource( _STR_Cancel, NULL));
     699             :     }
     700           0 :     va_start(ap,question);
     701           0 :     gw = DlgCreate8(title,question,ap,(const char **) ocb,0,1,&d,true,def,true,false);
     702           0 :     va_end(ap);
     703           0 :     if ( def!=NULL && *def!='\0' )
     704           0 :         GGadgetSetTitle8(GWidgetGetControl(gw,2),def);
     705           0 :     while ( !d.done )
     706           0 :         GDrawProcessOneEvent(NULL);
     707           0 :     if ( d.ret==0 )
     708           0 :         ret = GGadgetGetTitle8(GWidgetGetControl(gw,2));
     709           0 :     GDrawDestroyWindow(gw);
     710           0 :     GDrawSync(NULL);
     711           0 :     GDrawProcessPendingEvents(NULL);
     712           0 :     if ( !_ggadget_use_gettext ) {
     713           0 :         free(ocb[0]); free(ocb[1]);
     714             :     }
     715           0 : return(ret);
     716             : }
     717             : 
     718           0 : char *GWidgetAskPassword8(const char *title,const char *def,
     719             :         const char *question,...) {
     720             :     struct dlg_info d;
     721             :     GWindow gw;
     722           0 :     char *ret = NULL;
     723             :     char *ocb[3];
     724             :     va_list ap;
     725             : 
     726           0 :     if ( screen_display==NULL )
     727           0 : return( copy(def ));
     728             : 
     729           0 :     ocb[2]=NULL;
     730           0 :     if ( _ggadget_use_gettext ) {
     731           0 :         ocb[0] = _("_OK");
     732           0 :         ocb[1] = _("_Cancel");
     733             :     } else {
     734           0 :         ocb[0] = u2utf8_copy(GStringGetResource( _STR_OK, NULL));
     735           0 :         ocb[1] = u2utf8_copy(GStringGetResource( _STR_Cancel, NULL));
     736             :     }
     737           0 :     va_start(ap,question);
     738           0 :     gw = DlgCreate8(title,question,ap,(const char **) ocb,0,1,&d,2,def,true,false);
     739           0 :     va_end(ap);
     740           0 :     if ( def!=NULL && *def!='\0' )
     741           0 :         GGadgetSetTitle8(GWidgetGetControl(gw,2),def);
     742           0 :     while ( !d.done )
     743           0 :         GDrawProcessOneEvent(NULL);
     744           0 :     if ( d.ret==0 )
     745           0 :         ret = GGadgetGetTitle8(GWidgetGetControl(gw,2));
     746           0 :     GDrawDestroyWindow(gw);
     747           0 :     GDrawSync(NULL);
     748           0 :     GDrawProcessPendingEvents(NULL);
     749           0 :     if ( !_ggadget_use_gettext ) {
     750           0 :         free(ocb[0]); free(ocb[1]);
     751             :     }
     752           0 : return(ret);
     753             : }
     754             : 
     755           0 : void _GWidgetPostNotice8(const char *title,const char *statement,va_list ap, int timeout) {
     756             :     GWindow gw;
     757             :     char *ob[2];
     758             : 
     759             :     /* Force an old notice to disappear */
     760           0 :     if ( title==NULL ) {
     761           0 :         if ( last!=NULL )
     762           0 :             GDrawDestroyWindow(last);
     763           0 : return;
     764             :     }
     765             : 
     766           0 :     ob[1]=NULL;
     767           0 :     if ( _ggadget_use_gettext )
     768           0 :         ob[0] = _("_OK");
     769             :     else
     770           0 :         ob[0] = u2utf8_copy(GStringGetResource( _STR_OK, NULL));
     771           0 :     gw = DlgCreate8(title,statement,ap,(const char **) ob,0,0,NULL,false,NULL,false,true);
     772           0 :     if ( gw!=NULL && timeout>0 ) 
     773           0 :         GDrawRequestTimer(gw,timeout*1000,0,NULL);
     774             :     /* Continue merrily on our way. Window will destroy itself in 40 secs */
     775             :     /*  or when user kills it. We can ignore it */
     776           0 :     if ( !_ggadget_use_gettext )
     777           0 :         free(ob[0]);
     778           0 :     last = gw;
     779           0 :     last_title = title;
     780             : }
     781             : 
     782           0 : void GWidgetPostNotice8(const char *title,const char *statement,...) {
     783             :     va_list ap;
     784             : 
     785             :     /* Force an old notice to disappear */
     786           0 :     if ( title==NULL ) {
     787           0 :         if ( last!=NULL )
     788           0 :             GDrawDestroyWindow(last);
     789           0 : return;
     790             :     }
     791             : 
     792           0 :     va_start(ap,statement);
     793           0 :     _GWidgetPostNotice8(title,statement,ap,40);
     794           0 :     va_end(ap);
     795             : }
     796             : 
     797           0 : void GWidgetPostNoticeTimeout8(int timeout,const char *title,const char *statement,...) {
     798             :     va_list ap;
     799             : 
     800             :     /* Force an old notice to disappear */
     801           0 :     if ( title==NULL ) {
     802           0 :         if ( last!=NULL )
     803           0 :             GDrawDestroyWindow(last);
     804           0 : return;
     805             :     }
     806             : 
     807           0 :     va_start(ap,statement);
     808           0 :     _GWidgetPostNotice8(title,statement,ap,timeout);
     809           0 :     va_end(ap);
     810             : }
     811             : 
     812           0 : int GWidgetPostNoticeActive8(const char *title) {
     813           0 : return( last!=NULL && last_title == title );
     814             : }
     815             : 
     816          14 : void GWidgetError8(const char *title,const char *statement, ...) {
     817             :     struct dlg_info d;
     818             :     GWindow gw;
     819             :     char *ob[2];
     820             :     va_list ap;
     821             : 
     822          14 :     ob[1]=NULL;
     823          14 :     if ( _ggadget_use_gettext )
     824          14 :         ob[0] = _("_OK");
     825             :     else
     826           0 :         ob[0] = u2utf8_copy(GStringGetResource( _STR_OK, NULL));
     827          14 :     va_start(ap,statement);
     828          14 :     gw = DlgCreate8(title,statement,ap,(const char **) ob,0,0,&d,false,NULL,true,true);
     829          14 :     va_end(ap);
     830          14 :     if ( gw!=NULL ) {
     831           0 :         while ( !d.done )
     832           0 :             GDrawProcessOneEvent(NULL);
     833           0 :         GDrawDestroyWindow(gw);
     834             :     }
     835          14 :     if ( !_ggadget_use_gettext )
     836           0 :         free(ob[0]);
     837          14 : }
     838             : 
     839           0 : static GWindow ChoiceDlgCreate8(struct dlg_info *d,const char *title,
     840             :         const char *question, va_list ap,
     841             :         const char **choices, int cnt, char *multisel,
     842             :         char *buts[2], int def,
     843             :         int restrict_input, int center) {
     844             :     GTextInfo qlabels[GLINE_MAX+1], *llabels, blabel[4];
     845             :     GGadgetCreateData *gcd, **array, boxes[5], *labarray[4], *barray[10], *barray2[8];
     846             :     int lb,l;
     847             :     GRect pos;
     848             :     GWindow gw;
     849             :     GWindowAttrs wattrs;
     850             :     extern FontInstance *_ggadget_default_font;
     851             :     int as, ds, ld, fh;
     852             :     int w, maxw;
     853             :     int i, y, listi;
     854             :     char buf[600];
     855             :     unichar_t *ubuf;
     856             :     extern GBox _GGadget_defaultbutton_box;
     857             : 
     858           0 :     memset(d,0,sizeof(*d));
     859           0 :     GProgressPauseTimer();
     860           0 :     vsnprintf(buf,sizeof(buf)/sizeof(buf[0]),question,ap);
     861           0 :     ubuf = utf82u_copy(buf);
     862           0 :     memset(qlabels,'\0',sizeof(qlabels));
     863           0 :     lb = FindLineBreaks(ubuf,qlabels);
     864           0 :     llabels = calloc(cnt+1,sizeof(GTextInfo));
     865           0 :     for ( i=0; i<cnt; ++i) {
     866           0 :         if ( choices[i][0]=='-' && choices[i][1]=='\0' )
     867           0 :             llabels[i].line = true;
     868             :         else {
     869           0 :             llabels[i].text = (unichar_t *) choices[i];
     870           0 :             llabels[i].text_is_1byte = true;
     871             :         }
     872           0 :         if ( multisel )
     873           0 :             llabels[i].selected = multisel[i];
     874             :         else
     875           0 :             llabels[i].selected = (i==def);
     876             :     }
     877             : 
     878           0 :     memset(&wattrs,0,sizeof(wattrs));
     879             :     /* If we have many questions in quick succession the dlg will jump around*/
     880             :     /*  as it tracks the cursor (which moves to the buttons). That's not good*/
     881             :     /*  So I don't do undercursor here */
     882           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_isdlg;
     883           0 :     if ( restrict_input )
     884           0 :         wattrs.mask |= wam_restrict;
     885             :     else 
     886           0 :         wattrs.mask |= wam_notrestricted;
     887           0 :     if ( center )
     888           0 :         wattrs.mask |= wam_centered;
     889             :     else
     890           0 :         wattrs.mask |= wam_undercursor;
     891           0 :     wattrs.not_restricted = true;
     892           0 :     wattrs.restrict_input_to_me = 1;
     893           0 :     wattrs.is_dlg = true;
     894           0 :     wattrs.event_masks = ~(1<<et_charup);
     895           0 :     wattrs.undercursor = 1;
     896           0 :     wattrs.centered = 2;
     897           0 :     wattrs.cursor = ct_pointer;
     898           0 :     wattrs.utf8_window_title = (char *) title;
     899           0 :     pos.x = pos.y = 0;
     900           0 :     pos.width = 220; pos.height = 60;           /* We'll figure size later */
     901             :                 /* but if we get the size too small, the cursor isn't in dlg */
     902           0 :     gw = GDrawCreateTopWindow(NULL,&pos,c_e_h,d,&wattrs);
     903             : 
     904           0 :     GGadgetInit();
     905           0 :     GDrawSetFont(gw,_ggadget_default_font);
     906           0 :     GDrawWindowFontMetrics(gw,_ggadget_default_font,&as,&ds,&ld);
     907           0 :     fh = as+ds;
     908           0 :     maxw = 220;
     909           0 :     for ( i=0; i<cnt; ++i) {
     910           0 :         if ( llabels[i].text!=NULL ) {          /* lines */
     911           0 :             w = GDrawGetText8Width(gw,(char *) llabels[i].text,-1);
     912           0 :             if ( w>900 ) w = 900;
     913           0 :             if ( w>maxw ) maxw = w;
     914             :         }
     915             :     }
     916           0 :     for ( i=0; i<lb; ++i ) {
     917           0 :         w = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     918           0 :         if ( w>maxw ) maxw = w;
     919             :     }
     920           0 :     maxw += GDrawPointsToPixels(gw,20);
     921             : 
     922           0 :     gcd = calloc(lb+1+2+2+2,sizeof(GGadgetCreateData));
     923           0 :     array = calloc(2*(lb+1+2+2+2+1),sizeof(GGadgetCreateData *));
     924           0 :     memset(boxes,0,sizeof(boxes));
     925           0 :     l=0;
     926           0 :     if ( lb==1 ) {
     927           0 :         gcd[0].gd.pos.width = GDrawGetTextWidth(gw,qlabels[0].text,-1);
     928           0 :         gcd[0].gd.pos.x = (maxw-gcd[0].gd.pos.width)/2;
     929           0 :         gcd[0].gd.pos.y = GDrawPointsToPixels(gw,6);
     930           0 :         gcd[0].gd.pos.height = fh;
     931           0 :         gcd[0].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     932           0 :         gcd[0].gd.label = &qlabels[0];
     933           0 :         gcd[0].creator = GLabelCreate;
     934           0 :         labarray[0] = GCD_Glue; labarray[1] = &gcd[0]; labarray[2] = GCD_Glue; labarray[3] = NULL;
     935           0 :         boxes[2].gd.flags = gg_visible|gg_enabled;
     936           0 :         boxes[2].gd.u.boxelements = labarray;
     937           0 :         boxes[2].creator = GHBoxCreate;
     938           0 :         array[0] = &boxes[2]; array[1] = NULL;
     939           0 :         i = l = 1;
     940           0 :     } else for ( i=0; i<lb; ++i ) {
     941           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,8);
     942           0 :         gcd[i].gd.pos.y = GDrawPointsToPixels(gw,6)+i*fh;
     943           0 :         gcd[i].gd.pos.width = GDrawGetTextWidth(gw,qlabels[i].text,-1);
     944           0 :         gcd[i].gd.pos.height = fh;
     945           0 :         gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     946           0 :         gcd[i].gd.label = &qlabels[i];
     947           0 :         gcd[i].creator = GLabelCreate;
     948           0 :         array[2*l] = &gcd[i]; array[2*l++ +1] = NULL;
     949             :     }
     950             : 
     951           0 :     y = GDrawPointsToPixels(gw,12)+lb*fh;
     952           0 :     gcd[i].gd.pos.x = GDrawPointsToPixels(gw,8); gcd[i].gd.pos.y = y;
     953           0 :     gcd[i].gd.pos.width = maxw - 2*GDrawPointsToPixels(gw,8);
     954           0 :     gcd[i].gd.pos.height = (cnt<4?4:cnt<8?cnt:8)*fh + 2*GDrawPointsToPixels(gw,6);
     955           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     956           0 :     if ( multisel )
     957           0 :         gcd[i].gd.flags |= gg_list_multiplesel;
     958             :     else
     959           0 :         gcd[i].gd.flags |= gg_list_exactlyone;
     960           0 :     gcd[i].gd.u.list = llabels;
     961           0 :     gcd[i].gd.cid = CID_List;
     962           0 :     listi = i;
     963           0 :     gcd[i++].creator = GListCreate;
     964           0 :     y += gcd[i-1].gd.pos.height + GDrawPointsToPixels(gw,10);
     965           0 :     array[2*l] = &gcd[i-1]; array[2*l++ +1] = NULL;
     966             : 
     967           0 :     memset(blabel,'\0',sizeof(blabel));
     968           0 :     if ( multisel ) {
     969           0 :         y -= GDrawPointsToPixels(gw,5);
     970           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,15); gcd[i].gd.pos.y = y;
     971           0 :         gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0;
     972           0 :         gcd[i].gd.label = &blabel[2];
     973           0 :         if ( _ggadget_use_gettext ) {
     974           0 :             blabel[2].text = (unichar_t *) _("Select _All");
     975           0 :             blabel[2].text_is_1byte = true;
     976             :         } else
     977           0 :             blabel[2].text = (unichar_t *) _STR_SelectAll;
     978           0 :         blabel[2].text_in_resource = true;
     979           0 :         gcd[i].gd.cid = CID_SelectAll;
     980           0 :         gcd[i].gd.handle_controlevent = GCD_Select;
     981           0 :         gcd[i++].creator = GButtonCreate;
     982           0 :         barray2[0] = GCD_Glue; barray2[1] = &gcd[i-1];
     983             : 
     984           0 :         gcd[i].gd.pos.x = maxw-GDrawPointsToPixels(gw,15)-
     985           0 :                 GDrawPointsToPixels(gw,GIntGetResource(_NUM_Buttonsize));
     986           0 :         gcd[i].gd.pos.y = y;
     987           0 :         gcd[i].gd.pos.width = -1;
     988           0 :         gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels | gg_pos_use0 ;
     989           0 :         gcd[i].gd.label = &blabel[3];
     990           0 :         if ( _ggadget_use_gettext ) {
     991           0 :             blabel[3].text = (unichar_t *) _("_None");
     992           0 :             blabel[3].text_is_1byte = true;
     993             :         } else
     994           0 :             blabel[3].text = (unichar_t *) _STR_None;
     995           0 :         blabel[3].text_in_resource = true;
     996           0 :         gcd[i].gd.cid = CID_SelectNone;
     997           0 :         gcd[i].gd.handle_controlevent = GCD_Select;
     998           0 :         gcd[i++].creator = GButtonCreate;
     999           0 :         y += GDrawPointsToPixels(gw,30);
    1000           0 :         barray2[2] = GCD_Glue; barray2[3] = &gcd[i-1]; barray2[4] = GCD_Glue; barray2[5] = NULL;
    1001           0 :         boxes[3].gd.flags = gg_visible|gg_enabled;
    1002           0 :         boxes[3].gd.u.boxelements = barray2;
    1003           0 :         boxes[3].creator = GHBoxCreate;
    1004           0 :         array[2*l] = &boxes[3]; array[2*l++ +1] = NULL;
    1005             :     }
    1006             : 
    1007           0 :     if ( _GGadget_defaultbutton_box.flags&box_draw_default ) {
    1008           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,15)-3; gcd[i].gd.pos.y = y-3;
    1009             :     } else {
    1010           0 :         gcd[i].gd.pos.x = GDrawPointsToPixels(gw,15); gcd[i].gd.pos.y = y;
    1011             :     }
    1012           0 :     gcd[i].gd.pos.width = -1;
    1013           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels |gg_but_default | gg_pos_use0;
    1014           0 :     gcd[i].gd.label = &blabel[0];
    1015           0 :     blabel[0].text = (unichar_t *) buts[0];
    1016           0 :     blabel[0].text_is_1byte = true;
    1017           0 :     blabel[0].text_in_resource = true;
    1018           0 :     gcd[i].gd.cid = CID_OK;
    1019           0 :     gcd[i++].creator = GButtonCreate;
    1020           0 :     barray[0] = GCD_Glue; barray[1] = &gcd[i-1]; barray[2] = GCD_Glue; barray[3] = GCD_Glue;
    1021             : 
    1022           0 :     gcd[i].gd.pos.x = maxw-GDrawPointsToPixels(gw,15)-
    1023           0 :             GDrawPointsToPixels(gw,GIntGetResource(_NUM_Buttonsize));
    1024           0 :     gcd[i].gd.pos.y = y;
    1025           0 :     gcd[i].gd.pos.width = -1;
    1026           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_pos_in_pixels |gg_but_cancel | gg_pos_use0;
    1027           0 :     gcd[i].gd.label = &blabel[1];
    1028           0 :     blabel[1].text = (unichar_t *) buts[1];
    1029           0 :     blabel[1].text_is_1byte = true;
    1030           0 :     blabel[1].text_in_resource = true;
    1031           0 :     gcd[i].gd.cid = CID_Cancel;
    1032           0 :     gcd[i++].creator = GButtonCreate;
    1033           0 :     barray[4] = barray[5] = barray[6] = GCD_Glue; barray[7] = &gcd[i-1]; barray[8] = GCD_Glue; barray[9] = NULL;
    1034             : 
    1035           0 :     boxes[4].gd.flags = gg_visible|gg_enabled;
    1036           0 :     boxes[4].gd.u.boxelements = barray;
    1037           0 :     boxes[4].creator = GHBoxCreate;
    1038           0 :     array[2*l] = &boxes[4]; array[2*l++ +1] = NULL;
    1039           0 :     array[2*l] = NULL;
    1040             : 
    1041           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    1042           0 :     boxes[0].gd.flags = gg_visible|gg_enabled;
    1043           0 :     boxes[0].gd.u.boxelements = array;
    1044           0 :     boxes[0].creator = GHVGroupCreate;
    1045             : 
    1046           0 :     GGadgetsCreate(gw,boxes);
    1047           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandgluesame);
    1048           0 :     if ( boxes[3].ret!=NULL )
    1049           0 :         GHVBoxSetExpandableCol(boxes[3].ret,gb_expandgluesame);
    1050           0 :     if ( boxes[2].ret!=NULL )
    1051           0 :         GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
    1052           0 :     GHVBoxFitWindow(boxes[0].ret);
    1053           0 :     GWidgetHidePalettes();
    1054           0 :     GDrawSetVisible(gw,true);
    1055           0 :     d->ret = -1;
    1056           0 :     d->size_diff = pos.height - gcd[listi].gd.pos.height;
    1057           0 :     free(llabels);
    1058           0 :     free(array);
    1059           0 :     free(gcd);
    1060           0 :     for ( i=0; i<lb; ++i )
    1061           0 :         free(qlabels[i].text);
    1062           0 :     free(ubuf);
    1063           0 :     GProgressResumeTimer();
    1064           0 : return( gw );
    1065             : }
    1066             : 
    1067           0 : int GWidgetChoices8(const char *title, const char **choices,int cnt, int def,
    1068             :         const char *question,...) {
    1069             :     struct dlg_info d;
    1070             :     GWindow gw;
    1071             :     va_list ap;
    1072             :     char *buts[3];
    1073             : 
    1074           0 :     if ( screen_display==NULL )
    1075           0 : return( -2 );
    1076             : 
    1077           0 :     va_start(ap,question);
    1078           0 :     if ( _ggadget_use_gettext ) {
    1079           0 :         buts[0] = _("_OK");
    1080           0 :         buts[1] = _("_Cancel");
    1081             :     } else {
    1082           0 :         buts[0] = u2utf8_copy(GStringGetResource(_STR_OK,NULL));
    1083           0 :         buts[1] = u2utf8_copy(GStringGetResource(_STR_Cancel,NULL));
    1084             :     }
    1085           0 :     buts[2] = NULL;
    1086           0 :     gw = ChoiceDlgCreate8(&d,title,question,ap,
    1087             :             choices,cnt,NULL, buts,def,true,false);
    1088           0 :     va_end(ap);
    1089           0 :     while ( !d.done )
    1090           0 :         GDrawProcessOneEvent(NULL);
    1091           0 :     GDrawDestroyWindow(gw);
    1092           0 :     GDrawSync(NULL);
    1093           0 :     GDrawProcessPendingEvents(NULL);
    1094           0 :     if ( !_ggadget_use_gettext ) {
    1095           0 :         free(buts[0]); free(buts[1]);
    1096             :     }
    1097           0 : return(d.ret);
    1098             : }
    1099             : 
    1100           0 : int GWidgetChoicesB8(char *title, const char **choices, int cnt, int def,
    1101             :         char *buts[2], const char *question,...) {
    1102             :     struct dlg_info d;
    1103             :     GWindow gw;
    1104             :     va_list ap;
    1105             : 
    1106           0 :     if ( screen_display==NULL )
    1107           0 : return( -2 );
    1108             : 
    1109           0 :     va_start(ap,question);
    1110           0 :     gw = ChoiceDlgCreate8(&d,title,question,ap,
    1111             :             choices,cnt,NULL,buts,def,true,false);
    1112           0 :     va_end(ap);
    1113           0 :     while ( !d.done )
    1114           0 :         GDrawProcessOneEvent(NULL);
    1115           0 :     GDrawDestroyWindow(gw);
    1116           0 :     GDrawSync(NULL);
    1117           0 :     GDrawProcessPendingEvents(NULL);
    1118           0 : return(d.ret);
    1119             : }
    1120             : 
    1121           0 : int GWidgetChoicesBM8(char *title, const char **choices,char *sel,
    1122             :         int cnt, char *buts[2], const char *question,...) {
    1123             :     struct dlg_info d;
    1124             :     GWindow gw;
    1125             :     va_list ap;
    1126             :     GGadget *list;
    1127             :     GTextInfo **lsel;
    1128             :     int i; int32 len;
    1129             :     char *buttons[3];
    1130             : 
    1131           0 :     if ( screen_display==NULL )
    1132           0 : return( -2 );
    1133             : 
    1134           0 :     if ( buts==NULL ) {
    1135           0 :         buts = buttons;
    1136           0 :         buttons[2] = NULL;
    1137           0 :         if ( _ggadget_use_gettext ) {
    1138           0 :             buts[0] = _("_OK");
    1139           0 :             buts[1] = _("_Cancel");
    1140             :         } else {
    1141           0 :             buts[0] = u2utf8_copy(GStringGetResource(_STR_OK,NULL));
    1142           0 :             buts[1] = u2utf8_copy(GStringGetResource(_STR_Cancel,NULL));
    1143             :         }
    1144             :     }
    1145           0 :     va_start(ap,question);
    1146           0 :     gw = ChoiceDlgCreate8(&d,title,question,ap,
    1147             :             choices,cnt,sel,buts,-1,true,false);
    1148           0 :     va_end(ap);
    1149           0 :     while ( !d.done )
    1150           0 :         GDrawProcessOneEvent(NULL);
    1151           0 :     if ( d.ret==-1 ) {
    1152           0 :         for ( i=0; i<cnt; ++i )
    1153           0 :             sel[i] = 0;
    1154             :     } else {
    1155           0 :         list = GWidgetGetControl(gw,CID_List);
    1156           0 :         lsel = GGadgetGetList(list,&len);
    1157           0 :         for ( i=0; i<len; ++i )
    1158           0 :             sel[i] = lsel[i]->selected;
    1159             :     }
    1160           0 :     GDrawDestroyWindow(gw);
    1161           0 :     GDrawSync(NULL);
    1162           0 :     GDrawProcessPendingEvents(NULL);
    1163           0 :     if ( !_ggadget_use_gettext ) {
    1164           0 :         free(buts[0]); free(buts[1]);
    1165             :     }
    1166           0 : return(d.ret);
    1167             : }

Generated by: LCOV version 1.10