1998-03-28 02:44:41 +00:00
|
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
|
*
|
1999-11-02 22:43:10 +00:00
|
|
|
|
* 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/
|
1998-03-28 02:44:41 +00:00
|
|
|
|
*
|
1999-11-02 22:43:10 +00:00
|
|
|
|
* 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.
|
1998-03-28 02:44:41 +00:00
|
|
|
|
*
|
1999-11-02 22:43:10 +00:00
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-03-28 02:44:41 +00:00
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-02 22:43:10 +00:00
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
|
* Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
1998-03-28 02:44:41 +00:00
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
dialogs.c --- General UI functions used elsewhere.
|
|
|
|
|
Created: Jamie Zawinski <jwz@netscape.com>, 23-Jun-94.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* #define DOCINFO_SOURCE_TEXT */
|
|
|
|
|
#define DOCINFO_VISUAL_TEXT
|
|
|
|
|
|
|
|
|
|
#include "mozilla.h"
|
|
|
|
|
#include "net.h" /* for fe_makeSecureTitle */
|
|
|
|
|
#include "xlate.h"
|
|
|
|
|
#include "xfe.h"
|
|
|
|
|
#include "felocale.h"
|
|
|
|
|
#include "outline.h"
|
|
|
|
|
#include "mailnews.h"
|
|
|
|
|
|
|
|
|
|
#include <Xm/FileSBP.h> /* for hacking FS lossage */
|
|
|
|
|
|
|
|
|
|
#include <Xm/XmAll.h>
|
|
|
|
|
#include <Xm/CascadeB.h>
|
|
|
|
|
|
|
|
|
|
#include <Xfe/XfeP.h> /* for xfe widgets and utilities */
|
|
|
|
|
|
|
|
|
|
#include "libi18n.h"
|
|
|
|
|
#include "intl_csi.h"
|
|
|
|
|
|
|
|
|
|
#include "np.h"
|
|
|
|
|
#include "xp_trace.h"
|
|
|
|
|
#include <layers.h>
|
|
|
|
|
#include "xeditor.h"
|
|
|
|
|
#include "xp_qsort.h"
|
|
|
|
|
|
|
|
|
|
/* for XP_GetString() */
|
|
|
|
|
#include <xpgetstr.h>
|
|
|
|
|
extern int XFE_OPEN_FILE;
|
|
|
|
|
extern int XFE_ERROR_OPENING_FILE;
|
1998-09-25 10:23:01 +00:00
|
|
|
|
extern int XFE_CANNOT_READ_FILE;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
extern int XFE_ERROR_OPENING_PIPE;
|
|
|
|
|
extern int XFE_NO_SUBJECT;
|
|
|
|
|
extern int XFE_UNKNOWN_ERROR_CODE;
|
|
|
|
|
extern int XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST;
|
|
|
|
|
extern int XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE;
|
|
|
|
|
extern int XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY;
|
|
|
|
|
extern int XFE_ERROR_SAVING_OPTIONS;
|
|
|
|
|
extern int XFE_X_RESOURCES_NOT_INSTALLED_CORRECTLY;
|
|
|
|
|
extern int XFE_OUTBOX_CONTAINS_MSG;
|
|
|
|
|
extern int XFE_OUTBOX_CONTAINS_MSGS;
|
|
|
|
|
extern int XFE_CONTINUE_MOVEMAIL;
|
|
|
|
|
extern int XFE_CANCEL_MOVEMAIL;
|
|
|
|
|
extern int XFE_MOVEMAIL_EXPLANATION;
|
|
|
|
|
extern int XFE_SHOW_NEXT_TIME;
|
|
|
|
|
extern int XFE_MAIL_SPOOL_UNKNOWN;
|
|
|
|
|
extern int XFE_CANT_SAVE_PREFS;
|
|
|
|
|
extern int XFE_JAVASCRIPT_APP;
|
|
|
|
|
extern int XFE_DIALOGS_PRINTING;
|
|
|
|
|
extern int XFE_DIALOGS_DEFAULT_VISUAL_AND_COLORMAP;
|
|
|
|
|
extern int XFE_DIALOGS_DEFAULT_VISUAL_AND_PRIVATE_COLORMAP;
|
|
|
|
|
extern int XFE_DIALOGS_NON_DEFAULT_VISUAL;
|
|
|
|
|
extern int XFE_DIALOGS_FROM_NETWORK;
|
|
|
|
|
extern int XFE_DIALOGS_FROM_DISK_CACHE;
|
|
|
|
|
extern int XFE_DIALOGS_FROM_MEMORY_CACHE;
|
|
|
|
|
extern int XFE_DIALOGS_DEFAULT;
|
|
|
|
|
|
|
|
|
|
#if XmVersion >= 2000
|
|
|
|
|
extern void _XmOSBuildFileList(String,String,unsigned char,String * *,
|
|
|
|
|
unsigned int *,unsigned int *);
|
|
|
|
|
|
|
|
|
|
extern char * _XmStringGetTextConcat(XmString);
|
|
|
|
|
|
|
|
|
|
extern int _XmOSFileCompare(XmConst void *,XmConst void *);
|
|
|
|
|
|
|
|
|
|
extern String _XmOSFindPatternPart(String);
|
|
|
|
|
|
|
|
|
|
extern void _XmOSQualifyFileSpec(String,String,String *,String *);
|
|
|
|
|
|
|
|
|
|
extern XmGeoMatrix _XmGeoMatrixAlloc(unsigned int,unsigned int,unsigned int);
|
|
|
|
|
|
|
|
|
|
extern Boolean _XmGeoSetupKid(XmKidGeometry,Widget);
|
|
|
|
|
|
|
|
|
|
extern void _XmMenuBarFix(XmGeoMatrix,int,XmGeoMajorLayout,XmKidGeometry);
|
|
|
|
|
|
|
|
|
|
extern void _XmSeparatorFix(XmGeoMatrix,int,XmGeoMajorLayout,XmKidGeometry);
|
|
|
|
|
|
|
|
|
|
extern void _XmDestroyParentCallback(Widget,XtPointer,XtPointer);
|
|
|
|
|
|
|
|
|
|
#endif /* XmVersion >= 2000 */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define DOCINFO_CHARSET_TEXT
|
|
|
|
|
|
|
|
|
|
/* Kludge around conflicts between Motif and xp_core.h... */
|
|
|
|
|
#undef Bool
|
|
|
|
|
#define Bool char
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
Answer_Invalid = -1,
|
|
|
|
|
Answer_Cancel = 0,
|
|
|
|
|
Answer_OK,
|
|
|
|
|
Answer_Apply,
|
|
|
|
|
Answer_Destroy } Answers;
|
|
|
|
|
|
|
|
|
|
struct fe_confirm_data {
|
|
|
|
|
MWContext *context;
|
|
|
|
|
Answers answer;
|
|
|
|
|
void *return_value;
|
|
|
|
|
void *return_value_2;
|
|
|
|
|
Widget widget;
|
|
|
|
|
Widget text, text2;
|
|
|
|
|
Boolean must_match;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
|
|
|
extern void fe_getMessageBody(MWContext *context, char **pBody, uint32 *body_size, MSG_FontCode **font_changes);
|
|
|
|
|
extern void fe_doneWithMessageBody(MWContext *context, char *pBody, uint32 body_size);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern const char* FE_GetFolderDirectory(MWContext* context);
|
|
|
|
|
|
|
|
|
|
/*static void fe_confirm_cb (Widget, XtPointer, XtPointer);*/
|
|
|
|
|
static void fe_clear_text_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_ok_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_apply_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_cancel_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_finish_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
|
|
|
|
|
static void fe_destroy_snarf_text_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_snarf_pw_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_destroy_snarf_pw2_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
|
|
|
|
|
void fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* A real Info dialog - with ! instead of error icon.
|
|
|
|
|
* Now we don't have to have "error: no new messages on server"
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
FE_Message(MWContext * context, const char* message)
|
|
|
|
|
{
|
|
|
|
|
if (context && context->type != MWContextBiff)
|
|
|
|
|
fe_Message(context, message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FE_Alert is no longer defined in fe_proto.h */
|
|
|
|
|
void
|
|
|
|
|
FE_Alert (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
if (context && context->type == MWContextBiff)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (context)
|
|
|
|
|
XFE_Alert (context, message);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Widget toplevel = FE_GetToplevelWidget();
|
|
|
|
|
if ( toplevel ) {
|
|
|
|
|
fe_Alert_2(toplevel, message);
|
|
|
|
|
} else {
|
|
|
|
|
/* So that didn't even work. Write to stdout and
|
|
|
|
|
* exit.
|
|
|
|
|
*/
|
|
|
|
|
XP_ABORT((message));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
/* Hack for 109371 */
|
|
|
|
|
void
|
|
|
|
|
FE_Alert_modal (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
if (context && context->type == MWContextBiff)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (context)
|
|
|
|
|
fe_Alert_modal(CONTEXT_WIDGET (context), message);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Widget toplevel = FE_GetToplevelWidget();
|
|
|
|
|
if ( toplevel ) {
|
|
|
|
|
fe_Alert_2(toplevel, message);
|
|
|
|
|
} else {
|
|
|
|
|
/* So that didn't even work. Write to stdout and
|
|
|
|
|
* exit.
|
|
|
|
|
*/
|
|
|
|
|
XP_ABORT((message));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
/* Lame hack to get the right title for javascript dialogs.
|
|
|
|
|
* This should be instead added to the call arguments.
|
|
|
|
|
*/
|
|
|
|
|
static MWContext *javaScriptCallingContextHack = 0;
|
|
|
|
|
|
|
|
|
|
/* Display a message, and wait for the user to click "Ok".
|
|
|
|
|
A pointer to the string is not retained.
|
|
|
|
|
The call to FE_Alert() returns immediately - it does not
|
|
|
|
|
wait for the user to click OK.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
XFE_Alert (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
/* Keep the context around, so we can pull the domain name
|
|
|
|
|
* full the dialog title.
|
|
|
|
|
*/
|
|
|
|
|
if (context->bJavaScriptCalling)
|
|
|
|
|
javaScriptCallingContextHack = context;
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
fe_Alert_2(CONTEXT_WIDGET (context), message);
|
1998-03-28 02:44:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Just like XFE_Alert, but with a different dialog title. */
|
|
|
|
|
void
|
|
|
|
|
fe_stderr (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
(void) fe_dialog (CONTEXT_WIDGET (context),
|
|
|
|
|
(fe_globalData.stderr_dialog_p &&
|
|
|
|
|
fe_globalData.stdout_dialog_p
|
|
|
|
|
? "stdout_stderr"
|
|
|
|
|
: fe_globalData.stderr_dialog_p ? "stderr"
|
|
|
|
|
: fe_globalData.stdout_dialog_p ? "stdout" : "???" ),
|
|
|
|
|
message, FALSE, 0, FALSE, FALSE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Let the user confirm or deny assertion `message' (returns True or False.)
|
|
|
|
|
A pointer to the prompt-string is not retained.
|
|
|
|
|
*/
|
|
|
|
|
XP_Bool
|
|
|
|
|
XFE_Confirm (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
return fe_Confirm_2 (CONTEXT_WIDGET (context), message);
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
/*
|
|
|
|
|
* Yet Another front end function that
|
|
|
|
|
* noone told us we were supposed to implement.
|
|
|
|
|
*/
|
|
|
|
|
PRBool
|
|
|
|
|
XP_Confirm(MWContext *c, const char *msg)
|
|
|
|
|
{
|
|
|
|
|
return XFE_Confirm(c,msg);
|
|
|
|
|
}
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
Boolean
|
|
|
|
|
fe_Confirm_2 (Widget parent, const char *message)
|
|
|
|
|
{
|
|
|
|
|
return (Bool) ((int) fe_dialog (parent, "question", message,
|
|
|
|
|
TRUE, 0, TRUE, FALSE, 0));
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
void
|
|
|
|
|
fe_Alert_modal (Widget parent, const char *message)
|
|
|
|
|
{
|
|
|
|
|
(void) fe_dialog (parent, "error", message, FALSE, 0, TRUE, FALSE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
void
|
|
|
|
|
fe_Alert_2 (Widget parent, const char *message)
|
|
|
|
|
{
|
|
|
|
|
(void) fe_dialog (parent, "error", message, FALSE, 0, FALSE, FALSE, 0);
|
|
|
|
|
}
|
|
|
|
|
|
1998-08-25 19:44:12 +00:00
|
|
|
|
#if !defined(HAVE_SYSERRLIST)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
#include <sys/errno.h>
|
|
|
|
|
extern char *sys_errlist[];
|
|
|
|
|
extern int sys_nerr;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Like perror, but with a dialog.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
fe_perror (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
fe_perror_2 (CONTEXT_WIDGET (context), message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_perror_2 (Widget parent, const char *message)
|
|
|
|
|
{
|
|
|
|
|
int e = errno;
|
|
|
|
|
char *es = 0;
|
|
|
|
|
char buf1 [2048];
|
|
|
|
|
char buf2 [512];
|
|
|
|
|
char *b = buf1;
|
|
|
|
|
if (e >= 0 && e < sys_nerr)
|
|
|
|
|
{
|
|
|
|
|
es = sys_errlist [e];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PR_snprintf (buf2, sizeof (buf2), XP_GetString( XFE_UNKNOWN_ERROR_CODE ),
|
|
|
|
|
errno);
|
|
|
|
|
es = buf2;
|
|
|
|
|
}
|
|
|
|
|
if (message)
|
|
|
|
|
PR_snprintf (buf1, sizeof (buf1), "%.900s\n%.900s", message, es);
|
|
|
|
|
else
|
|
|
|
|
b = buf2;
|
|
|
|
|
fe_Alert_2 (parent, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_UnmanageChild_safe (Widget w)
|
|
|
|
|
{
|
|
|
|
|
if (w) XtUnmanageChild (w);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_NukeBackingStore (Widget widget)
|
|
|
|
|
{
|
|
|
|
|
XSetWindowAttributes attrs;
|
|
|
|
|
unsigned long attrmask;
|
|
|
|
|
|
|
|
|
|
if (!XtIsTopLevelShell (widget))
|
|
|
|
|
widget = XtParent (widget);
|
|
|
|
|
XtRealizeWidget (widget);
|
|
|
|
|
|
|
|
|
|
attrmask = CWBackingStore | CWSaveUnder;
|
|
|
|
|
attrs.backing_store = NotUseful;
|
|
|
|
|
attrs.save_under = False;
|
|
|
|
|
XChangeWindowAttributes (XtDisplay (widget), XtWindow (widget),
|
|
|
|
|
attrmask, &attrs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Widget
|
|
|
|
|
|
|
|
|
|
#ifdef OSF1
|
|
|
|
|
fe_CreateTextField (Widget parent, char *name, Arg *av, int ac)
|
|
|
|
|
#else
|
|
|
|
|
fe_CreateTextField (Widget parent, const char *name, Arg *av, int ac)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
Widget w;
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
w = XmCreateTextField (parent, (char *) name, av, ac);
|
|
|
|
|
#else
|
|
|
|
|
XtSetArg (av[ac], XmNeditMode, XmSINGLE_LINE_EDIT); ac++;
|
|
|
|
|
w = XmCreateTextField (parent, (char *) name, av, ac);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
fe_HackTextTranslations (w);
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget
|
|
|
|
|
fe_CreateText (Widget parent, const char *name, Arg *av, int ac)
|
|
|
|
|
{
|
|
|
|
|
Widget w = XmCreateText (parent, (char *) name, av, ac);
|
|
|
|
|
fe_HackTextTranslations (w);
|
|
|
|
|
return w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_select_text(Widget text)
|
|
|
|
|
{
|
|
|
|
|
XmTextPosition first = 0;
|
|
|
|
|
XmTextPosition last = XmTextGetLastPosition (text);
|
|
|
|
|
XP_ASSERT (XtIsRealized(text));
|
|
|
|
|
XmTextSetSelection (text, first, last,
|
|
|
|
|
XtLastTimestampProcessed (XtDisplay (text)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The purpose of this function is try disable all grabs and settle
|
|
|
|
|
* focus issues. This will be called before we popup a dialog
|
|
|
|
|
* (modal or non-modal). This needs to do all these:
|
|
|
|
|
* - if a menu was posted, unpost it.
|
|
|
|
|
* - if a popup menu was up, pop it down.
|
|
|
|
|
* - if an option menu, pop it down.
|
|
|
|
|
*/
|
|
|
|
|
void fe_fixFocusAndGrab(MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
Widget focus_w;
|
|
|
|
|
Widget mainw;
|
|
|
|
|
XEvent event;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
mainw = CONTEXT_WIDGET(context);
|
|
|
|
|
focus_w = XmGetFocusWidget(mainw);
|
|
|
|
|
|
|
|
|
|
/* Unpost Menubar */
|
|
|
|
|
if (focus_w && XmIsCascadeButton(focus_w) &&
|
|
|
|
|
XmIsRowColumn(XtParent(focus_w))) {
|
|
|
|
|
/* 1. Found the menubar. Unpost it.
|
|
|
|
|
* To do that, we makeup a dummy event and use it with the
|
|
|
|
|
* CleanupMenuBar() action.
|
|
|
|
|
* WARNING: if focus_w was a XmCascadeButtonGadget we wont be able to
|
|
|
|
|
* do this.
|
|
|
|
|
*/
|
|
|
|
|
event.xany.type = 0;
|
|
|
|
|
event.xany.serial = 0;
|
|
|
|
|
event.xany.send_event = 0;
|
|
|
|
|
event.xany.display = fe_display;
|
|
|
|
|
event.xany.window = XtWindow(focus_w);
|
|
|
|
|
XtCallActionProc(focus_w, "CleanupMenuBar", &event, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Identify and Popdown any OptionMenu that was active */
|
|
|
|
|
if (focus_w && XmIsRowColumn(XtParent(focus_w))) {
|
|
|
|
|
unsigned char type;
|
|
|
|
|
Widget w;
|
|
|
|
|
XtVaGetValues(XtParent(focus_w), XmNrowColumnType, &type, 0);
|
|
|
|
|
if (type == XmMENU_OPTION) {
|
|
|
|
|
XtVaGetValues(focus_w, XmNsubMenuId, &w, 0);
|
|
|
|
|
if (w) XtUnmanageChild(w);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Identify and Popdown any popup menus that were active */
|
|
|
|
|
for (i=0; i < XfeNumPopups(mainw); i++) {
|
|
|
|
|
Widget popup = XfePopupListIndex(mainw,i);
|
|
|
|
|
if (XtIsShell(popup) && XmIsMenuShell(popup))
|
|
|
|
|
if (XfeShellIsPoppedUp(popup)) {
|
|
|
|
|
#ifdef DEBUG_dora
|
|
|
|
|
printf("popdown... name %s shell is popped up\n", XtName(popup));
|
|
|
|
|
#endif
|
|
|
|
|
XtPopdown(popup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *fe_makeSecureTitle( MWContext *context )
|
|
|
|
|
{
|
|
|
|
|
History_entry *h;
|
|
|
|
|
char *domain = 0;
|
|
|
|
|
char *title = 0;
|
|
|
|
|
|
|
|
|
|
if( !context )
|
|
|
|
|
{
|
|
|
|
|
return title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h = SHIST_GetCurrent (&context->hist);
|
|
|
|
|
|
|
|
|
|
if (!h || !h->address) return title;
|
|
|
|
|
|
|
|
|
|
domain = NET_ParseURL(h->address, GET_HOST_PART);
|
|
|
|
|
|
|
|
|
|
if (domain) {
|
|
|
|
|
title = PR_smprintf("%s - %s", domain, XP_GetString(XFE_JAVASCRIPT_APP));
|
|
|
|
|
XP_FREE(domain);
|
|
|
|
|
} else {
|
|
|
|
|
title = PR_smprintf("%s", XP_GetString(XFE_JAVASCRIPT_APP));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
fe_prompt (MWContext *context, Widget mainw,
|
|
|
|
|
const char *title, const char *message,
|
|
|
|
|
XP_Bool question_p, const char *default_text,
|
|
|
|
|
XP_Bool wait_p, XP_Bool select_p,
|
|
|
|
|
char **passwd)
|
|
|
|
|
{
|
|
|
|
|
/* Keep the context around, so we can pull the domain name
|
|
|
|
|
* full the dialog title.
|
|
|
|
|
*/
|
|
|
|
|
if (context->bJavaScriptCalling)
|
|
|
|
|
javaScriptCallingContextHack = context;
|
|
|
|
|
|
|
|
|
|
return fe_dialog(mainw, title, message, question_p,
|
|
|
|
|
default_text, wait_p, select_p, passwd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function is complete madness - it takes a billion flags
|
|
|
|
|
and does everything in the world because somehow I thought it would save
|
|
|
|
|
me a bunch of lines of code but it's just a MESS!
|
|
|
|
|
*/
|
|
|
|
|
void *
|
|
|
|
|
fe_dialog (Widget mainw,
|
|
|
|
|
const char *title, const char *message,
|
|
|
|
|
XP_Bool question_p, const char *default_text,
|
|
|
|
|
XP_Bool wait_p, XP_Bool select_p,
|
|
|
|
|
char **passwd)
|
|
|
|
|
{
|
|
|
|
|
Widget shell, dialog;
|
|
|
|
|
Widget text = 0, pwtext = 0;
|
|
|
|
|
XmString xm_message = 0;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
char title2 [255];
|
|
|
|
|
struct fe_MWContext_cons *cons;
|
|
|
|
|
int i;
|
|
|
|
|
char *javaScriptTitle = 0; /* dialog title when javascript calls */
|
|
|
|
|
XP_Bool javaScriptCalling = FALSE;
|
|
|
|
|
|
|
|
|
|
strcpy (title2, title);
|
|
|
|
|
strcat (title2, "_popup");
|
|
|
|
|
|
|
|
|
|
/* Use this global variable hackery to get the context */
|
|
|
|
|
if (javaScriptCallingContextHack) {
|
|
|
|
|
javaScriptTitle = fe_makeSecureTitle(javaScriptCallingContextHack);
|
|
|
|
|
javaScriptCallingContextHack = NULL;
|
|
|
|
|
javaScriptCalling = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mainw) {
|
|
|
|
|
/* Yikes. Well, this can happen if someone calls FE_Alert() on a biff
|
|
|
|
|
context or some other context without a window. We could ignore it,
|
|
|
|
|
but I think it better to try and put the dialog up *someplace*. So,
|
|
|
|
|
look for some context with a reasonable window. */
|
|
|
|
|
for (cons = fe_all_MWContexts ; cons && !mainw; cons = cons->next) {
|
|
|
|
|
mainw = CONTEXT_WIDGET(cons->context);
|
|
|
|
|
}
|
|
|
|
|
if (!mainw) return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(!XtIsWMShell(mainw) && (XtParent(mainw)!=0))
|
|
|
|
|
mainw = XtParent(mainw);
|
|
|
|
|
|
|
|
|
|
/* so, if the context that is popping up the dialog is hidden, we need
|
|
|
|
|
to pop it up _somewhere_, so we run down the list of contexts *again*,
|
|
|
|
|
and pop it up over one of them. This should work. I think. */
|
|
|
|
|
if (!XfeIsViewable(mainw))
|
|
|
|
|
{
|
|
|
|
|
Widget attempt = mainw;
|
|
|
|
|
/* instead of popping up the dialog at (0,0) pop it up over
|
|
|
|
|
the active context */
|
|
|
|
|
for (cons = fe_all_MWContexts ;
|
|
|
|
|
cons && !XfeIsViewable(attempt);
|
|
|
|
|
cons = cons->next)
|
|
|
|
|
{
|
|
|
|
|
attempt = CONTEXT_WIDGET(cons->context);
|
|
|
|
|
|
|
|
|
|
while(!XtIsWMShell(attempt) && (XtParent(attempt)!=0))
|
|
|
|
|
attempt = XtParent(attempt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* oh well, we tried. */
|
|
|
|
|
if (attempt)
|
|
|
|
|
mainw = attempt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If any dialog is already up we will cascade these dialogs. Thus this
|
|
|
|
|
* dialog will be the child of the last popped up dialog.
|
|
|
|
|
*/
|
|
|
|
|
i = XfeNumPopups(mainw);
|
|
|
|
|
while (i>0)
|
|
|
|
|
if (XmIsDialogShell(XfePopupListIndex(mainw,i-1)) &&
|
|
|
|
|
(XfeIsViewable(XfePopupListIndex(mainw,i-1)))) {
|
|
|
|
|
/* Got a new mainw */
|
|
|
|
|
Widget newmainw = XfePopupListIndex(mainw,i-1);
|
|
|
|
|
#ifdef DEBUG_dp
|
|
|
|
|
fprintf(stderr, "Using mainw: %s[%x] (%s[%x] num_popup=%d)\n",
|
|
|
|
|
XtName(newmainw), newmainw,
|
|
|
|
|
XtName(mainw), mainw, i);
|
|
|
|
|
#endif /* DEBUG_dp */
|
|
|
|
|
mainw = newmainw;
|
|
|
|
|
i = XfeNumPopups(mainw);
|
|
|
|
|
}
|
|
|
|
|
else i--;
|
|
|
|
|
|
|
|
|
|
/* Popdown any popup menu that was active. If not, this could get motif
|
|
|
|
|
* motif really confused as to who has focus as the new dialog that we
|
|
|
|
|
* are going to popup will undo a grab that the popup did without the
|
|
|
|
|
* popup's knowledge.
|
|
|
|
|
*/
|
|
|
|
|
for (cons = fe_all_MWContexts ; cons; cons = cons->next)
|
|
|
|
|
fe_fixFocusAndGrab(cons->context);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
shell = XmCreateDialogShell (mainw, title2, av, ac);
|
|
|
|
|
|
|
|
|
|
/* If it is java script that is posting this, use this special title */
|
|
|
|
|
if (javaScriptTitle) {
|
|
|
|
|
XtVaSetValues (shell, XmNtitle, javaScriptTitle, 0);
|
|
|
|
|
free(javaScriptTitle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
if (message)
|
|
|
|
|
xm_message = XmStringCreateLtoR ((char *) message,
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, (wait_p
|
|
|
|
|
? XmDIALOG_FULL_APPLICATION_MODAL
|
|
|
|
|
: XmDIALOG_MODELESS)); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType,
|
|
|
|
|
(default_text
|
|
|
|
|
? XmDIALOG_MESSAGE
|
|
|
|
|
: (question_p
|
|
|
|
|
? XmDIALOG_QUESTION
|
|
|
|
|
: (javaScriptCalling
|
|
|
|
|
? XmDIALOG_WARNING
|
|
|
|
|
: XmDIALOG_ERROR)))); ac++;
|
|
|
|
|
if (xm_message) XtSetArg (av[ac], XmNmessageString, xm_message), ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
dialog = XmCreateMessageBox (shell, "dialog", av, ac);
|
|
|
|
|
if (xm_message) XmStringFree (xm_message);
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XtNameToWidget (dialog, "*Help"));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (! question_p )
|
|
|
|
|
{
|
|
|
|
|
Widget cancel = 0;
|
|
|
|
|
XtVaGetValues (dialog, XmNcancelButton, &cancel, 0);
|
|
|
|
|
if (! cancel) abort ();
|
|
|
|
|
XtUnmanageChild (cancel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (default_text)
|
|
|
|
|
{
|
|
|
|
|
Widget clear;
|
|
|
|
|
Widget text_parent = dialog;
|
|
|
|
|
Widget ulabel = 0, plabel = 0;
|
|
|
|
|
|
|
|
|
|
text = 0;
|
|
|
|
|
pwtext = 0;
|
|
|
|
|
|
|
|
|
|
if (passwd && passwd != (char **) 1)
|
|
|
|
|
{
|
|
|
|
|
ac = 0;
|
|
|
|
|
text_parent = XmCreateForm (dialog, "dialogform", av, ac);
|
|
|
|
|
ulabel = XmCreateLabelGadget (text_parent, "userLabel", av, ac);
|
|
|
|
|
plabel = XmCreateLabelGadget (text_parent, "passwdLabel", av, ac);
|
|
|
|
|
XtVaSetValues (ulabel,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNbottomWidget, plabel,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNrightWidget, plabel,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (plabel,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (passwd != (char **) 1)
|
|
|
|
|
{
|
|
|
|
|
ac = 0;
|
|
|
|
|
text = fe_CreateTextField (text_parent, "text", av, ac);
|
|
|
|
|
fe_SetTextField(text, default_text);
|
|
|
|
|
XtVaSetValues (text, XmNcursorPosition, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (passwd)
|
|
|
|
|
{
|
|
|
|
|
ac = 0;
|
|
|
|
|
pwtext = fe_CreateTextField (text_parent, "pwtext", av, ac);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (text && pwtext)
|
|
|
|
|
{
|
|
|
|
|
if (fe_globalData.nonterminal_text_translations)
|
|
|
|
|
XtOverrideTranslations (text, fe_globalData.
|
|
|
|
|
nonterminal_text_translations);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNbottomWidget, pwtext,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, ulabel,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (pwtext,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, plabel,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtManageChild (ulabel);
|
|
|
|
|
XtManageChild (plabel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (text)
|
|
|
|
|
XtManageChild (text);
|
|
|
|
|
if (pwtext)
|
|
|
|
|
XtManageChild (pwtext);
|
|
|
|
|
|
|
|
|
|
if (text && pwtext)
|
|
|
|
|
XtManageChild (text_parent);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (text_parent, XmNinitialFocus, (text ? text : pwtext), 0);
|
|
|
|
|
XtVaSetValues (dialog, XmNinitialFocus, (text ? text : pwtext), 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
clear = XmCreatePushButtonGadget (dialog, "clear", av, ac);
|
|
|
|
|
if (pwtext)
|
|
|
|
|
XtAddCallback (clear, XmNactivateCallback, fe_clear_text_cb, pwtext);
|
|
|
|
|
if (text)
|
|
|
|
|
XtAddCallback (clear, XmNactivateCallback, fe_clear_text_cb, text);
|
|
|
|
|
XtManageChild (clear);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! wait_p)
|
|
|
|
|
{
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_cb, shell);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cb, shell);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
if (text && select_p)
|
|
|
|
|
fe_select_text (text);
|
|
|
|
|
return False;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
void *ret_val = 0;
|
|
|
|
|
|
|
|
|
|
/* data.context = context; */
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
data.widget = shell;
|
|
|
|
|
data.text = (text ? text : pwtext);
|
|
|
|
|
data.text2 = ((text && pwtext) ? pwtext : 0);
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
data.return_value_2 = 0;
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (shell, XmNdeleteResponse, XmDESTROY, 0);
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
if (text)
|
|
|
|
|
XtAddCallback (text, XmNdestroyCallback, fe_destroy_snarf_text_cb,
|
|
|
|
|
&data);
|
|
|
|
|
|
|
|
|
|
if (text && pwtext)
|
|
|
|
|
XtAddCallback (pwtext, XmNdestroyCallback, fe_destroy_snarf_pw2_cb,
|
|
|
|
|
&data);
|
|
|
|
|
else if (pwtext)
|
|
|
|
|
XtAddCallback (pwtext, XmNdestroyCallback, fe_destroy_snarf_pw_cb,
|
|
|
|
|
&data);
|
|
|
|
|
|
|
|
|
|
if (pwtext)
|
|
|
|
|
fe_SetupPasswdText (pwtext, 1024);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
if (text)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (text, XmNcursorPosition, 0, 0);
|
|
|
|
|
XtVaSetValues (text, XmNcursorPositionVisible, True, 0);
|
|
|
|
|
if (select_p)
|
|
|
|
|
fe_select_text (text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (default_text)
|
|
|
|
|
{
|
|
|
|
|
if (data.answer == Answer_OK) /* user clicked OK at the text */
|
|
|
|
|
{
|
|
|
|
|
if (text && pwtext)
|
|
|
|
|
{
|
|
|
|
|
if (!data.return_value || !data.return_value_2) abort ();
|
|
|
|
|
*passwd = data.return_value_2;
|
|
|
|
|
ret_val = data.return_value;
|
|
|
|
|
}
|
|
|
|
|
else if (text || pwtext)
|
|
|
|
|
{
|
|
|
|
|
if (! data.return_value) abort ();
|
|
|
|
|
ret_val = data.return_value;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
else /* user clicked cancel */
|
|
|
|
|
{
|
|
|
|
|
if (data.return_value)
|
|
|
|
|
free (data.return_value);
|
|
|
|
|
if (data.return_value_2)
|
|
|
|
|
free (data.return_value_2);
|
|
|
|
|
ret_val = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret_val = (data.answer == Answer_OK
|
|
|
|
|
? (void *) True
|
|
|
|
|
: (void *) False);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We need to suck the values out of the widgets before destroying them.
|
|
|
|
|
*/
|
|
|
|
|
/* Ok, with the new way, it got destroyed by the callbacks on the
|
|
|
|
|
OK and Cancel buttons. */
|
|
|
|
|
/* XtDestroyWidget (shell); */
|
|
|
|
|
return ret_val;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_Message (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget shell, dialog;
|
|
|
|
|
XmString xm_message;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
shell = XmCreateDialogShell (mainw, "message_popup", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
xm_message = XmStringCreateLtoR ((char *) message, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_MESSAGE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNmessageString, xm_message); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
dialog = XmCreateMessageBox (shell, "message", av, ac);
|
|
|
|
|
XmStringFree (xm_message);
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XtNameToWidget (dialog, "*Help"));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Widget cancel = 0;
|
|
|
|
|
XtVaGetValues (dialog, XmNcancelButton, &cancel, 0);
|
|
|
|
|
if (! cancel) abort ();
|
|
|
|
|
XtUnmanageChild (cancel);
|
|
|
|
|
}
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_cb, shell);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cb, shell);
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_ok_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
data->answer = Answer_OK;
|
|
|
|
|
XtDestroyWidget(data->widget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_cancel_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
data->answer = Answer_Cancel;
|
|
|
|
|
XtDestroyWidget(data->widget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_apply_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
data->answer = Answer_Apply;
|
|
|
|
|
XtDestroyWidget(data->widget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_finish_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
if (data->answer == Answer_Invalid)
|
|
|
|
|
data->answer = Answer_Destroy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_snarf_text_cb (Widget widget, XtPointer closure,XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
Widget text = data->text;
|
|
|
|
|
if (text)
|
|
|
|
|
{
|
|
|
|
|
char *plaintext = 0;
|
|
|
|
|
data->return_value = 0;
|
|
|
|
|
plaintext = fe_GetTextField(text);
|
|
|
|
|
data->return_value = XP_STRDUP(plaintext ? plaintext : "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_snarf_pw_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
Widget text = data->text;
|
|
|
|
|
if (text)
|
|
|
|
|
data->return_value = fe_GetPasswdText (text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_snarf_pw2_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
Widget text = data->text2;
|
|
|
|
|
if (text)
|
|
|
|
|
data->return_value_2 = fe_GetPasswdText (text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Callback used by the clear button to nuke the contents of the text field. */
|
|
|
|
|
static void
|
|
|
|
|
fe_clear_text_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
Widget text = (Widget) closure;
|
|
|
|
|
fe_SetTextField (text, "");
|
|
|
|
|
/* Focus on the text widget after this, since otherwise you have to
|
|
|
|
|
click again. */
|
|
|
|
|
XmProcessTraversal (text, XmTRAVERSE_CURRENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* When we are not blocking waiting for a response to a dialog, this is used
|
|
|
|
|
by the buttons to make it get lost when no longer needed (the default would
|
|
|
|
|
otherwise be to merely unmanage it instead of destroying it.) */
|
|
|
|
|
static void
|
|
|
|
|
fe_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
Widget shell = XtParent (widget);
|
|
|
|
|
while (!XmIsDialogShell (shell))
|
|
|
|
|
shell = XtParent (shell);
|
|
|
|
|
XtDestroyWidget (shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create a XmString that will render in the given width or less. If
|
|
|
|
|
the given string is too big, then chop out stuff by clipping out the
|
|
|
|
|
center and replacing it with "...". */
|
|
|
|
|
XmString
|
|
|
|
|
fe_StringChopCreate(char* message, char* tag, XmFontList font_list,
|
|
|
|
|
int maxwidth)
|
|
|
|
|
{
|
|
|
|
|
XmString label = XmStringCreate ((char *) message, tag);
|
|
|
|
|
int string_width;
|
|
|
|
|
uint16 csid;
|
|
|
|
|
|
|
|
|
|
if (!font_list) return label;
|
|
|
|
|
|
|
|
|
|
string_width = XmStringWidth(font_list, label);
|
|
|
|
|
if (string_width >= maxwidth) {
|
|
|
|
|
/* The string is bigger than the label. Mid-truncate it. */
|
|
|
|
|
|
|
|
|
|
XmString try;
|
|
|
|
|
int length = 0;
|
|
|
|
|
int maxlength = XP_STRLEN(message);
|
|
|
|
|
char* text = XP_ALLOC(maxlength + 10);
|
|
|
|
|
if (!text) return label;
|
|
|
|
|
|
|
|
|
|
csid = INTL_CharSetNameToID(tag);
|
|
|
|
|
if (csid==CS_UNKNOWN) {
|
|
|
|
|
csid = INTL_CharSetNameToID(INTL_ResourceCharSet());
|
|
|
|
|
}
|
|
|
|
|
string_width = 0;
|
|
|
|
|
while (string_width < maxwidth && length < maxlength) {
|
|
|
|
|
length++;
|
|
|
|
|
INTL_MidTruncateString(csid, message, text, length);
|
|
|
|
|
try = XmStringCreate(text, tag);
|
|
|
|
|
if (!try) break;
|
|
|
|
|
string_width = XmStringWidth(font_list, try);
|
|
|
|
|
if (string_width >= maxwidth) {
|
|
|
|
|
XmStringFree(try);
|
|
|
|
|
} else {
|
|
|
|
|
XmStringFree(label);
|
|
|
|
|
label = try;
|
|
|
|
|
}
|
|
|
|
|
try = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free (text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return label;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dealing with field/value pairs.
|
|
|
|
|
|
|
|
|
|
This takes a "value" widget and an arbitrary number of "label" widgets.
|
|
|
|
|
It finds the widest label, and attaches the "value" widget to the left
|
|
|
|
|
edge of its parent with an offset such that it falls just beyond the
|
|
|
|
|
right edge of the widest label widget.
|
|
|
|
|
|
|
|
|
|
The argument list is expected to be NULL-terminated.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* #ifdef AIXV3 */
|
|
|
|
|
/* I don't understand - this seems not to be broken any more, and now
|
|
|
|
|
the "hack" way doesn't compile either. Did someone upgrade me?? */
|
|
|
|
|
/* # define BROKEN_VARARGS */
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
|
|
|
|
#ifdef BROKEN_VARARGS
|
|
|
|
|
/* Sorry, we can't be bothered to implement varargs correctly. */
|
|
|
|
|
# undef va_list
|
|
|
|
|
# undef va_start
|
|
|
|
|
# undef va_arg
|
|
|
|
|
# undef va_end
|
|
|
|
|
# define va_list int
|
|
|
|
|
# define va_start(list,first_arg) list = 0
|
|
|
|
|
# define va_arg(list, type) (++list, (type) (list == 1 ? varg0 : \
|
|
|
|
|
list == 2 ? varg1 : \
|
|
|
|
|
list == 3 ? varg2 : \
|
|
|
|
|
list == 4 ? varg3 : \
|
|
|
|
|
list == 5 ? varg4 : \
|
|
|
|
|
list == 6 ? varg5 : \
|
|
|
|
|
list == 7 ? varg6 : \
|
|
|
|
|
list == 8 ? varg7 : \
|
|
|
|
|
list == 9 ? varg8 : 0))
|
|
|
|
|
# define va_end(list)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
#ifdef BROKEN_VARARGS
|
|
|
|
|
fe_attach_field_to_labels (Widget value_field,
|
|
|
|
|
void *varg0, void *varg1, void *varg2, void *varg3,
|
|
|
|
|
void *varg4, void *varg5, void *varg6, void *varg7,
|
|
|
|
|
void *varg8)
|
|
|
|
|
#else
|
|
|
|
|
fe_attach_field_to_labels (Widget value_field, ...)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
va_list vargs;
|
|
|
|
|
Widget current;
|
|
|
|
|
Widget widest = 0;
|
|
|
|
|
Position left = 0;
|
|
|
|
|
long max_width = -1;
|
|
|
|
|
|
|
|
|
|
va_start (vargs, value_field);
|
|
|
|
|
while ((current = va_arg (vargs, Widget)))
|
|
|
|
|
{
|
|
|
|
|
Dimension width = 0;
|
|
|
|
|
Position left = 0;
|
|
|
|
|
Position right = 10;
|
|
|
|
|
|
|
|
|
|
#ifdef Motif_doesnt_suck
|
|
|
|
|
/* Getting the leftOffset of a Gadget may randomly dump core */
|
|
|
|
|
if (XmIsGadget (current))
|
|
|
|
|
abort ();
|
|
|
|
|
XtVaGetValues (current,
|
|
|
|
|
XmNwidth, &width,
|
|
|
|
|
XmNleftOffset, &left,
|
|
|
|
|
/* XmNrightOffset, &right,*/
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
width = XfeWidth(current);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
width += (left + right);
|
|
|
|
|
if (((long) width) > max_width)
|
|
|
|
|
{
|
|
|
|
|
widest = current;
|
|
|
|
|
max_width = (long) width;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
va_end (vargs);
|
|
|
|
|
|
|
|
|
|
if (! widest)
|
|
|
|
|
abort ();
|
|
|
|
|
#ifdef Motif_doesnt_suck
|
|
|
|
|
XtVaGetValues (value_field, XmNleftOffset, &left, 0);
|
|
|
|
|
#endif
|
|
|
|
|
XtVaSetValues (value_field,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftOffset, max_width + left,
|
|
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Files
|
|
|
|
|
*/
|
|
|
|
|
static XmString fe_file_selection_directory;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This code tried to make some minor improvements to the standard
|
|
|
|
|
* Motif 1.2* File Selection Box dialog. The code here attempts
|
|
|
|
|
* to use the existing Motif code for the bulk of the work, and to
|
|
|
|
|
* replace some parts of Motif's behavior with something simpler.
|
|
|
|
|
* I've also added some nice things conceptually lifted from the Mac
|
|
|
|
|
* file picker, and at the request of users. In hindsight it might
|
|
|
|
|
* have been easier to just write a new file picker widget, preferably
|
|
|
|
|
* one that is semantically compatible with the Motif widget. Next time.
|
|
|
|
|
*
|
|
|
|
|
* Anyway, this stuff is conditionally compiled. Most of this is
|
|
|
|
|
* controlled by the USE_WINNING_FILE_SELECTION define. When
|
|
|
|
|
* you turn this guy on, it enables a bunch of hacks to the standard
|
|
|
|
|
* Motif behavior. Best to take a look, but below is a snippet from
|
|
|
|
|
* the resource file. Note that some of the hacks (the simple layout
|
|
|
|
|
* hacks) require Motif source knowledge because they must attack the
|
|
|
|
|
* FSB class record directly. We've moved that code out (see the
|
|
|
|
|
* define FEATURE_MOTIF_FSB_CLASS_HACKING) because we can't make the
|
|
|
|
|
* Motif code public.
|
|
|
|
|
*
|
|
|
|
|
* Related to these hacks, but somewhat orthogonal to them, we try to
|
|
|
|
|
* save the last accessed directory. This makes life a little easier
|
|
|
|
|
* than always going back to (say) HOME.
|
|
|
|
|
*
|
|
|
|
|
* From the resource file:
|
|
|
|
|
*
|
|
|
|
|
* This resource enables some hacks to the File Selection Box
|
|
|
|
|
* which use a simpler layout algorithm than the standard Motif
|
|
|
|
|
* code. The directory and file listings are always maintained
|
|
|
|
|
* as equal size. We don't do this for SGI, as they have solved
|
|
|
|
|
* the problem. See *useEnhancedFSB above.
|
|
|
|
|
* @NOTSGI@*nsMotifFSBHacks: True
|
|
|
|
|
*
|
|
|
|
|
* This resource enables the CDE mode of the File Selection Box.
|
|
|
|
|
* You must be running a CDE enhanced Motif library for this
|
|
|
|
|
* option to work. This resource will apply pathMode=1 to the
|
|
|
|
|
* File Selection Box. If you specify nsMotifFSBHacks and
|
|
|
|
|
* nsMotifFSBCdeMode, some of the keyboard and filter enhancements
|
|
|
|
|
* of nsMotifFSBHacks will also be applied, the layout hacks will not.
|
|
|
|
|
* *nsMotifFSBCdeMode: False
|
|
|
|
|
*
|
|
|
|
|
* ...djw
|
|
|
|
|
*/
|
|
|
|
|
#ifdef USE_WINNING_FILE_SELECTION
|
|
|
|
|
|
|
|
|
|
#include <Xm/XmP.h>
|
|
|
|
|
#include <Xm/XmosP.h>
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_force_configure(Widget widget)
|
|
|
|
|
{
|
|
|
|
|
Dimension width = _XfeWidth(widget);
|
|
|
|
|
Dimension height = _XfeHeight(widget);
|
|
|
|
|
Dimension border_width = _XfeBorderWidth(widget);
|
|
|
|
|
|
|
|
|
|
_XfeHeight(widget) += 1;
|
|
|
|
|
XtResizeWidget(widget, width, height, border_width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_get_dir_entries(String directory, String pattern,
|
|
|
|
|
unsigned type,
|
|
|
|
|
String** file_list_r, unsigned int* nfiles_r)
|
|
|
|
|
{
|
|
|
|
|
unsigned int n;
|
|
|
|
|
unsigned len = strlen(directory);
|
|
|
|
|
|
|
|
|
|
*file_list_r = NULL;
|
|
|
|
|
#ifdef XM_GET_DIR_ENTRIES_OK
|
|
|
|
|
_XmOSGetDirEntries(directory, pattern, type, FALSE, FALSE,
|
|
|
|
|
file_list_r, nfiles_r, &n);
|
|
|
|
|
#else
|
|
|
|
|
_XmOSBuildFileList(directory, pattern, type,
|
|
|
|
|
file_list_r, nfiles_r, &n);
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < *nfiles_r; n++) {
|
|
|
|
|
String old_s = (*file_list_r)[n];
|
|
|
|
|
String new_s;
|
|
|
|
|
|
|
|
|
|
if (strncmp(directory, old_s, len) == 0) {
|
|
|
|
|
new_s = (String)XtNewString(&old_s[len]);
|
|
|
|
|
XtFree(old_s);
|
|
|
|
|
(*file_list_r)[n] = new_s;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_file_search_proc(Widget widget, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
XmFileSelectionBoxCallbackStruct* search_data
|
|
|
|
|
= (XmFileSelectionBoxCallbackStruct *)call_data;
|
|
|
|
|
String directory;
|
|
|
|
|
String pattern;
|
|
|
|
|
String* file_list;
|
|
|
|
|
unsigned int nfiles;
|
|
|
|
|
Arg args[10];
|
|
|
|
|
Cardinal n;
|
|
|
|
|
Cardinal nn;
|
|
|
|
|
XmString* xm_string_file_list;
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
|
|
|
|
|
if (!(directory = _XmStringGetTextConcat(search_data->dir))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(pattern = _XmStringGetTextConcat(search_data->pattern))) {
|
|
|
|
|
XtFree(directory);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* _XmOSGetDirEntries() is being really wierd! Use this guy
|
|
|
|
|
* instead..djw
|
|
|
|
|
*/
|
|
|
|
|
file_list = NULL;
|
|
|
|
|
fe_file_selection_get_dir_entries(directory, pattern, XmFILE_REGULAR,
|
|
|
|
|
&file_list, &nfiles);
|
|
|
|
|
|
|
|
|
|
for (n = 0, nn = 0; n < nfiles; n++) {
|
|
|
|
|
if (file_list[n][0] == '.') /* no more dot files ! */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
file_list[nn++] = file_list[n];
|
|
|
|
|
}
|
|
|
|
|
nfiles = nn;
|
|
|
|
|
|
|
|
|
|
if (nfiles != 0) {
|
|
|
|
|
if (nfiles > 1)
|
|
|
|
|
XP_QSORT((void *)file_list, nfiles, sizeof(char *), _XmOSFileCompare);
|
|
|
|
|
|
|
|
|
|
xm_string_file_list = (XmString*)XtMalloc(nfiles * sizeof(XmString));
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < nfiles; n++) {
|
|
|
|
|
xm_string_file_list[n] = XmStringLtoRCreate(file_list[n],
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
xm_string_file_list = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The Motif book says update the XmNdirectory */
|
|
|
|
|
xm_directory = XmStringLtoRCreate(directory, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
|
|
|
|
|
/* Update the list widget */
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args[n], XmNfileListItems, xm_string_file_list); n++;
|
|
|
|
|
XtSetArg(args[n], XmNfileListItemCount, nfiles); n++;
|
|
|
|
|
XtSetArg(args[n], XmNlistUpdated, TRUE); n++;
|
|
|
|
|
XtSetArg(args[n], XmNdirectory, xm_directory); n++;
|
|
|
|
|
#if 0
|
|
|
|
|
XtSetArg(args[n], XmNdirectoryValid, TRUE); n++;
|
|
|
|
|
#endif
|
|
|
|
|
XtSetValues(widget, args, n);
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
fe_force_configure(widget);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* And save directory default for next time */
|
|
|
|
|
if (fe_file_selection_directory)
|
|
|
|
|
XmStringFree(fe_file_selection_directory);
|
|
|
|
|
fe_file_selection_directory = xm_directory;
|
|
|
|
|
|
|
|
|
|
if (nfiles != 0) {
|
|
|
|
|
/*
|
|
|
|
|
* Cleanup.
|
|
|
|
|
*/
|
|
|
|
|
for (n = 0; n < nfiles; n++) {
|
|
|
|
|
XmStringFree(xm_string_file_list[n]);
|
|
|
|
|
XtFree(file_list[n]);
|
|
|
|
|
}
|
|
|
|
|
XtFree((char *)xm_string_file_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtFree((char *)directory);
|
|
|
|
|
XtFree((char *)pattern);
|
|
|
|
|
|
|
|
|
|
if (file_list)
|
|
|
|
|
XtFree((char *)file_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_dir_search_proc(Widget widget, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
XmFileSelectionBoxCallbackStruct* search_data
|
|
|
|
|
= (XmFileSelectionBoxCallbackStruct *)call_data;
|
|
|
|
|
String directory;
|
|
|
|
|
Arg args[10];
|
|
|
|
|
Cardinal n;
|
|
|
|
|
Cardinal m;
|
|
|
|
|
String * dir_list;
|
|
|
|
|
unsigned int ndirs;
|
|
|
|
|
unsigned int mdirs;
|
|
|
|
|
XmString * xm_string_dir_list;
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
int attempts;
|
|
|
|
|
char* p;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues(widget, XmNdirectory, &xm_directory, 0);
|
|
|
|
|
|
|
|
|
|
if (XmStringByteCompare(xm_directory, search_data->dir) == True) {
|
|
|
|
|
/* Update the list widget */
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args[n], XmNlistUpdated, FALSE); n++;
|
|
|
|
|
XtSetArg(args[n], XmNdirectoryValid, TRUE); n++;
|
|
|
|
|
XtSetValues(widget, args, n);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
directory = _XmStringGetTextConcat(search_data->dir);
|
|
|
|
|
|
|
|
|
|
ndirs = 0;
|
|
|
|
|
for (attempts = 0; ndirs == 0; attempts++) {
|
|
|
|
|
dir_list = NULL;
|
|
|
|
|
fe_file_selection_get_dir_entries(directory, "*", XmFILE_DIRECTORY,
|
|
|
|
|
&dir_list, &ndirs);
|
|
|
|
|
if (ndirs) {
|
|
|
|
|
if (attempts != 0) {
|
|
|
|
|
XmFileSelectionBoxCallbackStruct new_data;
|
|
|
|
|
XmQualifyProc q_proc;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Cleanup old stuff that won't be re-used.
|
|
|
|
|
*/
|
|
|
|
|
XmStringFree(search_data->dir);
|
|
|
|
|
if (search_data->mask)
|
|
|
|
|
XmStringFree(search_data->mask);
|
|
|
|
|
|
|
|
|
|
memset(&new_data, 0, sizeof(XmFileSelectionBoxCallbackStruct));
|
|
|
|
|
new_data.reason = search_data->reason;
|
|
|
|
|
new_data.event = search_data->event;
|
|
|
|
|
new_data.dir = XmStringLtoRCreate(directory,
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
new_data.dir_length = XmStringLength(new_data.dir);
|
|
|
|
|
new_data.pattern = search_data->pattern;
|
|
|
|
|
new_data.pattern_length = search_data->pattern_length;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Reset the spec, because we may get called 50M
|
|
|
|
|
* times if this broken state.
|
|
|
|
|
*/
|
|
|
|
|
XtVaSetValues(widget,
|
|
|
|
|
XmNdirectory, new_data.dir,
|
|
|
|
|
XmNdirSpec, new_data.dir,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Call qualify proc to install new directory
|
|
|
|
|
* into widget.
|
|
|
|
|
*/
|
|
|
|
|
XtVaGetValues(widget, XmNqualifySearchDataProc, &q_proc, 0);
|
|
|
|
|
(*q_proc)(widget, (XtPointer)&new_data,
|
|
|
|
|
(XtPointer)search_data);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (attempts == 0) {
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Unable to access directory:\n %.900s\n",
|
|
|
|
|
directory);
|
|
|
|
|
fprintf(stderr, buf);
|
|
|
|
|
#endif
|
|
|
|
|
XBell(XtDisplay(widget), 0); /* emulate Motif */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dir_list)
|
|
|
|
|
XtFree((char *) dir_list);
|
|
|
|
|
|
|
|
|
|
if (directory[0] == '\0' || strcmp(directory, "/") == 0)
|
|
|
|
|
return; /* I give in! */
|
|
|
|
|
|
|
|
|
|
while ((p = strrchr(directory, '/')) != NULL) {
|
|
|
|
|
if (p[1] == '\0') { /* "/" at end */
|
|
|
|
|
p[0] = '\0';
|
|
|
|
|
} else {
|
|
|
|
|
p[1] = '\0';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ndirs > 1)
|
|
|
|
|
XP_QSORT((void *)dir_list, ndirs, sizeof(char *), _XmOSFileCompare);
|
|
|
|
|
|
|
|
|
|
xm_string_dir_list = (XmString *)XtMalloc(ndirs * sizeof(XmString));
|
|
|
|
|
|
|
|
|
|
for (m = n = 0; n < ndirs; n++) {
|
|
|
|
|
if (strcmp(dir_list[n], ".") == 0) /* don't want that */
|
|
|
|
|
continue;
|
|
|
|
|
xm_string_dir_list[m++] = XmStringLtoRCreate(dir_list[n],
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
mdirs = m;
|
|
|
|
|
|
|
|
|
|
/* Update the list widget */
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args[n], XmNdirListItems, xm_string_dir_list); n++;
|
|
|
|
|
XtSetArg(args[n], XmNdirListItemCount, mdirs); n++;
|
|
|
|
|
XtSetArg(args[n], XmNlistUpdated, TRUE); n++;
|
|
|
|
|
XtSetArg(args[n], XmNdirectoryValid, TRUE); n++;
|
|
|
|
|
XtSetValues(widget, args, n);
|
|
|
|
|
|
|
|
|
|
/* And save directory default for next time */
|
|
|
|
|
xm_directory = XmStringLtoRCreate(directory, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
if (fe_file_selection_directory)
|
|
|
|
|
XmStringFree(fe_file_selection_directory);
|
|
|
|
|
fe_file_selection_directory = xm_directory;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Cleanup.
|
|
|
|
|
*/
|
|
|
|
|
for (n = 0; n < mdirs; n++) {
|
|
|
|
|
XmStringFree(xm_string_dir_list[n]);
|
|
|
|
|
}
|
|
|
|
|
for (n = 0; n < ndirs; n++) {
|
|
|
|
|
XtFree(dir_list[n]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtFree((char *)xm_string_dir_list);
|
|
|
|
|
XtFree((char *)directory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_qualify_search_data_proc(Widget widget,
|
|
|
|
|
XtPointer sd, XtPointer qsd)
|
|
|
|
|
{
|
|
|
|
|
XmFileSelectionBoxCallbackStruct* s_data
|
|
|
|
|
= (XmFileSelectionBoxCallbackStruct *)sd;
|
|
|
|
|
XmFileSelectionBoxCallbackStruct* qs_data
|
|
|
|
|
= (XmFileSelectionBoxCallbackStruct *)qsd;
|
|
|
|
|
String mask_string = _XmStringGetTextConcat(s_data->mask);
|
|
|
|
|
String dir_string = _XmStringGetTextConcat(s_data->dir);
|
|
|
|
|
String pattern_string = _XmStringGetTextConcat(s_data->pattern);
|
|
|
|
|
String dir_part = NULL;
|
|
|
|
|
String pattern_part = NULL;
|
|
|
|
|
String q_dir_string = NULL;
|
|
|
|
|
String q_mask_string = NULL;
|
|
|
|
|
String q_pattern_string = NULL;
|
|
|
|
|
String dir_free_string = NULL;
|
|
|
|
|
String pattern_free_string = NULL;
|
|
|
|
|
String p;
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
XmString xm_pattern;
|
|
|
|
|
XmString xm_dir_spec;
|
|
|
|
|
|
|
|
|
|
if (dir_string != NULL) {
|
|
|
|
|
if (dir_string[0] == '/') {
|
|
|
|
|
dir_part = dir_string;
|
|
|
|
|
} else {
|
|
|
|
|
XtVaGetValues(widget, XmNdirectory, &xm_directory, 0);
|
|
|
|
|
if (xm_directory != NULL) {
|
|
|
|
|
dir_part = _XmStringGetTextConcat(xm_directory);
|
|
|
|
|
p = (String)XtMalloc(strlen(dir_part) +
|
|
|
|
|
strlen(dir_string) + 2);
|
|
|
|
|
strcpy(p, dir_part);
|
|
|
|
|
strcat(p, dir_string);
|
|
|
|
|
XtFree(dir_string);
|
|
|
|
|
XtFree(dir_part);
|
|
|
|
|
dir_part = dir_string = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (mask_string != NULL) { /* use filter value */
|
|
|
|
|
pattern_part = _XmOSFindPatternPart(mask_string);
|
|
|
|
|
|
|
|
|
|
if (pattern_part != mask_string) {
|
|
|
|
|
pattern_part[-1] = '\0'; /* zap dir trailing '/' */
|
|
|
|
|
/* "" or "/" */
|
|
|
|
|
if (*mask_string == '\0') {
|
|
|
|
|
dir_part = "/";
|
|
|
|
|
} else if (*mask_string == '/' && mask_string[1] == '\0') {
|
|
|
|
|
dir_part = "//";
|
|
|
|
|
} else {
|
|
|
|
|
dir_part = mask_string;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else { /* use XmNdirectory */
|
|
|
|
|
XtVaGetValues(widget, XmNdirectory, &xm_directory, 0);
|
|
|
|
|
if (xm_directory != NULL) {
|
|
|
|
|
dir_part = _XmStringGetTextConcat(xm_directory);
|
|
|
|
|
dir_free_string = dir_part; /* to force free */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pattern_string != NULL) {
|
|
|
|
|
pattern_part = pattern_string;
|
|
|
|
|
} else {
|
|
|
|
|
if (mask_string != NULL) {
|
|
|
|
|
if (!pattern_part)
|
|
|
|
|
pattern_part = _XmOSFindPatternPart(mask_string);
|
|
|
|
|
} else {
|
|
|
|
|
XtVaGetValues(widget, XmNpattern, &xm_pattern, 0);
|
|
|
|
|
if (xm_pattern != NULL) {
|
|
|
|
|
pattern_part = _XmStringGetTextConcat(xm_pattern);
|
|
|
|
|
pattern_free_string = pattern_part; /* so it gets freed */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* It's ok for dir_part to be NULL, as _XmOSQualifyFileSpec
|
|
|
|
|
* will just use the cwd.
|
|
|
|
|
*/
|
|
|
|
|
_XmOSQualifyFileSpec(dir_part, pattern_part,
|
|
|
|
|
&q_dir_string, &q_pattern_string);
|
|
|
|
|
|
|
|
|
|
qs_data->reason = s_data->reason ;
|
|
|
|
|
qs_data->event = s_data->event ;
|
|
|
|
|
if (s_data->value) {
|
|
|
|
|
qs_data->value = XmStringCopy(s_data->value);
|
|
|
|
|
} else {
|
|
|
|
|
XtVaGetValues(widget, XmNdirSpec, &xm_dir_spec, 0);
|
|
|
|
|
qs_data->value = XmStringCopy(xm_dir_spec);
|
|
|
|
|
}
|
|
|
|
|
qs_data->length = XmStringLength(qs_data->value) ;
|
|
|
|
|
q_mask_string = (String)XtMalloc(strlen(q_dir_string) +
|
|
|
|
|
strlen(q_pattern_string) + 1);
|
|
|
|
|
strcpy(q_mask_string, q_dir_string);
|
|
|
|
|
strcat(q_mask_string, q_pattern_string);
|
|
|
|
|
qs_data->mask = XmStringLtoRCreate(q_mask_string, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
qs_data->mask_length = XmStringLength(qs_data->mask);
|
|
|
|
|
qs_data->dir = XmStringLtoRCreate(q_dir_string, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
qs_data->dir_length = XmStringLength(qs_data->dir) ;
|
|
|
|
|
qs_data->pattern = XmStringLtoRCreate(q_pattern_string,
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
qs_data->pattern_length = XmStringLength(qs_data->pattern);
|
|
|
|
|
|
|
|
|
|
if (dir_free_string)
|
|
|
|
|
XtFree(dir_free_string);
|
|
|
|
|
if (pattern_free_string)
|
|
|
|
|
XtFree(pattern_free_string);
|
|
|
|
|
if (dir_string)
|
|
|
|
|
XtFree(dir_string);
|
|
|
|
|
if (pattern_string)
|
|
|
|
|
XtFree(pattern_string);
|
|
|
|
|
if (mask_string)
|
|
|
|
|
XtFree(mask_string);
|
|
|
|
|
if (q_dir_string)
|
|
|
|
|
XtFree(q_dir_string);
|
|
|
|
|
if (q_pattern_string)
|
|
|
|
|
XtFree(q_pattern_string);
|
|
|
|
|
if (q_mask_string)
|
|
|
|
|
XtFree(q_mask_string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char* fe_file_selection_home = 0;
|
|
|
|
|
|
|
|
|
|
static char*
|
|
|
|
|
fe_file_selection_gethome()
|
|
|
|
|
{
|
|
|
|
|
if (!fe_file_selection_home) {
|
|
|
|
|
char* foo = getenv("HOME");
|
|
|
|
|
char* p;
|
|
|
|
|
|
|
|
|
|
if (!foo)
|
|
|
|
|
foo = "/"; /* hah */
|
|
|
|
|
|
|
|
|
|
fe_file_selection_home = XP_STRDUP(foo);
|
|
|
|
|
|
|
|
|
|
p = strrchr(fe_file_selection_home, '/');
|
|
|
|
|
if (p != NULL && p != fe_file_selection_home && p[1] == '\0')
|
|
|
|
|
*p = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fe_file_selection_home;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_dirspec_cb(Widget widget, XtPointer closure, XtPointer cb)
|
|
|
|
|
{
|
|
|
|
|
XmTextVerifyCallbackStruct* vd = (XmTextVerifyCallbackStruct*)cb;
|
|
|
|
|
Widget fsb = (Widget)closure;
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
String directory;
|
|
|
|
|
String ptr;
|
|
|
|
|
|
|
|
|
|
if (vd->startPos == 0 && vd->text->ptr != NULL) {
|
|
|
|
|
if (vd->text->ptr[0] == '~') { /* expand $HOME */
|
|
|
|
|
|
|
|
|
|
char* home = fe_file_selection_gethome();
|
|
|
|
|
|
|
|
|
|
ptr = (String)XtMalloc(strlen(home) + strlen(vd->text->ptr) + 2);
|
|
|
|
|
|
|
|
|
|
strcpy(ptr, home);
|
|
|
|
|
strcat(ptr, "/");
|
|
|
|
|
if (vd->text->length > 1)
|
|
|
|
|
strcat(ptr, &vd->text->ptr[1]);
|
|
|
|
|
|
|
|
|
|
XtFree(vd->text->ptr);
|
|
|
|
|
vd->text->ptr = ptr;
|
|
|
|
|
vd->text->length = strlen(ptr);
|
|
|
|
|
|
|
|
|
|
} else if (vd->text->ptr[0] != '/') {
|
|
|
|
|
XtVaGetValues(fsb, XmNdirectory, &xm_directory, 0);
|
|
|
|
|
if (xm_directory != NULL) {
|
|
|
|
|
directory = _XmStringGetTextConcat(xm_directory);
|
|
|
|
|
|
|
|
|
|
ptr = (String)XtMalloc(strlen(directory) +
|
|
|
|
|
strlen(vd->text->ptr) + 2);
|
|
|
|
|
strcpy(ptr, directory);
|
|
|
|
|
strcat(ptr, vd->text->ptr);
|
|
|
|
|
|
|
|
|
|
XtFree(vd->text->ptr);
|
|
|
|
|
vd->text->ptr = ptr;
|
|
|
|
|
vd->text->length = strlen(ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_filter_cb(Widget apply, XtPointer closure, XtPointer cbd)
|
|
|
|
|
{
|
|
|
|
|
Widget fsb = (Widget)closure;
|
|
|
|
|
Widget dir = XmFileSelectionBoxGetChild(fsb, XmDIALOG_DIR_LIST);
|
|
|
|
|
int* position_list;
|
|
|
|
|
int position_count;
|
|
|
|
|
|
|
|
|
|
if (XmListGetSelectedPos(dir, &position_list, &position_count)) {
|
|
|
|
|
|
|
|
|
|
if (position_count == 1 && position_list[0] == 1)
|
|
|
|
|
XmListSelectPos(dir, 1, True);
|
|
|
|
|
|
|
|
|
|
if (position_count > 0 && position_list != NULL)
|
|
|
|
|
XtFree((char*)position_list);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_directory_up_action(Widget widget,
|
|
|
|
|
XEvent* event,
|
|
|
|
|
String* av, Cardinal* ac)
|
|
|
|
|
{
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
String directory;
|
|
|
|
|
String p;
|
|
|
|
|
|
|
|
|
|
while (!XtIsSubclass(widget, xmFileSelectionBoxWidgetClass)) {
|
|
|
|
|
widget = XtParent(widget);
|
|
|
|
|
if (!widget)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtVaGetValues(widget, XmNdirectory, &xm_directory, 0);
|
|
|
|
|
|
|
|
|
|
if (xm_directory != NULL) {
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
directory = _XmStringGetTextConcat(xm_directory);
|
|
|
|
|
|
|
|
|
|
len = XP_STRLEN(directory);
|
|
|
|
|
|
|
|
|
|
if (len > 0 && directory[len-1] == '/')
|
|
|
|
|
directory[len-1] = '\0';
|
|
|
|
|
|
|
|
|
|
if ((p = XP_STRRCHR(directory, '/')) != NULL) {
|
|
|
|
|
p[1] = '\0';
|
|
|
|
|
|
|
|
|
|
xm_directory = XmStringCreateSimple(directory);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues(widget, XmNdirectory, xm_directory, 0);
|
|
|
|
|
|
|
|
|
|
XmStringFree(xm_directory);
|
|
|
|
|
}
|
|
|
|
|
XtFree(directory);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static XtActionsRec fe_file_selection_actions[] =
|
|
|
|
|
{
|
|
|
|
|
{ "FileSelectionBoxCdDotDot", fe_file_selection_directory_up_action },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static _XmConst char fe_file_selection_accelerators[] =
|
|
|
|
|
"~Alt Meta<Key>osfUp: FileSelectionBoxCdDotDot()\n"
|
|
|
|
|
"Alt ~Meta<Key>osfUp: FileSelectionBoxCdDotDot()";
|
|
|
|
|
|
|
|
|
|
static unsigned fe_file_selection_add_actions_done;
|
|
|
|
|
|
|
|
|
|
static XtPointer
|
|
|
|
|
fe_file_selection_register_actions_mappee(Widget widget, XtPointer data)
|
|
|
|
|
{
|
|
|
|
|
XtOverrideTranslations(widget, (XtTranslations)data);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_register_actions(Widget widget)
|
|
|
|
|
{
|
|
|
|
|
if (!fe_file_selection_add_actions_done) {
|
|
|
|
|
XtAppAddActions(fe_XtAppContext,
|
|
|
|
|
fe_file_selection_actions,
|
|
|
|
|
countof(fe_file_selection_actions));
|
|
|
|
|
fe_file_selection_add_actions_done++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fe_WidgetTreeWalk(widget,
|
|
|
|
|
fe_file_selection_register_actions_mappee,
|
|
|
|
|
(XtPointer) XtParseTranslationTable(fe_file_selection_accelerators));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
Boolean hack;
|
|
|
|
|
Boolean cde;
|
|
|
|
|
} fe_fsb_res_st;
|
|
|
|
|
|
|
|
|
|
static XtResource fe_fsb_resources[] =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
"nsMotifFSBHacks", XtCBoolean, XtRBoolean, sizeof(Boolean),
|
|
|
|
|
XtOffset(fe_fsb_res_st *, hack), XtRImmediate,
|
|
|
|
|
#ifdef IRIX
|
|
|
|
|
/* Irix has the nice enhanced FSB, so they don't need it */
|
|
|
|
|
(XtPointer)False
|
|
|
|
|
#else
|
|
|
|
|
(XtPointer)True
|
|
|
|
|
#endif
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"nsMotifFSBCdeMode", XtCBoolean, XtRBoolean, sizeof(Boolean),
|
|
|
|
|
XtOffset(fe_fsb_res_st *, cde), XtRImmediate, (XtPointer)False
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
FSB_LOSING,
|
|
|
|
|
FSB_HACKS,
|
|
|
|
|
FSB_CDE,
|
|
|
|
|
FSB_CDE_PLUS
|
|
|
|
|
} fe_fsb_mode;
|
|
|
|
|
|
|
|
|
|
static fe_fsb_mode
|
|
|
|
|
fe_file_selection_box_get_resources(Widget parent)
|
|
|
|
|
{
|
|
|
|
|
static Boolean done;
|
|
|
|
|
static fe_fsb_res_st result;
|
|
|
|
|
|
|
|
|
|
if (!done) {
|
|
|
|
|
|
|
|
|
|
while (!XtIsTopLevelShell(parent))
|
|
|
|
|
parent = XtParent(parent);
|
|
|
|
|
|
|
|
|
|
XtGetApplicationResources(parent,
|
|
|
|
|
(XtPointer)&result,
|
|
|
|
|
fe_fsb_resources, XtNumber(fe_fsb_resources),
|
|
|
|
|
0, 0);
|
|
|
|
|
done++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.hack && result.cde)
|
|
|
|
|
return FSB_CDE_PLUS;
|
|
|
|
|
else if (result.hack && !result.cde)
|
|
|
|
|
return FSB_HACKS;
|
|
|
|
|
else if (!result.hack && result.cde)
|
|
|
|
|
return FSB_CDE;
|
|
|
|
|
else
|
|
|
|
|
return FSB_LOSING;
|
|
|
|
|
}
|
|
|
|
|
#endif /*USE_WINNING_FILE_SELECTION*/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_selection_save_directory_cb(Widget widget, XtPointer a, XtPointer b)
|
|
|
|
|
{
|
|
|
|
|
XmString xm_directory;
|
|
|
|
|
XmString xm_dirspec;
|
|
|
|
|
/* And save directory default for next time */
|
|
|
|
|
XtVaGetValues(widget,
|
|
|
|
|
XmNdirectory, &xm_directory,
|
|
|
|
|
XmNdirSpec, &xm_dirspec,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
if (xm_dirspec != 0) {
|
|
|
|
|
char* directory = _XmStringGetTextConcat(xm_dirspec);
|
|
|
|
|
|
|
|
|
|
if (directory != NULL) {
|
|
|
|
|
if (directory[0] == '/') {
|
|
|
|
|
|
|
|
|
|
char* end = strrchr(directory, '/');
|
|
|
|
|
|
|
|
|
|
if (end != NULL) {
|
|
|
|
|
if (end != directory)
|
|
|
|
|
*end = '\0';
|
|
|
|
|
|
|
|
|
|
if (xm_directory != NULL)
|
|
|
|
|
XmStringFree(xm_directory);
|
|
|
|
|
|
|
|
|
|
xm_directory = XmStringCreateLocalized(directory);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
XtFree(directory);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (xm_directory != 0) {
|
|
|
|
|
if (fe_file_selection_directory)
|
|
|
|
|
XmStringFree(fe_file_selection_directory);
|
|
|
|
|
fe_file_selection_directory = xm_directory;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget
|
|
|
|
|
fe_CreateFileSelectionBox(Widget parent, char* name,
|
|
|
|
|
Arg* p_args, Cardinal p_n)
|
|
|
|
|
{
|
|
|
|
|
Arg args[32];
|
|
|
|
|
Cardinal n;
|
|
|
|
|
Cardinal i;
|
|
|
|
|
Widget fsb;
|
|
|
|
|
Boolean directory_set = FALSE;
|
|
|
|
|
#ifdef USE_WINNING_FILE_SELECTION
|
|
|
|
|
Boolean dir_search_set = FALSE;
|
|
|
|
|
Boolean file_search_set = FALSE;
|
|
|
|
|
Boolean qualify_set = FALSE;
|
|
|
|
|
Widget dir_list;
|
|
|
|
|
Widget file_list;
|
|
|
|
|
Widget dirspec;
|
|
|
|
|
Widget filter;
|
|
|
|
|
Widget filter_button;
|
|
|
|
|
fe_fsb_mode mode = fe_file_selection_box_get_resources(parent);
|
|
|
|
|
#endif /*USE_WINNING_FILE_SELECTION*/
|
|
|
|
|
|
|
|
|
|
for (n = 0, i = 0; i < p_n && i < 30; i++) {
|
|
|
|
|
if (p_args[i].name == XmNdirectory)
|
|
|
|
|
directory_set = TRUE;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_WINNING_FILE_SELECTION
|
|
|
|
|
if (mode == FSB_HACKS) {
|
|
|
|
|
if (p_args[i].name == XmNdirSearchProc)
|
|
|
|
|
dir_search_set = TRUE;
|
|
|
|
|
else if (p_args[i].name == XmNfileSearchProc)
|
|
|
|
|
file_search_set = TRUE;
|
|
|
|
|
else if (p_args[i].name == XmNqualifySearchDataProc)
|
|
|
|
|
qualify_set = TRUE;
|
|
|
|
|
else
|
|
|
|
|
args[n++] = p_args[i];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif /*USE_WINNING_FILE_SELECTION*/
|
|
|
|
|
{
|
|
|
|
|
args[n++] = p_args[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Add last visited directory
|
|
|
|
|
*/
|
|
|
|
|
if (!directory_set) {
|
|
|
|
|
XtSetArg(args[n], XmNdirectory, fe_file_selection_directory); n++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef USE_WINNING_FILE_SELECTION
|
|
|
|
|
if (mode == FSB_CDE || mode == FSB_CDE_PLUS) {
|
|
|
|
|
XtSetArg(args[n], "pathMode", 1); n++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode == FSB_HACKS) {
|
|
|
|
|
|
|
|
|
|
if (!dir_search_set) {
|
|
|
|
|
XtSetArg(args[n], XmNdirSearchProc,
|
|
|
|
|
fe_file_selection_dir_search_proc); n++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!file_search_set) {
|
|
|
|
|
XtSetArg(args[n], XmNfileSearchProc,
|
|
|
|
|
fe_file_selection_file_search_proc); n++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!qualify_set) {
|
|
|
|
|
XtSetArg(args[n], XmNqualifySearchDataProc,
|
|
|
|
|
fe_file_selection_qualify_search_data_proc); n++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef FEATURE_MOTIF_FSB_CLASS_HACKING
|
|
|
|
|
/*
|
|
|
|
|
* This routine is now in the Xm patches tree, as it requires
|
|
|
|
|
* access to the Motif source...djw
|
|
|
|
|
*/
|
|
|
|
|
fe_FileSelectionBoxHackClassRecord(parent);
|
|
|
|
|
#endif /*FEATURE_MOTIF_FSB_CLASS_HACKING*/
|
|
|
|
|
|
|
|
|
|
fsb = XmCreateFileSelectionBox(parent, name, args, n);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* XmCreateFileSelectionBox() sets directory list
|
|
|
|
|
* XmNscrollBarDisplayPolicy to STATIC which always shows
|
|
|
|
|
* the horizontal scrollbar. Bye...
|
|
|
|
|
*/
|
|
|
|
|
dir_list = XmFileSelectionBoxGetChild(fsb, XmDIALOG_DIR_LIST);
|
|
|
|
|
XtVaSetValues(dir_list, XmNscrollBarDisplayPolicy, XmAS_NEEDED, 0);
|
|
|
|
|
file_list = XmFileSelectionBoxGetChild(fsb, XmDIALOG_LIST);
|
|
|
|
|
XtVaSetValues(file_list, XmNscrollBarDisplayPolicy, XmAS_NEEDED, 0);
|
|
|
|
|
dirspec = XmFileSelectionBoxGetChild(fsb, XmDIALOG_TEXT);
|
|
|
|
|
XtAddCallback(dirspec, XmNmodifyVerifyCallback,
|
|
|
|
|
fe_file_selection_dirspec_cb, (XtPointer)fsb);
|
|
|
|
|
filter = XmFileSelectionBoxGetChild(fsb, XmDIALOG_FILTER_TEXT);
|
|
|
|
|
XtAddCallback(filter, XmNmodifyVerifyCallback,
|
|
|
|
|
fe_file_selection_dirspec_cb, (XtPointer)fsb);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif /*USE_WINNING_FILE_SELECTION*/
|
|
|
|
|
{
|
|
|
|
|
fsb = XmCreateFileSelectionBox(parent, name, args, n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef IRIX
|
|
|
|
|
#ifndef IRIX5_3
|
|
|
|
|
/* FIX 98019
|
|
|
|
|
*
|
|
|
|
|
* For IRIX 6.2 and later:
|
|
|
|
|
* Reset filetype mask to suit custom Sgm file dialog.
|
|
|
|
|
* (otherwise directories don't show up in the list.)
|
|
|
|
|
*/
|
|
|
|
|
XtVaSetValues(fsb,XmNfileTypeMask,XmFILE_ANY_TYPE,NULL);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
#ifdef IRIX
|
|
|
|
|
#ifndef IRIX5_3
|
|
|
|
|
/* FIX 98019
|
|
|
|
|
*
|
|
|
|
|
* For IRIX 6.2 and later:
|
|
|
|
|
* Reset filetype mask to suit custom Sgm file dialog.
|
|
|
|
|
* (otherwise directories don't show up in the list.)
|
|
|
|
|
*/
|
|
|
|
|
XtVaSetValues(fsb,XmNfileTypeMask,XmFILE_ANY_TYPE,NULL);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
#ifdef USE_WINNING_FILE_SELECTION
|
|
|
|
|
if (mode == FSB_HACKS || mode == FSB_CDE_PLUS) {
|
|
|
|
|
filter_button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_APPLY_BUTTON);
|
|
|
|
|
XtAddCallback(filter_button, XmNactivateCallback,
|
|
|
|
|
fe_file_selection_filter_cb, fsb);
|
|
|
|
|
|
|
|
|
|
fe_file_selection_register_actions(fsb);
|
|
|
|
|
}
|
|
|
|
|
#endif /*USE_WINNING_FILE_SELECTION*/
|
|
|
|
|
|
|
|
|
|
XtAddCallback(fsb, XmNokCallback,
|
|
|
|
|
fe_file_selection_save_directory_cb, NULL);
|
|
|
|
|
|
|
|
|
|
return fsb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget
|
|
|
|
|
fe_CreateFileSelectionDialog(Widget parent,
|
|
|
|
|
String name,
|
|
|
|
|
Arg* fsb_args,
|
|
|
|
|
Cardinal fsb_n)
|
|
|
|
|
{
|
|
|
|
|
Widget fsb; /* new fsb widget */
|
|
|
|
|
Widget ds; /* DialogShell */
|
|
|
|
|
ArgList ds_args; /* arglist for shell */
|
|
|
|
|
char ds_name[256];
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Create DialogShell parent.
|
|
|
|
|
*/
|
|
|
|
|
XP_STRCPY(ds_name, name);
|
|
|
|
|
XP_STRCAT(ds_name, "_popup"); /* motif compatible */
|
|
|
|
|
|
|
|
|
|
ds_args = (ArgList)XtMalloc(sizeof(Arg) * (fsb_n + 1));
|
|
|
|
|
XP_MEMCPY(ds_args, fsb_args, (sizeof(Arg) * fsb_n));
|
|
|
|
|
XtSetArg(ds_args[fsb_n], XmNallowShellResize, True);
|
|
|
|
|
ds = XmCreateDialogShell(parent, ds_name, ds_args, fsb_n + 1);
|
|
|
|
|
|
|
|
|
|
XtFree((char*)ds_args);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Create FileSelectionBox.
|
|
|
|
|
*/
|
|
|
|
|
fsb = fe_CreateFileSelectionBox(ds, name, fsb_args, fsb_n);
|
|
|
|
|
XtAddCallback(fsb, XmNdestroyCallback, _XmDestroyParentCallback, NULL);
|
|
|
|
|
|
|
|
|
|
return(fsb) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void fe_file_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_file_destroy_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
static void fe_file_type_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
static void fe_file_type_hack_extension (struct fe_file_type_data *ftd);
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* fe_ReadFilename_2
|
|
|
|
|
* context:
|
|
|
|
|
* If context is non-null, it uses context's data to display the fsb.
|
|
|
|
|
* iparent, filebp, ftdp:
|
|
|
|
|
* If context is NULL, then this uses these to create the file
|
|
|
|
|
* selection box.
|
|
|
|
|
* 'iparent' is the parent shell under which the FSB will be created.
|
|
|
|
|
* 'filebp' is a pointer to the file selection box widget. [CANT BE NULL]
|
|
|
|
|
* 'ftdp' is a pointer to file type data used by FSB code. [CANT BE NULL]
|
|
|
|
|
* We allocate one and return it back to the caller.
|
|
|
|
|
* Everytime we are called with the same filebp, we need to
|
|
|
|
|
* be called with the same ftdp.
|
|
|
|
|
*
|
|
|
|
|
* WARNING: 1. Allocates *ftdp
|
|
|
|
|
* 2. filebp and ftdp go together. For every filebp we need to
|
|
|
|
|
* use the ftdp that was created with it.
|
|
|
|
|
*
|
|
|
|
|
* Just another form of fe_ReadFileName() so that other parts of fe
|
|
|
|
|
* eg. bookmarks can use this as they dont have a context and I
|
|
|
|
|
* think making a dummy context is bad.
|
|
|
|
|
* - dp
|
|
|
|
|
*
|
|
|
|
|
* Akkana note: bug 82924 was fixed in FE_PromptForFileName()
|
|
|
|
|
* (in src/context_funcs.cpp), but has not yet been fixed here.
|
|
|
|
|
* The three filename prompting routines need to be integrated into one;
|
|
|
|
|
* see comment under FE_PromptForFileName().
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
fe_ReadFileName_2 ( MWContext* context,
|
|
|
|
|
Widget iparent, Widget* filebp,
|
|
|
|
|
struct fe_file_type_data **ftdp,
|
|
|
|
|
const char *title, const char *default_url,
|
|
|
|
|
Boolean must_match, int *save_as_type)
|
|
|
|
|
{
|
|
|
|
|
Widget fileb;
|
|
|
|
|
struct fe_file_type_data *ftd;
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
Widget sabox, samenu, sabutton;
|
|
|
|
|
|
|
|
|
|
if (context) {
|
|
|
|
|
fileb = CONTEXT_DATA (context)->file_dialog;
|
|
|
|
|
ftd = CONTEXT_DATA (context)->ftd;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fileb = *filebp;
|
|
|
|
|
ftd = *ftdp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! title) title = XP_GetString(XFE_OPEN_FILE);
|
|
|
|
|
|
|
|
|
|
if (! fileb)
|
|
|
|
|
{
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac, i;
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget parent;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
|
|
|
|
|
if (context) parent = CONTEXT_WIDGET (context);
|
|
|
|
|
else parent = iparent;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNallowShellResize, True); ac++;*/
|
|
|
|
|
shell = XmCreateDialogShell (parent, "fileSelector_popup", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL);
|
|
|
|
|
ac++;
|
|
|
|
|
ftd = (struct fe_file_type_data *)
|
|
|
|
|
calloc (sizeof (struct fe_file_type_data), 1);
|
|
|
|
|
if (context) CONTEXT_DATA (context)->ftd = ftd;
|
|
|
|
|
else *ftdp = ftd;
|
|
|
|
|
XtSetArg (av[ac], XmNuserData, ftd); ac++;
|
|
|
|
|
fileb = fe_CreateFileSelectionBox (shell, "fileSelector", av, ac);
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XtNameToWidget (fileb, "*Help"));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
sabox = XmCreateFrame (fileb, "frame", av, ac);
|
|
|
|
|
samenu = XmCreatePulldownMenu (sabox, "formatType", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
ftd->fileb = fileb;
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
ftd->options [fe_FILE_TYPE_TEXT] =
|
|
|
|
|
XmCreatePushButtonGadget (samenu, "text", av, ac);
|
|
|
|
|
ftd->options [fe_FILE_TYPE_HTML] =
|
|
|
|
|
XmCreatePushButtonGadget (samenu, "html", av, ac);
|
|
|
|
|
#ifdef SAVE_ALL
|
|
|
|
|
ftd->options [fe_FILE_TYPE_HTML_AND_IMAGES] =
|
|
|
|
|
XmCreatePushButtonGadget (samenu, "tree", av, ac);
|
|
|
|
|
#endif /* SAVE_ALL */
|
|
|
|
|
ftd->options [fe_FILE_TYPE_PS] =
|
|
|
|
|
XmCreatePushButtonGadget (samenu, "ps", av, ac);
|
|
|
|
|
/* ftd->selected_option = fe_FILE_TYPE_TEXT; */
|
|
|
|
|
/* Make the default "save as" type html (ie, source) */
|
|
|
|
|
ftd->selected_option = fe_FILE_TYPE_HTML;
|
|
|
|
|
XtVaSetValues (samenu, XmNmenuHistory,
|
|
|
|
|
ftd->options [ftd->selected_option], 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av [ac], XmNsubMenuId, samenu); ac++;
|
|
|
|
|
sabutton = fe_CreateOptionMenu (sabox, "formatType", av, ac);
|
|
|
|
|
for (i = 0; i < countof (ftd->options); i++)
|
|
|
|
|
if (ftd->options[i])
|
|
|
|
|
{
|
|
|
|
|
XtAddCallback (ftd->options[i], XmNactivateCallback,
|
|
|
|
|
fe_file_type_cb, ftd);
|
|
|
|
|
XtManageChild (ftd->options[i]);
|
|
|
|
|
}
|
|
|
|
|
XtManageChild (sabutton);
|
|
|
|
|
|
|
|
|
|
if (context) CONTEXT_DATA (context)->file_dialog = fileb;
|
|
|
|
|
else *filebp = fileb;
|
|
|
|
|
|
|
|
|
|
fe_HackDialogTranslations (fileb);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Without this the "*fileSelector.width:" resource doesn't work
|
|
|
|
|
on subsequent invocations of this box. Don't ask me why. I
|
|
|
|
|
tried permutations of allowShellResize as well with no effect.
|
|
|
|
|
(It's better to keep the widgets themselves around, if not the
|
|
|
|
|
windows, so that the default text is persistent.)
|
|
|
|
|
*/
|
|
|
|
|
#if 0
|
|
|
|
|
XtUnrealizeWidget (fileb);
|
|
|
|
|
#endif
|
|
|
|
|
sabox = XtNameToWidget (fileb, "*frame");
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Restore the values saved in fe_file_selection_save_directory_cb()
|
|
|
|
|
*/
|
|
|
|
|
if (fe_file_selection_directory != 0) {
|
|
|
|
|
XtVaSetValues(fileb, XmNdirectory, fe_file_selection_directory, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
ftd->orig_url = default_url;
|
|
|
|
|
ftd->conversion_allowed_p = (save_as_type != 0);
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (fileb, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
XtRemoveAllCallbacks (fileb, XmNnoMatchCallback);
|
|
|
|
|
XtRemoveAllCallbacks (fileb, XmNokCallback);
|
|
|
|
|
XtRemoveAllCallbacks (fileb, XmNapplyCallback);
|
|
|
|
|
XtRemoveAllCallbacks (fileb, XmNcancelCallback);
|
|
|
|
|
XtRemoveAllCallbacks (fileb, XmNdestroyCallback);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (fileb, XmNnoMatchCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNokCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNcancelCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNdestroyCallback, fe_file_destroy_cb, &data);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (XtParent (fileb), XmNtitle, title, 0);
|
|
|
|
|
#if 0 /* mustMatch doesn't work! */
|
|
|
|
|
XtVaSetValues (fileb, XmNmustMatch, must_match, 0);
|
|
|
|
|
#else
|
|
|
|
|
XtVaSetValues (fileb, XmNmustMatch, False, 0);
|
|
|
|
|
data.must_match = must_match;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
String dirmask = 0;
|
|
|
|
|
XmString xms;
|
|
|
|
|
char *s, *tail;
|
|
|
|
|
char buf [2048];
|
|
|
|
|
const char *def;
|
|
|
|
|
|
|
|
|
|
if (! default_url)
|
|
|
|
|
def = 0;
|
|
|
|
|
else if ((def = strrchr (default_url, '/')))
|
|
|
|
|
def++;
|
|
|
|
|
else
|
|
|
|
|
def = default_url;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (fileb, XmNdirSpec, &xms, 0);
|
|
|
|
|
XmStringGetLtoR (xms, XmFONTLIST_DEFAULT_TAG, &s); /* s - is XtMalloc */
|
|
|
|
|
XmStringFree (xms);
|
|
|
|
|
|
|
|
|
|
/* Take the file name part off of `s', leaving only the dir. */
|
|
|
|
|
tail = strrchr (s, '/');
|
|
|
|
|
if (tail) *tail = 0;
|
|
|
|
|
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/%.900s", s, (def ? def : ""));
|
|
|
|
|
if (def)
|
|
|
|
|
{
|
|
|
|
|
/* Grab the file name part (it's sitting right after the end of `s')
|
|
|
|
|
and map out the characters which ought not go into file names.
|
|
|
|
|
Also, terminate the file name at ? or #, since those aren't
|
|
|
|
|
really a part of the URL's file, but are modifiers to it.
|
|
|
|
|
*/
|
|
|
|
|
for (tail = buf+strlen(s)+1; *tail; tail++)
|
|
|
|
|
if (*tail == '?' || *tail == '#')
|
|
|
|
|
*tail = 0;
|
|
|
|
|
else if (*tail < '+' || *tail > 'z' ||
|
|
|
|
|
*tail == ':' || *tail == ';' ||
|
|
|
|
|
*tail == '<' || *tail == '>' ||
|
|
|
|
|
*tail == '\\' || *tail == '^' ||
|
|
|
|
|
*tail == '\'' || *tail == '`' ||
|
|
|
|
|
*tail == ',')
|
|
|
|
|
*tail = '_';
|
|
|
|
|
}
|
|
|
|
|
XtFree (s);
|
|
|
|
|
|
|
|
|
|
/* If the dialog already existed, its data is out of date. Resync. */
|
|
|
|
|
XtVaGetValues (fileb, XmNdirMask, &dirmask, 0);
|
|
|
|
|
XmFileSelectionDoSearch (fileb, dirmask);
|
|
|
|
|
|
|
|
|
|
/* Change the default file name. */
|
|
|
|
|
xms = XmStringCreate (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
XtVaSetValues (fileb, XmNdirSpec, xms, 0);
|
|
|
|
|
XmStringFree (xms);
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
fe_file_type_hack_extension (ftd);
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
|
|
|
|
|
if (save_as_type)
|
|
|
|
|
XtManageChild (sabox);
|
|
|
|
|
else
|
|
|
|
|
XtUnmanageChild (sabox);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (fileb);
|
|
|
|
|
XtManageChild (fileb);
|
|
|
|
|
/* #### check for unmanagement here */
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer != Answer_Destroy) {
|
|
|
|
|
/* Call the ok -> save directory callback because it's been removed */
|
|
|
|
|
fe_file_selection_save_directory_cb(fileb, NULL, NULL);
|
|
|
|
|
XtUnmanageChild(fileb);
|
|
|
|
|
XtRemoveCallback(fileb, XmNdestroyCallback, fe_file_destroy_cb, &data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (save_as_type)
|
|
|
|
|
*save_as_type = ftd->selected_option;
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_Destroy) {
|
|
|
|
|
if (!data.context) {
|
|
|
|
|
XP_ASSERT(filebp && ftdp);
|
|
|
|
|
*filebp = 0;
|
|
|
|
|
*ftdp = 0;
|
|
|
|
|
}
|
|
|
|
|
if (ftd) {
|
|
|
|
|
/*
|
|
|
|
|
* If the context got destroyed, this could have been freed by the
|
|
|
|
|
* context. Our destroy routine checks for the parent context being
|
|
|
|
|
* freed and sets the return_value to -1 if the context was destroyed.
|
|
|
|
|
*/
|
|
|
|
|
if (data.return_value != (void *)-1)
|
|
|
|
|
XP_FREE(ftd);
|
|
|
|
|
}
|
|
|
|
|
data.answer = Answer_Cancel; /* Simulate CANCEL */
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (char *) data.return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
fe_ReadFileName (MWContext *context, const char *title,
|
|
|
|
|
const char *default_url,
|
|
|
|
|
Boolean must_match,
|
|
|
|
|
int *save_as_type)
|
|
|
|
|
{
|
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
|
|
fe_ProtectContext(context);
|
|
|
|
|
ret = fe_ReadFileName_2( context, NULL, NULL, NULL,
|
|
|
|
|
title, default_url, must_match, save_as_type);
|
|
|
|
|
fe_UnProtectContext(context);
|
|
|
|
|
if (fe_IsContextDestroyed(context)) {
|
|
|
|
|
free(CONTEXT_DATA(context));
|
|
|
|
|
free(context);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
if (data->answer == Answer_Invalid) {
|
|
|
|
|
data->answer = Answer_Destroy;
|
|
|
|
|
/* Reset the context file dialog storage. Be sure that this destroy isnt
|
|
|
|
|
* a result of the context itself being destroyed.
|
|
|
|
|
*/
|
|
|
|
|
if (data->context)
|
|
|
|
|
if (!XfeIsAlive(CONTEXT_WIDGET(data->context))) {
|
|
|
|
|
/* Indicates the context was destroyed too */
|
|
|
|
|
data->return_value = (void *)-1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
CONTEXT_DATA(data->context)->file_dialog = 0;
|
|
|
|
|
CONTEXT_DATA(data->context)->ftd = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
XmFileSelectionBoxCallbackStruct *sbc =
|
|
|
|
|
(XmFileSelectionBoxCallbackStruct *) call_data;
|
|
|
|
|
|
|
|
|
|
switch (sbc->reason)
|
|
|
|
|
{
|
|
|
|
|
case XmCR_NO_MATCH:
|
|
|
|
|
{
|
|
|
|
|
NOMATCH:
|
|
|
|
|
XBell (XtDisplay (widget), 0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case XmCR_OK:
|
|
|
|
|
{
|
|
|
|
|
XmStringGetLtoR (sbc->value, XmFONTLIST_DEFAULT_TAG,
|
|
|
|
|
(char **) &data->return_value);
|
|
|
|
|
#if 1
|
|
|
|
|
/* mustMatch doesn't work!! */
|
|
|
|
|
{
|
|
|
|
|
struct stat st;
|
|
|
|
|
if (data->must_match &&
|
|
|
|
|
data->return_value &&
|
|
|
|
|
stat (data->return_value, &st))
|
|
|
|
|
{
|
|
|
|
|
free (data->return_value);
|
|
|
|
|
data->return_value = 0;
|
|
|
|
|
goto NOMATCH;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
data->answer = Answer_OK;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case XmCR_CANCEL:
|
|
|
|
|
{
|
|
|
|
|
data->answer = Answer_Cancel;
|
|
|
|
|
data->return_value = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_type_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_file_type_data *ftd = (struct fe_file_type_data *) closure;
|
|
|
|
|
int i;
|
|
|
|
|
ftd->selected_option = -1;
|
|
|
|
|
for (i = 0; i < countof (ftd->options); i++)
|
|
|
|
|
if (ftd->options [i] == widget)
|
|
|
|
|
{
|
|
|
|
|
ftd->selected_option = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
fe_file_type_hack_extension (ftd);
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_DECODERS
|
|
|
|
|
static void
|
|
|
|
|
fe_file_type_hack_extension_1 (struct fe_file_type_data *ftd,
|
|
|
|
|
Boolean dirspec_p)
|
|
|
|
|
{
|
|
|
|
|
int desired_type;
|
|
|
|
|
const char *default_file_name = "index.html";
|
|
|
|
|
XmString xm_file = 0;
|
|
|
|
|
char *file = 0;
|
|
|
|
|
char *name_part = 0;
|
|
|
|
|
char *ext = 0;
|
|
|
|
|
char *orig_ext = 0;
|
|
|
|
|
const char *new_ext = 0;
|
|
|
|
|
char *orig_url_copy = 0;
|
|
|
|
|
|
|
|
|
|
if (!ftd || !ftd->fileb)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (ftd->conversion_allowed_p)
|
|
|
|
|
desired_type = ftd->selected_option;
|
|
|
|
|
else
|
|
|
|
|
desired_type = fe_FILE_TYPE_HTML;
|
|
|
|
|
|
|
|
|
|
/* Find a default file name.
|
|
|
|
|
If this URL ends in a file part, use that, otherwise, assume "index.html".
|
|
|
|
|
Then, once we've got a default file name, set the default extension to
|
|
|
|
|
use for "Save As Source" from that.
|
|
|
|
|
*/
|
|
|
|
|
if (ftd->orig_url)
|
|
|
|
|
{
|
|
|
|
|
const char *orig_name_part;
|
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
|
|
orig_url_copy = strdup (ftd->orig_url);
|
|
|
|
|
|
|
|
|
|
/* take off form and anchor data. */
|
|
|
|
|
if ((s = strchr (orig_url_copy, '?')))
|
|
|
|
|
*s = 0;
|
|
|
|
|
if ((s = strchr (orig_url_copy, '#')))
|
|
|
|
|
*s = 0;
|
|
|
|
|
|
|
|
|
|
orig_name_part = strrchr (orig_url_copy, '/');
|
|
|
|
|
if (! orig_name_part)
|
|
|
|
|
orig_name_part = strrchr (orig_url_copy, ':');
|
|
|
|
|
if (orig_name_part)
|
|
|
|
|
orig_name_part++;
|
|
|
|
|
else if (orig_url_copy && *orig_url_copy)
|
|
|
|
|
orig_name_part = orig_url_copy;
|
|
|
|
|
|
|
|
|
|
if (orig_name_part && *orig_name_part)
|
|
|
|
|
default_file_name = orig_name_part;
|
|
|
|
|
|
|
|
|
|
orig_ext = strrchr (default_file_name, '.');
|
|
|
|
|
|
|
|
|
|
if (!orig_ext && !dirspec_p)
|
|
|
|
|
{
|
|
|
|
|
/* If we're up in the filter area, and there is as yet no
|
|
|
|
|
orig_ext, then that means that there was file name without
|
|
|
|
|
an extension (as opposed to no file name, when we would
|
|
|
|
|
have defaulted to "index.html".) So, for the purposes
|
|
|
|
|
of the filter, set the extension to ".*".
|
|
|
|
|
*/
|
|
|
|
|
orig_ext = ".*";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get `file' from what's currently typed into the text field.
|
|
|
|
|
*/
|
|
|
|
|
XtVaGetValues (ftd->fileb,
|
|
|
|
|
(dirspec_p ? XmNdirSpec : XmNdirMask), &xm_file, 0);
|
|
|
|
|
if (! xm_file) return;
|
|
|
|
|
XmStringGetLtoR (xm_file, XmFONTLIST_DEFAULT_TAG, &file); /* file- XtMalloc */
|
|
|
|
|
XmStringFree (xm_file);
|
|
|
|
|
|
|
|
|
|
/* If the file ends in "/" then stick the default file name on the end. */
|
|
|
|
|
if (dirspec_p && file && *file && file [strlen (file) - 1] == '/')
|
|
|
|
|
{
|
|
|
|
|
char *file2 = (char *) malloc (strlen (file) +
|
|
|
|
|
strlen (default_file_name) + 1);
|
|
|
|
|
strcpy (file2, file);
|
|
|
|
|
strcat (file2, default_file_name);
|
|
|
|
|
XtFree (file);
|
|
|
|
|
file = file2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name_part = strrchr (file, '/');
|
|
|
|
|
if (! name_part)
|
|
|
|
|
name_part = strrchr (file, ':');
|
|
|
|
|
if (name_part)
|
|
|
|
|
name_part++;
|
|
|
|
|
|
|
|
|
|
if (!name_part || !*name_part)
|
|
|
|
|
name_part = 0;
|
|
|
|
|
|
|
|
|
|
if (name_part)
|
|
|
|
|
ext = strrchr (name_part, '.');
|
|
|
|
|
|
|
|
|
|
switch (desired_type)
|
|
|
|
|
{
|
|
|
|
|
case fe_FILE_TYPE_HTML:
|
|
|
|
|
case fe_FILE_TYPE_HTML_AND_IMAGES:
|
|
|
|
|
new_ext = orig_ext;
|
|
|
|
|
break;
|
|
|
|
|
case fe_FILE_TYPE_TEXT:
|
|
|
|
|
case fe_FILE_TYPE_FORMATTED_TEXT:
|
|
|
|
|
/* The user has selected "text". Change the extension to "txt"
|
|
|
|
|
only if the original URL had extension "html" or "htm". */
|
|
|
|
|
if (orig_ext &&
|
|
|
|
|
(!strcasecomp (orig_ext, ".html") ||
|
|
|
|
|
!strcasecomp (orig_ext, ".htm")))
|
|
|
|
|
new_ext = ".txt";
|
|
|
|
|
else
|
|
|
|
|
new_ext = orig_ext;
|
|
|
|
|
break;
|
|
|
|
|
case fe_FILE_TYPE_PS:
|
|
|
|
|
new_ext = ".ps";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ext && new_ext /* && !!strcasecomp (ext, new_ext) */ )
|
|
|
|
|
{
|
|
|
|
|
char *file2;
|
|
|
|
|
*ext = 0;
|
|
|
|
|
file2 = (char *) malloc (strlen (file) + strlen (new_ext) + 1);
|
|
|
|
|
strcpy (file2, file);
|
|
|
|
|
strcat (file2, new_ext);
|
|
|
|
|
xm_file = XmStringCreateLtoR (file2, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
|
|
|
|
|
if (dirspec_p)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (ftd->fileb, XmNdirSpec, xm_file, 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
XmString saved_value = 0;
|
|
|
|
|
|
|
|
|
|
/* Don't let what's currently typed into the `Selection' field
|
|
|
|
|
to change as a result of running this search again -- that's
|
|
|
|
|
totally bogus. */
|
|
|
|
|
XtVaGetValues (ftd->fileb, XmNdirSpec, &saved_value, 0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (ftd->fileb, XmNdirMask, xm_file, 0);
|
|
|
|
|
XmFileSelectionDoSearch (ftd->fileb, xm_file);
|
|
|
|
|
if (saved_value)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (ftd->fileb, XmNdirSpec, saved_value, 0);
|
|
|
|
|
XmStringFree (saved_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XmStringFree (xm_file);
|
|
|
|
|
free (file2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (orig_url_copy)
|
|
|
|
|
free (orig_url_copy);
|
|
|
|
|
|
|
|
|
|
XtFree (file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_file_type_hack_extension (struct fe_file_type_data *ftd)
|
|
|
|
|
{
|
|
|
|
|
fe_file_type_hack_extension_1 (ftd, False);
|
|
|
|
|
fe_file_type_hack_extension_1 (ftd, True);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* NEW_DECODERS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Open URL - prompts asynchronously
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static char *last_open_url_text = 0;
|
|
|
|
|
|
|
|
|
|
struct fe_open_url_data {
|
|
|
|
|
MWContext *context;
|
|
|
|
|
Widget widget;
|
|
|
|
|
Widget text;
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
Widget in_editor;
|
|
|
|
|
#endif
|
|
|
|
|
Widget in_browser;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static char*
|
|
|
|
|
cleanup_selection(char* target, char* source, unsigned max_size)
|
|
|
|
|
{
|
|
|
|
|
char* p;
|
|
|
|
|
char* q;
|
|
|
|
|
char* end;
|
|
|
|
|
|
|
|
|
|
for (p = source; isspace(*p); p++) /* skip beginning whitespace */
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
end = &p[max_size-1];
|
|
|
|
|
q = target;
|
|
|
|
|
|
|
|
|
|
while (p < end) {
|
|
|
|
|
/*
|
|
|
|
|
* Stop if we detect an unprintable, or newline.
|
|
|
|
|
*/
|
|
|
|
|
if (!isprint(*p) || *p == '\n' || *p == '\r')
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (isspace(*p))
|
|
|
|
|
*q++ = ' ', p++;
|
|
|
|
|
else
|
|
|
|
|
*q++ = *p++;
|
|
|
|
|
}
|
|
|
|
|
/* strip trailing whitespace */
|
|
|
|
|
while (q > target && isspace(q[-1]))
|
|
|
|
|
q--;
|
|
|
|
|
|
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
|
|
return target;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
file_dialog_get_url(MWContext* context, char* address, MWContextType ge_type)
|
|
|
|
|
{
|
|
|
|
|
if (address != NULL) {
|
|
|
|
|
if (ge_type == MWContextBrowser) {
|
|
|
|
|
fe_BrowserGetURL(context, address);
|
|
|
|
|
}
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
else if (ge_type == MWContextEditor) {
|
|
|
|
|
fe_EditorEdit(context, NULL, NULL, address); /* try to re-use */
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_open_url_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_open_url_data *data = (struct fe_open_url_data *) closure;
|
|
|
|
|
char* text = NULL;
|
|
|
|
|
MWContext* context;
|
|
|
|
|
MWContextType ge_type = MWContextAny;
|
|
|
|
|
|
|
|
|
|
if (call_data == NULL || /* when it's a destroy callback */
|
|
|
|
|
!XfeIsAlive(widget) || /* on it's way */
|
|
|
|
|
data == NULL) /* data from hell */
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
context = data->context;
|
|
|
|
|
|
|
|
|
|
if (widget == data->in_browser
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
|| widget == data->in_editor
|
|
|
|
|
#endif
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
text = fe_GetTextField(data->text);
|
|
|
|
|
|
|
|
|
|
if (! text)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cleanup_selection(text, text, strlen(text)+1);
|
|
|
|
|
|
|
|
|
|
if (*text != '\0') {
|
|
|
|
|
|
|
|
|
|
if (last_open_url_text)
|
|
|
|
|
XtFree(last_open_url_text);
|
|
|
|
|
|
|
|
|
|
last_open_url_text = text;
|
|
|
|
|
|
|
|
|
|
if (widget == data->in_browser)
|
|
|
|
|
ge_type = MWContextBrowser;
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
else if (widget == data->in_editor)
|
|
|
|
|
ge_type = MWContextEditor;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtUnmanageChild(data->widget);
|
|
|
|
|
XtDestroyWidget(data->widget);
|
|
|
|
|
free(data);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Call common routine to divert the get_url()
|
|
|
|
|
*/
|
|
|
|
|
file_dialog_get_url(context, text, ge_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_open_url_browse_cb(Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_open_url_data* data = (struct fe_open_url_data *)closure;
|
|
|
|
|
|
|
|
|
|
fe_browse_file_of_text(data->context, data->text, False);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_OpenURLDialog(MWContext* context)
|
|
|
|
|
{
|
|
|
|
|
struct fe_open_url_data *data;
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Widget label;
|
|
|
|
|
Widget text;
|
|
|
|
|
Widget in_browser;
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
Widget in_editor;
|
|
|
|
|
#endif
|
|
|
|
|
Widget form;
|
|
|
|
|
Widget browse;
|
|
|
|
|
Arg args[20];
|
|
|
|
|
int n;
|
|
|
|
|
char* string;
|
|
|
|
|
|
|
|
|
|
dialog = fe_CreatePromptDialog(context, "openURLDialog",
|
|
|
|
|
FALSE, TRUE, TRUE, TRUE, TRUE);
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
form = XmCreateForm(dialog, "form", args, n);
|
|
|
|
|
XtManageChild(form);
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args [n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
XtSetArg(args [n], XmNtopAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
XtSetArg(args [n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
|
|
|
|
|
label = XmCreateLabelGadget(form, "label", args, n);
|
|
|
|
|
XtManageChild(label);
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args [n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
|
|
|
|
XtSetArg(args [n], XmNtopWidget, label); n++;
|
|
|
|
|
XtSetArg(args [n], XmNrightAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
XtSetArg(args [n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
browse = XmCreatePushButtonGadget(form, "choose", args, n);
|
|
|
|
|
XtManageChild(browse);
|
|
|
|
|
|
|
|
|
|
string = last_open_url_text? last_open_url_text : "";
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args [n], XmNleftAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
XtSetArg(args [n], XmNtopAttachment, XmATTACH_WIDGET); n++;
|
|
|
|
|
XtSetArg(args [n], XmNtopWidget, label); n++;
|
|
|
|
|
XtSetArg(args [n], XmNrightAttachment, XmATTACH_WIDGET); n++;
|
|
|
|
|
XtSetArg(args [n], XmNrightWidget, browse); n++;
|
|
|
|
|
XtSetArg(args [n], XmNbottomAttachment, XmATTACH_FORM); n++;
|
|
|
|
|
XtSetArg(args [n], XmNeditable, True); n++;
|
|
|
|
|
XtSetArg(args [n], XmNcursorPositionVisible, True); n++;
|
|
|
|
|
text = fe_CreateTextField(form, "openURLText", args, n);
|
|
|
|
|
fe_SetTextField(text, string);
|
|
|
|
|
XtManageChild(text);
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
|
|
|
in_browser = XmCreatePushButtonGadget(dialog, "openInBrowser", args, n);
|
|
|
|
|
#else
|
|
|
|
|
in_browser = XmCreatePushButtonGadget(dialog, "OK", args, n);
|
|
|
|
|
#endif
|
|
|
|
|
XtManageChild(in_browser);
|
|
|
|
|
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
n = 0;
|
|
|
|
|
XtSetArg(args[n], XmNsensitive, !fe_IsEditorDisabled()); n++;
|
|
|
|
|
in_editor = XmCreatePushButtonGadget(dialog, "openInEditor", args, n);
|
|
|
|
|
XtManageChild(in_editor);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
data = (struct fe_open_url_data *)calloc(sizeof(struct fe_open_url_data), 1);
|
|
|
|
|
data->context = context;
|
|
|
|
|
data->widget = dialog;
|
|
|
|
|
data->text = text;
|
|
|
|
|
data->in_browser = in_browser;
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
data->in_editor = in_editor;
|
|
|
|
|
|
|
|
|
|
if (context->type == MWContextEditor)
|
|
|
|
|
XtVaSetValues(dialog, XmNdefaultButton, in_editor, 0);
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
XtVaSetValues(dialog, XmNdefaultButton, in_browser, 0);
|
|
|
|
|
|
|
|
|
|
XtAddCallback(browse, XmNactivateCallback,fe_open_url_browse_cb, data);
|
|
|
|
|
#ifdef EDITOR
|
|
|
|
|
XtAddCallback(in_editor, XmNactivateCallback, fe_open_url_cb, data);
|
|
|
|
|
#endif
|
|
|
|
|
XtAddCallback(in_browser, XmNactivateCallback, fe_open_url_cb, data);
|
|
|
|
|
XtAddCallback(dialog, XmNcancelCallback, fe_open_url_cb, data);
|
|
|
|
|
XtAddCallback(dialog, XmNdestroyCallback, fe_open_url_cb, data);
|
|
|
|
|
XtAddCallback(dialog, XmNapplyCallback, fe_clear_text_cb, text);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_OpenURLChooseFileDialog (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
char *text;
|
|
|
|
|
|
|
|
|
|
if (!context) return;
|
|
|
|
|
|
|
|
|
|
text = fe_ReadFileName (context,
|
|
|
|
|
XP_GetString(XFE_OPEN_FILE),
|
|
|
|
|
last_open_url_text,
|
|
|
|
|
FALSE, /* must match */
|
|
|
|
|
0); /* save_as_type */
|
|
|
|
|
|
|
|
|
|
file_dialog_get_url(context, text, context->type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Prompt the user for their password. The message string is displayed
|
|
|
|
|
* to the user so they know what they are giving their password for.
|
|
|
|
|
* The characters of the password are not echoed.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
XFE_PromptPassword (MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
return (char *) fe_dialog (CONTEXT_WIDGET (context),
|
|
|
|
|
"password", message, TRUE, "", TRUE, FALSE,
|
|
|
|
|
((char **) 1));
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
/*
|
|
|
|
|
* Yet Another front end function that
|
|
|
|
|
* noone told us we were supposed to implement.
|
|
|
|
|
*/
|
|
|
|
|
char *XP_PromptPassword(MWContext *context, const char *message)
|
|
|
|
|
{
|
|
|
|
|
return XFE_PromptPassword(context, message);
|
|
|
|
|
}
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
/* Prompt for a username and password
|
|
|
|
|
*
|
|
|
|
|
* message is a prompt message.
|
|
|
|
|
*
|
|
|
|
|
* if username and password are not NULL they should be used
|
|
|
|
|
* as default values and NOT MODIFIED. New values should be malloc'd
|
|
|
|
|
* and put in their place.
|
|
|
|
|
*
|
|
|
|
|
* If the User hit's cancel FALSE should be returned, otherwise
|
|
|
|
|
* TRUE should be returned.
|
|
|
|
|
*/
|
|
|
|
|
XP_Bool
|
|
|
|
|
XFE_PromptUsernameAndPassword (MWContext *context,
|
|
|
|
|
const char *message,
|
|
|
|
|
char **username,
|
|
|
|
|
char **password)
|
|
|
|
|
{
|
|
|
|
|
char *pw = "";
|
|
|
|
|
char *un = (char *) fe_dialog (CONTEXT_WIDGET (context),
|
|
|
|
|
"password", message, TRUE,
|
|
|
|
|
(*username ? *username : ""), TRUE, FALSE,
|
|
|
|
|
&pw);
|
|
|
|
|
if (pw)
|
|
|
|
|
{
|
|
|
|
|
*username = un;
|
|
|
|
|
*password = XP_STRDUP(pw);
|
|
|
|
|
return(TRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*username = 0;
|
|
|
|
|
*password = 0;
|
|
|
|
|
return(FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-22 21:19:46 +00:00
|
|
|
|
/*
|
|
|
|
|
* Yet Another front end function that
|
|
|
|
|
* noone told us we were supposed to implement.
|
|
|
|
|
*/
|
|
|
|
|
PRBool XP_PromptUsernameAndPassword (MWContext *window_id,
|
|
|
|
|
const char *message,
|
|
|
|
|
char **username,
|
|
|
|
|
char **password)
|
|
|
|
|
{
|
|
|
|
|
return XFE_PromptUsernameAndPassword(window_id, message, username, password);
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Prompting for visuals
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void fe_visual_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
|
|
|
|
|
Visual *
|
|
|
|
|
fe_ReadVisual (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Display *dpy = XtDisplay (mainw);
|
|
|
|
|
Screen *screen = XtScreen (mainw);
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
int i;
|
|
|
|
|
Widget shell;
|
|
|
|
|
XmString *items;
|
|
|
|
|
int item_count;
|
|
|
|
|
int default_item = 0;
|
|
|
|
|
XVisualInfo vi_in, *vi_out;
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
vi_in.screen = fe_ScreenNumber (screen);
|
|
|
|
|
vi_out = XGetVisualInfo (dpy, VisualScreenMask, &vi_in, &item_count);
|
|
|
|
|
if (! vi_out) item_count = 0;
|
|
|
|
|
items = (XmString *) calloc (sizeof (XmString), item_count + 1);
|
|
|
|
|
for (i = 0; i < item_count; i++)
|
|
|
|
|
{
|
|
|
|
|
char *vdesc = fe_VisualDescription (screen, vi_out [i].visual);
|
|
|
|
|
items[i] = XmStringCreate (vdesc, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
free (vdesc);
|
|
|
|
|
if (vi_out [i].visual == v)
|
|
|
|
|
default_item = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNautoUnmanage, False); ac++;*/
|
|
|
|
|
XtSetArg (av[ac], XmNlistItems, items); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNlistItemCount, item_count); ac++;
|
|
|
|
|
shell = XmCreateSelectionDialog (mainw, "visual", av, ac);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (shell, XmNokCallback, fe_visual_cb, &data);
|
|
|
|
|
XtAddCallback (shell, XmNcancelCallback, fe_visual_cb, &data);
|
|
|
|
|
XtAddCallback (shell, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_TEXT));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Widget list = XmSelectionBoxGetChild (shell, XmDIALOG_LIST);
|
|
|
|
|
XtVaSetValues (list,
|
|
|
|
|
XmNselectedItems, (items + default_item),
|
|
|
|
|
XmNselectedItemCount, 1,
|
|
|
|
|
0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = shell;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (shell);
|
|
|
|
|
XtManageChild (shell);
|
|
|
|
|
|
|
|
|
|
/* #### check for destruction here */
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < item_count; i++)
|
|
|
|
|
XmStringFree (items [i]);
|
|
|
|
|
free (items);
|
|
|
|
|
|
|
|
|
|
if (vi_out)
|
|
|
|
|
{
|
|
|
|
|
int index = (int) data.return_value;
|
|
|
|
|
Visual *v = (data.answer == 1 ? vi_out [index].visual : 0);
|
|
|
|
|
XFree ((char *) vi_out);
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void fe_visual_cb (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data *data = (struct fe_confirm_data *) closure;
|
|
|
|
|
XmSelectionBoxCallbackStruct *cb =
|
|
|
|
|
(XmSelectionBoxCallbackStruct *) call_data;
|
|
|
|
|
XmString *items;
|
|
|
|
|
int count;
|
|
|
|
|
int i;
|
|
|
|
|
XtVaGetValues (data->widget,
|
|
|
|
|
XmNlistItems, &items,
|
|
|
|
|
XmNlistItemCount, &count,
|
|
|
|
|
0);
|
|
|
|
|
switch (cb->reason)
|
|
|
|
|
{
|
|
|
|
|
case XmCR_OK:
|
|
|
|
|
case XmCR_APPLY:
|
|
|
|
|
{
|
|
|
|
|
data->answer = 1;
|
|
|
|
|
data->return_value = (void *) -1;
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
if (XmStringCompare (items[i], cb->value))
|
|
|
|
|
data->return_value = (void *) i;
|
|
|
|
|
if (data->return_value == (void *) -1)
|
|
|
|
|
abort ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case XmCR_CANCEL:
|
|
|
|
|
data->answer = 0;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Displaying source
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct fe_source_data
|
|
|
|
|
{
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Widget name, url, text;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static void
|
|
|
|
|
fe_close_source_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
MWContext *context = (MWContext *) closure;
|
|
|
|
|
if (! CONTEXT_DATA (context)->sd) return;
|
|
|
|
|
XtUnmanageChild (CONTEXT_DATA (context)->sd->dialog);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_source_save_as_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
MWContext *context = (MWContext *) closure;
|
|
|
|
|
char *url = 0;
|
|
|
|
|
URL_Struct *url_struct;
|
|
|
|
|
if (! CONTEXT_DATA (context)->sd) return;
|
|
|
|
|
url = fe_GetTextField (CONTEXT_DATA (context)->sd->url);
|
|
|
|
|
if (! url) return;
|
|
|
|
|
url_struct = NET_CreateURLStruct (url, FALSE);
|
|
|
|
|
fe_SaveURL (context, url_struct);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 0 /* This is history. Should remove this code out later. */
|
|
|
|
|
Widget
|
|
|
|
|
fe_ViewSourceDialog (MWContext *context, const char *title, const char *url)
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
struct fe_source_data *sd = CONTEXT_DATA (context)->sd;
|
|
|
|
|
|
|
|
|
|
if (! sd)
|
|
|
|
|
{
|
|
|
|
|
Widget shell, form, text;
|
|
|
|
|
Widget url_label, url_text, title_label, title_text;
|
|
|
|
|
Widget ok_button, save_button;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
sd = (struct fe_source_data *) calloc(sizeof (struct fe_source_data), 1);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++;
|
|
|
|
|
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_INFORMATION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
shell = XmCreateTemplateDialog (mainw, "source", av, ac);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_OK_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
/* fe_UnmanageChild_safe (XmMessageBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_APPLY_BUTTON));*/
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_DEFAULT_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_HELP_BUTTON));
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
save_button = XmCreatePushButtonGadget (shell, "save", av, ac);
|
|
|
|
|
ok_button = XmCreatePushButtonGadget (shell, "OK", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
form = XmCreateForm (shell, "form", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
title_label = XmCreateLabelGadget (form, "titleLabel", av, ac);
|
|
|
|
|
url_label = XmCreateLabelGadget (form, "urlLabel", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av [ac], XmNeditable, False); ac++;
|
|
|
|
|
XtSetArg (av [ac], XmNcursorPositionVisible, False); ac++;
|
|
|
|
|
title_text = fe_CreateTextField (form, "titleText", av, ac);
|
|
|
|
|
url_text = fe_CreateTextField (form, "urlText", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av [ac], XmNeditable, False); ac++;
|
|
|
|
|
XtSetArg (av [ac], XmNcursorPositionVisible, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
|
|
|
|
|
text = XmCreateScrolledText (form, "text", av, ac);
|
|
|
|
|
fe_HackDialogTranslations (text);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (title_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, title_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, title_text,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, title_text,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (url_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, url_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, url_text,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, url_text,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (title_text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (url_text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, title_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, title_text,
|
|
|
|
|
XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNrightWidget, title_text,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (XtParent (text),
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, url_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
fe_attach_field_to_labels (title_text, title_label, url_label, 0);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (save_button, XmNactivateCallback,
|
|
|
|
|
fe_source_save_as_cb, context);
|
|
|
|
|
XtAddCallback (ok_button, XmNactivateCallback,
|
|
|
|
|
fe_close_source_cb, context);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (shell, XmNdefaultButton, save_button, 0);
|
|
|
|
|
|
|
|
|
|
XtManageChild (title_label);
|
|
|
|
|
XtManageChild (title_text);
|
|
|
|
|
XtManageChild (url_label);
|
|
|
|
|
XtManageChild (url_text);
|
|
|
|
|
XtManageChild (text);
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
XtManageChild (save_button);
|
|
|
|
|
XtManageChild (ok_button);
|
|
|
|
|
|
|
|
|
|
sd->dialog = shell;
|
|
|
|
|
sd->text = text;
|
|
|
|
|
sd->url = url_text;
|
|
|
|
|
sd->name = title_text;
|
|
|
|
|
CONTEXT_DATA (context)->sd = sd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (sd->text, XmNcursorPosition, 0);
|
|
|
|
|
fe_SetTextField (sd->text, "");
|
|
|
|
|
XtVaSetValues (sd->name, XmNcursorPosition, 0, 0);
|
|
|
|
|
fe_SetTextField (sd->name, (title ? title : ""));
|
|
|
|
|
XtVaSetValues (sd->url, XmNcursorPosition, 0, 0);
|
|
|
|
|
fe_SetTextField (sd->url, (url ? url : ""));
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (sd->dialog);
|
|
|
|
|
XtManageChild (sd->dialog);
|
|
|
|
|
return sd->text;
|
|
|
|
|
}
|
|
|
|
|
#endif /* 0 */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* User information
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <pwd.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_DefaultUserInfo (char **uid, char **name, Boolean really_default_p)
|
|
|
|
|
{
|
|
|
|
|
struct passwd *pw = getpwuid (geteuid ());
|
|
|
|
|
char *user_name, *tmp;
|
|
|
|
|
char *real_uid = (pw ? pw->pw_name : "");
|
|
|
|
|
char *user_uid = 0;
|
|
|
|
|
|
|
|
|
|
if (really_default_p)
|
|
|
|
|
{
|
|
|
|
|
user_uid = real_uid;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
user_uid = getenv ("LOGNAME");
|
|
|
|
|
if (! user_uid) user_uid = getenv ("USER");
|
|
|
|
|
if (! user_uid) user_uid = real_uid;
|
|
|
|
|
|
|
|
|
|
/* If the env vars claim a different user, get the real name of
|
|
|
|
|
that user instead of the actual user. */
|
|
|
|
|
if (strcmp (user_uid, real_uid))
|
|
|
|
|
{
|
|
|
|
|
struct passwd *pw2 = getpwnam (user_uid);
|
|
|
|
|
if (pw2) pw = pw2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user_uid = strdup (user_uid);
|
|
|
|
|
user_name = strdup ((pw && pw->pw_gecos ? pw->pw_gecos : "&"));
|
|
|
|
|
|
|
|
|
|
/* Terminate the string at the first comma, to lose phone numbers and crap
|
|
|
|
|
like that. This may lose for "Jr."s, but who cares: Unix sucks. */
|
|
|
|
|
if ((tmp = strchr (user_name, ',')))
|
|
|
|
|
*tmp = 0;
|
|
|
|
|
|
|
|
|
|
if ((tmp = strchr (user_name, '&')))
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
char *new = (char *) malloc (strlen (user_name) + strlen (user_uid) + 1);
|
|
|
|
|
for (i = 0, j = 0; user_name[i]; i++)
|
|
|
|
|
if (tmp == user_name + i)
|
|
|
|
|
{
|
|
|
|
|
strcpy (new + j, user_uid);
|
|
|
|
|
new[j] = toupper (new[j]);
|
|
|
|
|
j += strlen (user_uid);
|
|
|
|
|
tmp = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
new[j++] = user_name[i];
|
|
|
|
|
}
|
|
|
|
|
free (user_name);
|
|
|
|
|
user_name = new;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*uid = user_uid;
|
|
|
|
|
*name = user_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Synchronous loading of a URL
|
|
|
|
|
Internally, we use the URL mechanism to do some things during which time
|
|
|
|
|
we want the interface to be blocked - for example, formatting a document
|
|
|
|
|
for inclusion in a mail window, and printing, and so on. This code lets
|
|
|
|
|
us put up a dialog box with a status message and a cancel button, and
|
|
|
|
|
bring it down when the event is over.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* #define SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SYNCHRONOUS_URL_DIALOG_WORKS
|
|
|
|
|
static void
|
|
|
|
|
fe_synchronous_url_cancel_cb (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
MWContext *context = (MWContext *) closure;
|
|
|
|
|
XP_InterruptContext (context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make sure the the popped up modal dialog receives at least
|
|
|
|
|
* on FocusIn event, because Motif seems to expect/require it.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
fe_dialog_expose_eh (Widget widget, XtPointer closure, XEvent *event)
|
|
|
|
|
{
|
|
|
|
|
MWContext *context = (MWContext *) closure;
|
|
|
|
|
Widget dialog = CONTEXT_DATA (context)->synchronous_url_dialog;
|
|
|
|
|
|
|
|
|
|
XtRemoveEventHandler(dialog, ExposureMask, FALSE,
|
|
|
|
|
(XtEventHandler)fe_dialog_expose_eh, context);
|
|
|
|
|
XSetInputFocus(XtDisplay (dialog), XtWindow(dialog),
|
|
|
|
|
RevertToParent, CurrentTime);
|
|
|
|
|
XSync (XtDisplay (dialog), False);
|
|
|
|
|
}
|
|
|
|
|
#endif /* SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_LowerSynchronousURLDialog (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
if (CONTEXT_DATA (context)->synchronous_url_dialog)
|
|
|
|
|
{
|
|
|
|
|
#ifdef SYNCHRONOUS_URL_DIALOG_WORKS
|
|
|
|
|
Widget shell = XtParent (CONTEXT_DATA (context)->synchronous_url_dialog);
|
|
|
|
|
|
|
|
|
|
/* Don't call XP_InterruptContext a (possibly) second time. */
|
|
|
|
|
XtRemoveCallback (CONTEXT_DATA (context)->synchronous_url_dialog,
|
|
|
|
|
XtNdestroyCallback,
|
|
|
|
|
fe_synchronous_url_cancel_cb, context);
|
|
|
|
|
XtUnmanageChild (CONTEXT_DATA (context)->synchronous_url_dialog);
|
|
|
|
|
XSync (XtDisplay (shell), False);
|
|
|
|
|
XtDestroyWidget (shell);
|
|
|
|
|
#endif /* SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_dialog = 0;
|
|
|
|
|
|
|
|
|
|
/* If this context was destroyed, do not proceed furthur */
|
|
|
|
|
if (fe_IsContextDestroyed(context))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
assert (CONTEXT_DATA (context)->active_url_count > 0);
|
|
|
|
|
if (CONTEXT_DATA (context)->active_url_count > 0)
|
|
|
|
|
CONTEXT_DATA (context)->active_url_count--;
|
|
|
|
|
if (CONTEXT_DATA (context)->active_url_count <= 0)
|
|
|
|
|
XFE_AllConnectionsComplete (context);
|
|
|
|
|
fe_SetCursor (context, False);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_synchronous_url_exit (URL_Struct *url, int status, MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
if (status == MK_CHANGING_CONTEXT)
|
|
|
|
|
return;
|
|
|
|
|
fe_LowerSynchronousURLDialog (context);
|
|
|
|
|
if (status < 0 && url->error_msg)
|
|
|
|
|
{
|
|
|
|
|
FE_Alert (context, url->error_msg);
|
|
|
|
|
}
|
|
|
|
|
NET_FreeURLStruct (url);
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_exit_status = status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_RaiseSynchronousURLDialog (MWContext *context, Widget parent,
|
|
|
|
|
const char *title)
|
|
|
|
|
{
|
|
|
|
|
#ifdef SYNCHRONOUS_URL_DIALOG_WORKS
|
|
|
|
|
Widget shell, dialog;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
char title2 [255];
|
|
|
|
|
Boolean popped_up;
|
|
|
|
|
#endif /* SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
CONTEXT_DATA (context)->active_url_count++;
|
|
|
|
|
if (CONTEXT_DATA (context)->active_url_count == 1)
|
|
|
|
|
{
|
|
|
|
|
CONTEXT_DATA (context)->clicking_blocked = True;
|
|
|
|
|
fe_StartProgressGraph (context);
|
|
|
|
|
fe_SetCursor (context, False);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef SYNCHRONOUS_URL_DIALOG_WORKS
|
|
|
|
|
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_dialog = (Widget) ~0;
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_exit_status = 0;
|
|
|
|
|
|
|
|
|
|
#else /* SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
strcpy (title2, title);
|
|
|
|
|
strcat (title2, "_popup");
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, parent); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
shell = XmCreateDialogShell (parent, title2, av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_WORKING); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
dialog = XmCreateMessageBox (shell, (char *) title, av, ac);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_cb, shell);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cb, shell);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_synchronous_url_cancel_cb,
|
|
|
|
|
context);
|
|
|
|
|
XtAddEventHandler(dialog, ExposureMask, FALSE,
|
|
|
|
|
(XtEventHandler)fe_dialog_expose_eh, context);
|
|
|
|
|
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_dialog = dialog;
|
|
|
|
|
CONTEXT_DATA (context)->synchronous_url_exit_status = 0;
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
XSync (XtDisplay (dialog), False);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We wait here until we KNOW the dialog is popped up,
|
|
|
|
|
* otherwise Motif will misbehave.
|
|
|
|
|
*/
|
|
|
|
|
popped_up = FALSE;
|
|
|
|
|
while (!popped_up)
|
|
|
|
|
{
|
|
|
|
|
XEvent event;
|
|
|
|
|
|
|
|
|
|
XtAppNextEvent(XtWidgetToApplicationContext(dialog), &event);
|
|
|
|
|
if ((event.type == Expose)&&(event.xexpose.window == XtWindow(dialog)))
|
|
|
|
|
{
|
|
|
|
|
popped_up = TRUE;
|
|
|
|
|
}
|
|
|
|
|
XtDispatchEvent(&event);
|
|
|
|
|
}
|
|
|
|
|
#endif /* SYNCHRONOUS_URL_DIALOG_WORKS */
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fe_await_synchronous_url (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
/* Loop dispatching X events until the dialog box goes down as a result
|
|
|
|
|
of the exit routine being called (which may be a result of the Cancel
|
|
|
|
|
button being hit. */
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
fe_ProtectContext(context);
|
|
|
|
|
while (CONTEXT_DATA (context)->synchronous_url_dialog)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
fe_UnProtectContext(context);
|
|
|
|
|
status = CONTEXT_DATA (context)->synchronous_url_exit_status;
|
|
|
|
|
if (fe_IsContextDestroyed(context)) {
|
|
|
|
|
free(CONTEXT_DATA(context));
|
|
|
|
|
free(context);
|
|
|
|
|
}
|
|
|
|
|
return (status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fe_GetSynchronousURL (MWContext *context,
|
|
|
|
|
Widget widget_to_grab,
|
|
|
|
|
const char *title,
|
|
|
|
|
URL_Struct *url,
|
|
|
|
|
int output_format,
|
|
|
|
|
void *call_data)
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
url->fe_data = call_data;
|
|
|
|
|
fe_RaiseSynchronousURLDialog (context, widget_to_grab, title);
|
|
|
|
|
status = NET_GetURL (url, output_format, context, fe_synchronous_url_exit);
|
|
|
|
|
if (status < 0)
|
|
|
|
|
return status;
|
|
|
|
|
else
|
|
|
|
|
return fe_await_synchronous_url (context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-09-04 19:21:43 +00:00
|
|
|
|
#if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
/* Sending mail
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void fe_mail_text_modify_cb (Widget, XtPointer, XtPointer);
|
|
|
|
|
|
|
|
|
|
Boolean
|
|
|
|
|
fe_CheckDeferredMail (void)
|
|
|
|
|
{
|
1998-09-04 19:21:43 +00:00
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
1998-03-28 02:44:41 +00:00
|
|
|
|
struct fe_MWContext_cons* rest;
|
|
|
|
|
Boolean haveQueuedMail = False;
|
|
|
|
|
int numMsgs = 0;
|
|
|
|
|
MSG_ViewIndex row = 0;
|
|
|
|
|
|
|
|
|
|
for (rest = fe_all_MWContexts; rest; rest = rest->next) {
|
|
|
|
|
MWContext* context = rest->context;
|
|
|
|
|
fe_MailNewsContextData* d = MAILNEWS_CONTEXT_DATA(context);
|
|
|
|
|
if (context->type == MWContextMail) {
|
|
|
|
|
MSG_CommandStatus (d->folderpane, MSG_DeliverQueuedMessages, NULL, 0,
|
|
|
|
|
&haveQueuedMail, NULL, NULL, NULL);
|
|
|
|
|
if (haveQueuedMail) {
|
|
|
|
|
MSG_FolderLine line;
|
|
|
|
|
/* ###tw This is just too vile for words. */
|
|
|
|
|
while (MSG_GetFolderLineByIndex(d->folderpane, row, 1, &line)) {
|
|
|
|
|
if (line.flags & MSG_FOLDER_FLAG_QUEUE) {
|
|
|
|
|
numMsgs = line.total;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
row++;
|
|
|
|
|
}
|
|
|
|
|
if (numMsgs) {
|
|
|
|
|
char buf [256];
|
|
|
|
|
void * sendNow = 0;
|
|
|
|
|
if (numMsgs == 1)
|
|
|
|
|
sendNow = fe_dialog (CONTEXT_WIDGET (fe_all_MWContexts->context),
|
|
|
|
|
"sendNow",
|
|
|
|
|
XP_GetString (XFE_OUTBOX_CONTAINS_MSG),
|
|
|
|
|
TRUE, 0, TRUE, FALSE, 0);
|
|
|
|
|
else {
|
|
|
|
|
PR_snprintf (buf, 256, XP_GetString (XFE_OUTBOX_CONTAINS_MSGS), numMsgs);
|
|
|
|
|
sendNow = fe_dialog (CONTEXT_WIDGET (fe_all_MWContexts->context),
|
|
|
|
|
"sendNow", buf, TRUE, 0, TRUE, FALSE, 0);
|
|
|
|
|
}
|
|
|
|
|
if (sendNow) {
|
|
|
|
|
MSG_Command (d->folderpane, MSG_DeliverQueuedMessages, NULL, 0);
|
|
|
|
|
return False;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-09-04 19:21:43 +00:00
|
|
|
|
#endif /* MOZ_MAIL_NEWS */
|
1998-03-28 02:44:41 +00:00
|
|
|
|
/* return True means no mail - weird, but consistent
|
|
|
|
|
* with fe_CheckUnsentMail below. We can change them
|
|
|
|
|
* later.
|
|
|
|
|
*/
|
|
|
|
|
return True;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean
|
|
|
|
|
fe_CheckUnsentMail (void)
|
|
|
|
|
{
|
|
|
|
|
struct fe_MWContext_cons* rest;
|
|
|
|
|
for (rest = fe_all_MWContexts; rest; rest = rest->next) {
|
|
|
|
|
MWContext* context = rest->context;
|
|
|
|
|
if (context->type == MWContextMessageComposition) {
|
|
|
|
|
return XFE_Confirm(fe_all_MWContexts->context,
|
|
|
|
|
fe_globalData.unsent_mail_message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static char* fe_last_attach_type = NULL;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_del_attachment(struct fe_mail_attach_data *mad, int pos)
|
|
|
|
|
{
|
|
|
|
|
if (pos > mad->nattachments) return;
|
|
|
|
|
else XP_ASSERT(pos <= mad->nattachments);
|
|
|
|
|
|
|
|
|
|
pos--;
|
|
|
|
|
if (mad->attachments[pos].url)
|
|
|
|
|
XP_FREE((char *)mad->attachments[pos].url);
|
|
|
|
|
pos++;
|
|
|
|
|
while (pos < mad->nattachments) {
|
|
|
|
|
mad->attachments[pos-1] = mad->attachments[pos];
|
|
|
|
|
pos++;
|
|
|
|
|
}
|
|
|
|
|
mad->nattachments--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_add_attachmentData(struct fe_mail_attach_data *mad,
|
|
|
|
|
const struct MSG_AttachmentData *data)
|
|
|
|
|
{
|
|
|
|
|
struct MSG_AttachmentData *m;
|
|
|
|
|
char *name = (char *)data->url;
|
|
|
|
|
XmString xmstr;
|
|
|
|
|
|
|
|
|
|
if (!name || !*name) return;
|
|
|
|
|
|
|
|
|
|
if (mad->nattachments >= XFE_MAX_ATTACHMENTS) return;
|
|
|
|
|
else XP_ASSERT(mad->nattachments < XFE_MAX_ATTACHMENTS);
|
|
|
|
|
|
|
|
|
|
xmstr = XmStringCreate(name, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
XmListAddItem(mad->list, xmstr, 0);
|
|
|
|
|
|
|
|
|
|
m = &mad->attachments[mad->nattachments];
|
|
|
|
|
*m = *data;
|
|
|
|
|
m->url = XP_STRDUP(data->url);
|
|
|
|
|
|
|
|
|
|
mad->nattachments++;
|
|
|
|
|
if (mad->nattachments == 1)
|
|
|
|
|
XmListSelectPos(mad->list, 1, True);
|
|
|
|
|
|
|
|
|
|
XmListSelectItem(mad->list, xmstr, TRUE);
|
|
|
|
|
XmStringFree(xmstr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_add_attachment(struct fe_mail_attach_data *mad, char *name)
|
|
|
|
|
{
|
|
|
|
|
struct MSG_AttachmentData m = {0};
|
|
|
|
|
Boolean b;
|
|
|
|
|
XmString xmstr;
|
|
|
|
|
|
|
|
|
|
if (!name || !*name) return;
|
|
|
|
|
|
|
|
|
|
if(mad->nattachments >= XFE_MAX_ATTACHMENTS) return;
|
|
|
|
|
else XP_ASSERT(mad->nattachments < XFE_MAX_ATTACHMENTS);
|
|
|
|
|
|
|
|
|
|
xmstr = XmStringCreate(name, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
XmListAddItem(mad->list, xmstr, 0);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mad->text_p, XmNset, &b, 0);
|
|
|
|
|
if (b)
|
|
|
|
|
m.desired_type = TEXT_PLAIN;
|
|
|
|
|
else {
|
|
|
|
|
XtVaGetValues (mad->postscript_p, XmNset, &b, 0);
|
|
|
|
|
if (b)
|
|
|
|
|
m.desired_type = APPLICATION_POSTSCRIPT;
|
|
|
|
|
}
|
|
|
|
|
m.url = name;
|
|
|
|
|
|
|
|
|
|
mad->attachments[mad->nattachments] = m;
|
|
|
|
|
mad->nattachments++;
|
|
|
|
|
|
|
|
|
|
XmListSelectItem(mad->list, xmstr, TRUE);
|
|
|
|
|
XmStringFree(xmstr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************
|
|
|
|
|
* Location popup related routines *
|
|
|
|
|
***********************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_locationOk_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
char *url = fe_GetTextField(mad->location_text);
|
|
|
|
|
|
|
|
|
|
if (url && *url)
|
|
|
|
|
fe_add_attachment(mad, url);
|
|
|
|
|
else
|
|
|
|
|
if (url) XtFree(url);
|
|
|
|
|
XtUnmanageChild(mad->location_shell);
|
|
|
|
|
}
|
|
|
|
|
static void
|
|
|
|
|
fe_locationClear_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
fe_SetTextField (mad->location_text, "");
|
|
|
|
|
/* Focus on the text widget after this, since otherwise you have to
|
|
|
|
|
click again. */
|
|
|
|
|
XmProcessTraversal (mad->location_text, XmTRAVERSE_CURRENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_locationCancel_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
XtUnmanageChild(mad->location_shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_make_location(struct fe_mail_attach_data *mad)
|
|
|
|
|
{
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget parent;
|
|
|
|
|
Widget form;
|
|
|
|
|
Widget label, location_label, location_text;
|
|
|
|
|
Widget ok_button, clear_button, cancel_button;
|
|
|
|
|
|
|
|
|
|
Widget kids [20];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (mad->location_shell) return;
|
|
|
|
|
|
|
|
|
|
#ifdef dp_DEBUG
|
|
|
|
|
fprintf(stderr, "Making attach_location widgets : fe_attach_make_location().\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
parent = CONTEXT_WIDGET(mad->context);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNallowShellResize, True); ac++; */
|
|
|
|
|
/* XtSetArg (av[ac], XmNtransientFor, parent); ac++; */
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmUNMAP); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++;
|
|
|
|
|
shell = XmCreateTemplateDialog (parent, "location_popup", av, ac);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_OK_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_DEFAULT_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
ok_button = XmCreatePushButtonGadget (shell, "OK", av, ac);
|
|
|
|
|
clear_button = XmCreatePushButtonGadget (shell, "clear", av, ac);
|
|
|
|
|
cancel_button = XmCreatePushButtonGadget (shell, "cancel", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
form = XmCreateForm(shell, "form", av, ac);
|
|
|
|
|
label = XmCreateLabelGadget( form, "label", av, ac);
|
|
|
|
|
location_label = XmCreateLabelGadget( form, "locationLabel", av, ac);
|
|
|
|
|
location_text = fe_CreateTextField( form, "locationText", av, ac);
|
|
|
|
|
|
|
|
|
|
if (fe_globalData.nonterminal_text_translations)
|
|
|
|
|
XtOverrideTranslations (location_text, fe_globalData.
|
|
|
|
|
nonterminal_text_translations);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (location_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, label,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (location_text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, label,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, location_label,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
_XfeHeight(location_label) = _XfeHeight(location_text);
|
|
|
|
|
|
|
|
|
|
XtAddCallback(ok_button, XmNactivateCallback, fe_locationOk_cb, mad);
|
|
|
|
|
XtAddCallback(clear_button, XmNactivateCallback, fe_locationClear_cb, mad);
|
|
|
|
|
XtAddCallback(cancel_button, XmNactivateCallback, fe_locationCancel_cb, mad);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const char *str = MSG_GetAssociatedURL (mad->comppane);
|
|
|
|
|
fe_SetTextFieldAndCallBack (location_text, (char *) (str ? str : ""));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fe_HackDialogTranslations (form);
|
|
|
|
|
|
|
|
|
|
mad->location_shell = shell;
|
|
|
|
|
i = 0;
|
|
|
|
|
kids[i++] = mad->location_text = location_text;
|
|
|
|
|
kids[i++] = location_label;
|
|
|
|
|
kids[i++] = label;
|
|
|
|
|
XtManageChildren(kids, i);
|
|
|
|
|
i = 0;
|
|
|
|
|
kids[i++] = ok_button;
|
|
|
|
|
kids[i++] = clear_button;
|
|
|
|
|
kids[i++] = cancel_button;
|
|
|
|
|
XtManageChildren(kids, i);
|
|
|
|
|
|
|
|
|
|
XtManageChild(form);
|
|
|
|
|
XtManageChild(shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*************************
|
|
|
|
|
* File Attachment popup *
|
|
|
|
|
*************************/
|
|
|
|
|
static void
|
|
|
|
|
fe_attachFile_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
XmFileSelectionBoxCallbackStruct *sbc =
|
|
|
|
|
(XmFileSelectionBoxCallbackStruct *) call_data;
|
|
|
|
|
char *file;
|
|
|
|
|
char *msg;
|
|
|
|
|
|
|
|
|
|
switch (sbc->reason) {
|
|
|
|
|
case XmCR_NO_MATCH:
|
|
|
|
|
XBell (XtDisplay (widget), 0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XmCR_OK:
|
|
|
|
|
XmStringGetLtoR (sbc->value, XmFONTLIST_DEFAULT_TAG, &file);
|
|
|
|
|
if (!fe_isFileExist(file)) {
|
|
|
|
|
msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST ), file);
|
|
|
|
|
if (msg) {
|
|
|
|
|
fe_Alert_2(XtParent(mad->file_shell), msg);
|
|
|
|
|
XP_FREE(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (!fe_isFileReadable(file)) {
|
|
|
|
|
msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE ) , file);
|
|
|
|
|
if (msg) {
|
|
|
|
|
fe_Alert_2(XtParent(mad->file_shell), msg);
|
|
|
|
|
XP_FREE(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (fe_isDir(file)) {
|
|
|
|
|
msg = PR_smprintf( XP_GetString( XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY ), file);
|
|
|
|
|
if (msg) {
|
|
|
|
|
fe_Alert_2(XtParent(mad->file_shell), msg);
|
|
|
|
|
if (msg) XP_FREE(msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fe_add_attachment(mad, file);
|
|
|
|
|
XtUnmanageChild(mad->file_shell);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case XmCR_CANCEL:
|
|
|
|
|
XtUnmanageChild(mad->file_shell);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_make_file(struct fe_mail_attach_data *mad)
|
|
|
|
|
{
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget parent;
|
|
|
|
|
Widget fileb;
|
|
|
|
|
Boolean dirp = False;
|
|
|
|
|
|
|
|
|
|
if (mad->file_shell) return;
|
|
|
|
|
|
|
|
|
|
#ifdef dp_DEBUG
|
|
|
|
|
fprintf(stderr, "Making attach_file widgets : fe_attach_make_file().\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
parent = CONTEXT_WIDGET (mad->context);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNallowShellResize, True); ac++;*/
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmUNMAP); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++;
|
|
|
|
|
shell = XmCreateDialogShell (parent, "fileBrowser_popup", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNfileTypeMask,
|
|
|
|
|
(dirp ? XmFILE_DIRECTORY : XmFILE_REGULAR)); ac++;
|
|
|
|
|
fileb = fe_CreateFileSelectionBox (shell, "fileBrowser", av, ac);
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (fileb, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
XtAddCallback(fileb, XmNnoMatchCallback, fe_attachFile_cb, mad);
|
|
|
|
|
XtAddCallback(fileb, XmNokCallback, fe_attachFile_cb, mad);
|
|
|
|
|
XtAddCallback(fileb, XmNcancelCallback, fe_attachFile_cb, mad);
|
|
|
|
|
|
|
|
|
|
mad->file_shell = fileb;
|
|
|
|
|
|
|
|
|
|
fe_HackDialogTranslations (fileb);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (fileb);
|
|
|
|
|
XtManageChild (fileb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_doc_type_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
int *poslist, npos;
|
|
|
|
|
int attach_pos = -1;
|
|
|
|
|
|
|
|
|
|
if (XmListGetSelectedPos(mad->list, &poslist, &npos)) {
|
|
|
|
|
attach_pos = poslist[npos - 1] - 1;
|
|
|
|
|
XP_FREE(poslist);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* my how intuitive, if the file is attach as source, desired type = NULL.
|
|
|
|
|
*/
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
if (widget == mad->text_p) {
|
|
|
|
|
XtVaSetValues (mad->source_p, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (mad->postscript_p, XmNset, False, 0);
|
|
|
|
|
if (attach_pos >= 0)
|
|
|
|
|
mad->attachments[attach_pos].desired_type = TEXT_PLAIN;
|
|
|
|
|
}
|
|
|
|
|
else if (widget == mad->source_p) {
|
|
|
|
|
XtVaSetValues (mad->text_p, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (mad->postscript_p, XmNset, False, 0);
|
|
|
|
|
if (attach_pos >= 0)
|
|
|
|
|
mad->attachments[attach_pos].desired_type = NULL;
|
|
|
|
|
}
|
|
|
|
|
else if (widget == mad->postscript_p) {
|
|
|
|
|
XtVaSetValues (mad->source_p, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (mad->text_p, XmNset, False, 0);
|
|
|
|
|
if (attach_pos >= 0)
|
|
|
|
|
mad->attachments[attach_pos].desired_type = APPLICATION_POSTSCRIPT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attachDestroy_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
#ifdef dp_DEBUG
|
|
|
|
|
fprintf(stderr, "fe_attachDestroy_cb()\n");
|
|
|
|
|
fprintf(stderr, "Destroying fe_mail_attach_data...\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Free the list of attachments too */
|
|
|
|
|
for(i=0; i<mad->nattachments; i++) {
|
|
|
|
|
XP_FREE((char *)mad->attachments[i].url);
|
|
|
|
|
}
|
|
|
|
|
if (mad->location_shell)
|
|
|
|
|
XtDestroyWidget(mad->location_shell);
|
|
|
|
|
if (mad->file_shell)
|
|
|
|
|
XtDestroyWidget(XtParent(mad->file_shell));
|
|
|
|
|
CONTEXT_DATA(mad->context) ->mad = NULL;
|
|
|
|
|
free (mad);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attachCancel_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
|
|
|
|
|
/* We dont need to delete all the attachments that we have as they will
|
|
|
|
|
be deleted either the next time we show the attach window (or) when
|
|
|
|
|
the message composition context gets destroyed */
|
|
|
|
|
|
|
|
|
|
XtUnmanageChild(mad->shell);
|
|
|
|
|
if (mad->location_shell)
|
|
|
|
|
XtUnmanageChild(mad->location_shell);
|
|
|
|
|
if (mad->file_shell)
|
|
|
|
|
XtUnmanageChild(mad->file_shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attachOk_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
const char* ptr;
|
|
|
|
|
|
|
|
|
|
mad->attachments[mad->nattachments].url = NULL;
|
|
|
|
|
MSG_SetAttachmentList(mad->comppane, mad->attachments);
|
|
|
|
|
ptr = MSG_GetCompHeader(mad->comppane, MSG_ATTACHMENTS_HEADER_MASK);
|
|
|
|
|
fe_SetTextFieldAndCallBack(CONTEXT_DATA(mad->context)->mcAttachments,
|
|
|
|
|
ptr ? (char*) ptr : "");
|
|
|
|
|
|
|
|
|
|
/* We dont need to delete all the attachments that we have as they will
|
|
|
|
|
be deleted either the next time we show the attach window (or) when
|
|
|
|
|
the message composition context gets destroyed */
|
|
|
|
|
|
|
|
|
|
XtUnmanageChild(mad->shell);
|
|
|
|
|
if (mad->location_shell)
|
|
|
|
|
XtUnmanageChild(mad->location_shell);
|
|
|
|
|
if (mad->file_shell)
|
|
|
|
|
XtUnmanageChild(mad->file_shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_location_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
|
|
|
|
|
if (!mad->location_shell) fe_attach_make_location(mad);
|
|
|
|
|
|
|
|
|
|
XtManageChild(mad->location_shell);
|
|
|
|
|
XMapRaised(XtDisplay(mad->location_shell), XtWindow(mad->location_shell));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_file_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
|
|
|
|
|
if (!mad->file_shell) fe_attach_make_file(mad);
|
|
|
|
|
|
|
|
|
|
XtManageChild(mad->file_shell);
|
|
|
|
|
XMapRaised(XtDisplay(mad->file_shell), XtWindow(mad->file_shell));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_delete_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
int *poslist, npos;
|
|
|
|
|
int i, pos;
|
|
|
|
|
|
|
|
|
|
if (XmListGetSelectedPos(mad->list, &poslist, &npos)) {
|
|
|
|
|
for(i=0; i<npos; i++) {
|
|
|
|
|
XmListDeletePos(mad->list, poslist[i]);
|
|
|
|
|
fe_del_attachment(mad, poslist[i]);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* After deleting an item from the list, select the
|
|
|
|
|
* previous item in the list (or the last if it was
|
|
|
|
|
* the first.)
|
|
|
|
|
*/
|
|
|
|
|
pos = poslist[npos - 1] - 1;
|
|
|
|
|
if (pos < 0)
|
|
|
|
|
pos = 0;
|
|
|
|
|
XmListSelectPos(mad->list, pos, TRUE);
|
|
|
|
|
XP_FREE(poslist);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If nothing left in the list selected, desensitize
|
|
|
|
|
* the delete button.
|
|
|
|
|
*/
|
|
|
|
|
if (!XmListGetSelectedPos(mad->list, &poslist, &npos)) {
|
|
|
|
|
XtVaSetValues(mad->delete, XmNsensitive, False, 0);
|
|
|
|
|
}
|
|
|
|
|
else XP_FREE(poslist);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_attach_select_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = (struct fe_mail_attach_data *) closure;
|
|
|
|
|
XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
|
|
|
|
|
const char *s;
|
|
|
|
|
Widget which_w = 0;
|
|
|
|
|
|
|
|
|
|
if (cbs->item_position > mad->nattachments) return;
|
|
|
|
|
else XP_ASSERT(cbs->item_position <= mad->nattachments);
|
|
|
|
|
|
|
|
|
|
s = mad->attachments[cbs->item_position-1].desired_type;
|
|
|
|
|
|
|
|
|
|
if (!s || !*s)
|
|
|
|
|
which_w = mad->source_p;
|
|
|
|
|
else if (!XP_STRCMP(s, APPLICATION_POSTSCRIPT))
|
|
|
|
|
which_w = mad->postscript_p;
|
|
|
|
|
else if (!XP_STRCMP(s, TEXT_PLAIN))
|
|
|
|
|
which_w = mad->text_p;
|
|
|
|
|
|
|
|
|
|
if (which_w == 0) return;
|
|
|
|
|
else XP_ASSERT (which_w != 0);
|
|
|
|
|
fe_attach_doc_type_cb(which_w, mad, NULL);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues(mad->delete, XmNsensitive, True, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_make_attach_dialog(MWContext* context)
|
|
|
|
|
{
|
|
|
|
|
fe_ContextData* data = CONTEXT_DATA(context);
|
|
|
|
|
Widget shell, form;
|
|
|
|
|
Widget list;
|
|
|
|
|
Widget messb;
|
|
|
|
|
Widget attach_location, attach_file, delete;
|
|
|
|
|
Widget label;
|
|
|
|
|
Widget text_p, source_p, postscript_p;
|
|
|
|
|
Widget ok_button, cancel_button;
|
|
|
|
|
Widget kids [50];
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
struct fe_mail_attach_data *mad = data->mad;
|
|
|
|
|
|
|
|
|
|
XP_ASSERT(context->type == MWContextMessageComposition);
|
|
|
|
|
|
|
|
|
|
if (mad && mad->shell)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (CONTEXT_WIDGET(context), XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, CONTEXT_WIDGET(context)); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
shell = XmCreateTemplateDialog (CONTEXT_WIDGET(context), "attach", av, ac);
|
|
|
|
|
/* fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_SEPARATOR)); */
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_OK_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
/* fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_APPLY_BUTTON));*/
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_DEFAULT_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (shell, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
ok_button = XmCreatePushButtonGadget (shell, "OK", av, ac);
|
|
|
|
|
cancel_button = XmCreatePushButtonGadget (shell, "cancel", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
|
|
|
|
|
form = XmCreateForm (shell, "form", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_WORK_AREA); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNresizePolicy, XmRESIZE_GROW); ac++;
|
|
|
|
|
messb = XmCreateMessageBox(form, "messagebox", av, ac);
|
|
|
|
|
fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_OK_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe(XmMessageBoxGetChild(messb, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
ac = 0;
|
|
|
|
|
list = XmCreateList(messb, "list", av, ac);
|
|
|
|
|
attach_location = XmCreatePushButtonGadget(messb, "attachLocation", av, ac);
|
|
|
|
|
attach_file = XmCreatePushButtonGadget(messb, "attachFile", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNsensitive, False); ac++;
|
|
|
|
|
delete = XmCreatePushButtonGadget(messb, "delete", av, ac);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
label = XmCreateLabelGadget (form, "label", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNset, False); ac++;
|
|
|
|
|
source_p = XmCreateToggleButtonGadget (form, "sourceToggle", av, ac);
|
|
|
|
|
text_p = XmCreateToggleButtonGadget (form, "textToggle", av, ac);
|
|
|
|
|
postscript_p = XmCreateToggleButtonGadget (form, "postscriptToggle", av, ac);
|
|
|
|
|
|
|
|
|
|
/* Making the attachments in such a way that the list would grow is
|
|
|
|
|
the height of the dialog is increased */
|
|
|
|
|
XtVaSetValues (messb,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (source_p,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, label,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, label,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (text_p,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, label,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, source_p,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (postscript_p,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, label,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, text_p,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
#ifdef dp_DEBUG
|
|
|
|
|
fprintf(stderr, "Creating new fe_mail_attach_data...\n");
|
|
|
|
|
#endif
|
|
|
|
|
data->mad = mad = (struct fe_mail_attach_data *)
|
|
|
|
|
calloc (sizeof (struct fe_mail_attach_data), 1);
|
|
|
|
|
mad->nattachments = 0;
|
|
|
|
|
|
|
|
|
|
mad->context = context;
|
|
|
|
|
mad->shell = shell;
|
|
|
|
|
mad->list = list;
|
|
|
|
|
mad->comppane = data->comppane;
|
|
|
|
|
|
|
|
|
|
XtManageChild(list);
|
|
|
|
|
ac = 0;
|
|
|
|
|
kids [ac++] = attach_location;
|
|
|
|
|
kids [ac++] = mad->attach_file = attach_file;
|
|
|
|
|
kids [ac++] = mad->delete = delete;
|
|
|
|
|
XtManageChildren (kids, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
kids [ac++] = messb;
|
|
|
|
|
kids [ac++] = label;
|
|
|
|
|
kids [ac++] = mad->source_p = source_p;
|
|
|
|
|
kids [ac++] = mad->text_p = text_p;
|
|
|
|
|
kids [ac++] = mad->postscript_p = postscript_p;
|
|
|
|
|
|
|
|
|
|
XtManageChildren (kids, ac);
|
|
|
|
|
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
XtManageChild (ok_button);
|
|
|
|
|
XtManageChild (cancel_button);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (ok_button, XmNactivateCallback, fe_attachOk_cb, mad);
|
|
|
|
|
XtAddCallback (cancel_button, XmNactivateCallback, fe_attachCancel_cb, mad);
|
|
|
|
|
XtAddCallback (shell, XtNdestroyCallback, fe_attachDestroy_cb, mad);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (attach_location, XmNactivateCallback,
|
|
|
|
|
fe_attach_location_cb, mad);
|
|
|
|
|
XtAddCallback (attach_file, XmNactivateCallback, fe_attach_file_cb, mad);
|
|
|
|
|
XtAddCallback (delete, XmNactivateCallback, fe_attach_delete_cb, mad);
|
|
|
|
|
XtAddCallback (list, XmNbrowseSelectionCallback, fe_attach_select_cb, mad);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (text_p, XmNvalueChangedCallback,
|
|
|
|
|
fe_attach_doc_type_cb, mad);
|
|
|
|
|
XtAddCallback (source_p, XmNvalueChangedCallback,
|
|
|
|
|
fe_attach_doc_type_cb, mad);
|
|
|
|
|
XtAddCallback (postscript_p, XmNvalueChangedCallback,
|
|
|
|
|
fe_attach_doc_type_cb, mad);
|
|
|
|
|
|
|
|
|
|
/* Remember the last attachment typed used. */
|
|
|
|
|
XtVaSetValues((fe_last_attach_type == NULL ? source_p :
|
|
|
|
|
strcmp(fe_last_attach_type, TEXT_PLAIN) == 0 ? text_p :
|
|
|
|
|
strcmp(fe_last_attach_type,
|
|
|
|
|
APPLICATION_POSTSCRIPT) == 0 ? postscript_p :
|
|
|
|
|
source_p),
|
|
|
|
|
XmNset, True, 0);
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
/* Decide whether to attach a file or a URL based on what the URL is.
|
|
|
|
|
If there's something in the Attachement: field already, use that.
|
|
|
|
|
Otherwise, use the document associated with this mail window.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
char *string = 0;
|
|
|
|
|
const char *url = 0;
|
|
|
|
|
const char *file;
|
|
|
|
|
|
|
|
|
|
string = fe_GetTextField (data->mcAttachments);
|
|
|
|
|
|
|
|
|
|
url = fe_StringTrim(string);
|
|
|
|
|
if (url && !*url) {
|
|
|
|
|
url = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!url) {
|
|
|
|
|
url = MSG_GetAssociatedURL(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! url)
|
|
|
|
|
file = 0;
|
|
|
|
|
else if (url[0] == '/')
|
|
|
|
|
file = url;
|
|
|
|
|
else if (!strncasecomp (url, "file://localhost/", 17))
|
|
|
|
|
file = url + 16;
|
|
|
|
|
else if (!strncasecomp (url, "file://", 7))
|
|
|
|
|
file = 0;
|
|
|
|
|
else if (!strncasecomp (url, "file:/", 6))
|
|
|
|
|
file = url + 5;
|
|
|
|
|
else
|
|
|
|
|
file = 0;
|
|
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
|
fe_SetTextField (file_text, file);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (doc_p, XmNset, True, 0);
|
|
|
|
|
fe_SetTextField (doc_text, url);
|
|
|
|
|
if (string) free (string);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (shell);
|
|
|
|
|
XtManageChild (shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Prompts for attachment info.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
fe_mailto_attach_dialog(MWContext* context)
|
|
|
|
|
{
|
|
|
|
|
struct fe_mail_attach_data *mad = CONTEXT_DATA(context)->mad;
|
|
|
|
|
const struct MSG_AttachmentData *list;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
XP_ASSERT(context->type == MWContextMessageComposition);
|
|
|
|
|
|
|
|
|
|
if (!mad || !mad->shell) {
|
|
|
|
|
fe_make_attach_dialog(context);
|
|
|
|
|
mad = CONTEXT_DATA(context)->mad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free the existing list of attachments */
|
|
|
|
|
XmListDeleteAllItems(mad->list);
|
|
|
|
|
for(i=0; i<mad->nattachments; i++) {
|
|
|
|
|
XP_FREE((char *)mad->attachments[i].url);
|
|
|
|
|
}
|
|
|
|
|
mad->nattachments = 0;
|
|
|
|
|
|
|
|
|
|
/* Refresh the list of attachments */
|
|
|
|
|
list = MSG_GetAttachmentList(mad->comppane);
|
|
|
|
|
while (list && list->url != NULL) {
|
|
|
|
|
fe_add_attachmentData(mad, list);
|
|
|
|
|
list++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtManageChild(mad->shell);
|
|
|
|
|
XMapRaised(XtDisplay(mad->shell), XtWindow(mad->shell));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_attach_dropfunc(Widget dropw, void* closure, fe_dnd_Event type,
|
|
|
|
|
fe_dnd_Source* source, XEvent* event)
|
|
|
|
|
{
|
|
|
|
|
MWContext *compose_context;
|
|
|
|
|
MWContext *src_context;
|
|
|
|
|
const struct MSG_AttachmentData *old_list, *a;
|
|
|
|
|
struct MSG_AttachmentData *new_list;
|
|
|
|
|
Boolean sensitive_p = False;
|
|
|
|
|
char **urls, **ss;
|
|
|
|
|
const char* s;
|
|
|
|
|
int old_count = 0;
|
|
|
|
|
int new_count = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (type != FE_DND_DROP)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
compose_context = (MWContext *) closure;
|
|
|
|
|
if (!compose_context) return;
|
|
|
|
|
XP_ASSERT(compose_context->type == MWContextMessageComposition);
|
|
|
|
|
if (compose_context->type != MWContextMessageComposition)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues(CONTEXT_DATA(compose_context)->mcAttachments,
|
|
|
|
|
XmNsensitive, &sensitive_p, 0);
|
|
|
|
|
if (!sensitive_p)
|
|
|
|
|
{
|
|
|
|
|
/* If the Attachments field is not sensitive, then that means that
|
|
|
|
|
an attachment (or delivery?) is in progress, and bad things would
|
|
|
|
|
happen were we to try and attach things right now. So just beep.
|
|
|
|
|
*/
|
|
|
|
|
XBell (XtDisplay (CONTEXT_WIDGET(compose_context)), 0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
src_context = fe_WidgetToMWContext((Widget) source->closure);
|
|
|
|
|
if (!src_context) return;
|
|
|
|
|
switch (src_context->type)
|
|
|
|
|
{
|
|
|
|
|
case MWContextMail:
|
|
|
|
|
case MWContextNews:
|
|
|
|
|
/* ###tw Should get a list of all the selected URLs from the mail/news
|
|
|
|
|
window...*/
|
|
|
|
|
urls = 0;
|
|
|
|
|
break;
|
|
|
|
|
case MWContextBookmarks:
|
|
|
|
|
/* #### Get a list of all the selected URLs out of the bookmarks
|
|
|
|
|
window... */
|
|
|
|
|
urls = 0;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
XP_ASSERT(0);
|
|
|
|
|
urls = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!urls)
|
|
|
|
|
{
|
|
|
|
|
XBell (XtDisplay (CONTEXT_WIDGET(compose_context)), 0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
new_count = 0;
|
|
|
|
|
for (ss = urls; *ss; ss++)
|
|
|
|
|
new_count++;
|
|
|
|
|
XP_ASSERT(new_count > 0);
|
|
|
|
|
if (new_count <= 0) return; /* #### leaks `urls'; but it already asserted. */
|
|
|
|
|
|
|
|
|
|
old_list = MSG_GetAttachmentList(CONTEXT_DATA(compose_context)->comppane);
|
|
|
|
|
old_count = 0;
|
|
|
|
|
if (old_list)
|
|
|
|
|
for (a = old_list; a->url; a++)
|
|
|
|
|
old_count++;
|
|
|
|
|
|
|
|
|
|
new_list = (struct MSG_AttachmentData *)
|
|
|
|
|
XP_ALLOC(sizeof(struct MSG_AttachmentData) * (old_count + new_count + 1));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < old_count; i++)
|
|
|
|
|
{
|
|
|
|
|
XP_MEMSET(&new_list[i], 0, sizeof(new_list[i]));
|
|
|
|
|
if (old_list[i].url)
|
|
|
|
|
new_list[i].url = XP_STRDUP(old_list[i].url);
|
|
|
|
|
if (old_list[i].desired_type)
|
|
|
|
|
new_list[i].desired_type = XP_STRDUP(old_list[i].desired_type);
|
|
|
|
|
if (old_list[i].real_type)
|
|
|
|
|
new_list[i].real_type = XP_STRDUP(old_list[i].real_type);
|
|
|
|
|
if (old_list[i].real_encoding)
|
|
|
|
|
new_list[i].real_encoding = XP_STRDUP(old_list[i].real_encoding);
|
|
|
|
|
if (old_list[i].real_name)
|
|
|
|
|
new_list[i].real_name = XP_STRDUP(old_list[i].real_name);
|
|
|
|
|
if (old_list[i].description)
|
|
|
|
|
new_list[i].description = XP_STRDUP(old_list[i].description);
|
|
|
|
|
if (old_list[i].x_mac_type)
|
|
|
|
|
new_list[i].x_mac_type = XP_STRDUP(old_list[i].x_mac_type);
|
|
|
|
|
if (old_list[i].x_mac_creator)
|
|
|
|
|
new_list[i].x_mac_creator = XP_STRDUP(old_list[i].x_mac_creator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (new_count > 0)
|
|
|
|
|
XP_MEMSET(new_list + old_count, 0,
|
|
|
|
|
sizeof(struct MSG_AttachmentData) * (new_count + 1));
|
|
|
|
|
|
|
|
|
|
i = old_count;
|
|
|
|
|
for (ss = urls; *ss; ss++)
|
|
|
|
|
new_list[i++].url = *ss;
|
|
|
|
|
|
|
|
|
|
MSG_SetAttachmentList(CONTEXT_DATA(compose_context)->comppane, new_list);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < old_count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (new_list[i].url) XP_FREE((char*)new_list[i].url);
|
|
|
|
|
if (new_list[i].desired_type) XP_FREE((char*)new_list[i].desired_type);
|
|
|
|
|
if (new_list[i].real_type) XP_FREE((char*)new_list[i].real_type);
|
|
|
|
|
if (new_list[i].real_encoding) XP_FREE((char*)new_list[i].real_encoding);
|
|
|
|
|
if (new_list[i].real_name) XP_FREE((char*)new_list[i].real_name);
|
|
|
|
|
if (new_list[i].description) XP_FREE((char*)new_list[i].description);
|
|
|
|
|
if (new_list[i].x_mac_type) XP_FREE((char*)new_list[i].x_mac_type);
|
|
|
|
|
if (new_list[i].x_mac_creator) XP_FREE((char*)new_list[i].x_mac_creator);
|
|
|
|
|
}
|
|
|
|
|
XP_FREE (new_list);
|
|
|
|
|
for (ss = urls; *ss; ss++)
|
|
|
|
|
XP_FREE(*ss);
|
|
|
|
|
XP_FREE(urls);
|
|
|
|
|
|
|
|
|
|
/* Now they're attached; update the display. */
|
|
|
|
|
s = MSG_GetCompHeader(CONTEXT_DATA(compose_context)->comppane,
|
|
|
|
|
MSG_ATTACHMENTS_HEADER_MASK);
|
|
|
|
|
fe_SetTextFieldAndCallBack(CONTEXT_DATA(compose_context)->mcAttachments,
|
|
|
|
|
s ? (char*) s : "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* 0 */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
FE_GetMessageBody (MSG_Pane* comppane,
|
|
|
|
|
char **body,
|
|
|
|
|
uint32 *body_size,
|
|
|
|
|
MSG_FontCode **font_changes)
|
|
|
|
|
{
|
|
|
|
|
MWContext* context = MSG_GetContext(comppane);
|
|
|
|
|
if (context->type != MWContextMessageComposition) return -1;
|
|
|
|
|
fe_getMessageBody(context, body, body_size, font_changes);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
FE_DoneWithMessageBody(MSG_Pane* comppane, char* body, uint32 body_size)
|
|
|
|
|
{
|
|
|
|
|
MWContext* context = MSG_GetContext(comppane);
|
|
|
|
|
fe_doneWithMessageBody(context, body, body_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_mail_text_modify_cb (Widget text, XtPointer client_data,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
MWContext* context = (MWContext*) client_data;
|
|
|
|
|
CONTEXT_DATA(context)->mcCitedAndUnedited = False;
|
|
|
|
|
CONTEXT_DATA(context)->mcEdited = True;
|
|
|
|
|
/* MSG_MessageBodyEdited(CONTEXT_DATA(context)->comppane); */
|
|
|
|
|
}
|
|
|
|
|
|
1998-09-04 19:21:43 +00:00
|
|
|
|
#endif /* MOZ_MAIL_NEWS || MOZ_MAIL_COMPOSE */
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
#define cite_abort 0
|
|
|
|
|
#define cite_protect_me_from_myself 1
|
|
|
|
|
#define cite_let_me_be_a_loser 2
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static int
|
|
|
|
|
FE_BogusQuotationQuery (MWContext *context, Boolean double_p)
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
Widget parent = CONTEXT_WIDGET (context);
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, parent); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
dialog = XmCreatePromptDialog (parent, (double_p ?
|
|
|
|
|
"citationQuery"
|
|
|
|
|
: "doubleCitationQuery")
|
|
|
|
|
, av, ac);
|
|
|
|
|
|
|
|
|
|
/* fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR));*/
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNapplyCallback, fe_destroy_apply_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = dialog;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
return (data.answer == 0 ? cite_abort :
|
|
|
|
|
data.answer == 1 ? cite_protect_me_from_myself :
|
|
|
|
|
data.answer == 2 ? cite_let_me_be_a_loser : 99);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Print setup
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct fe_print_data
|
|
|
|
|
{
|
|
|
|
|
MWContext *context;
|
|
|
|
|
History_entry *hist;
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget printer, file, command_text, file_text, browse;
|
|
|
|
|
Widget first, last;
|
|
|
|
|
Widget portrait, landscape;
|
|
|
|
|
Widget grey, color;
|
|
|
|
|
Widget letter, legal, exec, a4;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_to_toggle_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
if (!cb->set)
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
else if (widget == fpd->printer)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->file, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->browse, XmNsensitive, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->file_text, XmNsensitive, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->command_text, XmNsensitive, True, 0);
|
|
|
|
|
XmProcessTraversal (fpd->command_text, XmTRAVERSE_CURRENT);
|
|
|
|
|
}
|
|
|
|
|
else if (widget == fpd->file)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->printer, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->browse, XmNsensitive, True, 0);
|
|
|
|
|
XtVaSetValues (fpd->file_text, XmNsensitive, True, 0);
|
|
|
|
|
XtVaSetValues (fpd->command_text, XmNsensitive, False, 0);
|
|
|
|
|
XmProcessTraversal (fpd->file_text, XmTRAVERSE_CURRENT);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_order_toggle_cb (Widget widget, XtPointer closure,XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
if (!cb->set)
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
else if (widget == fpd->first)
|
|
|
|
|
XtVaSetValues (fpd->last, XmNset, False, 0);
|
|
|
|
|
else if (widget == fpd->last)
|
|
|
|
|
XtVaSetValues (fpd->first, XmNset, False, 0);
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_orientation_toggle_cb (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
if (!cb->set)
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
else if (widget == fpd->portrait)
|
|
|
|
|
XtVaSetValues (fpd->landscape, XmNset, False, 0);
|
|
|
|
|
else if (widget == fpd->landscape)
|
|
|
|
|
XtVaSetValues (fpd->portrait, XmNset, False, 0);
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_color_toggle_cb (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
if (!cb->set)
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
else if (widget == fpd->grey)
|
|
|
|
|
XtVaSetValues (fpd->color, XmNset, False, 0);
|
|
|
|
|
else if (widget == fpd->color)
|
|
|
|
|
XtVaSetValues (fpd->grey, XmNset, False, 0);
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_paper_toggle_cb (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
if (!cb->set)
|
|
|
|
|
XtVaSetValues (widget, XmNset, True, 0);
|
|
|
|
|
else if (widget == fpd->letter)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->legal, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->exec, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->a4, XmNset, False, 0);
|
|
|
|
|
}
|
|
|
|
|
else if (widget == fpd->legal)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->letter, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->exec, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->a4, XmNset, False, 0);
|
|
|
|
|
}
|
|
|
|
|
else if (widget == fpd->exec)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->letter, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->legal, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->a4, XmNset, False, 0);
|
|
|
|
|
}
|
|
|
|
|
else if (widget == fpd->a4)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fpd->letter, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->legal, XmNset, False, 0);
|
|
|
|
|
XtVaSetValues (fpd->exec, XmNset, False, 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp)
|
|
|
|
|
{
|
|
|
|
|
char *text = 0;
|
|
|
|
|
XmString xmpat, xmfile;
|
|
|
|
|
char buf [1024];
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget parent;
|
|
|
|
|
Widget fileb;
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
data.context = context;
|
|
|
|
|
|
|
|
|
|
/* Find the top level window of which this text field is a descendant,
|
|
|
|
|
and make the file requester be a transient for that. */
|
|
|
|
|
parent = text_field;
|
|
|
|
|
while (parent && !XtIsShell (parent))
|
|
|
|
|
parent = XtParent (parent);
|
|
|
|
|
assert (parent);
|
|
|
|
|
if (! parent)
|
|
|
|
|
parent = CONTEXT_WIDGET (context);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
text = fe_GetTextField(text_field);
|
|
|
|
|
text = fe_StringTrim (text);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( text && *text )
|
|
|
|
|
text = XP_STRTOK(text, " ");
|
|
|
|
|
|
|
|
|
|
if (!text || !*text)
|
|
|
|
|
{
|
|
|
|
|
xmpat = 0;
|
|
|
|
|
xmfile = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (dirp)
|
|
|
|
|
{
|
|
|
|
|
if (text [strlen (text) - 1] == '/')
|
|
|
|
|
text [strlen (text) - 1] = 0;
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
xmpat = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
xmfile = XmStringCreateLtoR (text, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char *f;
|
|
|
|
|
if (text [strlen (text) - 1] == '/')
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
else
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s", text);
|
|
|
|
|
xmfile = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
if (text[0] == '/') /* only do this for absolute path */
|
|
|
|
|
f = strrchr (text, '/');
|
|
|
|
|
else
|
|
|
|
|
f = NULL;
|
|
|
|
|
if (f && f != text)
|
|
|
|
|
*f = 0;
|
|
|
|
|
if (f) {
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
xmpat = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* do not change dirmask and pattern if input is a file;
|
|
|
|
|
* otherwise, the text widget in the file selection box
|
|
|
|
|
* will insert the file name at the wrong position.
|
|
|
|
|
* Windows version has similar behavior if a relative file
|
|
|
|
|
* is entered.
|
|
|
|
|
*/
|
|
|
|
|
buf[0] = '\0'; /* input was just a file. no '/' in it. */
|
|
|
|
|
xmpat = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (text) free (text);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNallowShellResize, True); ac++;*/
|
|
|
|
|
shell = XmCreateDialogShell (parent, "fileBrowser_popup", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNfileTypeMask,
|
|
|
|
|
(dirp ? XmFILE_DIRECTORY : XmFILE_REGULAR)); ac++;
|
|
|
|
|
fileb = fe_CreateFileSelectionBox (shell, "fileBrowser", av, ac);
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (fileb, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (xmpat)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (fileb,
|
|
|
|
|
XmNdirMask, xmpat,
|
|
|
|
|
XmNpattern, xmpat, 0);
|
|
|
|
|
#if 0
|
|
|
|
|
/*
|
|
|
|
|
* The XtVaSetValues on dirMask/pattern will cause this anyway.
|
|
|
|
|
*/
|
|
|
|
|
XmFileSelectionDoSearch (fileb, xmpat);
|
|
|
|
|
#endif
|
|
|
|
|
XtVaSetValues (fileb, XmNdirSpec, xmfile, 0);
|
|
|
|
|
XmStringFree (xmpat);
|
|
|
|
|
XmStringFree (xmfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtAddCallback (fileb, XmNnoMatchCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNokCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNcancelCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
|
|
|
|
|
fe_HackDialogTranslations (fileb);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (fileb);
|
|
|
|
|
XtManageChild (fileb);
|
|
|
|
|
/* #### check for destruction here */
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_OK)
|
|
|
|
|
if (data.return_value)
|
|
|
|
|
{
|
|
|
|
|
fe_SetTextField(text_field, data.return_value);
|
|
|
|
|
free (data.return_value);
|
|
|
|
|
}
|
|
|
|
|
if (data.answer != Answer_Destroy)
|
|
|
|
|
XtDestroyWidget(shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_browse_file_of_text_in_url (MWContext *context, Widget text_field, Boolean dirp)
|
|
|
|
|
{
|
|
|
|
|
char *orig_text = 0;
|
|
|
|
|
char *text = 0;
|
|
|
|
|
XmString xmpat, xmfile;
|
|
|
|
|
char buf [1024];
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
Widget shell;
|
|
|
|
|
Widget parent;
|
|
|
|
|
Widget fileb;
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
data.context = context;
|
|
|
|
|
|
|
|
|
|
/* Find the top level window of which this text field is a descendant,
|
|
|
|
|
and make the file requester be a transient for that. */
|
|
|
|
|
|
|
|
|
|
parent = text_field;
|
|
|
|
|
while (parent && !XtIsShell (parent))
|
|
|
|
|
parent = XtParent (parent);
|
|
|
|
|
assert (parent);
|
|
|
|
|
if (! parent)
|
|
|
|
|
parent = CONTEXT_WIDGET (context);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (parent, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
text = fe_GetTextField(text_field);
|
|
|
|
|
orig_text = text;
|
|
|
|
|
text = fe_StringTrim (text);
|
|
|
|
|
|
|
|
|
|
if (!strncasecomp (text, "http://", 7)) {
|
|
|
|
|
/* ignore url using http */
|
|
|
|
|
free(orig_text);
|
|
|
|
|
orig_text = 0;
|
|
|
|
|
text = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (text) {
|
|
|
|
|
if (!strncasecomp (text, "file://", 7)) {
|
|
|
|
|
/* get to the absolute file path */
|
|
|
|
|
text += 7;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( text && *text )
|
|
|
|
|
text = XP_STRTOK(text, " ");
|
|
|
|
|
|
|
|
|
|
if (!text || !*text){
|
|
|
|
|
xmpat = 0;
|
|
|
|
|
xmfile = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (dirp){
|
|
|
|
|
if (text [strlen (text) - 1] == '/')
|
|
|
|
|
text [strlen (text) - 1] = 0;
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
xmpat = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
xmfile = XmStringCreateLtoR (text, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char *f;
|
|
|
|
|
if (text [strlen (text) - 1] == '/')
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
else
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s", text);
|
|
|
|
|
xmfile = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
if (text[0] == '/') /* only do this for absolute path */
|
|
|
|
|
f = strrchr (text, '/');
|
|
|
|
|
else
|
|
|
|
|
f = NULL;
|
|
|
|
|
if (f && f != text)
|
|
|
|
|
*f = 0;
|
|
|
|
|
if (f) {
|
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%.900s/*", text);
|
|
|
|
|
xmpat = XmStringCreateLtoR (buf, XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Do not change dirmask and pattern if input is a file;
|
|
|
|
|
* otherwise, the text widget in the file selection box
|
|
|
|
|
* will insert the file name at the wrong position.
|
|
|
|
|
* Windows version has similar behavior if a relative file
|
|
|
|
|
* is entered.
|
|
|
|
|
*/
|
|
|
|
|
buf[0] = '\0'; /* input was just a file. no '/' in it. */
|
|
|
|
|
xmpat = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (orig_text) free (orig_text);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
/* XtSetArg (av[ac], XmNallowShellResize, True); ac++;*/
|
|
|
|
|
shell = XmCreateDialogShell (parent, "fileBrowser_popup", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNfileTypeMask, (dirp ? XmFILE_DIRECTORY : XmFILE_REGULAR)); ac++;
|
|
|
|
|
fileb = fe_CreateFileSelectionBox (shell, "fileBrowser", av, ac);
|
|
|
|
|
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (fileb, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (xmpat) {
|
|
|
|
|
XtVaSetValues (fileb,
|
|
|
|
|
XmNdirMask, xmpat,
|
|
|
|
|
XmNpattern, xmpat, 0);
|
|
|
|
|
#if 0
|
|
|
|
|
/*
|
|
|
|
|
* The XtVaSetValues on dirMask/pattern will cause this anyway.
|
|
|
|
|
*/
|
|
|
|
|
XmFileSelectionDoSearch (fileb, xmpat);
|
|
|
|
|
#endif
|
|
|
|
|
XtVaSetValues (fileb, XmNdirSpec, xmfile, 0);
|
|
|
|
|
XmStringFree (xmpat);
|
|
|
|
|
XmStringFree (xmfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtAddCallback (fileb, XmNnoMatchCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNokCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNcancelCallback, fe_file_cb, &data);
|
|
|
|
|
XtAddCallback (fileb, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
data.return_value = 0;
|
|
|
|
|
|
|
|
|
|
fe_HackDialogTranslations (fileb);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (fileb);
|
|
|
|
|
XtManageChild (fileb);
|
|
|
|
|
/* #### check for destruction here */
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_OK)
|
|
|
|
|
if (data.return_value) {
|
|
|
|
|
/* prepend the answer with file url */
|
|
|
|
|
char path[1025];
|
|
|
|
|
sprintf(path, "file://%s", data.return_value);
|
|
|
|
|
fe_SetTextField (text_field, path);
|
|
|
|
|
free (data.return_value);
|
|
|
|
|
}
|
|
|
|
|
if (data.answer != Answer_Destroy)
|
|
|
|
|
XtDestroyWidget(shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_browse_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
fe_browse_file_of_text (fpd->context, fpd->file_text, False);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define XFE_DEFAULT_PRINT_FILENAME "netscape.ps"
|
|
|
|
|
static char *last_print_file_name = 0;
|
|
|
|
|
static Boolean last_to_file_p = False;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ps_pipe_close (PrintSetup *p)
|
|
|
|
|
{
|
|
|
|
|
fe_synchronous_url_exit (p->url, 0, (MWContext *) p->carg);
|
|
|
|
|
pclose (p->out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ps_file_close (PrintSetup *p)
|
|
|
|
|
{
|
|
|
|
|
fe_synchronous_url_exit (p->url, 0, (MWContext *) p->carg);
|
|
|
|
|
fclose (p->out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
XFE_InitializePrintSetup (PrintSetup *p)
|
|
|
|
|
{
|
1998-09-25 10:23:01 +00:00
|
|
|
|
int i;
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
XL_InitializePrintSetup (p);
|
|
|
|
|
p->reverse = fe_globalPrefs.print_reversed;
|
|
|
|
|
p->color = fe_globalPrefs.print_color;
|
|
|
|
|
p->landscape = fe_globalPrefs.print_landscape;
|
|
|
|
|
/* #### p->n_up = fe_globalPrefs.print_n_up;*/
|
|
|
|
|
|
|
|
|
|
/* @@@ need to fix this -- erik */
|
|
|
|
|
p->bigger = 0; /* -1 = small, 0 = medium, 1 = large, 2 = huge */
|
|
|
|
|
|
|
|
|
|
if (fe_globalPrefs.print_paper_size == 0)
|
|
|
|
|
{
|
|
|
|
|
p->width = 8.5 * 72;
|
|
|
|
|
p->height = 11 * 72;
|
|
|
|
|
}
|
|
|
|
|
else if (fe_globalPrefs.print_paper_size == 1)
|
|
|
|
|
{
|
|
|
|
|
p->width = 8.5 * 72;
|
|
|
|
|
p->height = 14 * 72;
|
|
|
|
|
}
|
|
|
|
|
else if (fe_globalPrefs.print_paper_size == 2)
|
|
|
|
|
{
|
|
|
|
|
p->width = 7.5 * 72;
|
|
|
|
|
p->height = 10 * 72;
|
|
|
|
|
}
|
|
|
|
|
else if (fe_globalPrefs.print_paper_size == 3)
|
|
|
|
|
{
|
|
|
|
|
p->width = 210 * 0.039 * 72;
|
|
|
|
|
p->height = 297 * 0.039 * 72;
|
|
|
|
|
}
|
1998-09-25 10:23:01 +00:00
|
|
|
|
p->paper_size = fe_globalPrefs.print_paper_size;
|
|
|
|
|
|
|
|
|
|
/* initialize things related to other font to be NULL */
|
|
|
|
|
for (i=0; i<N_FONTS; i++) {
|
|
|
|
|
p->otherFontName[i] = NULL;
|
|
|
|
|
p->otherFontInfo[i] = NULL;
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_Print(MWContext *context, URL_Struct *url, Boolean last_to_file_p,
|
|
|
|
|
char *last_print_file_name)
|
|
|
|
|
{
|
|
|
|
|
SHIST_SavedData saved_data;
|
|
|
|
|
PrintSetup p;
|
|
|
|
|
char *type = NULL;
|
|
|
|
|
char name[1024];
|
|
|
|
|
char clas[1024];
|
|
|
|
|
char mimecharset[48];
|
|
|
|
|
XrmValue value;
|
|
|
|
|
XrmDatabase db = XtDatabase(XtDisplay(CONTEXT_WIDGET(context)));
|
|
|
|
|
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
|
|
|
|
|
|
1998-09-25 10:23:01 +00:00
|
|
|
|
FILE *afmfile; /* AFM (font metrics) file descriptor */
|
|
|
|
|
char *measures[2] = { "variable", "fixed" };
|
|
|
|
|
char *styles[4] = { "normal", "bold", "italic", "boldItalic" };
|
|
|
|
|
int measure, style, i; /* Loop variable */
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
XFE_InitializePrintSetup (&p);
|
|
|
|
|
|
|
|
|
|
if (last_to_file_p)
|
|
|
|
|
{
|
|
|
|
|
if (! *last_print_file_name)
|
|
|
|
|
{
|
|
|
|
|
FE_Alert (context, fe_globalData.no_file_message);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the file exists, confirm overwriting it. */
|
|
|
|
|
{
|
|
|
|
|
XP_StatStruct st;
|
|
|
|
|
char buf [2048];
|
|
|
|
|
if (!stat (last_print_file_name, &st))
|
|
|
|
|
{
|
|
|
|
|
PR_snprintf (buf, sizeof (buf),
|
|
|
|
|
fe_globalData.overwrite_file_message,
|
|
|
|
|
last_print_file_name);
|
|
|
|
|
if (!FE_Confirm (context, buf))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p.out = fopen (last_print_file_name, "w");
|
|
|
|
|
if (! p.out)
|
|
|
|
|
{
|
|
|
|
|
char buf [2048];
|
|
|
|
|
PR_snprintf (buf, sizeof (buf),
|
|
|
|
|
XP_GetString(XFE_ERROR_OPENING_FILE),
|
|
|
|
|
last_print_file_name);
|
|
|
|
|
fe_perror (context, buf);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fe_globalPrefs.print_command =
|
|
|
|
|
fe_StringTrim (fe_globalPrefs.print_command);
|
|
|
|
|
if (! *fe_globalPrefs.print_command)
|
|
|
|
|
{
|
|
|
|
|
FE_Alert (context, fe_globalData.no_print_command_message);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
p.out = popen (fe_globalPrefs.print_command, "w");
|
|
|
|
|
if (! p.out)
|
|
|
|
|
{
|
|
|
|
|
char buf [2048];
|
|
|
|
|
PR_snprintf (buf, sizeof (buf),
|
|
|
|
|
XP_GetString(XFE_ERROR_OPENING_PIPE),
|
|
|
|
|
fe_globalPrefs.print_command);
|
|
|
|
|
fe_perror (context, buf);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure layout saves the current state. */
|
|
|
|
|
LO_SaveFormData(context);
|
|
|
|
|
|
|
|
|
|
/* Hold on to the saved data. */
|
|
|
|
|
XP_MEMCPY(&saved_data, &url->savedData, sizeof(SHIST_SavedData));
|
|
|
|
|
|
|
|
|
|
/* make damn sure the form_data slot is zero'd or else all
|
|
|
|
|
* hell will break loose
|
|
|
|
|
*/
|
|
|
|
|
XP_MEMSET (&url->savedData, 0, sizeof (SHIST_SavedData));
|
|
|
|
|
NPL_PreparePrint(context, &url->savedData);
|
|
|
|
|
|
|
|
|
|
INTL_CharSetIDToName(INTL_GetCSIWinCSID(c), mimecharset);
|
|
|
|
|
|
|
|
|
|
PR_snprintf(clas, sizeof (clas),
|
|
|
|
|
"%s.DocumentFonts.Charset.PSCode", fe_progclass);
|
|
|
|
|
PR_snprintf(name, sizeof (name),
|
|
|
|
|
"%s.documentFonts.%s.pscode", fe_progclass, mimecharset);
|
|
|
|
|
if (XrmGetResource(db, name, clas, &type, &value))
|
|
|
|
|
p.otherFontCharSetID = INTL_CharSetNameToID(value.addr);
|
|
|
|
|
|
1998-09-25 10:23:01 +00:00
|
|
|
|
/* read in font spec from the resource
|
|
|
|
|
NOTE: Currently eight fonts styles are used
|
|
|
|
|
*/
|
|
|
|
|
for (measure = 0; measure < 2; measure++)
|
|
|
|
|
for (style = 0; style < 4; style++) {
|
|
|
|
|
int index = measure * 4 + style;
|
|
|
|
|
|
|
|
|
|
PR_snprintf(clas, sizeof (clas),
|
|
|
|
|
"%s.DocumentFonts.Charset.Measure.Style.PSName", fe_progclass);
|
|
|
|
|
PR_snprintf(name, sizeof (name),
|
|
|
|
|
"%s.documentFonts.%s.%s.%s.psname", fe_progclass, mimecharset,
|
|
|
|
|
measures[measure], styles[style]);
|
|
|
|
|
|
|
|
|
|
if (XrmGetResource(db, name, clas, &type, &value)
|
|
|
|
|
&& XP_STRLEN(value.addr) > 0 ) {
|
|
|
|
|
/* read in font name for this style */
|
|
|
|
|
p.otherFontName[index] = (char*)malloc(strlen(value.addr)+1);
|
|
|
|
|
strncpy(p.otherFontName[index], value.addr, XP_STRLEN(value.addr)+1);
|
|
|
|
|
|
|
|
|
|
/* Read and parse AFM file if psafmfile is specified */
|
|
|
|
|
PR_snprintf(clas, sizeof (clas),
|
|
|
|
|
"%s.DocumentFonts.Charset.Measure.Style.PSAFMFile", fe_progclass);
|
|
|
|
|
PR_snprintf(name, sizeof (name),
|
|
|
|
|
"%s.documentFonts.%s.%s.%s.psafmfile", fe_progclass,
|
|
|
|
|
mimecharset, measures[measure], styles[style]);
|
|
|
|
|
|
|
|
|
|
if (XrmGetResource(db, name, clas, &type, &value)
|
|
|
|
|
&& XP_STRLEN(value.addr) > 0) {
|
|
|
|
|
/* open the file according to the name */
|
|
|
|
|
afmfile = fopen(value.addr, "r");
|
|
|
|
|
if (!afmfile) {
|
|
|
|
|
/* fail to open file */
|
|
|
|
|
char buf [2048];
|
|
|
|
|
PR_snprintf(buf, sizeof (buf),
|
|
|
|
|
XP_GetString(XFE_ERROR_OPENING_FILE),
|
|
|
|
|
value.addr);
|
|
|
|
|
fprintf(stderr, buf);
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
}
|
|
|
|
|
else { /* parse the afm file */
|
|
|
|
|
int err;
|
|
|
|
|
if (err = XP_parseAFMFile(afmfile,
|
|
|
|
|
&(p.otherFontInfo[index]))) {
|
|
|
|
|
/* error in parsing */
|
|
|
|
|
char buf [2048];
|
|
|
|
|
if (p.otherFontInfo[index] != NULL)
|
|
|
|
|
free(p.otherFontInfo[index]);
|
|
|
|
|
p.otherFontInfo[index] = NULL;
|
|
|
|
|
fclose(afmfile);
|
|
|
|
|
PR_snprintf(buf, sizeof (buf),
|
|
|
|
|
XP_GetString(XFE_CANNOT_READ_FILE),
|
|
|
|
|
value.addr);
|
|
|
|
|
fprintf(stderr, buf);
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
fprintf(stderr, "Error code is %d\n", err);
|
|
|
|
|
}
|
|
|
|
|
else /* successfully parsed */
|
|
|
|
|
fclose(afmfile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else { /* no psafmfile, then look for psmetric */
|
|
|
|
|
PR_snprintf(clas, sizeof (clas),
|
|
|
|
|
"%s.DocumentFonts.Charset.Measure.Style.PSMetric", fe_progclass);
|
|
|
|
|
PR_snprintf(name, sizeof (name),
|
|
|
|
|
"%s.documentFonts.%s.%s.%s.psmetric", fe_progclass,
|
|
|
|
|
mimecharset, measures[measure], styles[style]);
|
|
|
|
|
|
|
|
|
|
if (XrmGetResource(db, name, clas, &type, &value)) {
|
|
|
|
|
int params[4];
|
|
|
|
|
int param = 0;
|
|
|
|
|
int len = XP_STRLEN(value.addr);
|
|
|
|
|
char *start = value.addr;
|
|
|
|
|
i = params[0] = params[1] = params[2] = params[3] = 0;
|
|
|
|
|
while (i <= len) {
|
|
|
|
|
if (i != 0 && !isdigit(*(value.addr+i))
|
|
|
|
|
&& isdigit(*(value.addr+i-1)) ) {
|
|
|
|
|
*(value.addr+i) = '\0';
|
|
|
|
|
params[param++] = atoi(start);
|
|
|
|
|
start = value.addr + i + 1;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
if (param > 0) {
|
|
|
|
|
p.otherFontInfo[index] = (PS_FontInfo *)
|
|
|
|
|
malloc(sizeof(PS_FontInfo));
|
|
|
|
|
p.otherFontInfo[index]->chars[0].wx = params[0];
|
|
|
|
|
p.otherFontInfo[index]->chars[0].wy = params[1];
|
|
|
|
|
p.otherFontInfo[index]->fontBBox.ury = params[2];
|
|
|
|
|
p.otherFontInfo[index]->fontBBox.lly = params[3];
|
|
|
|
|
for (i=1; i<256; i++)
|
|
|
|
|
p.otherFontInfo[index]->chars[i] =
|
|
|
|
|
p.otherFontInfo[index]->chars[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* end of reading font specifications */
|
|
|
|
|
|
|
|
|
|
/* post-parsing process, to map unspecified fonts to specified fonts */
|
|
|
|
|
if (p.otherFontName[LO_FONT_NORMAL] == NULL)
|
|
|
|
|
p.otherFontName[LO_FONT_NORMAL] = p.otherFontName[LO_FONT_FIXED];
|
|
|
|
|
else if (p.otherFontName[LO_FONT_FIXED] == NULL)
|
|
|
|
|
p.otherFontName[LO_FONT_FIXED] = p.otherFontName[LO_FONT_NORMAL];
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
1998-09-25 10:23:01 +00:00
|
|
|
|
|
|
|
|
|
for (i=0; i<N_FONTS; i++) {
|
|
|
|
|
if (p.otherFontName[i] == NULL)
|
|
|
|
|
p.otherFontName[i] = p.otherFontName[i & LO_FONT_FIXED];
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
if (last_to_file_p)
|
|
|
|
|
p.completion = ps_file_close;
|
|
|
|
|
else
|
|
|
|
|
p.completion = ps_pipe_close;
|
|
|
|
|
|
|
|
|
|
p.carg = context;
|
|
|
|
|
fe_RaiseSynchronousURLDialog (context, CONTEXT_WIDGET (context),
|
|
|
|
|
XP_GetString(XFE_DIALOGS_PRINTING));
|
|
|
|
|
XL_TranslatePostscript (context, url, &saved_data, &p);
|
|
|
|
|
fe_await_synchronous_url (context);
|
1998-09-25 10:23:01 +00:00
|
|
|
|
|
|
|
|
|
/* dispose used memory blocks */
|
|
|
|
|
for (i=0; i<N_FONTS; i++) {
|
|
|
|
|
if (p.otherFontName[i] != NULL) {
|
|
|
|
|
int j;
|
|
|
|
|
for (j = i+1; j < N_FONTS; j++)
|
|
|
|
|
if (p.otherFontName[i] == p.otherFontName[j])
|
|
|
|
|
p.otherFontName[j] = NULL;
|
|
|
|
|
free(p.otherFontName[i]);
|
|
|
|
|
p.otherFontName[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (p.otherFontInfo[i] != NULL) {
|
|
|
|
|
int j;
|
|
|
|
|
for (j = i+1; j < N_FONTS; j++)
|
|
|
|
|
if (p.otherFontInfo[i] == p.otherFontInfo[j])
|
|
|
|
|
p.otherFontInfo[j] = NULL;
|
|
|
|
|
free(p.otherFontInfo[i]);
|
|
|
|
|
p.otherFontInfo[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
} /* end of dispose */
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
/* XXX do we need to delete the URL ? */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_destroy_cb(Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
if (!fpd) return;
|
|
|
|
|
|
|
|
|
|
/* Remove this callback so that we make absolutely sure we wont
|
|
|
|
|
* free the fpd again.
|
|
|
|
|
*/
|
|
|
|
|
XtRemoveCallback(widget, XmNdestroyCallback, fe_print_destroy_cb, fpd);
|
|
|
|
|
free(fpd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_print_cb (Widget widget, XtPointer closure, XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *) closure;
|
|
|
|
|
URL_Struct *url;
|
|
|
|
|
Boolean b;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Pop down the print dialog immediately.
|
|
|
|
|
*/
|
|
|
|
|
fe_UnmanageChild_safe (fpd->shell);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (fpd->printer, XmNset, &b, 0);
|
|
|
|
|
last_to_file_p = !b;
|
|
|
|
|
if (fe_globalPrefs.print_command) free (fe_globalPrefs.print_command);
|
|
|
|
|
XtVaGetValues (fpd->command_text, XmNvalue, &fe_globalPrefs.print_command,0);
|
|
|
|
|
if (last_print_file_name) free (last_print_file_name);
|
|
|
|
|
last_print_file_name = fe_GetTextField(fpd->file_text);
|
|
|
|
|
XtVaGetValues (fpd->portrait, XmNset, &b, 0);
|
|
|
|
|
fe_globalPrefs.print_landscape = !b;
|
|
|
|
|
XtVaGetValues (fpd->last, XmNset, &b, 0);
|
|
|
|
|
fe_globalPrefs.print_reversed = b;
|
|
|
|
|
XtVaGetValues (fpd->grey, XmNset, &b, 0);
|
|
|
|
|
fe_globalPrefs.print_color = !b;
|
|
|
|
|
XtVaGetValues (fpd->letter, XmNset, &b, 0);
|
|
|
|
|
if (b) fe_globalPrefs.print_paper_size = 0;
|
|
|
|
|
XtVaGetValues (fpd->legal, XmNset, &b, 0);
|
|
|
|
|
if (b) fe_globalPrefs.print_paper_size = 1;
|
|
|
|
|
XtVaGetValues (fpd->exec, XmNset, &b, 0);
|
|
|
|
|
if (b) fe_globalPrefs.print_paper_size = 2;
|
|
|
|
|
XtVaGetValues (fpd->a4, XmNset, &b, 0);
|
|
|
|
|
if (b) fe_globalPrefs.print_paper_size = 3;
|
|
|
|
|
|
|
|
|
|
url = SHIST_CreateWysiwygURLStruct (fpd->context, fpd->hist);
|
|
|
|
|
if (url) {
|
|
|
|
|
last_print_file_name = fe_StringTrim (last_print_file_name);
|
|
|
|
|
|
|
|
|
|
fe_Print(fpd->context, url, last_to_file_p, last_print_file_name);
|
|
|
|
|
} else {
|
|
|
|
|
FE_Alert(fpd->context, fe_globalData.no_url_loaded_message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We need this check to see if this widget is being_destroyed
|
|
|
|
|
* or not in its ok_callback because fe_Print() goes off and
|
|
|
|
|
* calls fe_await_synchronous_url() while has a mini eventloop
|
|
|
|
|
* in it. This could cause a destroy of this widget. Motif, in
|
|
|
|
|
* all its smartness, keeps this widget's memory around. This
|
|
|
|
|
* is the only think we can check. context, shell, fpd all might
|
|
|
|
|
* have been destroyed and deallocated.
|
|
|
|
|
*/
|
|
|
|
|
if (XfeIsAlive(widget)) {
|
|
|
|
|
XtDestroyWidget (fpd->shell);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_PrintDialog (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget kids [50];
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac, i, labels_width;
|
|
|
|
|
Widget shell, form;
|
|
|
|
|
Widget print_to_label, print_command_label;
|
|
|
|
|
Widget print_command_text, file_name_label, file_name_text;
|
|
|
|
|
Widget browse_button, line, print_label;
|
|
|
|
|
Widget first_first_toggle, last_first_toggle, orientation_label;
|
|
|
|
|
Widget portrait_toggle, landscape_toggle;
|
|
|
|
|
Widget print_color_label, greyscale_toggle;
|
|
|
|
|
Widget color_toggle, paper_size_label, paper_size_radio_box, letter_toggle;
|
|
|
|
|
Widget legal_toggle, executive_toggle, a4_toggle;
|
|
|
|
|
Widget to_printer_toggle, to_file_toggle;
|
|
|
|
|
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
|
|
|
|
|
struct fe_print_data *fpd = (struct fe_print_data *)
|
|
|
|
|
calloc (sizeof (struct fe_print_data), 1);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNuserData, False); ac++;
|
|
|
|
|
shell = XmCreatePromptDialog (mainw, "printSetup", av, ac);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (shell, XmNokCallback, fe_print_cb, fpd);
|
|
|
|
|
XtAddCallback (shell, XmNcancelCallback, fe_destroy_cb, shell);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell,
|
|
|
|
|
XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_TEXT));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (shell, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
XtAddCallback (shell, XmNdestroyCallback, fe_print_destroy_cb, fpd);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
ac = 0;
|
|
|
|
|
form = XmCreateForm (shell, "form", av, ac);
|
|
|
|
|
kids [i++] = print_to_label =
|
|
|
|
|
XmCreateLabelGadget (form, "printToLabel", av, ac);
|
|
|
|
|
kids [i++] = to_printer_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "toPrinterToggle", av, ac);
|
|
|
|
|
kids [i++] = to_file_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "toFileToggle", av, ac);
|
|
|
|
|
kids [i++] = print_command_label =
|
|
|
|
|
XmCreateLabelGadget (form, "printCommandLabel", av, ac);
|
|
|
|
|
kids [i++] = print_command_text =
|
|
|
|
|
fe_CreateTextField (form, "printCommandText", av, ac);
|
|
|
|
|
kids [i++] = file_name_label =
|
|
|
|
|
XmCreateLabelGadget (form, "fileNameLabel", av, ac);
|
|
|
|
|
kids [i++] = file_name_text =
|
|
|
|
|
fe_CreateTextField (form, "fileNameText", av, ac);
|
|
|
|
|
kids [i++] = browse_button =
|
|
|
|
|
XmCreatePushButtonGadget (form, "browseButton", av, ac);
|
|
|
|
|
kids [i++] = line = XmCreateSeparator (form, "line", av, ac);
|
|
|
|
|
kids [i++] = print_label = XmCreateLabelGadget (form, "printLabel", av, ac);
|
|
|
|
|
kids [i++] = first_first_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "firstFirstToggle", av, ac);
|
|
|
|
|
kids [i++] = last_first_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "lastFirstToggle", av, ac);
|
|
|
|
|
kids [i++] = orientation_label =
|
|
|
|
|
XmCreateLabelGadget (form, "orientationLabel", av, ac);
|
|
|
|
|
kids [i++] = portrait_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "portraitToggle", av, ac);
|
|
|
|
|
kids [i++] = landscape_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "landscapeToggle", av, ac);
|
|
|
|
|
kids [i++] = print_color_label =
|
|
|
|
|
XmCreateLabelGadget (form, "printColorLabel", av, ac);
|
|
|
|
|
kids [i++] = greyscale_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "greyscaleToggle", av, ac);
|
|
|
|
|
kids [i++] = color_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "colorToggle", av, ac);
|
|
|
|
|
kids [i++] = paper_size_label =
|
|
|
|
|
XmCreateLabelGadget (form, "paperSizeLabel", av, ac);
|
|
|
|
|
kids [i++] = paper_size_radio_box =
|
|
|
|
|
XmCreateRadioBox (form, "paperSizeRadioBox", av, ac);
|
|
|
|
|
kids [i++] = letter_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "letterToggle", av, ac);
|
|
|
|
|
kids [i++] = legal_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "legalToggle", av, ac);
|
|
|
|
|
kids [i++] = executive_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "executiveToggle", av, ac);
|
|
|
|
|
kids [i++] = a4_toggle =
|
|
|
|
|
XmCreateToggleButtonGadget (form, "a4Toggle", av, ac);
|
|
|
|
|
|
|
|
|
|
labels_width = XfeVaGetWidestWidget(print_to_label, print_command_label,
|
|
|
|
|
file_name_label, 0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (print_to_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, to_printer_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, to_printer_toggle,
|
|
|
|
|
RIGHT_JUSTIFY_VA_ARGS(print_to_label,labels_width),
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (to_printer_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftOffset, labels_width,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (to_file_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, to_printer_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, to_printer_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, to_printer_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (print_command_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, print_command_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, print_command_text,
|
|
|
|
|
RIGHT_JUSTIFY_VA_ARGS(print_command_label,labels_width),
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (print_command_text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, to_printer_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, to_printer_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (file_name_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, file_name_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, file_name_text,
|
|
|
|
|
RIGHT_JUSTIFY_VA_ARGS(file_name_label,labels_width),
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (file_name_text,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, print_command_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, print_command_text,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, browse_button,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (browse_button,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, print_command_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (browse_button, XmNheight, _XfeHeight(file_name_text), 0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (line,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, file_name_text,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (print_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, first_first_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, first_first_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, first_first_toggle,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (first_first_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, line,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, print_command_text,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (last_first_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, first_first_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, first_first_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, first_first_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (orientation_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, portrait_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, portrait_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, portrait_toggle,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (portrait_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, first_first_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, first_first_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (landscape_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, portrait_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, portrait_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, portrait_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (print_color_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, greyscale_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, greyscale_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, greyscale_toggle,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (greyscale_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, portrait_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, portrait_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (color_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, greyscale_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, greyscale_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, greyscale_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (paper_size_label,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, letter_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, letter_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNrightWidget, letter_toggle,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (letter_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, greyscale_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, greyscale_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (legal_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, letter_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, letter_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, letter_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (executive_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, letter_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNleftWidget, letter_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (a4_toggle,
|
|
|
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNtopWidget, executive_toggle,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
|
|
|
XmNbottomWidget, executive_toggle,
|
|
|
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNleftWidget, executive_toggle,
|
|
|
|
|
XmNrightAttachment, XmATTACH_NONE,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (to_printer_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_to_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (to_file_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_to_toggle_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (browse_button, XmNactivateCallback,
|
|
|
|
|
fe_print_browse_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (first_first_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_order_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (last_first_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_order_toggle_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (portrait_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_orientation_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (landscape_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_orientation_toggle_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (greyscale_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_color_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (color_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_color_toggle_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (letter_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_paper_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (legal_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_paper_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (executive_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_paper_toggle_cb, fpd);
|
|
|
|
|
XtAddCallback (a4_toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_print_paper_toggle_cb, fpd);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (print_command_text, XmNvalue, fe_globalPrefs.print_command,0);
|
|
|
|
|
if (!last_print_file_name || !*last_print_file_name) {
|
|
|
|
|
/* Use a default file name. We need to strdup here as we free this
|
|
|
|
|
later. */
|
|
|
|
|
last_print_file_name = strdup( XFE_DEFAULT_PRINT_FILENAME );
|
|
|
|
|
}
|
|
|
|
|
fe_SetTextField(file_name_text, last_print_file_name);
|
|
|
|
|
if (last_to_file_p)
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (to_file_toggle, XmNset, True, 0);
|
|
|
|
|
XtVaSetValues (print_command_text, XmNsensitive, False, 0);
|
|
|
|
|
XtVaSetValues (shell, XmNinitialFocus, file_name_text, 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
XtVaSetValues (to_printer_toggle, XmNset, True, 0);
|
|
|
|
|
XtVaSetValues (file_name_text, XmNsensitive, False, 0);
|
|
|
|
|
XtVaSetValues (browse_button, XmNsensitive, False, 0);
|
|
|
|
|
XtVaSetValues (shell, XmNinitialFocus, print_command_text, 0);
|
|
|
|
|
}
|
|
|
|
|
XtVaSetValues ((fe_globalPrefs.print_reversed
|
|
|
|
|
? last_first_toggle : first_first_toggle),
|
|
|
|
|
XmNset, True, 0);
|
|
|
|
|
XtVaSetValues ((fe_globalPrefs.print_landscape
|
|
|
|
|
? landscape_toggle : portrait_toggle),
|
|
|
|
|
XmNset, True, 0);
|
|
|
|
|
XtVaSetValues ((fe_globalPrefs.print_color
|
|
|
|
|
? color_toggle : greyscale_toggle),
|
|
|
|
|
XmNset, True, 0);
|
|
|
|
|
XtVaSetValues ((fe_globalPrefs.print_paper_size == 0 ? letter_toggle :
|
|
|
|
|
fe_globalPrefs.print_paper_size == 1 ? legal_toggle :
|
|
|
|
|
fe_globalPrefs.print_paper_size == 2 ? executive_toggle :
|
|
|
|
|
a4_toggle),
|
|
|
|
|
XmNset, True, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XtManageChildren (kids, i);
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
|
|
|
|
|
fpd->context = context;
|
|
|
|
|
fpd->hist = SHIST_GetCurrent (&context->hist);
|
|
|
|
|
fpd->shell = shell;
|
|
|
|
|
fpd->printer = to_printer_toggle;
|
|
|
|
|
fpd->file = to_file_toggle;
|
|
|
|
|
fpd->command_text = print_command_text;
|
|
|
|
|
fpd->file_text = file_name_text;
|
|
|
|
|
fpd->browse = browse_button;
|
|
|
|
|
fpd->first = first_first_toggle;
|
|
|
|
|
fpd->last = last_first_toggle;
|
|
|
|
|
fpd->portrait = portrait_toggle;
|
|
|
|
|
fpd->landscape = landscape_toggle;
|
|
|
|
|
fpd->grey = greyscale_toggle;
|
|
|
|
|
fpd->color = color_toggle;
|
|
|
|
|
fpd->letter = letter_toggle;
|
|
|
|
|
fpd->legal = legal_toggle;
|
|
|
|
|
fpd->exec = executive_toggle;
|
|
|
|
|
fpd->a4 = a4_toggle;
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (shell);
|
|
|
|
|
XtManageChild (shell);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Streaming audio
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
1998-09-02 07:02:04 +00:00
|
|
|
|
FE_AskStreamQuestion (MWContext *context)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
dialog = XmCreatePromptDialog (mainw, "streamingAudioQuery", av, ac);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNapplyCallback, fe_destroy_apply_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = dialog;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_Cancel || data.answer == Answer_Destroy)
|
|
|
|
|
return -1;
|
|
|
|
|
else if (data.answer == Answer_OK)
|
|
|
|
|
return 1;
|
|
|
|
|
else if (data.answer == Answer_Apply)
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Care and feeding of lawyers and other parasites */
|
|
|
|
|
|
|
|
|
|
static XtErrorHandler old_xt_warning_handler = NULL;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xt_warning_handler(String msg)
|
|
|
|
|
{
|
|
|
|
|
if (!msg)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef DEBUG
|
|
|
|
|
/* Ignore warnings that contain "Actions not found" (non debug only) */
|
|
|
|
|
if (XP_STRSTR(msg,"Actions not found"))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
(*old_xt_warning_handler)(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_LicenseDialog (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
Widget form, label1, text, label2;
|
|
|
|
|
Widget accept, reject;
|
|
|
|
|
|
|
|
|
|
char crockery [1024];
|
|
|
|
|
PR_snprintf (crockery, sizeof (crockery), "%d ", getuid ());
|
|
|
|
|
strcat (crockery, fe_version);
|
|
|
|
|
|
|
|
|
|
if (fe_VendorAnim)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (fe_globalPrefs.license_accepted &&
|
|
|
|
|
!strcmp (crockery, fe_globalPrefs.license_accepted))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdefaultButton, 0); ac++;
|
|
|
|
|
dialog = XmCreateTemplateDialog (mainw, "licenseDialog", av, ac);
|
|
|
|
|
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
/* fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON));*/
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog,XmDIALOG_DEFAULT_BUTTON));
|
|
|
|
|
fe_UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
accept = XmCreatePushButtonGadget (dialog, "accept", av, ac);
|
|
|
|
|
reject = XmCreatePushButtonGadget (dialog, "reject", av, ac);
|
|
|
|
|
form = XmCreateForm (dialog, "form", av, ac);
|
|
|
|
|
label1 = XmCreateLabelGadget (form, "label1", av, ac);
|
|
|
|
|
|
|
|
|
|
XtSetArg (av [ac], XmNeditable, False); ac++;
|
|
|
|
|
XtSetArg (av [ac], XmNcursorPositionVisible, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
|
|
|
|
|
text = XmCreateScrolledText (form, "text", av, ac);
|
|
|
|
|
fe_HackDialogTranslations (text);
|
|
|
|
|
ac = 0;
|
|
|
|
|
label2 = XmCreateLabelGadget (form, "label2", av, ac);
|
|
|
|
|
|
|
|
|
|
XtVaSetValues (label1,
|
|
|
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (XtParent (text),
|
|
|
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNtopWidget, label1,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_WIDGET,
|
|
|
|
|
XmNbottomWidget, label2,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
XtVaSetValues (label2,
|
|
|
|
|
XmNtopAttachment, XmATTACH_NONE,
|
|
|
|
|
XmNbottomAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
|
|
|
XmNrightAttachment, XmATTACH_FORM,
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
char *license = 0;
|
|
|
|
|
int32 length = 0;
|
|
|
|
|
char *ctype = 0;
|
|
|
|
|
void *data = FE_AboutData ("license", &license, &length, &ctype);
|
|
|
|
|
if (!license || length < 300)
|
|
|
|
|
{
|
|
|
|
|
license = "Please fill in";
|
|
|
|
|
/* abort (); */
|
|
|
|
|
}
|
|
|
|
|
XtVaSetValues (text, XmNvalue, license, 0);
|
|
|
|
|
if (data) free (data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XtManageChild (label1);
|
|
|
|
|
XtManageChild (text);
|
|
|
|
|
XtManageChild (XtParent (text));
|
|
|
|
|
XtManageChild (label2);
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
XtManageChild (accept);
|
|
|
|
|
XtManageChild (reject);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
XtVaSetValues (dialog, XmNdefaultButton, accept, 0);
|
|
|
|
|
XtAddCallback (accept, XmNactivateCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
XtAddCallback (reject, XmNactivateCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb, &data);
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = dialog;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
|
|
|
|
|
/* Install a warning handler that ignores translation warnings */
|
|
|
|
|
old_xt_warning_handler = XtAppSetWarningHandler(fe_XtAppContext,
|
|
|
|
|
xt_warning_handler);
|
|
|
|
|
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
/* Restore the original warning handler after the dialog is managed */
|
|
|
|
|
XtAppSetWarningHandler(fe_XtAppContext,old_xt_warning_handler);
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_Cancel || data.answer == Answer_Destroy)
|
|
|
|
|
{
|
|
|
|
|
if (fe_pidlock) unlink (fe_pidlock);
|
|
|
|
|
exit (0);
|
|
|
|
|
}
|
|
|
|
|
else if (data.answer == Answer_OK)
|
|
|
|
|
{
|
|
|
|
|
/* Store crockery into preferences, and save. */
|
|
|
|
|
StrAllocCopy (fe_globalPrefs.license_accepted, crockery);
|
|
|
|
|
if (!XFE_UpgradePrefs ((char *) fe_globalData.user_prefs_file,
|
|
|
|
|
&fe_globalPrefs))
|
|
|
|
|
fe_perror (context, XP_GetString(XFE_CANT_SAVE_PREFS));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_UpdateDocInfoDialog (MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
/* nada for now */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_security_dialog_toggle (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
XP_Bool *prefs_toggle = (XP_Bool *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
*prefs_toggle = cb->set;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fe_movemail_dialog_toggle (Widget widget, XtPointer closure,
|
|
|
|
|
XtPointer call_data)
|
|
|
|
|
{
|
|
|
|
|
XP_Bool *prefs_toggle = (XP_Bool *) closure;
|
|
|
|
|
XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
|
|
|
|
|
*prefs_toggle = cb->set;
|
|
|
|
|
if (!XFE_SavePrefs ((char *) fe_globalData.user_prefs_file, &fe_globalPrefs))
|
|
|
|
|
fe_perror (fe_all_MWContexts->context,
|
|
|
|
|
XP_GetString( XFE_ERROR_SAVING_OPTIONS ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
|
|
|
/*
|
|
|
|
|
* fe_MovemailWarning
|
|
|
|
|
* Stolen from FE_SecurityDialog
|
|
|
|
|
*/
|
|
|
|
|
extern Boolean
|
|
|
|
|
fe_MovemailWarning(MWContext *context)
|
|
|
|
|
{
|
|
|
|
|
if ( fe_globalPrefs.movemail_warn == True ) {
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Widget form;
|
|
|
|
|
Widget toggle;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
XmString ok_label;
|
|
|
|
|
XmString cancel_label;
|
|
|
|
|
XmString selection_label;
|
|
|
|
|
XmString toggle_label;
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
char buf[256];
|
|
|
|
|
char* from;
|
|
|
|
|
const char* to;
|
|
|
|
|
|
|
|
|
|
from = fe_mn_getmailbox();
|
|
|
|
|
to = FE_GetFolderDirectory(context);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This dialog should probably be popped up in fe_mn_getmailbox()
|
|
|
|
|
* instead. Otherwise, we have to check everywhere it's used.
|
|
|
|
|
* (Only two places at this point, though.)
|
|
|
|
|
*/
|
|
|
|
|
if ( from == NULL ) {
|
|
|
|
|
FE_Alert(context, XP_GetString(XFE_MAIL_SPOOL_UNKNOWN));
|
|
|
|
|
return False;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PR_snprintf(buf, sizeof(buf), XP_GetString(XFE_MOVEMAIL_EXPLANATION),
|
|
|
|
|
from, to, from);
|
|
|
|
|
|
|
|
|
|
ok_label = XmStringCreateLtoR(XP_GetString(XFE_CONTINUE_MOVEMAIL),
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
cancel_label = XmStringCreateLtoR(XP_GetString(XFE_CANCEL_MOVEMAIL),
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
selection_label = XmStringCreateLtoR(buf,
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
toggle_label = XmStringCreateLtoR(XP_GetString(XFE_SHOW_NEXT_TIME),
|
|
|
|
|
XmFONTLIST_DEFAULT_TAG);
|
|
|
|
|
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle,
|
|
|
|
|
XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNchildPlacement, XmPLACE_BELOW_SELECTION); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNokLabelString, ok_label); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcancelLabelString, cancel_label); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNselectionLabelString, selection_label); ac++;
|
|
|
|
|
dialog = XmCreatePromptDialog (mainw, "movemailWarnDialog", av, ac);
|
|
|
|
|
|
|
|
|
|
if ( ok_label ) XmStringFree(ok_label);
|
|
|
|
|
if ( cancel_label ) XmStringFree(cancel_label);
|
|
|
|
|
if ( selection_label ) XmStringFree(selection_label);
|
|
|
|
|
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
|
|
|
|
|
XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
|
|
|
|
|
XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ac = 0;
|
|
|
|
|
form = XmCreateForm (dialog, "form", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNset, fe_globalPrefs.movemail_warn); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNlabelString, toggle_label); ac++;
|
|
|
|
|
toggle = XmCreateToggleButtonGadget (form, "toggle", av, ac);
|
|
|
|
|
if ( toggle_label ) XmStringFree(toggle_label);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_movemail_dialog_toggle, &fe_globalPrefs.movemail_warn);
|
|
|
|
|
XtManageChild (toggle);
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNapplyCallback, fe_destroy_apply_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb,&data);
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = dialog;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_Cancel || data.answer == Answer_Destroy)
|
|
|
|
|
return False;
|
|
|
|
|
else if (data.answer == Answer_OK)
|
|
|
|
|
return True;
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return True;
|
|
|
|
|
}
|
|
|
|
|
#endif /* MOZ_MAIL_NEWS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern Bool
|
|
|
|
|
FE_SecurityDialog (MWContext *context, int state, XP_Bool *prefs_toggle)
|
|
|
|
|
{
|
|
|
|
|
char *name;
|
|
|
|
|
Bool cancel_p = True;
|
|
|
|
|
Bool cancel_default_p = False;
|
|
|
|
|
switch (state)
|
|
|
|
|
{
|
|
|
|
|
case SD_INSECURE_POST_FROM_SECURE_DOC:
|
|
|
|
|
name = "insecurePostFromSecureDocDialog";
|
|
|
|
|
cancel_p = True;
|
|
|
|
|
cancel_default_p = True;
|
|
|
|
|
break;
|
|
|
|
|
case SD_INSECURE_POST_FROM_INSECURE_DOC:
|
|
|
|
|
name = "insecurePostFromInsecureDocDialog";
|
|
|
|
|
cancel_p = True;
|
|
|
|
|
break;
|
|
|
|
|
case SD_ENTERING_SECURE_SPACE:
|
|
|
|
|
name = "enteringSecureDialog";
|
|
|
|
|
cancel_p = False;
|
|
|
|
|
break;
|
|
|
|
|
case SD_LEAVING_SECURE_SPACE:
|
|
|
|
|
name = "leavingSecureDialog";
|
|
|
|
|
cancel_p = True;
|
|
|
|
|
break;
|
|
|
|
|
case SD_INSECURE_DOCS_WITHIN_SECURE_DOCS_NOT_SHOWN:
|
|
|
|
|
name = "mixedSecurityDialog";
|
|
|
|
|
cancel_p = False;
|
|
|
|
|
break;
|
|
|
|
|
case SD_REDIRECTION_TO_INSECURE_DOC:
|
|
|
|
|
name = "redirectionToInsecureDialog";
|
|
|
|
|
cancel_p = True;
|
|
|
|
|
break;
|
|
|
|
|
case SD_REDIRECTION_TO_SECURE_SITE:
|
|
|
|
|
name = "redirectionToSecureDialog";
|
|
|
|
|
cancel_p = True;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (prefs_toggle && !*prefs_toggle)
|
|
|
|
|
return True;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Widget mainw = CONTEXT_WIDGET (context);
|
|
|
|
|
Widget dialog;
|
|
|
|
|
Arg av [20];
|
|
|
|
|
int ac;
|
|
|
|
|
Visual *v = 0;
|
|
|
|
|
Colormap cmap = 0;
|
|
|
|
|
Cardinal depth = 0;
|
|
|
|
|
XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
|
|
|
|
|
XtNdepth, &depth, 0);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNvisual, v); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdepth, depth); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNcolormap, cmap); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNdialogStyle,
|
|
|
|
|
XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
|
|
|
|
|
if (cancel_p)
|
|
|
|
|
{
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
XtSetArg (av[ac], XmNdialogType, XmDIALOG_INFORMATION); ac++;
|
|
|
|
|
}
|
|
|
|
|
XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNchildPlacement, XmPLACE_BELOW_SELECTION); ac++;
|
|
|
|
|
dialog = XmCreatePromptDialog (mainw, name, av, ac);
|
|
|
|
|
|
|
|
|
|
XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_SEPARATOR));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
|
|
|
|
|
XmDIALOG_APPLY_BUTTON));
|
|
|
|
|
#ifdef NO_HELP
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
|
|
|
|
|
XmDIALOG_HELP_BUTTON));
|
|
|
|
|
#endif
|
|
|
|
|
if (! cancel_p)
|
|
|
|
|
fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
|
|
|
|
|
XmDIALOG_CANCEL_BUTTON));
|
|
|
|
|
|
|
|
|
|
if (prefs_toggle)
|
|
|
|
|
{
|
|
|
|
|
Widget form, toggle;
|
|
|
|
|
ac = 0;
|
|
|
|
|
form = XmCreateForm (dialog, "form", av, ac);
|
|
|
|
|
ac = 0;
|
|
|
|
|
XtSetArg (av[ac], XmNset, *prefs_toggle); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
|
|
|
|
|
XtSetArg (av[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
|
|
|
|
|
toggle = XmCreateToggleButtonGadget (form, "toggle", av, ac);
|
|
|
|
|
XtAddCallback (toggle, XmNvalueChangedCallback,
|
|
|
|
|
fe_security_dialog_toggle, prefs_toggle);
|
|
|
|
|
XtManageChild (toggle);
|
|
|
|
|
XtManageChild (form);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cancel_default_p)
|
|
|
|
|
{
|
|
|
|
|
Widget c = XmSelectionBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON);
|
|
|
|
|
if (!c) abort ();
|
|
|
|
|
XtVaSetValues (dialog, XmNdefaultButton, c, XmNinitialFocus, c, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fe_NukeBackingStore (dialog);
|
|
|
|
|
XtManageChild (dialog);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
struct fe_confirm_data data;
|
|
|
|
|
XtAddCallback (dialog, XmNokCallback, fe_destroy_ok_cb, &data);
|
|
|
|
|
if (cancel_p)
|
|
|
|
|
{
|
|
|
|
|
XtAddCallback (dialog, XmNapplyCallback, fe_destroy_apply_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNcancelCallback, fe_destroy_cancel_cb, &data);
|
|
|
|
|
XtAddCallback (dialog, XmNdestroyCallback, fe_destroy_finish_cb,&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data.context = context;
|
|
|
|
|
data.widget = dialog;
|
|
|
|
|
data.answer = Answer_Invalid;
|
|
|
|
|
|
|
|
|
|
while (data.answer == Answer_Invalid)
|
|
|
|
|
fe_EventLoop ();
|
|
|
|
|
|
|
|
|
|
if (data.answer == Answer_Cancel || data.answer == Answer_Destroy)
|
|
|
|
|
return False;
|
|
|
|
|
else if (data.answer == Answer_OK)
|
|
|
|
|
return True;
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-08-13 00:02:06 +00:00
|
|
|
|
|
|
|
|
|
/* Temporary stub. */
|
|
|
|
|
XP_Bool
|
1998-08-14 00:26:37 +00:00
|
|
|
|
XFE_SelectDialog(MWContext *pContext,
|
|
|
|
|
const char *pMessage,
|
|
|
|
|
const char **pList,
|
|
|
|
|
int16 *pCount)
|
1998-08-13 00:02:06 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
char *message = 0;
|
|
|
|
|
for (i = 0; i < *pCount; i++) {
|
|
|
|
|
StrAllocCopy(message, pMessage);
|
|
|
|
|
StrAllocCat(message, " = ");
|
|
|
|
|
StrAllocCat(message, pList[i]);
|
|
|
|
|
if (FE_Confirm(pContext, message)) {
|
|
|
|
|
/* user selected this one */
|
|
|
|
|
XP_FREE(message);
|
|
|
|
|
*pCount = i;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* user rejected all */
|
|
|
|
|
XP_FREE(message);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* temporary UI until FE implements this function as a single dialog box
|
|
|
|
|
*/
|
|
|
|
|
XP_Bool
|
1998-08-14 00:26:37 +00:00
|
|
|
|
XFE_CheckConfirm(MWContext *pContext,
|
|
|
|
|
const char *pConfirmMessage,
|
|
|
|
|
const char *pCheckMessage,
|
1998-08-13 00:02:06 +00:00
|
|
|
|
const char *pOKMessage, /* text on the OK button */
|
|
|
|
|
const char *pCancelMessage, /* text on the cancel button */
|
|
|
|
|
XP_Bool *pChecked)
|
|
|
|
|
{
|
|
|
|
|
Bool userHasAccepted = FE_Confirm(pContext, pConfirmMessage);
|
|
|
|
|
*pChecked = FE_Confirm (pContext, pCheckMessage);
|
|
|
|
|
return userHasAccepted;
|
|
|
|
|
}
|