home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / PrefsDialogBrowser.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  40.7 KB  |  1,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.    PrefsDialogBrowser.cpp -- the Browser page in XFE preferences dialogs
  20.    Created: Linda Wei <lwei@netscape.com>, 17-Sep-96.
  21.  */
  22.  
  23. #include "felocale.h"
  24. #include "structs.h"
  25. #include "fonts.h"
  26. #include "xpassert.h"
  27. #include "MozillaApp.h"
  28. #include "View.h"
  29. #include "xfe.h"
  30. #include "e_kit.h"
  31. #include "prefapi.h"
  32. #include "PrefsDialog.h"
  33. #include "PrefsLang.h"
  34. #include "prefapi.h"
  35.  
  36. #include <Xm/Label.h>
  37. #include <Xm/LabelG.h>
  38. #include <Xm/CascadeBG.h>
  39. #include <Xm/PushB.h>
  40. #include <Xm/PushBG.h>
  41. #include <Xm/ToggleB.h>
  42. #include <Xm/ArrowBG.h>
  43. #include <Xm/Form.h>
  44. #include <Xm/Frame.h>
  45. #include <Xm/RowColumn.h>
  46. #include <Xm/LabelG.h> 
  47. #include <Xm/TextF.h> 
  48. #include <Xm/ToggleBG.h> 
  49. #include <Xfe/Xfe.h>
  50.  
  51. extern "C"
  52. {
  53.     char     *XP_GetString(int i);
  54.     void      fe_browse_file_of_text_in_url(MWContext *context, Widget text_field, Boolean dirp);
  55.     void      fe_installBrowser();
  56.     void      fe_installBrowserLang(char *);
  57. }
  58.  
  59. static char *array_to_acceptLang(char **array, int cnt);
  60. extern int   fe_stringPrefToArray(const char *string, char ***array_p);
  61. extern char *fe_arrayToStringPref(char **array_p, int count);
  62.  
  63. #define OUTLINER_GEOMETRY_PREF "preferences.lang.outliner_geometry"
  64.  
  65. extern int XFE_LANG_COL_ORDER;
  66. extern int XFE_LANG_COL_LANG;
  67. extern int XFE_OUT_OF_MEMORY_URL;
  68.  
  69. // ************************************************************************
  70. // *************************       Browser        *************************
  71. // ************************************************************************
  72.  
  73. // Member:       XFE_PrefsPageBrowser
  74. // Description:  Constructor
  75. // Inputs:
  76. // Side effects: 
  77.  
  78. XFE_PrefsPageBrowser::XFE_PrefsPageBrowser(XFE_PrefsDialog *dialog)
  79.     : XFE_PrefsPage(dialog),
  80.       m_prefsDataBrowser(0),
  81.       m_home_changed(FALSE)
  82. {
  83. }
  84.  
  85. // Member:       ~XFE_PrefsPageBrowser
  86. // Description:  Destructor
  87. // Inputs:
  88. // Side effects: 
  89.  
  90. XFE_PrefsPageBrowser::~XFE_PrefsPageBrowser()
  91. {
  92.     delete m_prefsDataBrowser;
  93. }
  94.  
  95. // Member:       create
  96. // Description:  Creates page for Browser
  97. // Inputs:
  98. // Side effects: 
  99.  
  100. void XFE_PrefsPageBrowser::create()
  101. {
  102.     Widget            kids[100];
  103.     Arg               av[50];
  104.     int               ac;
  105.     int               i;
  106.  
  107.     PrefsDataBrowser *fep = NULL;
  108.  
  109.     fep = new PrefsDataBrowser;
  110.     memset(fep, 0, sizeof(PrefsDataBrowser));
  111.     m_prefsDataBrowser = fep;
  112.  
  113.     fep->context = getContext();
  114.     fep->prompt_dialog = getPrefsDialog()->getDialogChrome();
  115.  
  116.     Widget form;
  117.  
  118.     ac = 0;
  119.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  120.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  121.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  122.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  123.     form = XmCreateForm (m_wPageForm, "browser", av, ac);
  124.     XtManageChild (form);
  125.     m_wPage = fep->page = form;
  126.  
  127.     // Browser starts with
  128.  
  129.     Widget frame1;
  130.  
  131.     ac = 0;
  132.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  133.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  134.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  135.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  136.     frame1 = XmCreateFrame (form, "browserFrame", av, ac);
  137.  
  138.     Widget form1;
  139.  
  140.     ac = 0;
  141.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  142.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  143.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  144.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  145.     form1 = XmCreateForm (frame1, "browserBox", av, ac);
  146.  
  147.     Widget label1;
  148.  
  149.     ac = 0;
  150.     XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  151.     label1 = XmCreateLabelGadget (frame1, "browserBoxLabel", av, ac);
  152.  
  153.     // Browser starts with
  154.  
  155.     ac = 0;
  156.     i = 0;
  157.  
  158.     kids[i++] = fep->blank_page_toggle =
  159.         XmCreateToggleButtonGadget(form1, "blankPage", av, ac);
  160.  
  161.     kids[i++] = fep->home_page_toggle =
  162.         XmCreateToggleButtonGadget(form1, "homePage", av, ac);
  163.  
  164.     kids[i++] = fep->last_page_toggle =
  165.         XmCreateToggleButtonGadget(form1, "lastPage", av, ac);
  166.  
  167.     XtVaSetValues(fep->blank_page_toggle,
  168.                   XmNtopAttachment, XmATTACH_FORM,
  169.                   XmNleftAttachment, XmATTACH_FORM,
  170.                   XmNrightAttachment, XmATTACH_NONE,
  171.                   XmNbottomAttachment, XmATTACH_NONE,
  172.                   NULL);
  173.  
  174.     XtVaSetValues(fep->home_page_toggle,
  175.                   XmNtopAttachment, XmATTACH_WIDGET,
  176.                   XmNtopWidget, fep->blank_page_toggle,
  177.                   XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  178.                   XmNleftWidget, fep->blank_page_toggle,
  179.                   XmNrightAttachment, XmATTACH_NONE,
  180.                   XmNbottomAttachment, XmATTACH_NONE,
  181.                   NULL);
  182.  
  183.     XtVaSetValues(fep->last_page_toggle,
  184.                   XmNtopAttachment, XmATTACH_WIDGET,
  185.                   XmNtopWidget, fep->home_page_toggle,
  186.                   XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  187.                   XmNleftWidget, fep->blank_page_toggle,
  188.                   XmNrightAttachment, XmATTACH_NONE,
  189.                   XmNbottomAttachment, XmATTACH_NONE,
  190.                   NULL);
  191.  
  192.     XtManageChildren(kids, i);
  193.     XtManageChild(label1);
  194.     XtManageChild(form1);
  195.     XtManageChild(frame1);
  196.  
  197.     // Home page location and History expiration
  198.  
  199.     Widget frame2;
  200.  
  201.     ac = 0;
  202.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  203.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  204.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  205.     XtSetArg (av [ac], XmNtopWidget, frame1); ac++;
  206.     XtSetArg (av [ac], XmNtopOffset, 8); ac++;
  207.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  208.     frame2 = XmCreateFrame (form, "homePageFrame", av, ac);
  209.  
  210.     Widget form2;
  211.  
  212.     ac = 0;
  213.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  214.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  215.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  216.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  217.     form2 = XmCreateForm (frame2, "homePageBox", av, ac);
  218.  
  219.     Widget label2;
  220.  
  221.     ac = 0;
  222.     XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  223.     label2 = XmCreateLabelGadget (frame2, "homePageBoxLabel", av, ac);
  224.  
  225.     Widget home_page_label;
  226.     Widget loc_label;
  227.     Widget home_page_text;
  228.     Widget browse_button;
  229.     Widget use_current_button;
  230.  
  231.     ac = 0;
  232.     i = 0;
  233.  
  234.     kids[i++] = home_page_label = XmCreateLabelGadget(form2, "homePageLabel", av, ac);
  235.  
  236.     kids[i++] = loc_label = XmCreateLabelGadget(form2, "locLabel", av, ac);
  237.  
  238.     kids[i++] = home_page_text = fe_CreateTextField (form2, "homePageText", av, ac);
  239.  
  240.     kids[i++] = browse_button = XmCreatePushButtonGadget(form2, "browse", av, ac);
  241.  
  242.     kids[i++] = use_current_button = XmCreatePushButtonGadget(form2, "useCurrent", av, ac);
  243.  
  244.     fep->home_page_text = home_page_text;
  245.     fep->browse_button = browse_button;
  246.     fep->use_current_button = use_current_button;
  247.  
  248.     int labels_height;
  249.  
  250.     labels_height = XfeVaGetTallestWidget(loc_label,
  251.                                           home_page_text,
  252.                                           browse_button,
  253.                                           NULL);
  254.  
  255.     XtVaSetValues(home_page_label,
  256.                   XmNtopAttachment, XmATTACH_FORM,
  257.                   XmNleftAttachment, XmATTACH_FORM,
  258.                   XmNrightAttachment, XmATTACH_NONE,
  259.                   XmNbottomAttachment, XmATTACH_NONE,
  260.                   NULL);
  261.  
  262.     XtVaSetValues(loc_label,
  263.                   XmNheight, labels_height,
  264.                   XmNtopAttachment, XmATTACH_WIDGET,
  265.                   XmNtopWidget, home_page_label,
  266.                   XmNleftAttachment, XmATTACH_FORM,
  267.                   XmNrightAttachment, XmATTACH_NONE,
  268.                   XmNbottomAttachment, XmATTACH_NONE,
  269.                   NULL);
  270.  
  271.     XtVaSetValues(home_page_text,
  272.                   XmNheight, labels_height,
  273.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  274.                   XmNtopWidget, loc_label,
  275.                   XmNleftAttachment, XmATTACH_WIDGET,
  276.                   XmNleftWidget, loc_label,
  277.                   XmNrightAttachment, XmATTACH_FORM,
  278.                   XmNbottomAttachment, XmATTACH_NONE,
  279.                   NULL);
  280.  
  281.     XtVaSetValues(browse_button,
  282.                   XmNheight, labels_height,
  283.                   XmNtopAttachment, XmATTACH_WIDGET,
  284.                   XmNtopWidget, loc_label,
  285.                   XmNleftAttachment, XmATTACH_NONE,
  286.                   XmNrightAttachment, XmATTACH_FORM,
  287.                   XmNbottomAttachment, XmATTACH_NONE,
  288.                   NULL);
  289.  
  290.     XtVaSetValues(use_current_button,
  291.                   XmNheight, labels_height,
  292.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  293.                   XmNtopWidget, browse_button,
  294.                   XmNleftAttachment, XmATTACH_NONE,
  295.                   XmNrightAttachment, XmATTACH_WIDGET,
  296.                   XmNrightWidget, browse_button,
  297.                   XmNrightOffset, 8,
  298.                   XmNbottomAttachment, XmATTACH_NONE,
  299.                   NULL);
  300.  
  301.     XtManageChildren (kids, i);
  302.     XtManageChild(label2);
  303.     XtManageChild(form2);
  304.     XtManageChild(frame2);
  305.  
  306.     // History
  307.  
  308.     Widget frame3;
  309.  
  310.     ac = 0;
  311.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  312.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  313.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  314.     XtSetArg (av [ac], XmNtopWidget, frame2); ac++;
  315.     XtSetArg (av [ac], XmNtopOffset, 8); ac++;
  316.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  317.     frame3 = XmCreateFrame (form, "historyFrame", av, ac);
  318.  
  319.     Widget form3;
  320.  
  321.     ac = 0;
  322.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  323.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  324.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  325.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  326.     form3 = XmCreateForm (frame3, "historyBox", av, ac);
  327.  
  328.     Widget label3;
  329.  
  330.     ac = 0;
  331.     XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  332.     label3 = XmCreateLabelGadget (frame3, "historyBoxLabel", av, ac);
  333.  
  334.     Widget expire_label;
  335.     Widget expire_days_text;
  336.     Widget days_label;
  337.     Widget expire_now_button;
  338.  
  339.     ac = 0;
  340.     i = 0;
  341.  
  342.     kids[i++] = expire_label = XmCreateLabelGadget(form3, "expireLabel", av, ac);
  343.  
  344.     kids[i++] = days_label = XmCreateLabelGadget(form3, "daysLabel", av, ac);
  345.  
  346.     kids[i++] = expire_days_text = fe_CreateTextField (form3, "expireDays", av, ac);
  347.  
  348.     kids[i++] = expire_now_button = XmCreatePushButtonGadget(form3, "expireNow", av, ac);
  349.  
  350.     fep->expire_days_text = expire_days_text;
  351.  
  352.     XtVaSetValues(expire_label,
  353.                   XmNheight, labels_height,
  354.                   XmNtopAttachment, XmATTACH_FORM,
  355.                   XmNleftAttachment, XmATTACH_FORM,
  356.                   XmNrightAttachment, XmATTACH_NONE,
  357.                   XmNbottomAttachment, XmATTACH_NONE,
  358.                   NULL);
  359.  
  360.     XtVaSetValues(expire_days_text,
  361.                   XmNcolumns, 3,
  362.                   XmNheight, labels_height,
  363.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  364.                   XmNtopWidget, expire_label,
  365.                   XmNleftAttachment, XmATTACH_WIDGET,
  366.                   XmNleftWidget, expire_label,
  367.                   XmNrightAttachment, XmATTACH_NONE,
  368.                   XmNbottomAttachment, XmATTACH_NONE,
  369.                   NULL);
  370.  
  371.     XtVaSetValues(days_label,
  372.                   XmNheight, labels_height,
  373.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  374.                   XmNtopWidget, expire_label,
  375.                   XmNleftAttachment, XmATTACH_WIDGET,
  376.                   XmNleftWidget, expire_days_text,
  377.                   XmNrightAttachment, XmATTACH_NONE,
  378.                   XmNbottomAttachment, XmATTACH_NONE,
  379.                   NULL);
  380.  
  381.     XtVaSetValues(expire_now_button,
  382.                   XmNheight, labels_height,
  383.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  384.                   XmNtopWidget, expire_label,
  385.                   XmNleftAttachment, XmATTACH_NONE,
  386.                   XmNrightAttachment, XmATTACH_FORM,
  387.                   XmNbottomAttachment, XmATTACH_NONE,
  388.                   NULL);
  389.  
  390.     XtManageChildren (kids, i);
  391.     XtManageChild(label3);
  392.     XtManageChild(form3);
  393.     XtManageChild(frame3);
  394.  
  395.     XtAddCallback(fep->blank_page_toggle, XmNvalueChangedCallback,
  396.                   cb_setStartupPage, fep);
  397.     XtAddCallback(fep->home_page_toggle, XmNvalueChangedCallback,
  398.                   cb_setStartupPage, fep);
  399.     XtAddCallback(fep->last_page_toggle, XmNvalueChangedCallback,
  400.                   cb_setStartupPage, fep);
  401.  
  402.     XtAddCallback(browse_button, XmNactivateCallback,
  403.                   cb_browse, this);
  404.     XtAddCallback(use_current_button, XmNactivateCallback,
  405.                   cb_useCurrent, this);
  406.     XtAddCallback(expire_now_button, XmNactivateCallback,
  407.                   cb_expireNow, this);
  408.  
  409.     setCreated(TRUE);
  410. }
  411.  
  412. // Member:       init
  413. // Description:  Initializes page for Browser
  414. // Inputs:
  415. // Side effects: 
  416.  
  417. void XFE_PrefsPageBrowser::init()
  418. {
  419.     XP_ASSERT(m_prefsDataBrowser);
  420.     
  421.     PrefsDataBrowser   *fep = m_prefsDataBrowser;
  422.     XFE_GlobalPrefs    *prefs = &fe_globalPrefs;
  423.     Boolean            sensitive;
  424.     
  425.     // Browser starts with
  426.     sensitive = !PREF_PrefIsLocked("browser.startup.page");
  427.     XtVaSetValues(fep->blank_page_toggle, 
  428.                   XmNset, (prefs->browser_startup_page == BROWSER_STARTUP_BLANK),
  429.                   XmNsensitive, sensitive,
  430.                   0);
  431.  
  432.     XtVaSetValues(fep->home_page_toggle, 
  433.                   XmNset, (prefs->browser_startup_page == BROWSER_STARTUP_HOME),
  434.                   XmNsensitive, sensitive,
  435.                   0);
  436.  
  437.     XtVaSetValues(fep->last_page_toggle,
  438.                   XmNset, (prefs->browser_startup_page == BROWSER_STARTUP_LAST),
  439.                   XmNsensitive, sensitive,
  440.                   0);
  441.  
  442.     sensitive = !PREF_PrefIsLocked("browser.startup.homepage");
  443.     XtVaSetValues(fep->home_page_text, XmNsensitive, sensitive, 0);
  444.     fe_SetTextField(fep->home_page_text, prefs->home_document);
  445.     XtSetSensitive(fep->use_current_button, sensitive);
  446.     XtSetSensitive(fep->browse_button, sensitive);
  447.  
  448.     // History expires
  449.  
  450.     char buf [1024];
  451.     if (prefs->global_history_expiration >= 0)
  452.         PR_snprintf(buf, sizeof(buf), "%d", prefs->global_history_expiration);
  453.     else
  454.         *buf = 0;
  455.  
  456.     sensitive = !PREF_PrefIsLocked("browser.link_expiration");
  457.     XtVaSetValues(fep->expire_days_text,
  458.                   XmNvalue, buf,
  459.                   XmNsensitive, sensitive,
  460.                   0);
  461.  
  462.     setInitialized(TRUE);
  463. }
  464.  
  465. // Member:       install
  466. // Description:  
  467. // Inputs:
  468. // Side effects: 
  469.  
  470. void XFE_PrefsPageBrowser::install()
  471. {
  472.     fe_installBrowser();
  473.  
  474.     if (m_home_changed) {
  475.         // Notify whoever is interested in updating home button/menu item
  476.         XFE_MozillaApp::theApp()->notifyInterested(XFE_View::commandNeedsUpdating,
  477.                                                    (void*)xfeCmdHome);
  478.         m_home_changed = FALSE;
  479.     }
  480. }
  481.  
  482. // Member:       save
  483. // Description:  
  484. // Inputs:
  485. // Side effects: 
  486.  
  487. void XFE_PrefsPageBrowser::save()
  488. {
  489.     PrefsDataBrowser *fep = m_prefsDataBrowser;
  490.  
  491.     XP_ASSERT(fep);
  492.  
  493.     char *old_home = fe_globalPrefs.home_document;
  494.     Boolean b;
  495.  
  496.     XtVaGetValues(fep->blank_page_toggle, XmNset, &b, 0);
  497.     if (b) fe_globalPrefs.browser_startup_page = BROWSER_STARTUP_BLANK;
  498.  
  499.     XtVaGetValues(fep->home_page_toggle, XmNset, &b, 0);
  500.     if (b) fe_globalPrefs.browser_startup_page = BROWSER_STARTUP_HOME;
  501.  
  502.     XtVaGetValues(fep->last_page_toggle, XmNset, &b, 0);
  503.     if (b) fe_globalPrefs.browser_startup_page = BROWSER_STARTUP_LAST;
  504.  
  505.     char *s = fe_GetTextField(fep->home_page_text);
  506.     fe_globalPrefs.home_document = s ? s : XP_STRDUP("");
  507.  
  508.     // Send out notification to change sensitivity of the home button/menu item
  509.  
  510.     if ((old_home == 0) ||
  511.         (*old_home == '\0')){
  512.         if (XP_STRLEN(fe_globalPrefs.home_document) > 0) {
  513.             m_home_changed = TRUE;
  514.         }
  515.     } 
  516.     else {
  517.         if (XP_STRLEN(fe_globalPrefs.home_document) == 0) {
  518.             m_home_changed = TRUE;
  519.         }
  520.     }
  521.  
  522.     if (old_home) XP_FREE(old_home);
  523.  
  524.     // History expires
  525.  
  526.     int old_history_expiration = fe_globalPrefs.global_history_expiration;
  527.  
  528.     fe_globalPrefs.global_history_expiration = -1;
  529.  
  530.     char *text = 0;
  531.     char  dummy;
  532.     XtVaGetValues(fep->expire_days_text, XmNvalue, &text, 0);
  533.     sscanf(text, " %d %c", &fe_globalPrefs.global_history_expiration, &dummy);
  534.     if (fe_globalPrefs.global_history_expiration < 0)
  535.         fe_globalPrefs.global_history_expiration = -1;
  536.     if (text) XtFree(text);
  537.  
  538.     if (old_history_expiration != fe_globalPrefs.global_history_expiration) {
  539.         fe_RefreshAllAnchors();
  540.     }
  541.  
  542.     // Install preferences
  543.  
  544.     install();
  545. }
  546.  
  547. // Member:       getData
  548. // Description:  
  549. // Inputs:
  550. // Side effects: 
  551.  
  552. PrefsDataBrowser *XFE_PrefsPageBrowser::getData()
  553. {
  554.     return m_prefsDataBrowser;
  555. }
  556.  
  557. // Member:       cb_setStartupPage
  558. // Description:  
  559. // Inputs:
  560. // Side effects: 
  561.  
  562. void XFE_PrefsPageBrowser::cb_setStartupPage(Widget    w,
  563.                                              XtPointer closure,
  564.                                              XtPointer callData)
  565. {
  566.     PrefsDataBrowser             *fep = (PrefsDataBrowser *)closure;
  567.     XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)callData;
  568.  
  569.     if (! cb->set) {
  570.         XtVaSetValues(w, XmNset, True, 0);
  571.     }
  572.     else if (w == fep->blank_page_toggle){
  573.         XtVaSetValues(fep->home_page_toggle, XmNset, False, 0);
  574.         XtVaSetValues(fep->last_page_toggle, XmNset, False, 0);
  575.     }
  576.     else if (w == fep->home_page_toggle){
  577.         XtVaSetValues(fep->blank_page_toggle, XmNset, False, 0);
  578.         XtVaSetValues(fep->last_page_toggle, XmNset, False, 0);
  579.     }
  580.     else if (w == fep->last_page_toggle){
  581.         XtVaSetValues(fep->blank_page_toggle, XmNset, False, 0);
  582.         XtVaSetValues(fep->home_page_toggle, XmNset, False, 0);
  583.     }
  584.     else
  585.         abort();
  586. }
  587.  
  588. // Member:       cb_browse
  589. // Description:  
  590. // Inputs:
  591. // Side effects: 
  592.  
  593. void XFE_PrefsPageBrowser::cb_browse(Widget    /* w */,
  594.                                      XtPointer closure,
  595.                                      XtPointer /* callData */)
  596. {
  597.     XFE_PrefsPageBrowser *thePage = (XFE_PrefsPageBrowser *)closure;
  598.     XFE_PrefsDialog      *theDialog = thePage->getPrefsDialog();
  599.     PrefsDataBrowser     *fep = thePage->getData();
  600.  
  601.     fe_browse_file_of_text_in_url(theDialog->getContext(), fep->home_page_text, False);
  602. }
  603.  
  604. // Member:       cb_useCurrent
  605. // Description:  
  606. // Inputs:
  607. // Side effects: 
  608.  
  609. void XFE_PrefsPageBrowser::cb_useCurrent(Widget    /* w */,
  610.                                          XtPointer closure,
  611.                                          XtPointer /* callData */)
  612. {
  613.     XFE_PrefsPageBrowser *thePage = (XFE_PrefsPageBrowser *)closure;
  614.     XFE_PrefsDialog      *theDialog = thePage->getPrefsDialog();
  615.     PrefsDataBrowser     *fep = thePage->getData();
  616.     MWContext            *context = theDialog->getContext();
  617.     History_entry        *h = SHIST_GetCurrent (&context->hist);
  618.  
  619.     if (!h) return;
  620.       
  621.     if ((h->address) && 
  622.         (XP_STRLEN(h->address) > 0))
  623.         fe_SetTextField(fep->home_page_text, h->address);
  624. }
  625.  
  626. // Member:       cb_expireNow
  627. // Description:  
  628. // Inputs:
  629. // Side effects: 
  630.  
  631. void XFE_PrefsPageBrowser::cb_expireNow(Widget    /* widget */,
  632.                                         XtPointer closure,
  633.                                         XtPointer /* call_data */)
  634. {
  635.     XFE_PrefsPageBrowser *thePage = (XFE_PrefsPageBrowser *)closure;
  636.     PrefsDataBrowser     *fep = thePage->getData();
  637.  
  638.     if (XFE_Confirm(fep->context, fe_globalData.expire_now_message)) {
  639.         GH_ClearGlobalHistory();
  640.         fe_RefreshAllAnchors();
  641.     }
  642. }
  643.  
  644. // ************************************************************************
  645. // *************************  Browser/Languages   *************************
  646. // ************************************************************************
  647.  
  648. // Member:       XFE_PrefsPageBrowserLang
  649. // Description:  Constructor
  650. // Inputs:
  651. // Side effects: 
  652.  
  653. XFE_PrefsPageBrowserLang::XFE_PrefsPageBrowserLang(XFE_PrefsDialog *dialog)
  654.     : XFE_PrefsPage(dialog),
  655.       m_prefsDataBrowserLang(0),
  656.       m_rowIndex(0)
  657. {
  658. }
  659.  
  660. // Member:       ~XFE_PrefsPageBrowserLang
  661. // Description:  Destructor
  662. // Inputs:
  663. // Side effects: 
  664.  
  665. XFE_PrefsPageBrowserLang::~XFE_PrefsPageBrowserLang()
  666. {
  667.     int                     i;
  668.     PrefsDataBrowserLang   *fep = m_prefsDataBrowserLang;
  669.  
  670.     if (fep) {
  671.         delete fep->lang_outliner;
  672.  
  673.         if (fep->pref_lang_regs) {
  674.             for (i = 0; i < fep->pref_lang_count; i++) {
  675.                 XP_FREE(fep->pref_lang_regs[i]);
  676.             }
  677.             XP_FREE(m_prefsDataBrowserLang->pref_lang_regs);
  678.         }
  679.     }
  680.     delete m_prefsDataBrowserLang;
  681. }
  682.  
  683. const int XFE_PrefsPageBrowserLang::OUTLINER_COLUMN_ORDER = 0;
  684. const int XFE_PrefsPageBrowserLang::OUTLINER_COLUMN_LANG = 1;
  685.  
  686. const int XFE_PrefsPageBrowserLang::OUTLINER_COLUMN_MAX_LENGTH = 256;
  687. const int XFE_PrefsPageBrowserLang::OUTLINER_INIT_POS = (-1);
  688.  
  689. #define STRING_COL_ORDER "Order"
  690. #define STRING_COL_LANG  "Language"
  691.  
  692. // Member:       create
  693. // Description:  Creates page for BrowserLang
  694. // Inputs:
  695. // Side effects: 
  696.  
  697. void XFE_PrefsPageBrowserLang::create()
  698. {
  699.     Widget            kids[100];
  700.     Arg               av[50];
  701.     int               ac;
  702.     int               i;
  703.  
  704.     PrefsDataBrowserLang *fep = NULL;
  705.  
  706.     fep = new PrefsDataBrowserLang;
  707.     memset(fep, 0, sizeof(PrefsDataBrowserLang));
  708.     m_prefsDataBrowserLang = fep;
  709.  
  710.     fep->context = getContext();
  711.     fep->prompt_dialog = getPrefsDialog()->getDialogChrome();
  712.  
  713.     Widget form;
  714.  
  715.     ac = 0;
  716.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  717.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  718.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  719.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  720.     form = XmCreateForm (m_wPageForm, "lang", av, ac);
  721.     XtManageChild (form);
  722.     m_wPage = fep->page = form;
  723.  
  724.     Widget frame1;
  725.  
  726.     ac = 0;
  727.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  728.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  729.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  730.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  731.     frame1 = XmCreateFrame (form, "langFrame", av, ac);
  732.  
  733.     Widget form1;
  734.  
  735.     ac = 0;
  736.     XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  737.     XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  738.     XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  739.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  740.     form1 = XmCreateForm (frame1, "langBox", av, ac);
  741.  
  742.     Widget lang_label;
  743.     Widget up_button;
  744.     Widget down_button;
  745.     Widget add_button;
  746.     Widget delete_button;
  747.  
  748.     ac = 0;
  749.     i = 0;
  750.     
  751.     kids[i++] = lang_label = 
  752.         XmCreateLabelGadget(form1, "langLabel", av, ac);
  753.  
  754.     kids[i++] = up_button = 
  755.         XmCreateArrowButtonGadget(form1, "upButton", av, ac);
  756.  
  757.     kids[i++] = down_button = 
  758.         XmCreateArrowButtonGadget(form1, "downButton", av, ac);
  759.  
  760.     kids[i++] = add_button =
  761.         XmCreatePushButtonGadget(form1, "addButton", av, ac);
  762.  
  763.     kids[i++] = delete_button =
  764.         XmCreatePushButtonGadget(form1, "deleteButton", av, ac);
  765.  
  766.     fep->add_button = add_button;
  767.     fep->delete_button = delete_button;
  768.     fep->up_button = up_button;
  769.     fep->down_button = down_button;
  770.  
  771.     // Outliner
  772.  
  773.     int           num_columns = 2;
  774.     static int    default_column_widths[] = {8, 40};
  775.     XFE_Outliner *outliner;
  776.     Widget        lang_list;
  777.  
  778.     outliner = new XFE_Outliner("langList",            // name
  779.                                 this,                  // outlinable
  780.                                 getPrefsDialog(),      // top level                                  
  781.                                 form1,                 // parent
  782.                                 FALSE,                 // constant size
  783.                                 TRUE,                  // has headings
  784.                                 num_columns,           // number of columns
  785.                                 num_columns,           // number of visible columns
  786.                                 default_column_widths, // default column widths
  787.                                 OUTLINER_GEOMETRY_PREF
  788.                                 );
  789.  
  790.     fep->lang_outliner = outliner;
  791.     lang_list = fep->lang_list = outliner->getBaseWidget();
  792.  
  793.     XtVaSetValues(outliner->getBaseWidget(),
  794.                   XtVaTypedArg, XmNblankBackground, XmRString, "white", 6,
  795.                   XmNvisibleRows, 10,
  796.                   NULL);
  797.     XtVaSetValues(outliner->getBaseWidget(),
  798.                   XmNcellDefaults, True,
  799.                   XtVaTypedArg, XmNcellBackground, XmRString, "white", 6,
  800.                   NULL);
  801.  
  802.     outliner->setColumnResizable(OUTLINER_COLUMN_ORDER, False);
  803.     outliner->setColumnResizable(OUTLINER_COLUMN_LANG, False);
  804.     outliner->show();
  805.     
  806.     XtVaSetValues(lang_label,
  807.                   XmNtopAttachment, XmATTACH_FORM,
  808.                   XmNleftAttachment, XmATTACH_FORM,
  809.                   XmNrightAttachment, XmATTACH_NONE,
  810.                   XmNbottomAttachment, XmATTACH_NONE,
  811.                   NULL);
  812.  
  813.     XtVaSetValues(fep->lang_list,
  814.                   XmNtopAttachment, XmATTACH_WIDGET,
  815.                   XmNtopWidget, lang_label,
  816.                   XmNtopOffset, 4,
  817.                   XmNleftAttachment, XmATTACH_FORM,
  818.                   XmNrightAttachment, XmATTACH_NONE,
  819.                   XmNbottomAttachment, XmATTACH_NONE,
  820.                   NULL);
  821.  
  822.     Dimension list_height;
  823.     Dimension up_button_height;
  824.     int       down_button_top_offset;
  825.     int       up_button_top_offset;
  826.  
  827.     XtVaGetValues(down_button,
  828.                   XmNtopOffset, &down_button_top_offset,
  829.                   NULL);
  830.  
  831.     list_height = XfeHeight(lang_list);
  832.     up_button_height = XfeHeight(up_button);
  833.     up_button_top_offset = list_height/2 - up_button_height - down_button_top_offset/2;
  834.  
  835.     XtVaSetValues(up_button,
  836.                   XmNarrowDirection, XmARROW_UP,
  837.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  838.                   XmNtopWidget, lang_list,
  839.                   XmNtopOffset, up_button_top_offset,
  840.                   XmNleftAttachment, XmATTACH_WIDGET,
  841.                   XmNleftWidget, lang_list,
  842.                   XmNleftOffset, 8,
  843.                   XmNrightAttachment, XmATTACH_NONE,
  844.                   XmNbottomAttachment, XmATTACH_NONE,
  845.                   NULL);
  846.                   
  847.     XtVaSetValues(down_button,
  848.                   XmNarrowDirection, XmARROW_DOWN,
  849.                   XmNtopAttachment, XmATTACH_WIDGET,
  850.                   XmNtopWidget, up_button,
  851.                   XmNtopOffset, 4,
  852.                   XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  853.                   XmNleftWidget, up_button,
  854.                   XmNrightAttachment, XmATTACH_NONE,
  855.                   XmNbottomAttachment, XmATTACH_NONE,
  856.                   NULL);
  857.  
  858.     int labels_width;
  859.  
  860.     labels_width = XfeVaGetWidestWidget(add_button,
  861.                                         delete_button,
  862.                                         NULL);
  863.  
  864.     XtVaSetValues(add_button,
  865.                   XmNwidth, labels_width,
  866.                   XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  867.                   XmNtopWidget, lang_list,
  868.                   XmNleftAttachment, XmATTACH_WIDGET,
  869.                   XmNleftWidget, up_button,
  870.                   XmNleftOffset, 24,
  871.                   XmNrightAttachment, XmATTACH_NONE,
  872.                   XmNbottomAttachment, XmATTACH_NONE,
  873.                   NULL);
  874.  
  875.     XtVaSetValues(delete_button,
  876.                   XmNwidth, labels_width,
  877.                   XmNtopAttachment, XmATTACH_WIDGET,
  878.                   XmNtopWidget, add_button,
  879.                   XmNtopOffset, 4,
  880.                   XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
  881.                   XmNleftWidget, add_button,
  882.                   XmNrightAttachment, XmATTACH_NONE,
  883.                   XmNbottomAttachment, XmATTACH_NONE,
  884.                   NULL);
  885.  
  886.     XtAddCallback(add_button, XmNactivateCallback, cb_add, this);
  887.     XtAddCallback(delete_button, XmNactivateCallback, cb_delete, this);
  888.     XtAddCallback(up_button, XmNactivateCallback, cb_promote, this);
  889.     XtAddCallback(down_button, XmNactivateCallback, cb_demote, this);
  890.  
  891.     XtManageChildren(kids, i);
  892.     XtManageChild(form1);
  893.     XtManageChild(frame1);
  894.  
  895.     setCreated(TRUE);
  896. }
  897.  
  898. // Member:       init
  899. // Description:  Initializes page for BrowserLang
  900. // Inputs:
  901. // Side effects: 
  902.  
  903. void XFE_PrefsPageBrowserLang::init()
  904. {
  905.     XP_ASSERT(m_prefsDataBrowserLang);
  906.     PrefsDataBrowserLang   *fep = m_prefsDataBrowserLang;
  907.     XFE_GlobalPrefs        *prefs = &fe_globalPrefs;
  908.  
  909.     // Retrieve the preferred lang/region list from preferences
  910.  
  911.     if (fep->pref_lang_regs) {
  912.         for (int i = 0; i < fep->pref_lang_count; i++) {
  913.             XP_FREE(fep->pref_lang_regs[i]);
  914.         }
  915.         XP_FREE(m_prefsDataBrowserLang->pref_lang_regs);
  916.         fep->pref_lang_regs = 0;
  917.         fep->pref_lang_count = 0;
  918.     }
  919.  
  920.     fep->pref_lang_count = fe_stringPrefToArray(prefs->lang_regions, &fep->pref_lang_regs);
  921.     fep->lang_outliner->change(0, fep->pref_lang_count, fep->pref_lang_count);
  922.     setSelectionPos(OUTLINER_INIT_POS);
  923.  
  924.     setInitialized(TRUE);
  925. }
  926.  
  927. // Member:       install
  928. // Description:  
  929. // Inputs:
  930. // Side effects: 
  931.  
  932. void XFE_PrefsPageBrowserLang::install()
  933. {
  934.     XP_ASSERT(m_prefsDataBrowserLang);
  935.     PrefsDataBrowserLang   *fep = m_prefsDataBrowserLang;
  936.     char                   *new_accept_lang;
  937.  
  938.     if (fep->pref_lang_count > 0) {
  939.         new_accept_lang = array_to_acceptLang(fep->pref_lang_regs, fep->pref_lang_count);
  940.     }
  941.     else {
  942.         new_accept_lang = NULL;
  943.     }
  944.  
  945.     fe_installBrowserLang(new_accept_lang);
  946. }
  947.  
  948. // Member:       save
  949. // Description:  
  950. // Inputs:
  951. // Side effects: 
  952.  
  953. void XFE_PrefsPageBrowserLang::save()
  954. {
  955.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  956.  
  957.     XP_ASSERT(fep);
  958.  
  959.     char *new_regions = fe_arrayToStringPref(fep->pref_lang_regs, fep->pref_lang_count);
  960.     XP_ASSERT(new_regions);
  961.  
  962.     XP_FREE(fe_globalPrefs.lang_regions);
  963.     fe_globalPrefs.lang_regions = new_regions;
  964.  
  965.     // Install preferences
  966.  
  967.     install();
  968. }
  969.  
  970. // Member:       insertLang
  971. // Description:  
  972. // Inputs:
  973. // Side effects: 
  974.  
  975. void XFE_PrefsPageBrowserLang::insertLang(char *lang)
  976. {
  977.     // First figure out where to insert it
  978.  
  979.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  980.     int                   pos = 0;
  981.     int                   count = fep->pref_lang_count;
  982.     
  983.     if (count > 0) {
  984.         // Check if there is any selection
  985.         uint32     sel_count = 0;
  986.         const int *indices = 0;
  987.         fep->lang_outliner->getSelection(&indices, (int *) &sel_count);
  988.         if (sel_count > 0 && indices) {
  989.             pos = indices[0];
  990.         }
  991.     }
  992.  
  993.     // Insert at pos
  994.  
  995.     insertLangAtPos(pos, lang);
  996. }
  997.  
  998. // Member:       insertLangAtPos
  999. // Description:  
  1000. // Inputs:
  1001. // Side effects: 
  1002.  
  1003. void XFE_PrefsPageBrowserLang::insertLangAtPos(int pos, char *lang)
  1004. {
  1005.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1006.     int                   count = fep->pref_lang_count;
  1007.     int                   i;
  1008.     
  1009.     // Insert language at position
  1010.  
  1011.     if (count > 0) {
  1012.         for (i = 0; i < count; i++) {
  1013.             if (XP_STRCMP(lang, fep->pref_lang_regs[i]) == 0)
  1014.                 return;
  1015.         }
  1016.  
  1017.         char **pref_lang_regs = 0;
  1018.         pref_lang_regs = (char **)XP_CALLOC(count+1, sizeof(char *));
  1019.  
  1020.         for (i = 0; i < pos; i++) {
  1021.             pref_lang_regs[i] = fep->pref_lang_regs[i];
  1022.         }
  1023.         for (i = pos; i < count; i++) {
  1024.             pref_lang_regs[i+1] = fep->pref_lang_regs[i];
  1025.         }
  1026.         pref_lang_regs[pos] = XP_STRDUP(lang);
  1027.  
  1028.         XP_FREE(m_prefsDataBrowserLang->pref_lang_regs);        
  1029.         fep->pref_lang_regs = pref_lang_regs;
  1030.         fep->pref_lang_count++;
  1031.     }
  1032.     else {
  1033.         fep->pref_lang_regs = (char **)XP_CALLOC(1, sizeof(char *));
  1034.         fep->pref_lang_regs[0] = XP_STRDUP(lang);
  1035.         fep->pref_lang_count = 1;
  1036.     }
  1037.  
  1038.     // Repaint 
  1039.  
  1040.     fep->lang_outliner->change(0, fep->pref_lang_count, fep->pref_lang_count);
  1041.  
  1042.     // Set selection
  1043.  
  1044.     setSelectionPos(pos);
  1045. }
  1046.  
  1047. // Member:       deleteLangAtPos
  1048. // Description:  
  1049. // Inputs:
  1050. // Side effects: 
  1051.  
  1052. void XFE_PrefsPageBrowserLang::deleteLangAtPos(int pos)
  1053. {
  1054.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1055.     int                   count = fep->pref_lang_count;
  1056.     int                   i;
  1057.  
  1058.     if (pos >= count) return;
  1059.  
  1060.     // Remove the lang at pos
  1061.  
  1062.     if (count == 1) {
  1063.         fep->pref_lang_count = 0;
  1064.         XP_FREE(fep->pref_lang_regs[0]);
  1065.         XP_FREE(m_prefsDataBrowserLang->pref_lang_regs);
  1066.         m_prefsDataBrowserLang->pref_lang_regs = 0;
  1067.     }
  1068.     else {
  1069.         char **pref_lang_regs = 0;
  1070.         pref_lang_regs = (char **)XP_CALLOC(count-1, sizeof(char *));
  1071.         for (i = 0; i < pos; i++) {
  1072.             pref_lang_regs[i] = fep->pref_lang_regs[i];
  1073.         }
  1074.         for (i = pos; i < count - 1; i++) {
  1075.             pref_lang_regs[i] = fep->pref_lang_regs[i+1];
  1076.         }
  1077.         XP_FREE(m_prefsDataBrowserLang->pref_lang_regs[pos]);        
  1078.         XP_FREE(m_prefsDataBrowserLang->pref_lang_regs);        
  1079.         m_prefsDataBrowserLang->pref_lang_regs = pref_lang_regs;
  1080.         fep->pref_lang_count--;
  1081.     }
  1082.  
  1083.     // Repaint
  1084.  
  1085.     fep->lang_outliner->change(0, fep->pref_lang_count, fep->pref_lang_count);
  1086.  
  1087.     // Set selection if there is more than one entry 
  1088.  
  1089.     if (fep->pref_lang_count > 0) {
  1090.         if (pos >= fep->pref_lang_count) pos--;
  1091.         setSelectionPos(pos);
  1092.     }
  1093.     else {
  1094.         setSelectionPos(OUTLINER_INIT_POS);
  1095.     }
  1096. }
  1097.  
  1098. // Member:       swapLangs
  1099. // Description:  
  1100. // Inputs:
  1101. // Side effects: 
  1102.  
  1103. void XFE_PrefsPageBrowserLang::swapLangs(int pos1, int pos2, int sel_pos)
  1104. {
  1105.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1106.     int                   count = fep->pref_lang_count;
  1107.     char                 *temp;
  1108.  
  1109.     if ((pos1 >= count) ||
  1110.         (pos2 >= count) ||
  1111.         (sel_pos >= count))
  1112.         return;
  1113.  
  1114.     // Swap
  1115.  
  1116.     temp = m_prefsDataBrowserLang->pref_lang_regs[pos1];
  1117.     m_prefsDataBrowserLang->pref_lang_regs[pos1] = m_prefsDataBrowserLang->pref_lang_regs[pos2];
  1118.     m_prefsDataBrowserLang->pref_lang_regs[pos2] = temp;
  1119.  
  1120.     // Repaint
  1121.  
  1122.     fep->lang_outliner->change(0, fep->pref_lang_count, fep->pref_lang_count);
  1123.  
  1124.     // Set selection if there is more than one entry 
  1125.  
  1126.     setSelectionPos(sel_pos);
  1127. }
  1128.  
  1129. // Member:       setSelelctionPos
  1130. // Description:  
  1131. // Inputs:
  1132. // Side effects: 
  1133.  
  1134. void XFE_PrefsPageBrowserLang::setSelectionPos(int pos)
  1135. {
  1136.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1137.     int                   count = fep->pref_lang_count;
  1138.  
  1139.     if (pos >= count) return;
  1140.  
  1141.     if (pos == OUTLINER_INIT_POS) {
  1142.         XtVaSetValues(fep->delete_button, XmNsensitive, False, NULL);
  1143.         XtVaSetValues(fep->up_button, XmNsensitive, False, NULL);
  1144.         XtVaSetValues(fep->down_button, XmNsensitive, False, NULL);
  1145.     }
  1146.     else {
  1147.         fep->lang_outliner->selectItemExclusive(pos);
  1148.         XtVaSetValues(fep->delete_button, XmNsensitive, (count != 0), NULL);
  1149.         XtVaSetValues(fep->up_button, XmNsensitive, (pos != 0), NULL);
  1150.         XtVaSetValues(fep->down_button, XmNsensitive, (pos != (count-1)), NULL);
  1151.     }
  1152. }
  1153.  
  1154. // Member:       deselelctionPos
  1155. // Description:  
  1156. // Inputs:
  1157. // Side effects: 
  1158.  
  1159. void XFE_PrefsPageBrowserLang::deselectPos(int pos)
  1160. {
  1161.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1162.     int                   count = fep->pref_lang_count;
  1163.  
  1164.     if (pos >= count) return;
  1165.  
  1166.     fep->lang_outliner->deselectItem(pos);
  1167. }
  1168.  
  1169. // Member:       getData
  1170. // Description:  
  1171. // Inputs:
  1172. // Side effects: 
  1173.  
  1174. PrefsDataBrowserLang *XFE_PrefsPageBrowserLang::getData()
  1175. {
  1176.     return m_prefsDataBrowserLang;
  1177. }
  1178.  
  1179. // Member:       cb_add
  1180. // Description:  
  1181. // Inputs:
  1182. // Side effects: 
  1183.  
  1184. void XFE_PrefsPageBrowserLang::cb_add(Widget    /* widget */,
  1185.                                       XtPointer closure,
  1186.                                       XtPointer /* call_data */)
  1187. {
  1188.     XFE_PrefsPageBrowserLang *thePage = (XFE_PrefsPageBrowserLang *)closure;
  1189.     XFE_PrefsDialog          *theDialog = thePage->getPrefsDialog();
  1190.     Widget                    mainw = theDialog->getBaseWidget();
  1191.  
  1192.     // Instantiate a language dialog
  1193.  
  1194.     XFE_PrefsLangDialog *theLangDialog = 0;
  1195.  
  1196.     if ((theLangDialog =
  1197.          new XFE_PrefsLangDialog(theDialog, thePage, mainw, "prefsLang")) == 0) {
  1198.         fe_perror(thePage->getContext(), XP_GetString(XFE_OUT_OF_MEMORY_URL));
  1199.         return;
  1200.     }
  1201.  
  1202.     // Initialize and pop up the lang dialog
  1203.  
  1204.     theLangDialog->initPage();
  1205.     theLangDialog->show();
  1206. }
  1207.  
  1208. // Member:       cb_delete
  1209. // Description:  
  1210. // Inputs:
  1211. // Side effects: 
  1212.  
  1213. void XFE_PrefsPageBrowserLang::cb_delete(Widget    /* widget */,
  1214.                                          XtPointer closure,
  1215.                                          XtPointer /* call_data */)
  1216. {
  1217.     XFE_PrefsPageBrowserLang *thePage = (XFE_PrefsPageBrowserLang *)closure;
  1218.     PrefsDataBrowserLang     *fep = thePage->getData();
  1219.     int                       count = fep->pref_lang_count;
  1220.     int                       pos = 0;
  1221.     uint32                    sel_count = 0;
  1222.     const int                *indices = 0;
  1223.  
  1224.     if (count == 0) return;
  1225.  
  1226.     fep->lang_outliner->getSelection(&indices, (int *) &sel_count);
  1227.     if (sel_count > 0 && indices) {
  1228.         pos = indices[0];
  1229.         thePage->deleteLangAtPos(pos);
  1230.     }
  1231. }
  1232.  
  1233. // Member:       cb_promote
  1234. // Description:  
  1235. // Inputs:
  1236. // Side effects: 
  1237.  
  1238. void XFE_PrefsPageBrowserLang::cb_promote(Widget    /* widget */,
  1239.                                           XtPointer closure,
  1240.                                           XtPointer /* call_data */)
  1241. {
  1242.     XFE_PrefsPageBrowserLang *thePage = (XFE_PrefsPageBrowserLang *)closure;
  1243.     PrefsDataBrowserLang     *fep = thePage->getData();
  1244.     int                       count = fep->pref_lang_count;
  1245.     int                       pos = 0;
  1246.     uint32                    sel_count = 0;
  1247.     const int                *indices = 0;
  1248.  
  1249.     if (count == 0) return;
  1250.  
  1251.     fep->lang_outliner->getSelection(&indices, (int *) &sel_count);
  1252.     if (sel_count > 0 && indices) {
  1253.         pos = indices[0];
  1254.         if (pos != 0) {
  1255.             thePage->deselectPos(pos);
  1256.             thePage->swapLangs(pos, pos-1, pos-1);
  1257.         }
  1258.     }
  1259. }
  1260.  
  1261. // Member:       cb_demote
  1262. // Description:  
  1263. // Inputs:
  1264. // Side effects: 
  1265.  
  1266. void XFE_PrefsPageBrowserLang::cb_demote(Widget    /* widget */,
  1267.                                          XtPointer closure,
  1268.                                          XtPointer /* call_data */)
  1269. {
  1270.     XFE_PrefsPageBrowserLang *thePage = (XFE_PrefsPageBrowserLang *)closure;
  1271.     PrefsDataBrowserLang     *fep = thePage->getData();
  1272.     int                       count = fep->pref_lang_count;
  1273.     int                       pos = 0;
  1274.     uint32                    sel_count = 0;
  1275.     const int                *indices = 0;
  1276.  
  1277.     if (count == 0) return;
  1278.  
  1279.     fep->lang_outliner->getSelection(&indices, (int *) &sel_count);
  1280.     if (sel_count > 0 && indices) {
  1281.         pos = indices[0];
  1282.         if (pos != (count-1)) {
  1283.             thePage->deselectPos(pos);
  1284.             thePage->swapLangs(pos, pos+1, pos+1);
  1285.         }
  1286.     }
  1287. }
  1288.  
  1289. /* Outlinable interface methods */
  1290.  
  1291. void *XFE_PrefsPageBrowserLang::ConvFromIndex(int /* index */)
  1292. {
  1293.     return (void *)NULL;
  1294. }
  1295.  
  1296. int XFE_PrefsPageBrowserLang::ConvToIndex(void * /* item */)
  1297. {
  1298.     return 0;
  1299. }
  1300.  
  1301. char*XFE_PrefsPageBrowserLang::getColumnName(int column)
  1302. {
  1303.     switch (column){
  1304.     case OUTLINER_COLUMN_ORDER:
  1305.         return STRING_COL_ORDER;
  1306.     case OUTLINER_COLUMN_LANG:
  1307.         return STRING_COL_LANG;
  1308.     default:
  1309.         XP_ASSERT(0); 
  1310.         return 0;
  1311.     }
  1312. }
  1313.  
  1314. char *XFE_PrefsPageBrowserLang::getColumnHeaderText(int column)
  1315. {
  1316.   switch (column) 
  1317.     {
  1318.     case OUTLINER_COLUMN_ORDER:
  1319.       return XP_GetString(XFE_LANG_COL_ORDER);
  1320.     case OUTLINER_COLUMN_LANG:
  1321.       return XP_GetString(XFE_LANG_COL_LANG);
  1322.     default:
  1323.       XP_ASSERT(0);
  1324.       return 0;
  1325.     }
  1326. }
  1327.  
  1328. fe_icon *XFE_PrefsPageBrowserLang::getColumnHeaderIcon(int /* column */)
  1329. {
  1330.     return 0;
  1331.  
  1332. }
  1333.  
  1334. EOutlinerTextStyle XFE_PrefsPageBrowserLang::getColumnHeaderStyle(int /* column */)
  1335. {
  1336.     return OUTLINER_Default;
  1337. }
  1338.  
  1339. // This method acquires one line of data.
  1340. void *XFE_PrefsPageBrowserLang::acquireLineData(int line)
  1341. {
  1342.     m_rowIndex = line;
  1343.     return (void *)1;
  1344. }
  1345.  
  1346. void XFE_PrefsPageBrowserLang::getTreeInfo(Boolean * /* expandable */,
  1347.                                            Boolean * /* is_expanded */,
  1348.                                            int     * /* depth */,
  1349.                                            OutlinerAncestorInfo ** /* ancestor */)
  1350. {
  1351.     // No-op
  1352. }
  1353.  
  1354.  
  1355. EOutlinerTextStyle XFE_PrefsPageBrowserLang::getColumnStyle(int /*column*/)
  1356. {
  1357.     return OUTLINER_Default;
  1358. }
  1359.  
  1360. char *XFE_PrefsPageBrowserLang::getColumnText(int column)
  1361.     PrefsDataBrowserLang *fep = m_prefsDataBrowserLang;
  1362.     static char           line[OUTLINER_COLUMN_MAX_LENGTH+1];
  1363.  
  1364.     *line = 0;
  1365.  
  1366.     // if (m_rowIndex >= fep->pref_lang_count) return line;
  1367.  
  1368.     switch (column) {
  1369.     case OUTLINER_COLUMN_ORDER:
  1370.         sprintf(line, "%d", m_rowIndex+1); 
  1371.         break;
  1372.  
  1373.     case OUTLINER_COLUMN_LANG:
  1374.         sprintf(line, "%s", fep->pref_lang_regs[m_rowIndex]);
  1375.         break;
  1376.  
  1377.     default:
  1378.         break;
  1379.     }
  1380.  
  1381.     return line;
  1382. }
  1383.  
  1384. fe_icon *XFE_PrefsPageBrowserLang::getColumnIcon(int /* column */)
  1385. {
  1386.     return 0;
  1387. }
  1388.  
  1389. void XFE_PrefsPageBrowserLang::releaseLineData()
  1390. {
  1391.     // No-op
  1392. }
  1393.  
  1394. void XFE_PrefsPageBrowserLang::Buttonfunc(const OutlineButtonFuncData *data)
  1395. {
  1396.     int row = data->row;
  1397.  
  1398.     if (row < 0) {
  1399.         // header
  1400.         return;
  1401.     } 
  1402.  
  1403.     setSelectionPos(data->row);
  1404. }
  1405.  
  1406. void XFE_PrefsPageBrowserLang::Flippyfunc(const OutlineFlippyFuncData * /* data */)
  1407. {
  1408.     // No-op
  1409. }
  1410.  
  1411. XFE_Outliner *XFE_PrefsPageBrowserLang::getOutliner()
  1412. {
  1413.     return m_prefsDataBrowserLang->lang_outliner;
  1414. }
  1415.  
  1416. // ************************************************************************
  1417. // *************************         Misc         *************************
  1418. // ************************************************************************
  1419.  
  1420. /*
  1421.  * Get the tag part from a string
  1422.  * The tag is bracketed by '[' and ']'
  1423.  * and has no white space.
  1424.  *
  1425.  * Returns a pointer to the start of the tag.
  1426.  * also returns the tag length.
  1427.  *
  1428.  * Any error return NULL
  1429.  */
  1430. static char *
  1431. fe_lang_reg_get_tag(char *tag, int *len_p)
  1432. {
  1433.     char *q1, *q2;
  1434.  
  1435.   /* init the returned tag length */
  1436.     *len_p = 0;
  1437.  
  1438.     /* bstell: need to fix this to use Istrchr */
  1439.     /* use INTL_DefaultWinCharSetID to get the csid */
  1440.     /* (really need to store the csid of the list in preferences) */
  1441.     /* tag must start with '[' */
  1442.     q1 = strchr(tag, '[');
  1443.     if (q1 == NULL)
  1444.         return NULL;
  1445.     q1 += 1; /* point past the '[' */
  1446.  
  1447.     /* tag must end with ']' */
  1448.     q2 = strchr(q1, ']');
  1449.     if (q2 == NULL)
  1450.         return NULL;
  1451.  
  1452.   /* check length of tag (stop on any white-space) */
  1453.     *len_p = strcspn(q1, "] \t\n");
  1454.     if (*len_p < 1) /* need some text */
  1455.         return NULL;
  1456.  
  1457.     if (*len_p != (q2-q1)) {
  1458.         *len_p = 0;
  1459.         return NULL;
  1460.     }
  1461.  
  1462.     return q1;
  1463. }
  1464.  
  1465. static const char *accept_lang_seperator = ", ";
  1466. /*
  1467.  * Convert an array of strings
  1468.  * to HTTP Accept-Language string
  1469.  *
  1470.  *  returns a string built up from the array
  1471.  *
  1472.  * The caller must free the array
  1473.  */
  1474. static char *array_to_acceptLang(char **array, int cnt)
  1475. {
  1476.     char *al_string, *p, *q;
  1477.     int i, str_len, tag_len;
  1478.  
  1479.     /*
  1480.      * Handle an empty array
  1481.      */
  1482.     if (cnt == 0) {
  1483.         return NULL;
  1484.     }
  1485.  
  1486.     /*
  1487.    * Get the maximum possible length of the result
  1488.    */
  1489.     str_len = 0;
  1490.     for (i=0; i<cnt; i++) {
  1491.         if (i != 0)
  1492.             str_len += strlen(accept_lang_seperator);
  1493.         str_len += strlen(array[i]);
  1494.     }
  1495.     str_len += 1; /* space for the terminator */
  1496.     al_string = (char *)XP_ALLOC(str_len);
  1497.  
  1498.     /*
  1499.    * build up the tag from the parts
  1500.    */
  1501.     for (p=al_string, i=0; i<cnt; i++) {
  1502.         /*
  1503.          * Validity check this string
  1504.          */
  1505.         q = fe_lang_reg_get_tag(array[i], &tag_len);
  1506.         if (q == NULL)
  1507.             continue;
  1508.  
  1509.         /*
  1510.          * Add this tag part to the tag
  1511.          */
  1512.         if (i != 0) {
  1513.             strcpy(p, accept_lang_seperator);
  1514.             p += strlen(accept_lang_seperator);
  1515.         }
  1516.         strncpy(p, q, tag_len);
  1517.         p += tag_len;
  1518.         *p = '\0';
  1519.     }
  1520.  
  1521.     return al_string;
  1522. }
  1523.  
  1524.