Mozilla/mozilla/cmd/xfe/src/EditHdrDialog.cpp
dmose%mozilla.org 83e38c06cc updated license boilerplate to xPL v1.1
git-svn-id: svn://10.0.0.236/trunk@52594 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 22:43:10 +00:00

388 lines
11 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
EditHdrDialog.cpp -- add or remove arbitrary mail headers.
Created: Akkana Peck <akkana@netscape.com>, 19-Nov-97.
*/
#include "EditHdrDialog.h"
#include "xp_str.h"
#include "prefapi.h"
#include "xpgetstr.h"
#include <Xm/Form.h>
#include <Xm/List.h>
#include <Xm/RowColumn.h>
#include <Xm/LabelG.h>
#include <Xm/TextF.h>
#include <Xm/ToggleBG.h>
#include <Xm/PushBG.h>
// we need this in the post() method.
extern "C" void fe_EventLoop();
extern "C" char *
XFE_PromptWithCaption(MWContext *context, const char *caption,
const char *message, const char *deflt);
extern int XFE_CUSTOM_HEADER; // for XP_GetString
XFE_EditHdrDialog::XFE_EditHdrDialog(Widget parent, char *name,
MWContext* context)
: XFE_Dialog(parent,
name,
TRUE, // ok
TRUE, // cancel
FALSE, // help
FALSE, // apply
TRUE, // separator
TRUE // modal
)
{
m_contextData = context;
Widget form = XtCreateManagedWidget("dialogForm",
xmFormWidgetClass,
m_chrome,
NULL, 0);
Widget labl = XtVaCreateManagedWidget("editHdrLabel",
xmLabelGadgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
0);
Widget rc = XtVaCreateManagedWidget("buttonRC",
xmRowColumnWidgetClass, form,
XmNorientation, XmVERTICAL,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, labl,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
0);
Arg av[8];
int ac = 0;
// XtSetArg(av[ac], XmNvisibleItemCount, 6); ac++;
XtSetArg(av[ac], XmNselectionPolicy, XmEXTENDED_SELECT); ac++;
XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
XtSetArg(av[ac], XmNrightWidget, rc); ac++;
XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
XtSetArg(av[ac], XmNtopWidget, labl); ac++;
XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
m_list = XmCreateScrolledList(form, "hdrList", av, ac);
XtManageChild(m_list);
XtAddCallback(m_list, XmNdefaultActionCallback, butn_cb, this);
XtAddCallback(m_list, XmNextendedSelectionCallback, select_cb, this);
Widget butn = XtCreateManagedWidget("new",
xmPushButtonGadgetClass, rc,
NULL, 0);
XtAddCallback(butn, XmNactivateCallback, butn_cb, this);
m_editButton = XtCreateManagedWidget("edit",
xmPushButtonGadgetClass, rc,
NULL, 0);
XtAddCallback(m_editButton, XmNactivateCallback, butn_cb, this);
m_deleteButton = XtCreateManagedWidget("delete",
xmPushButtonGadgetClass, rc,
NULL, 0);
XtAddCallback(m_deleteButton, XmNactivateCallback, butn_cb, this);
// Edit and delete buttons aren't turned on until something is selected:
XtSetSensitive(m_editButton, FALSE);
XtSetSensitive(m_deleteButton, FALSE);
XtAddCallback(m_chrome, XmNokCallback, ok_cb, this);
XtAddCallback(m_chrome, XmNcancelCallback, cancel_cb, this);
}
XFE_EditHdrDialog::~XFE_EditHdrDialog()
{
// nothing needed (that I'm aware of) yet.
}
//
// It's not completely clear whether the string returned here should be
// freed or not. Currently we're not freeing it.
// The code eventually ends up in dialogs.c and it's not clear
// where the string is coming from.
// The only other place I can find where fe_prompt is used
// is in MNView.cpp, which also does not free the result.
//
char *
XFE_EditHdrDialog::promptHeader(char* oldhdr)
{
char* newhdr = XFE_PromptWithCaption(m_contextData,
"",
XP_GetString(XFE_CUSTOM_HEADER),
oldhdr);
return newhdr;
}
char*
XFE_EditHdrDialog::post()
{
m_doneWithLoop = False;
XtVaSetValues(m_chrome,
XmNdeleteResponse, XmUNMAP,
NULL);
// Get the current list of custom headers and show them in the list:
XmListDeleteAllItems(m_list);
int lengthOfHdrPref = 0;
PREF_GetCharPref("mailnews.customHeaders", 0, &lengthOfHdrPref);
if (lengthOfHdrPref > 0)
{
char* buf = new char [lengthOfHdrPref];
PREF_GetCharPref("mailnews.customHeaders", buf, &lengthOfHdrPref);
if (lengthOfHdrPref > 0)
{
char* sep = " ";
char* placeholder = 0;
char* next;
char* strtokbuf = buf;
while (next = XP_STRTOK_R(strtokbuf, sep, &placeholder))
{
strtokbuf = 0; // only want it for first XP_STRTOK_R call
while (isspace(*next))
++next;
XmString item = XmStringCreateSimple(next);
XmListAddItem(m_list, item, 0);
XmStringFree(item);
}
}
}
show();
while(!m_doneWithLoop)
fe_EventLoop();
if (!m_retVal)
return 0;
// User hit OK, so return the currently selected header:
int* posList = 0;
int posCount = 0;
XmListGetSelectedPos(m_list, &posList, &posCount);
if (!posCount)
return 0;
int itemCount;
XmString* items;
char* hdr;
XtVaGetValues(m_list,
XmNitemCount, &itemCount,
XmNitems, &items,
0);
if (posList[0]-1 >= itemCount)
return 0;
XmStringGetLtoR(items[posList[0]-1], XmFONTLIST_DEFAULT_TAG, &hdr);
if (posList)
XtFree((char*)posList);
return hdr; // yes, this return value should be freed by the caller
}
void
XFE_EditHdrDialog::selection(XmListCallbackStruct* cbs)
{
if (cbs->selected_item_count > 0)
XtSetSensitive(m_deleteButton, TRUE);
else
XtSetSensitive(m_deleteButton, FALSE);
if (cbs->selected_item_count == 1)
XtSetSensitive(m_editButton, TRUE);
else
XtSetSensitive(m_editButton, FALSE);
}
//
// Handle new/edit/delete buttons and default action callback.
// w is the widget (button or list) which caused the callback.
//
void
XFE_EditHdrDialog::button(Widget w)
{
if (*(XtName(w)) == 'n') // New button
{
// bring up an empty new-header dialog
char* newhdr = promptHeader(0);
if (newhdr)
{
XmListDeselectAllItems(m_list);
XmString xmhdr = XmStringCreateSimple(newhdr);
XmListAddItem(m_list, xmhdr, 0);
XmListSelectPos(m_list, 0, FALSE);
XmStringFree(xmhdr);
// This should leave the new header selected, so turn on buttons:
XtSetSensitive(m_editButton, TRUE);
XtSetSensitive(m_deleteButton, TRUE);
}
return;
}
int* posList = 0;
int posCount = 0;
XmListGetSelectedPos(m_list, &posList, &posCount);
if (posCount <= 0 || posList == 0)
{
if (posList)
XtFree((char*)posList);
return;
}
if (w == m_deleteButton)
{
XmListDeletePositions(m_list, posList, posCount);
// Now nothing is selected, so turn off edit/delete buttons:
XtSetSensitive(m_editButton, FALSE);
XtSetSensitive(m_deleteButton, FALSE);
}
else if (w == m_list || w == m_editButton)
{
int whichitem = posList[0] - 1;
int itemCount;
XmString* items;
char* hdr;
XtVaGetValues(m_list,
XmNitemCount, &itemCount,
XmNitems, &items,
0);
XmStringGetLtoR(items[whichitem], XmFONTLIST_DEFAULT_TAG, &hdr);
if (hdr)
{
char* newhdr = promptHeader(hdr);
if (newhdr)
{
XmString xmhdr = XmStringCreateSimple(newhdr);
XmListReplaceItemsPos(m_list, &xmhdr, 1, posList[0]);
XmStringFree(xmhdr);
}
XtFree(hdr);
}
}
XtFree((char*)posList);
}
void
XFE_EditHdrDialog::ok()
{
m_doneWithLoop = True;
m_retVal = True;
// Save the current set of headers in the pref "mailnews.customHeaders":
XmString* items;
int itemCount;
XtVaGetValues(m_list,
XmNitemCount, &itemCount,
XmNitems, &items,
0);
// first, figure out how many chars we need to allocate:
int totalLength = 0;
int i;
for (i=0; i < itemCount; ++i)
{
char* next;
XmStringGetLtoR(items[i], XmFONTLIST_DEFAULT_TAG, &next);
if (next)
{
totalLength += XP_STRLEN(next) + 1;
XtFree(next);
}
}
char* buf = new char [totalLength];
buf[0] = '\0';
for (i=0; i < itemCount; ++i)
{
char* next;
XmStringGetLtoR(items[i], XmFONTLIST_DEFAULT_TAG, &next);
if (next)
{
if (i > 0)
XP_STRCAT(buf, " ");
XP_STRCAT(buf, next);
XtFree(next);
}
}
PREF_SetCharPref("mailnews.customHeaders", buf);
hide();
}
void
XFE_EditHdrDialog::cancel()
{
m_doneWithLoop = True;
m_retVal = False;
hide();
}
void
XFE_EditHdrDialog::ok_cb(Widget, XtPointer clientData, XtPointer)
{
XFE_EditHdrDialog *obj = (XFE_EditHdrDialog*)clientData;
obj->ok();
}
void
XFE_EditHdrDialog::cancel_cb(Widget, XtPointer clientData, XtPointer)
{
XFE_EditHdrDialog *obj = (XFE_EditHdrDialog*)clientData;
obj->cancel();
}
void
XFE_EditHdrDialog::butn_cb(Widget w, XtPointer clientData, XtPointer)
{
XFE_EditHdrDialog *obj = (XFE_EditHdrDialog*)clientData;
obj->button(w);
}
void
XFE_EditHdrDialog::select_cb(Widget, XtPointer clientData, XtPointer callData)
{
XFE_EditHdrDialog *obj = (XFE_EditHdrDialog*)clientData;
obj->selection((XmListCallbackStruct *)callData);
}