Files
Mozilla/mozilla/cmd/xfe/src/PrefsLang.cpp
ltabb 8ed5afe62c Free the lizard
git-svn-id: svn://10.0.0.236/trunk@10 18797224-902f-48f8-a5cc-f745e15eee43
1998-03-28 02:44:41 +00:00

525 lines
13 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
PrefsLang.cpp -- The language dialog for preference, packaged from 3.0 code
*/
#include "felocale.h"
#include "structs.h"
#include "fonts.h"
#include "xpassert.h"
#include "xfe.h"
#include "e_kit.h"
#include "PrefsLang.h"
#include <Xm/ArrowBG.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/ScrolledW.h>
#include <Xm/ToggleB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/TextF.h>
#include <Xm/ToggleBG.h>
#include <Xfe/Xfe.h>
extern int XFE_ERROR_SAVING_OPTIONS;
extern "C"
{
char *XP_GetString(int i);
static int multiline_str_to_array(const char *string, char ***array_p);
static int multiline_pref_to_array(const char *string, char ***array_p);
}
// ==================== Public Member Functions ====================
// Member: XFE_PrefsLangDialog
// Description: Constructor
// Inputs:
// Side effects: Creates the More dialog for Mail Server Preferences
XFE_PrefsLangDialog::XFE_PrefsLangDialog(XFE_PrefsDialog *prefsDialog,
XFE_PrefsPageBrowserLang *langPage,
Widget parent, // dialog parent
char *name, // dialog name
Boolean modal) // modal dialog?
: XFE_Dialog(parent,
name,
TRUE, // ok
TRUE, // cancel
FALSE, // help
FALSE, // apply
FALSE, // separator
modal // modal
),
m_prefsDialog(prefsDialog),
m_langPage(langPage),
m_prefsDataLang(0)
{
PrefsDataLang *fep = NULL;
fep = new PrefsDataLang;
memset(fep, 0, sizeof(PrefsDataLang));
m_prefsDataLang = fep;
fep->avail_cnt = multiline_pref_to_array(fe_globalData.language_region_list,
&fep->avail_lang_regs);
Widget kids[100];
Arg av[50];
int ac;
int i;
Widget form;
form = XtVaCreateWidget("form", xmFormWidgetClass, m_chrome,
XmNmarginWidth, 8,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
XtManageChild (form);
Widget lang_label;
Widget lang_list;
Widget other_label;
Widget other_text;
ac = 0;
i = 0;
kids[i++] = lang_label =
XmCreateLabelGadget(form, "langLabel", av, ac);
lang_list = XmCreateScrolledList(form, "langList", av, ac);
XtManageChild(lang_list);
kids[i++] = XtParent(lang_list);
kids[i++] = other_label =
XmCreateLabelGadget(form, "otherLabel", av, ac);
kids[i++] = other_text =
fe_CreateTextField(form, "otherText", av, ac);
XtVaSetValues(lang_label,
XmNalignment, XmALIGNMENT_BEGINNING,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_NONE,
XmNbottomAttachment, XmATTACH_NONE,
NULL);
XtVaSetValues(XtParent(lang_list),
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, lang_label,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_NONE,
XmNbottomAttachment, XmATTACH_NONE,
NULL);
int labels_height;
labels_height = XfeVaGetTallestWidget(other_label,
other_text,
NULL);
XtVaSetValues(other_label,
XmNheight, labels_height,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, XtParent(lang_list),
XmNtopOffset, 8,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_NONE,
XmNbottomAttachment, XmATTACH_NONE,
NULL);
XtVaSetValues(other_text,
XmNcolumns, 35,
XmNheight, labels_height,
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNtopWidget, other_label,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, other_label,
XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNrightWidget, XtParent(lang_list),
XmNbottomAttachment, XmATTACH_NONE,
NULL);
fep->lang_list = lang_list;
fep->other_text = other_text;
// Add callbacks
XtAddCallback(m_chrome, XmNokCallback, cb_ok, this);
XtAddCallback(m_chrome, XmNcancelCallback, cb_cancel, this);
XtAddCallback(lang_list, XmNdefaultActionCallback, cb_ok, this);
XtAddCallback(other_text, XmNactivateCallback, cb_ok, this);
XtManageChildren(kids, i);
XtManageChild(form);
}
// Member: ~XFE_PrefsLangDialog
// Description: Destructor
// Inputs:
// Side effects:
XFE_PrefsLangDialog::~XFE_PrefsLangDialog()
{
XP_ASSERT(m_prefsDataLang);
PrefsDataLang *fep = m_prefsDataLang;
// Clean up
if (fep->avail_lang_regs != 0) {
for (int i = 0; i < fep->avail_cnt; i++) {
XP_FREE(fep->avail_lang_regs[i]);
}
XP_FREE(fep->avail_lang_regs);
}
delete m_prefsDataLang;
}
// Member: show
// Description: Pop up dialog
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::show()
{
// TODO: Initialize the dialog
// Manage the top level
XFE_Dialog::show();
// Set focus to the OK button
XmProcessTraversal(m_okButton, XmTRAVERSE_CURRENT);
}
// Member: initPage
// Description: Initializes page for MailNewsLang
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::initPage()
{
XP_ASSERT(m_prefsDataLang);
PrefsDataLang *fep = m_prefsDataLang;
// Retrieve the list of available languages
char **avail_lang_regs = fep->avail_lang_regs;
int avail_cnt = fep->avail_cnt;
// Put the list into the available languages/regions list
XmStringTable str_list = NULL;
int i;
str_list = (XmStringTable)XP_ALLOC(sizeof (XmString) * avail_cnt+1);
for (i=0; i<avail_cnt; i++) {
str_list[i] = XmStringCreateLocalized(avail_lang_regs[i]);
}
XmListAddItemsUnselected(fep->lang_list, str_list, avail_cnt, 1);
for (i=0; i<avail_cnt; i++) {
XmStringFree(str_list[i]);
}
XP_FREE(str_list);
// we always want something selected in the language/region list if possible
if (avail_cnt > 0)
XmListSelectPos(fep->lang_list, 1, False);
}
// Member: verifyPage
// Description: verify page for MailNewsLang
// Inputs:
// Side effects:
Boolean XFE_PrefsLangDialog::verifyPage()
{
return TRUE;
}
// Member: getContext
// Description: returns context
// Inputs:
// Side effects:
MWContext *XFE_PrefsLangDialog::getContext()
{
return (m_prefsDialog->getContext());
}
// Member: getLangPage
// Description: returns the Languages prefs page
// Inputs:
// Side effects:
XFE_PrefsPageBrowserLang *XFE_PrefsLangDialog::getLangPage()
{
return m_langPage;
}
// Member: getPrefsDialog
// Description: returns preferences dialog
// Inputs:
// Side effects:
XFE_PrefsDialog *XFE_PrefsLangDialog::getPrefsDialog()
{
return (m_prefsDialog);
}
// Friend: prefsLangCb_ok
// Description:
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::cb_ok(Widget w,
XtPointer closure,
XtPointer callData)
{
XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
PrefsDataLang *fep = theDialog->m_prefsDataLang;
int *pos_list;
int pos_count;
char *value = 0;
value = fe_GetTextField(fep->other_text);
if (value && (XP_STRLEN(value) > 0)) {
XFE_PrefsPageBrowserLang *lang_page = theDialog->getLangPage();
lang_page->insertLang(value);
}
else if (XmListGetSelectedPos(fep->lang_list, &pos_list, &pos_count)) {
int pos = pos_list[0] - 1;
char *lang = fep->avail_lang_regs[pos];
XFE_PrefsPageBrowserLang *lang_page = theDialog->getLangPage();
lang_page->insertLang(lang);
XtFree((char *)pos_list);
}
if (value) XP_FREE(value);
// Simulate a cancel
theDialog->cb_cancel(w, closure, callData);
}
// Member: prefsLangCb_cancel
// Description:
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::cb_cancel(Widget /* w */,
XtPointer closure,
XtPointer /* callData */)
{
XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
XtRemoveCallback(theDialog->m_chrome, XmNokCallback, cb_ok, theDialog);
XtRemoveCallback(theDialog->m_chrome, XmNcancelCallback, cb_cancel, theDialog);
// Delete the dialog
delete theDialog;
}
// Member: prefsLangCb_focusOther
// Description:
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::cb_focusOther(Widget /* w */,
XtPointer closure,
XtPointer /* callData */)
{
XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
XFE_PrefsDialog *thePrefsDialog = theDialog->getPrefsDialog();
PrefsDataLang *fep = theDialog->m_prefsDataLang;
fep->temp_default_button = XmSelectionBoxGetChild(thePrefsDialog->getDialogChrome(),
XmDIALOG_DEFAULT_BUTTON);
XtVaSetValues(thePrefsDialog->getDialogChrome(), XmNdefaultButton, NULL, NULL);
}
// Member: prefsLangCb_loseFocusOther
// Description:
// Inputs:
// Side effects:
void XFE_PrefsLangDialog::cb_loseFocusOther(Widget /* w */,
XtPointer closure,
XtPointer /* callData */)
{
XFE_PrefsLangDialog *theDialog = (XFE_PrefsLangDialog *)closure;
XFE_PrefsDialog *thePrefsDialog = theDialog->getPrefsDialog();
PrefsDataLang *fep = theDialog->m_prefsDataLang;
if (fep->temp_default_button) {
XtVaSetValues(thePrefsDialog->getDialogChrome(),
XmNdefaultButton, fep->temp_default_button,
NULL);
}
}
// ==================== Private Functions ====================
/*
* This belongs in a utility module
*
* Convert a multiline string (embedded new-lines)
* to an array of strings
* create the array
* copies the lines into the array
* returns length of the array
*
* To free the array:
* for (i=0; i<cnt; i++)
* XP_FREE(array[i]);
* XP_FREE(array);
*/
static int multiline_str_to_array(const char *string, char ***array_p)
{
char *p, *q, **array;
int i, cnt, len;
Boolean at_start_of_line;
/* handle null string */
if (string == NULL) {
/* always allocate an array so the caller can free it */
array = (char **)XP_ALLOC(sizeof(char *));
array[0] = NULL;
*array_p = array;
return 0;
}
/*
* count the number of lines
* (count beginnings so we will count any last line without a '\n')
* This supports multibyte text only because '\n' is less than 0x40
*/
cnt = 0;
at_start_of_line = True;
for (p=(char *)string; *p; p++) {
if (at_start_of_line) {
cnt += 1;
at_start_of_line = False;
}
if (*p == '\n') {
at_start_of_line = True;
}
}
/* copy lines into the array */
array = (char **)XP_ALLOC((cnt+1) * sizeof(char *));
i = 0;
len = 0;
for (p=q=(char *)string; *p; p++) {
if (*p == '\n') {
array[i] = (char *)XP_ALLOC(len+1);
strncpy(array[i], q, len);
/* add a string terminator */
array[i][len] = '\0';
i += 1;
len = 0;
q = p + 1;
}
else
len += 1;
}
if (len) { /* include ending chars with no newline */
array[i] = (char *)XP_ALLOC(len+1);
strncpy(array[i], q, len);
/* add a string terminator */
array[i][len] = '\0';
}
*array_p = array;
return cnt;
}
/*
* This belongs in a utility module
*
* Convert a multiline preference (embedded new-lines)
* to an array of strings
* create the array
* copies the lines into the array
* remove leading/trailing white space
* remove blank lines
* returns length of the array
*
* To free the array:
* for (i=0; i<cnt; i++)
* XP_FREE(array[i]);
* XP_FREE(array);
*/
static int multiline_pref_to_array(const char *string, char ***array_p)
{
int i, j, cnt;
char **array;
/*
* Convert the multiline string to an array
* (with leading/trailing white space and blank lines)
*/
cnt = multiline_str_to_array(string, array_p);
/*
* trim any leading/training white space
*/
array = *array_p;
for (i=0; i<cnt; i++) {
char *tmp;
tmp = XP_StripLine(array[i]);
/* we can't lose the malloc address else free will fail */
/* so if there was white space at the beginning we make a copy */
if (tmp != array[i]) {
char *tmp2 = array[i];
array[i] = strdup(tmp);
XP_FREE(tmp2);
}
}
/*
* remove any blank lines
*/
for (i=0; i<cnt; i++) {
if (array[i][0] == '\0') {
XP_FREE(array[i]);
for (j=i+1; j<cnt; j++)
array[j-1] = array[j];
cnt -= 1;
}
}
return cnt;
}