home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / PrefsLang.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  13.3 KB  |  525 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19.    PrefsLang.cpp -- The language dialog for preference, packaged from 3.0 code
  20.  */
  21.  
  22. #include "felocale.h"
  23. #include "structs.h"
  24. #include "fonts.h"
  25. #include "xpassert.h"
  26. #include "xfe.h"
  27. #include "e_kit.h"
  28. #include "PrefsLang.h"
  29.  
  30. #include <Xm/ArrowBG.h>
  31. #include <Xm/Label.h>
  32. #include <Xm/LabelG.h>
  33. #include <Xm/PushB.h>
  34. #include <Xm/PushBG.h>
  35. #include <Xm/ScrolledW.h>
  36. #include <Xm/ToggleB.h>
  37. #include <Xm/Form.h>
  38. #include <Xm/Frame.h>
  39. #include <Xm/TextF.h> 
  40. #include <Xm/ToggleBG.h> 
  41.  
  42. #include <Xfe/Xfe.h>
  43.  
  44. extern int XFE_ERROR_SAVING_OPTIONS;
  45.  
  46. extern "C"
  47. {
  48.     char *XP_GetString(int i);
  49.  
  50.     static int multiline_str_to_array(const char *string, char ***array_p);
  51.     static int multiline_pref_to_array(const char *string, char ***array_p);
  52. }
  53.  
  54. // ==================== Public Member Functions ====================
  55.  
  56. // Member:       XFE_PrefsLangDialog
  57. // Description:  Constructor
  58. // Inputs:
  59. // Side effects: Creates the More dialog for Mail Server Preferences
  60.  
  61. XFE_PrefsLangDialog::XFE_PrefsLangDialog(XFE_PrefsDialog *prefsDialog,
  62.                                          XFE_PrefsPageBrowserLang *langPage,
  63.                                          Widget     parent,      // dialog parent
  64.                                          char      *name,        // dialog name
  65.                                          Boolean    modal)       // modal dialog?
  66.     : XFE_Dialog(parent, 
  67.                  name,
  68.                  TRUE,     // ok
  69.                  TRUE,     // cancel
  70.                  FALSE,    // help
  71.                  FALSE,    // apply
  72.                  FALSE,    // separator
  73.                  modal     // modal
  74.                  ),
  75.       m_prefsDialog(prefsDialog),
  76.       m_langPage(langPage),
  77.       m_prefsDataLang(0)
  78. {
  79.     PrefsDataLang *fep = NULL;
  80.  
  81.     fep = new PrefsDataLang;
  82.     memset(fep, 0, sizeof(PrefsDataLang));
  83.     m_prefsDataLang = fep;
  84.  
  85.     fep->avail_cnt = multiline_pref_to_array(fe_globalData.language_region_list, 
  86.                                              &fep->avail_lang_regs);
  87.  
  88.     Widget     kids[100];
  89.     Arg        av[50];
  90.     int        ac;
  91.     int        i;
  92.  
  93.     Widget     form;
  94.     form = XtVaCreateWidget("form", xmFormWidgetClass, m_chrome,
  95.                             XmNmarginWidth, 8,
  96.                             XmNtopAttachment, XmATTACH_FORM,
  97.                             XmNleftAttachment, XmATTACH_FORM,
  98.                             XmNrightAttachment, XmATTACH_FORM,
  99.                             XmNbottomAttachment, XmATTACH_FORM,
  100.                             NULL);
  101.     XtManageChild (form);
  102.  
  103.     Widget lang_label;
  104.     Widget lang_list;
  105.     Widget other_label;
  106.     Widget other_text;
  107.  
  108.     ac = 0;
  109.     i = 0;
  110.  
  111.     kids[i++] = lang_label = 
  112.         XmCreateLabelGadget(form, "langLabel", av, ac);
  113.  
  114.     lang_list =    XmCreateScrolledList(form, "langList", av, ac);
  115.     XtManageChild(lang_list);
  116.     kids[i++] = XtParent(lang_list);
  117.  
  118.     kids[i++] = other_label = 
  119.         XmCreateLabelGadget(form, "otherLabel", av, ac);
  120.  
  121.     kids[i++] = other_text = 
  122.         fe_CreateTextField(form, "otherText", av, ac);
  123.  
  124.     XtVaSetValues(lang_label,
  125.                   XmNalignment, XmALIGNMENT_BEGINNING,
  126.                   XmNtopAttachment, XmATTACH_FORM,
  127.                   XmNleftAttachment, XmATTACH_FORM,
  128.                   XmNrightAttachment, XmATTACH_NONE,
  129.                   XmNbottomAttachment, XmATTACH_NONE,
  130.                   NULL);
  131.     
  132.     XtVaSetValues(XtParent(lang_list),
  133.                   XmNtopAttachment, XmATTACH_WIDGET,
  134.                   XmNtopWidget, lang_label,
  135.                   XmNleftAttachment, XmATTACH_FORM,
  136.                   XmNrightAttachment, XmATTACH_NONE,
  137.                   XmNbottomAttachment, XmATTACH_NONE,
  138.                   NULL);
  139.     
  140.     int labels_height;
  141.     labels_height = XfeVaGetTallestWidget(other_label,
  142.                                           other_text,
  143.                                           NULL);
  144.  
  145.     XtVaSetValues(other_label,
  146.                   XmNheight, labels_height,
  147.                   XmNtopAttachment, XmATTACH_WIDGET,
  148.                   XmNtopWidget, XtParent(lang_list),
  149.                   XmNtopOffset, 8,
  150.                   XmNleftAttachment, XmATTACH_FORM,
  151.                   XmNrightAttachment, XmATTACH_NONE,
  152.                   XmNbottomAttachment, XmATTACH_NONE,
  153.                   NULL);
  154.     
  155.     XtVaSetValues(other_text,
  156.                   XmNcolumns, 35,
  157.                   XmNheight, labels_height,
  158.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  159.                   XmNtopWidget, other_label,
  160.                   XmNleftAttachment, XmATTACH_WIDGET,
  161.                   XmNleftWidget, other_label,
  162.                   XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
  163.                   XmNrightWidget, XtParent(lang_list),
  164.                   XmNbottomAttachment, XmATTACH_NONE,
  165.                   NULL);
  166.     
  167.     fep->lang_list = lang_list;
  168.     fep->other_text = other_text;
  169.  
  170.     // Add callbacks
  171.  
  172.     XtAddCallback(m_chrome, XmNokCallback, cb_ok, this);
  173.     XtAddCallback(m_chrome, XmNcancelCallback, cb_cancel, this);
  174.     XtAddCallback(lang_list, XmNdefaultActionCallback, cb_ok, this);
  175.     XtAddCallback(other_text, XmNactivateCallback, cb_ok, this);
  176.  
  177.     XtManageChildren(kids, i);
  178.     XtManageChild(form);
  179. }
  180.  
  181. // Member:       ~XFE_PrefsLangDialog
  182. // Description:  Destructor
  183. // Inputs:
  184. // Side effects: 
  185.  
  186. XFE_PrefsLangDialog::~XFE_PrefsLangDialog()
  187. {
  188.     XP_ASSERT(m_prefsDataLang);
  189.     PrefsDataLang    *fep = m_prefsDataLang;
  190.  
  191.     // Clean up
  192.  
  193.     if (fep->avail_lang_regs != 0) {
  194.         for (int i = 0; i < fep->avail_cnt; i++) {
  195.             XP_FREE(fep->avail_lang_regs[i]);
  196.         }
  197.         XP_FREE(fep->avail_lang_regs);
  198.     }
  199.  
  200.     delete m_prefsDataLang;
  201. }
  202.  
  203. // Member:       show
  204. // Description:  Pop up dialog
  205. // Inputs:
  206. // Side effects: 
  207.  
  208. void XFE_PrefsLangDialog::show()
  209. {
  210.     // TODO: Initialize the dialog
  211.  
  212.     // Manage the top level
  213.  
  214.     XFE_Dialog::show();
  215.  
  216.     // Set focus to the OK button
  217.  
  218.     XmProcessTraversal(m_okButton, XmTRAVERSE_CURRENT);
  219. }
  220.  
  221. // Member:       initPage
  222. // Description:  Initializes page for MailNewsLang
  223. // Inputs:
  224. // Side effects: 
  225.  
  226. void XFE_PrefsLangDialog::initPage()
  227. {
  228.     XP_ASSERT(m_prefsDataLang);
  229.  
  230.     PrefsDataLang    *fep = m_prefsDataLang;
  231.  
  232.     // Retrieve the list of available languages
  233.  
  234.     char          **avail_lang_regs = fep->avail_lang_regs;
  235.     int             avail_cnt = fep->avail_cnt;
  236.  
  237.     // Put the list into the available languages/regions list
  238.  
  239.     XmStringTable   str_list = NULL;
  240.     int             i;
  241.  
  242.     str_list = (XmStringTable)XP_ALLOC(sizeof (XmString) * avail_cnt+1);
  243.     for (i=0; i<avail_cnt; i++) {
  244.         str_list[i] = XmStringCreateLocalized(avail_lang_regs[i]);
  245.     }
  246.     XmListAddItemsUnselected(fep->lang_list, str_list, avail_cnt, 1);
  247.     for (i=0; i<avail_cnt; i++) {
  248.       XmStringFree(str_list[i]);
  249.     }
  250.     XP_FREE(str_list);
  251.  
  252.     // we always want something selected in the language/region list if possible 
  253.  
  254.     if (avail_cnt > 0)
  255.         XmListSelectPos(fep->lang_list, 1, False);
  256. }
  257.  
  258. // Member:       verifyPage
  259. // Description:  verify page for MailNewsLang
  260. // Inputs:
  261. // Side effects: 
  262.  
  263. Boolean XFE_PrefsLangDialog::verifyPage()
  264. {
  265.     return TRUE;
  266. }
  267.  
  268. // Member:       getContext
  269. // Description:  returns context
  270. // Inputs:
  271. // Side effects: 
  272.  
  273. MWContext *XFE_PrefsLangDialog::getContext()
  274. {
  275.     return (m_prefsDialog->getContext());
  276. }
  277.  
  278. // Member:       getLangPage
  279. // Description:  returns the Languages prefs page
  280. // Inputs:
  281. // Side effects: 
  282.  
  283. XFE_PrefsPageBrowserLang *XFE_PrefsLangDialog::getLangPage()
  284. {
  285.     return m_langPage;
  286. }
  287.  
  288. // Member:       getPrefsDialog
  289. // Description:  returns preferences dialog
  290. // Inputs:
  291. // Side effects: 
  292.  
  293. XFE_PrefsDialog *XFE_PrefsLangDialog::getPrefsDialog()
  294. {
  295.     return (m_prefsDialog);
  296. }
  297.  
  298. // Friend:       prefsLangCb_ok
  299. // Description:  
  300. // Inputs:
  301. // Side effects: 
  302.  
  303. void XFE_PrefsLangDialog::cb_ok(Widget    w,
  304.                                 XtPointer closure,
  305.                                 XtPointer callData)
  306. {
  307.     XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
  308.     PrefsDataLang       *fep = theDialog->m_prefsDataLang;
  309.     int                 *pos_list;
  310.     int                  pos_count;
  311.     char                *value = 0;
  312.  
  313.     value = fe_GetTextField(fep->other_text);
  314.     if (value && (XP_STRLEN(value) > 0)) {
  315.         XFE_PrefsPageBrowserLang *lang_page = theDialog->getLangPage();
  316.         lang_page->insertLang(value);
  317.     }
  318.     else if (XmListGetSelectedPos(fep->lang_list, &pos_list, &pos_count)) {
  319.         int   pos = pos_list[0] - 1;
  320.         char *lang = fep->avail_lang_regs[pos];
  321.         XFE_PrefsPageBrowserLang *lang_page = theDialog->getLangPage();
  322.         lang_page->insertLang(lang);
  323.         XtFree((char *)pos_list);
  324.     }
  325.     if (value) XP_FREE(value);
  326.  
  327.     // Simulate a cancel
  328.  
  329.     theDialog->cb_cancel(w, closure, callData);
  330. }
  331.  
  332. // Member:       prefsLangCb_cancel
  333. // Description:  
  334. // Inputs:
  335. // Side effects: 
  336.  
  337. void XFE_PrefsLangDialog::cb_cancel(Widget    /* w */,
  338.                                     XtPointer closure,
  339.                                     XtPointer /* callData */)
  340. {
  341.     XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
  342.  
  343.     XtRemoveCallback(theDialog->m_chrome, XmNokCallback, cb_ok, theDialog);
  344.     XtRemoveCallback(theDialog->m_chrome, XmNcancelCallback, cb_cancel, theDialog);
  345.  
  346.     // Delete the dialog
  347.  
  348.     delete theDialog;
  349. }
  350.  
  351. // Member:       prefsLangCb_focusOther
  352. // Description:  
  353. // Inputs:
  354. // Side effects: 
  355.  
  356. void XFE_PrefsLangDialog::cb_focusOther(Widget    /* w */,
  357.                                         XtPointer closure,
  358.                                         XtPointer /* callData */)
  359. {
  360.     XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
  361.     XFE_PrefsDialog     *thePrefsDialog = theDialog->getPrefsDialog();
  362.     PrefsDataLang       *fep = theDialog->m_prefsDataLang;
  363.  
  364.     fep->temp_default_button = XmSelectionBoxGetChild(thePrefsDialog->getDialogChrome(),
  365.                                                       XmDIALOG_DEFAULT_BUTTON);
  366.     XtVaSetValues(thePrefsDialog->getDialogChrome(), XmNdefaultButton, NULL, NULL);
  367. }
  368.  
  369. // Member:       prefsLangCb_loseFocusOther
  370. // Description:  
  371. // Inputs:
  372. // Side effects: 
  373.  
  374. void XFE_PrefsLangDialog::cb_loseFocusOther(Widget    /* w */,
  375.                                             XtPointer closure,
  376.                                             XtPointer /* callData */)
  377. {
  378.     XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
  379.     XFE_PrefsDialog     *thePrefsDialog = theDialog->getPrefsDialog();
  380.     PrefsDataLang       *fep = theDialog->m_prefsDataLang;
  381.  
  382.     if (fep->temp_default_button) {
  383.         XtVaSetValues(thePrefsDialog->getDialogChrome(),
  384.                       XmNdefaultButton, fep->temp_default_button,
  385.                       NULL);
  386.     }
  387. }
  388.  
  389. // ==================== Private Functions ====================
  390.  
  391. /*
  392.  * This belongs in a utility module
  393.  *
  394.  * Convert a multiline string (embedded new-lines)
  395.  * to an array of strings
  396.  *  create the array
  397.  *  copies the lines into the array
  398.  *  returns length of the array
  399.  *
  400.  * To free the array:
  401.  *   for (i=0; i<cnt; i++)
  402.  *      XP_FREE(array[i]);
  403.  *   XP_FREE(array);
  404.  */
  405.  
  406. static int multiline_str_to_array(const char *string, char ***array_p)
  407. {
  408.     char *p, *q, **array;
  409.     int i, cnt, len;
  410.     Boolean at_start_of_line;
  411.     
  412.     /* handle null string */
  413.     if (string == NULL) {
  414.     /* always allocate an array so the caller can free it */
  415.     array = (char **)XP_ALLOC(sizeof(char *));
  416.     array[0] = NULL;
  417.     *array_p = array;
  418.     return 0;
  419.     }
  420.  
  421.     /* 
  422.      * count the number of lines 
  423.      * (count beginnings so we will count any last line without a '\n')
  424.      * This supports multibyte text only because '\n' is less than 0x40
  425.      */
  426.     cnt = 0;
  427.     at_start_of_line = True;
  428.     for (p=(char *)string; *p; p++) {
  429.     if (at_start_of_line) {
  430.         cnt += 1;
  431.         at_start_of_line = False;
  432.     }
  433.     if (*p == '\n') {
  434.         at_start_of_line = True;
  435.     }
  436.     }
  437.  
  438.     /* copy lines into the array */
  439.     array = (char **)XP_ALLOC((cnt+1) * sizeof(char *));
  440.     i = 0;
  441.     len = 0;
  442.     for (p=q=(char *)string; *p; p++) {
  443.     if (*p == '\n') {
  444.         array[i] = (char *)XP_ALLOC(len+1);
  445.         strncpy(array[i], q, len);
  446.         /* add a string terminator */
  447.         array[i][len] = '\0';
  448.         i += 1;
  449.         len = 0;
  450.         q = p + 1;
  451.     }
  452.     else
  453.         len += 1;
  454.     }
  455.     if (len) { /* include ending chars with no newline */
  456.     array[i] = (char *)XP_ALLOC(len+1);
  457.     strncpy(array[i], q, len);
  458.     /* add a string terminator */
  459.     array[i][len] = '\0';
  460.     }
  461.  
  462.     *array_p = array;
  463.     return cnt;
  464. }
  465.  
  466. /*
  467.  * This belongs in a utility module
  468.  *
  469.  * Convert a multiline preference (embedded new-lines)
  470.  * to an array of strings
  471.  *  create the array
  472.  *  copies the lines into the array
  473.  *  remove leading/trailing white space
  474.  *  remove blank lines
  475.  *  returns length of the array
  476.  *
  477.  * To free the array:
  478.  *   for (i=0; i<cnt; i++)
  479.  *      XP_FREE(array[i]);
  480.  *   XP_FREE(array);
  481.  */
  482.  
  483. static int multiline_pref_to_array(const char *string, char ***array_p)
  484. {
  485.   int i, j, cnt;
  486.   char **array;
  487.  
  488.   /*
  489.    * Convert the multiline string to an array
  490.    * (with leading/trailing white space and blank lines)
  491.    */
  492.   cnt = multiline_str_to_array(string, array_p);
  493.  
  494.   /*
  495.    * trim any leading/training white space
  496.    */
  497.   array = *array_p;
  498.   for (i=0; i<cnt; i++) {
  499.     char *tmp;
  500.     tmp = XP_StripLine(array[i]);
  501.     /* we can't lose the malloc address else free will fail */
  502.     /* so if there was white space at the beginning we make a copy */
  503.     if (tmp != array[i]) {
  504.     char *tmp2 = array[i];
  505.           array[i] = strdup(tmp);
  506.           XP_FREE(tmp2);
  507.     }
  508.   }
  509.  
  510.   /*
  511.    * remove any blank lines
  512.    */
  513.   for (i=0; i<cnt; i++) {
  514.     if (array[i][0] == '\0') {
  515.     XP_FREE(array[i]);
  516.     for (j=i+1; j<cnt; j++)
  517.         array[j-1] = array[j];
  518.     cnt -= 1;
  519.     }
  520.   }
  521.  
  522.   return cnt;
  523. }
  524.  
  525.