home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- TextEditorView.h - anything that has a text editable area in it.
- Crreated: Dora Hsu <dora@netscape.com>, Sept-30-96.
- */
-
-
-
- #include "TextEditorView.h"
- #include "SpellHandler.h"
- #include <Xm/Text.h>
- #include "libi18n.h"
- #include "felocale.h"
- #include "xfe.h" // for CONTEXT_DATA
- #include "Xfe/Xfe.h"
-
- #ifdef DEBUG_editor
- #define XDEBUG(x) x
- #else
- #define XDEBUG(x)
- #endif
-
- extern "C" void fe_mail_text_modify_cb (Widget, XtPointer, XtPointer);
- extern "C" void fe_HackTranslations (MWContext *, Widget);
-
- extern "C" XtPointer fe_GetFont(MWContext *context, int sizeNum, int fontmask);
- extern "C"
- unsigned char * fe_ConvertToLocaleEncoding(int16 charset, unsigned char *str);
-
-
- MenuSpec XFE_TextEditorView::popupmenu_spec[] = {
- { xfeCmdCut, PUSHBUTTON },
- { xfeCmdCopy, PUSHBUTTON },
- { xfeCmdPaste, PUSHBUTTON },
- { xfeCmdPasteAsQuoted, PUSHBUTTON },
- MENU_SEPARATOR,
- { xfeCmdQuoteOriginalText, PUSHBUTTON },
- {NULL}
- };
-
- const char *XFE_TextEditorView::textFocusIn = "XFE_TextEditorView::textFocusIn";
-
- XFE_TextEditorView::XFE_TextEditorView(XFE_Component* toplevel_component,
- XFE_View *parent_view,
- MSG_Pane *p,
- MWContext *context)
- : XFE_MNView(toplevel_component, parent_view, context, p)
- {
- m_popup = NULL;
- }
-
- void
- XFE_TextEditorView::createWidgets(Widget parentW, XP_Bool wrap_p)
- {
-
- int ac;
- Arg av[20];
- Widget textW;
- MWContext *context = getParent()->getContext();
- XmFontList fontList;
- Widget form;
-
- fontList = (XmFontList)fe_GetFont (context, 3, LO_FONT_FIXED);
-
- form = XmCreateForm(parentW, "plainTextForm", NULL, 0 );
-
- ac = 0;
- XtSetArg(av[ac], XmNtopOffset, 5); ac++;
- XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
- XtSetArg (av[ac], XmNfontList, fontList); ac++;
- XtSetArg (av[ac], XmNscrollHorizontal, !wrap_p); ac++;
- XtSetArg (av[ac], XmNwordWrap, wrap_p); ac++;
- XtSetArg (av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
- XtSetArg (av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
- XtSetArg (av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
- XtSetArg (av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
- textW = XmCreateScrolledText(parentW, "mailto_bodyText", av, ac);
- XtAddCallback (textW, XmNmodifyVerifyCallback,
- fe_mail_text_modify_cb, getParent()->getContext());
-
- // NOTE... [ we need this for the ComposeView focus mechanism...
- //
- XtAddCallback(textW, XmNfocusCallback, textFocusCallback, this);
-
- //
- setBaseWidget(form);
- XtManageChild(textW);
-
- // This is a hack...NEED here...
- // Otherwise, we cannot swap the text widget upon wrap on/off.
- CONTEXT_DATA(m_contextData)->mcBodyText = textW;
-
- }
-
- void
- XFE_TextEditorView::textFocus()
- {
- Widget textW = CONTEXT_DATA(m_contextData)->mcBodyText;
-
- getToplevel()->notifyInterested(XFE_TextEditorView::textFocusIn, textW);
- }
-
- void
- XFE_TextEditorView::textFocusCallback(Widget, XtPointer clientData, XtPointer)
- {
- XFE_TextEditorView *obj = (XFE_TextEditorView*)clientData;
-
- obj->textFocus();
- }
-
- void
- XFE_TextEditorView::setFont(XmFontList fontList)
- {
- int ac;
- Arg av[20];
- Widget textW = CONTEXT_DATA(m_contextData)->mcBodyText;
-
- ac = 0;
- XtSetArg (av[ac], XmNfontList, fontList); ac++;
- XtSetValues(textW, av, ac);
- if (fe_LocaleCharSetID & MULTIBYTE) {
- Dimension columns;
- XtVaGetValues(textW, XmNcolumns, &columns, NULL);
- XtVaSetValues(textW, XmNcolumns, (columns + 1) / 2, NULL);
- }
- }
-
- void
- XFE_TextEditorView::setComposeWrapState(XP_Bool wrap_p)
- {
- Boolean old_wrap, new_wrap, old_scroll, new_scroll;
- Widget text, parent, gramp;
- MWContext *context = getParent()->getContext();
-
- XP_ASSERT(context->type == MWContextMessageComposition);
- XP_ASSERT(CONTEXT_DATA(context)->mcBodyText);
-
- text = CONTEXT_DATA(context)->mcBodyText;
- if (!text) return;
-
- parent = XtParent(text);
- gramp = XtParent(parent);
-
- XtVaGetValues(text,
- XmNwordWrap, &old_wrap,
- XmNscrollHorizontal, &old_scroll,
- 0);
-
- new_wrap = wrap_p;
- new_scroll = !wrap_p;
- CONTEXT_DATA (context)->compose_wrap_lines_p = wrap_p;
-
- if (new_wrap == old_wrap &&
- new_scroll == old_scroll)
- return;
-
- {
- String body = 0;
- XmTextPosition cursor = 0;
- unsigned char top = 0, bot = 0, left = 0, right = 0;
- Widget topw = 0, botw = 0, leftw = 0, rightw = 0;
- Arg av [20];
- int ac = 0;
- XmFontList font_list = 0;
-
- /* #### warning much of this is cloned from mozilla.c
- (fe_create_composition_widgets) */
-
- XtVaGetValues (text,
- XmNcursorPosition, &cursor,
- XmNfontList, &font_list,
- 0);
- body = fe_GetTextField(text);
- XtVaGetValues (parent,
- XmNtopAttachment, &top, XmNtopWidget, &topw,
- XmNbottomAttachment, &bot, XmNbottomWidget, &botw,
- XmNleftAttachment, &left, XmNleftWidget, &leftw,
- XmNrightAttachment, &right, XmNrightWidget, &rightw,
- 0);
-
- XtUnmanageChild(parent);
- XtDestroyWidget(parent);
- CONTEXT_DATA(context)->mcBodyText = text = parent = 0;
-
- XtSetArg (av[ac], XmNeditable, True); ac++;
- XtSetArg (av[ac], XmNcursorPositionVisible, True); ac++;
- XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
-
- XtSetArg (av[ac], XmNscrollVertical, TRUE); ac++;
- XtSetArg (av[ac], XmNscrollHorizontal, new_scroll); ac++;
- XtSetArg (av[ac], XmNwordWrap, new_wrap); ac++;
-
- XtSetArg (av[ac], XmNfontList, font_list); ac++;
-
- text = XmCreateScrolledText (gramp, "mailto_bodyText", av, ac);
- parent = XtParent(text);
- // This is really a hack since we changed the widget in the
- // middle of displaying
- fe_HackTranslations(m_contextData, text);
-
- if (fe_LocaleCharSetID & MULTIBYTE) {
- Dimension columns;
- XtVaGetValues(text, XmNcolumns, &columns, NULL);
- XtVaSetValues(text, XmNcolumns, (columns + 1) / 2, NULL);
- }
-
-
- /* Warning -- this assumes no widgets are attached to this one
- (which is the normal state of affairs, since this is the widget
- that should grow.) */
- XtVaSetValues (parent,
- XmNtopAttachment, top, XmNtopWidget, topw,
- XmNbottomAttachment, bot, XmNbottomWidget, botw,
- XmNleftAttachment, left, XmNleftWidget, leftw,
- XmNrightAttachment, right, XmNrightWidget, rightw,
- 0);
- XtVaSetValues (text,
- XmNfontList, font_list,
- XmNcursorPosition, cursor,
- XmNwordWrap, new_wrap,
- 0);
- fe_SetTextField(text, (body ? body : ""));
- if (body) free(body);
-
- /* Put this callback back so that the "you haven't typed anything do
- you really want to send?" hack still works with this new text widget
- #### cloned from dialogs.c (FE_InitializeMailCompositionContext)
- */
- XtAddCallback (text, XmNmodifyVerifyCallback,
- fe_mail_text_modify_cb, context);
-
- // NOTE... [ we need this for the ComposeView focus mechanism...
- //
- XtAddCallback(text, XmNfocusCallback, textFocusCallback, this);
-
- CONTEXT_DATA(context)->mcBodyText = text;
- XtManageChild(text);
-
- /* just in case it didn't take... */
- XtVaSetValues (text, XmNcursorPosition, cursor, 0);
-
- /* Move focus back there. */
- XmProcessTraversal (text, XmTRAVERSE_CURRENT);
- }
- }
-
- void
- XFE_TextEditorView::doCommand(CommandType cmd, void */*calldata*/, XFE_CommandInfo* info)
- {
- XDEBUG( printf ("in XFE_TextEditorView::doCommand(%s)\n", Command::getString(cmd));)
-
- Widget destW = XmGetDestination(XtDisplay(getBaseWidget()));
- Widget focusW= XmGetFocusWidget(getBaseWidget());
-
- if ( (destW == CONTEXT_DATA(m_contextData)->mcBodyText ||
- focusW == CONTEXT_DATA(m_contextData)->mcBodyText))
- {
- // Now we are sure the focus is in the text area,
- // We should perform those commands that are operable in the area
-
- if (cmd == xfeCmdDelete)
- {
- XEvent *event = info->event;
- XtCallActionProc (CONTEXT_DATA(m_contextData)->mcBodyText, "delete-next-character", event, NULL, 0 );
- }
- else if ( cmd == xfeCmdSelectAll )
- {
- Widget text = CONTEXT_DATA(m_contextData)->mcBodyText;
- XmTextSetSelection(text, 0, XmTextGetLastPosition(text),
- info->event->xkey.time);
- }
- else if ( cmd == xfeCmdSpellCheck ) {
- xfe_TextSpellCheck(m_contextData);
- }
- #if 0
- else if ( cmd == xfeCmdFindInObject )
- {
- // Future work here
- return;
- }
- else if ( cmd == xfeCmdFindAgain )
- {
- // Future work here
- return;
- }
- #endif
- }
-
- #if 0
- //On XFE Compose Window, we don't do Popup anymore...as 4.x Spec indicated.
- // There are problem to deal with popup when view swaps...
- // This is a XFE framework problem...
- if ( cmd == xfeCmdShowPopup )
- {
- // May need to find out if it's an HTML view or not
- XEvent *event = info->event;
-
- if (m_popup)
- delete m_popup;
-
- m_popup = new XFE_PopupMenu( (XFE_Frame *) getToplevel(),
- XfeAncestorFindApplicationShell(getToplevel()->getBaseWidget()));
-
- m_popup->addMenuSpec(popupmenu_spec);
- m_popup->position (event);
- m_popup->show();
- }
- #endif
- }
-
-
-
-
- Boolean
- XFE_TextEditorView::isCommandEnabled(CommandType cmd, void */*calldata*/, XFE_CommandInfo*)
- {
- XDEBUG( printf ("in XFE_TextEditorView::isCommandEnabled(%s)\n", Command::getString(cmd));)
-
- Widget destW = XmGetDestination(XtDisplay(getBaseWidget()));
- Widget focusW= XmGetFocusWidget(getBaseWidget());
-
- if ( cmd == xfeCmdShowPopup )
- return True;
-
- else if (cmd == xfeCmdSpellCheck)
- {
- return xfe_SpellCheckerAvailable(m_contextData);
- }
-
- else if ( (destW == CONTEXT_DATA(m_contextData)->mcBodyText ||
- focusW == CONTEXT_DATA(m_contextData)->mcBodyText))
- {
- // Now we are sure the focus is in the mcBodyText Area,
- // we should turn on/off commands accordingly for this area
-
- if ( (cmd == xfeCmdDelete) ||
- (cmd == xfeCmdSelectAll)
- )
- return True;
- }
-
- XDEBUG( printf ("leaving XFE_TextEditorView::isCommandEnabled()\n");)
- return False;
- }
-
- Boolean
- XFE_TextEditorView::handlesCommand(CommandType command, void */*calldata*/, XFE_CommandInfo*)
- {
- XDEBUG( printf ("in XFE_TextEditorView::handlesCommand(%s)\n", Command::getString(command));)
-
- Widget destW = XmGetDestination(XtDisplay(getBaseWidget()));
- Widget focusW= XmGetFocusWidget(getBaseWidget());
-
- if (command == xfeCmdGetNewMessages
- || command == xfeCmdAddNewsgroup
- || command == xfeCmdDelete
- || command == xfeCmdShowPopup
- || command == xfeCmdSpellCheck
- || command == xfeCmdDelete
- || command == xfeCmdSelectAll )
- {
- return True;
- }
-
- XDEBUG( printf ("leaving XFE_TextEditorView::handlesCommand(%s)\n", Command::getString(command));)
- return False;
- }
-
- char*
- XFE_TextEditorView::getPlainText()
- {
- // This method suppose to get the text message in the widget
- // and return in a char string block
- return NULL;
- }
-
- // ---- These methods might need to move up to be XFE_EDITABLE ----------
-
- void
- XFE_TextEditorView::insertMessageCompositionText(
- const char* text, XP_Bool leaveCursorAtBeginning,
- XP_Bool /*isHTML*/ )
- {
-
- MWContext* context = getParent()->getContext();
- XmTextPosition pos = 0, newpos = 0;
- unsigned char *loc;
- Widget bodyTextW= CONTEXT_DATA(m_contextData)->mcBodyText;
-
- XtRemoveCallback(bodyTextW, XmNmodifyVerifyCallback,
- fe_mail_text_modify_cb, getParent()->getContext());
-
-
- XtVaGetValues(bodyTextW, XmNcursorPosition, &pos, 0);
- loc = fe_ConvertToLocaleEncoding(INTL_DefaultWinCharSetID(context),
- (unsigned char *) text);
- XmTextInsert(bodyTextW, pos, (char*) loc);
- if (((char *) loc) != text) {
- XP_FREE(loc);
- }
- XtVaGetValues(bodyTextW, XmNcursorPosition, &newpos, 0);
- if (leaveCursorAtBeginning) {
- XtVaSetValues(bodyTextW, XmNcursorPosition, pos, 0);
- }
- else if (pos == newpos) {
- /* On some motif (eg. AIX), text insertion point is not moved after
- * inserted text. We depend on that here.
- *
- * WARNING: XXX I18N watch. The strlen might not be the right i18n way.
- */
- newpos = pos+strlen(text);
- XtVaSetValues(bodyTextW, XmNcursorPosition, newpos, 0);
- }
- XtAddCallback (bodyTextW, XmNmodifyVerifyCallback,
- fe_mail_text_modify_cb, getParent()->getContext());
- }
-
- void
- XFE_TextEditorView::getMessageBody(
- char **pBody, uint32 *body_size,
- MSG_FontCode **font_changes)
- {
- MWContext *context = getParent()->getContext();
- Dimension columns = 0;
- char *loc;
- unsigned char *tmp;
- Widget bodyTextW= CONTEXT_DATA(m_contextData)->mcBodyText;
-
- *pBody = 0;
- loc = 0;
- tmp = 0;
- XtVaGetValues (bodyTextW, XmNvalue, &loc, XmNcolumns, &columns, 0);
- if (fe_LocaleCharSetID & MULTIBYTE) {
- columns *= 2;
- }
- if (loc) {
- tmp = fe_ConvertFromLocaleEncoding(INTL_DefaultWinCharSetID(context),
- (unsigned char *) loc);
- }
- if (tmp) {
-
- #ifdef WRAP_EDITOR_TO_WINDOW_WIDTH /* Old way: always wrap to window width */
-
- if (columns <= 0) columns = 79;
- *pBody = (char *) XP_WordWrap(INTL_DefaultWinCharSetID(context), tmp,
- columns, 1 /* look for '>' */);
-
- #else /* New way: obey the ``Wrap Lines to the new length specified by user'' toggle. */
-
- if (CONTEXT_DATA(context)->compose_wrap_lines_p)
- {
- if (fe_globalPrefs.msg_wrap_length >0)
- columns = fe_globalPrefs.msg_wrap_length;
- else columns = 72;
- *pBody = (char *) XP_WordWrap(INTL_DefaultWinCharSetID(context), tmp,
- columns, 1 /* look for '>' */);
- }
- else
- {
- /* Else, don't wrap it at all. */
- *pBody = (char*)tmp;
- tmp = 0;
- }
- #endif /* New way. */
-
- if (loc != (char *) tmp) {
- XP_FREE(tmp);
- }
- }
- *body_size = (*pBody ? strlen(*pBody) : 0);
- *font_changes = 0;
- }
-
- void
- XFE_TextEditorView::doneWithMessageBody(char* pBody)
- {
- Widget bodyTextW= CONTEXT_DATA(m_contextData)->mcBodyText;
- char *loc;
-
- XtVaGetValues(bodyTextW, XmNvalue, &loc, 0);
- if (pBody != loc) {
- XP_FREE(pBody);
- }
- }
-
- Boolean
- XFE_TextEditorView::isModified()
- {
-
- return (!(CONTEXT_DATA(m_contextData)->mcCitedAndUnedited) &&
- CONTEXT_DATA(m_contextData)->mcEdited);
- }
-
-
-
-
-