mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 15:15:23 +00:00
2125 lines
59 KiB
C++
2125 lines
59 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||
*
|
||
* The contents of this file are subject to the Netscape Public License
|
||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||
* http://www.mozilla.org/NPL/
|
||
*
|
||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||
* for the specific language governing rights and limitations under the
|
||
* NPL.
|
||
*
|
||
* The Initial Developer of this code under the NPL is Netscape
|
||
* Communications Corporation. Portions created by Netscape are
|
||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||
* Reserved.
|
||
*/
|
||
|
||
// UFormElementFactory.cp
|
||
|
||
#include "UFormElementFactory.h"
|
||
|
||
// PowerPlant
|
||
#include <LPane.h>
|
||
#include <LCommander.h>
|
||
#include <UReanimator.h>
|
||
#include <UMemoryMgr.h>
|
||
//#include <LEventHandler.h>
|
||
//#include <LStyleSet.h>
|
||
//#include <VStyleSet.h>
|
||
|
||
// MacFE
|
||
#include "CHTMLView.h"
|
||
#include "CBrowserContext.h"
|
||
#include "CEditorWindow.h"
|
||
#include "CURLDispatcher.h"
|
||
#include "resgui.h"
|
||
#include "uprefd.h"
|
||
#include "mforms.h"
|
||
#include <LScrollerView.h>
|
||
#include "CHyperScroller.h"
|
||
#include "macgui.h"
|
||
#include "macutil.h"
|
||
#include "ufilemgr.h"
|
||
#include "uintl.h"
|
||
#include "CAutoPtr.h"
|
||
|
||
// Backend
|
||
#include "lo_ele.h" // for struct def'n
|
||
#include "xlate.h"
|
||
#include "fe_proto.h"
|
||
#include "prefapi.h"
|
||
#include "edt.h"
|
||
|
||
// macros
|
||
#define FEDATAPANE ((FormFEData *)formElem->element_data->ele_minimal.FE_Data)->fPane
|
||
#define FEDATAHOST ((FormFEData *)formElem->element_data->ele_minimal.FE_Data)->fHost
|
||
// These defines add extra spacing to the controls.
|
||
// The spacing is needed because the layout puts them too close otherwise
|
||
#define buttonTopExtra 1
|
||
#define buttomLeftExtra 1
|
||
#define buttonRightExtra 1
|
||
#define buttonBottomExtra 1
|
||
|
||
#define textTopExtra 1
|
||
#define textLeftExtra 1
|
||
#define textRightExtra 1
|
||
#define textBottomExtra 1
|
||
|
||
void FE_FreeFormElement(
|
||
MWContext* /* inContext */,
|
||
LO_FormElementData * inFormData)
|
||
{
|
||
UFormElementFactory::FreeFormElement(inFormData);
|
||
}
|
||
|
||
// moose: temporary hack until we fix up lo_ele.h and ntypes.h to have an HTMLarea struct
|
||
typedef struct lo_FormElementTextareaData_struct lo_FormElementHTMLareaData;
|
||
|
||
// prototypes
|
||
static Boolean HasFormWidget(LO_FormElementStruct *formElem);
|
||
|
||
// utilities
|
||
inline FormFEData *GetFEData(LO_FormElementStruct *formElem) { return ((FormFEData *)formElem->element_data->ele_minimal.FE_Data); }
|
||
inline LPane *GetFEDataPane( LO_FormElementStruct *formElem) { return FEDATAPANE; }
|
||
|
||
// Sets the value of FE_Data structure in form element
|
||
// Returns true if form is being created from scratch
|
||
// or if we are printing. The return value is used to
|
||
// determine whether the form element should be initialized
|
||
// to default values, or from the layout data. If printing,
|
||
// we want the latter
|
||
static Boolean InitFE_Data(
|
||
MWContext *context,
|
||
LO_FormElementStruct* formElem,
|
||
LPane* pane,
|
||
LFormElement *host,
|
||
LCommander *commander)
|
||
{
|
||
if (!formElem->element_data)
|
||
return false;
|
||
FormFEData *feData;
|
||
Boolean noFEData = ( formElem->element_data->ele_minimal.FE_Data == NULL );
|
||
|
||
if ( noFEData )
|
||
{
|
||
FormFEData* feData = new FormFEData;
|
||
ThrowIfNil_( feData );
|
||
formElem->element_data->ele_minimal.FE_Data = feData;
|
||
}
|
||
|
||
feData = (FormFEData *)formElem->element_data->ele_minimal.FE_Data;
|
||
feData->fPane = pane;
|
||
feData->fHost = host;
|
||
feData->fCommander = commander;
|
||
|
||
Assert_(host);
|
||
if (host)
|
||
host->SetFEData(feData);
|
||
|
||
if (context->type == MWContextPrint)
|
||
return false; // force the form elements to use data from layout
|
||
|
||
return noFEData;
|
||
}
|
||
|
||
static Boolean HasFormWidget(
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
return ((formElem->element_data->ele_minimal.FE_Data != NULL) &&
|
||
(FEDATAPANE != NULL));
|
||
}
|
||
|
||
/******************************************************************************
|
||
* CWhiteScroller
|
||
* White background instead of gray 'wscr'
|
||
******************************************************************************/
|
||
class CWhiteScroller: public LScrollerView
|
||
{
|
||
public:
|
||
//friend class CHyperView; // this class no longer exists
|
||
|
||
enum { class_ID = 'wscr' };
|
||
|
||
CWhiteScroller( LStream* inStream );
|
||
virtual Boolean FocusDraw(LPane* inSubPane = nil);
|
||
virtual void DrawSelf();
|
||
};
|
||
|
||
CWhiteScroller::CWhiteScroller(LStream *inStream)
|
||
: LScrollerView(inStream)
|
||
{
|
||
}
|
||
|
||
// The only real routine. Sets background to white
|
||
Boolean CWhiteScroller::FocusDraw(LPane* /*inSubPane*/)
|
||
{
|
||
if (LScrollerView::FocusDraw())
|
||
{
|
||
UGraphics::SetBack(CPrefs::White);
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
void CWhiteScroller::DrawSelf()
|
||
{
|
||
Rect frame;
|
||
if (CalcLocalFrameRect(frame) && IsVisible() &&
|
||
mUpdateRgnH && ((*mUpdateRgnH)->rgnBBox.top != (*mUpdateRgnH)->rgnBBox.bottom)) // Only erase on update
|
||
::EraseRect(&frame);
|
||
|
||
// if ((mVerticalBar && mVerticalBar->IsVisible()) || (mHorizontalBar && mHorizontalBar->IsVisible()))
|
||
// ::EraseRect(&frame);
|
||
|
||
LScrollerView::DrawSelf();
|
||
}
|
||
|
||
/*********************************************************************
|
||
* StModifyPPob
|
||
* Modifying PPob for dynamic change of the text resource ID when loading
|
||
* Constructor modifies the resource by sticking a resID at the appropriate
|
||
* offset.
|
||
* Destructor restores it.
|
||
* Offsets are generated by looking them up in Resourcerer
|
||
*********************************************************************/
|
||
class StModifyPPob {
|
||
Int16 fResID;
|
||
Int16 fOffset;
|
||
Int16 fOldTextR;
|
||
public:
|
||
StModifyPPob(Int16 resID, // Resource of the PPob to be modified
|
||
Int16 offset, // Offset into the resource
|
||
Int16 csid, // Charset of the current doc
|
||
Boolean button); // Which TxtR are we looking for (TRUE = button, FALSE = text)
|
||
~StModifyPPob();
|
||
};
|
||
|
||
StModifyPPob::StModifyPPob(Int16 resID, Int16 offset, Int16 csid, Boolean button)
|
||
{
|
||
fResID = resID;
|
||
fOffset = offset;
|
||
|
||
Int16 newTextR;
|
||
if (button)
|
||
newTextR = CPrefs::GetButtonFontTextResIDs(csid);
|
||
else
|
||
newTextR = CPrefs::GetTextFieldTextResIDs(csid);
|
||
|
||
Handle r = ::GetResource('PPob', fResID);
|
||
ThrowIfNil_(r);
|
||
HNoPurge(r);
|
||
// Modify the resource
|
||
StHandleLocker lock(r);
|
||
Int16 * myPointer = (Int16*)(*r + fOffset);
|
||
fOldTextR = *myPointer;
|
||
*myPointer = newTextR;
|
||
}
|
||
|
||
StModifyPPob::~StModifyPPob()
|
||
{
|
||
Handle r = ::GetResource('PPob', fResID);
|
||
StHandleLocker lock(r);
|
||
Int16 * myPointer = (Int16*)(*r + fOffset);;
|
||
*myPointer = fOldTextR;
|
||
HPurge(r);
|
||
}
|
||
|
||
void UFormElementFactory::RegisterFormTypes()
|
||
{
|
||
RegisterClass_( CFormButton);
|
||
RegisterClass_( CGAFormPushButton);
|
||
RegisterClass_( CFormList);
|
||
RegisterClass_( CFormLittleText);
|
||
RegisterClass_( CFormBigText);
|
||
RegisterClass_( CFormHTMLArea);
|
||
RegisterClass_( CFormRadio);
|
||
RegisterClass_( CGAFormRadio);
|
||
RegisterClass_( CFormCheckbox);
|
||
RegisterClass_( CGAFormCheckbox);
|
||
RegisterClass_( CFormFile);
|
||
RegisterClass_( CFormFileEditField);
|
||
RegisterClass_( CWhiteScroller);
|
||
}
|
||
|
||
//
|
||
// Figures out what kind of form element we're dealing with and dispatches *that*
|
||
//
|
||
void UFormElementFactory::MakeFormElem(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
LO_FormElementStruct* formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return;
|
||
Try_ {
|
||
Int32 width;
|
||
Int32 height;
|
||
Int32 baseline;
|
||
|
||
switch ( formElem->element_data->type )
|
||
{
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX:
|
||
MakeTextFormElem(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
case FORM_TYPE_READONLY:
|
||
MakeReadOnlyFormElem(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_TEXTAREA:
|
||
MakeTextArea(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
MakeHTMLArea(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
#endif /*ENDER*/
|
||
|
||
case FORM_TYPE_RADIO:
|
||
case FORM_TYPE_CHECKBOX:
|
||
MakeToggle(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_KEYGEN:
|
||
case FORM_TYPE_OBJECT:
|
||
width = height = baseline = 0;
|
||
break;
|
||
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
MakeButton(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_FILE:
|
||
MakeFilePicker(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_SELECT_ONE:
|
||
MakePopup(inHTMLView, inNSContext, width, height, baseline,formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_SELECT_MULT:
|
||
MakeList(inHTMLView, inNSContext, width, height, baseline, formElem);
|
||
break;
|
||
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
default:
|
||
Assert_(FALSE);
|
||
break;
|
||
};
|
||
|
||
formElem->width = width;
|
||
formElem->height = height;
|
||
formElem->baseline = baseline;
|
||
}
|
||
Catch_(inErr)
|
||
{
|
||
Assert_(FALSE);
|
||
}
|
||
EndCatch_
|
||
}
|
||
|
||
// Creates a simple edit text field
|
||
// textData->size is the number of characters
|
||
// textData->max_size is the maximum number of characters
|
||
// textData->default_text is the default text
|
||
LPane* UFormElementFactory::MakeTextFormElem(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width, Int32 &height, Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CFormLittleText * editField;
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
// If we did not have a control, create one
|
||
lo_FormElementTextData * textData = (lo_FormElementTextData *) formElem->element_data;
|
||
LCommander::SetDefaultCommander(inHTMLView); // For tabbing
|
||
LPane::SetDefaultView(inHTMLView);
|
||
switch (textData->type) {
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_ISINDEX:
|
||
{
|
||
StModifyPPob modifier(formTextField, 0x3F, inNSContext->GetWinCSID(), false);
|
||
editField = (CFormLittleText *)UReanimator::ReadObjects('PPob', formTextField);
|
||
}
|
||
break;
|
||
case FORM_TYPE_PASSWORD:
|
||
editField = (CFormLittleText *)UReanimator::ReadObjects('PPob', formPasswordField);
|
||
break;
|
||
default:
|
||
Throw_(0);
|
||
}
|
||
ThrowIfNil_(editField);
|
||
|
||
editField->InitFormElement(*inNSContext, formElem);
|
||
|
||
editField->FinishCreate();
|
||
editField->AddListener(inHTMLView);
|
||
if (textData->max_size < 0)
|
||
textData->max_size = 32000;
|
||
editField->SetMaxChars(textData->max_size);
|
||
editField->SetVisibleChars(textData->size);
|
||
editField->SetLayoutForm(formElem);
|
||
// Should allow undo
|
||
LUndoer* theUndoer = new LUndoer;
|
||
editField->AddAttachment(theUndoer);
|
||
|
||
// Reset the value
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext,formElem,editField,editField, editField));
|
||
|
||
// Secure fields are disabled
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
editField = (CFormLittleText *)FEDATAPANE;
|
||
if (!editField)
|
||
return NULL;
|
||
editField->SetLayoutForm(formElem); // CWhiteEdit field only (never uses it...)
|
||
editField->SetLayoutElement(formElem); // mocha mix-in needs to know too...
|
||
}
|
||
|
||
// Figure out dimensions
|
||
SDimension16 size;
|
||
editField->GetFrameSize(size);
|
||
width = size.width + textLeftExtra + textRightExtra;
|
||
height = size.height + textTopExtra + textBottomExtra;;
|
||
TEHandle textH = editField->GetMacTEH();
|
||
baseline = (*textH)->fontAscent + 2 + textTopExtra;
|
||
return editField;
|
||
}
|
||
|
||
// Very similar to MakeTextFormElem, for now
|
||
LPane * UFormElementFactory::MakeReadOnlyFormElem(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CFormLittleText * editField;
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
// If we did not have a control, create one
|
||
lo_FormElementMinimalData * readData = (lo_FormElementMinimalData *) formElem->element_data;
|
||
LCommander::SetDefaultCommander(inHTMLView); // For tabbing
|
||
LPane::SetDefaultView(inHTMLView);
|
||
StModifyPPob modifier(formTextField, 0x3F, inNSContext->GetWinCSID(), false);
|
||
editField = (CFormLittleText *)UReanimator::ReadObjects('PPob', formTextField);
|
||
ThrowIfNil_(editField);
|
||
|
||
editField->InitFormElement(*inNSContext, formElem);
|
||
editField->FinishCreate();
|
||
editField->SetLayoutForm(formElem);
|
||
editField->Disable();
|
||
|
||
// Reset the value
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem,editField,editField, editField));
|
||
char * newText;
|
||
PA_LOCK(newText, char* , readData->value);
|
||
editField->SetDescriptor(CStr255(newText));
|
||
editField->SetVisibleChars(newText ? XP_STRLEN(newText) : 10);
|
||
PA_UNLOCK(readData->value);
|
||
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
|
||
editField = (CFormLittleText *)FEDATAPANE;
|
||
if (!editField)
|
||
return NULL;
|
||
editField->SetLayoutForm(formElem);
|
||
editField->SetLayoutElement(formElem);
|
||
}
|
||
|
||
|
||
|
||
// Figure out dimensions
|
||
SDimension16 size;
|
||
editField->GetFrameSize(size);
|
||
width = size.width + textLeftExtra + textRightExtra;
|
||
height = size.height + textTopExtra + textBottomExtra;;
|
||
TEHandle textH = editField->GetMacTEH();
|
||
baseline = (*textH)->fontAscent + 2 + textTopExtra;
|
||
return editField;
|
||
}
|
||
|
||
#define BigTextLeftIndent 5 // same constants are in the forms.r
|
||
#define BigTextRightIndent 1
|
||
#define BigTextTopIndent 1
|
||
#define BigTextBottomIndent 1
|
||
// Creates a text area
|
||
// textAreaData->default_text;
|
||
// textAreaData->rows;
|
||
// textAreaData->cols;
|
||
LPane* UFormElementFactory::MakeTextArea(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CWhiteScroller * theScroller = NULL;
|
||
CFormBigText * theTextView = NULL;
|
||
FontInfo fontInfo;
|
||
if (!HasFormWidget(formElem)) // If there is no form, create it
|
||
{
|
||
lo_FormElementTextareaData * textAreaData = (lo_FormElementTextareaData *) formElem->element_data;
|
||
|
||
// Create the view
|
||
LCommander::SetDefaultCommander(inHTMLView);
|
||
LView::SetDefaultView(inHTMLView);
|
||
|
||
// since I can't find an API to switch the word wrap property after the element
|
||
// has been initialized, we need to create two separate PPob's. Read in the
|
||
// appropriate one depending on if the text area requires wrapping or not.
|
||
ResIDT elementToRead = 0;
|
||
switch(textAreaData->auto_wrap) {
|
||
case TEXTAREA_WRAP_SOFT:
|
||
case TEXTAREA_WRAP_HARD:
|
||
elementToRead = formBigText;
|
||
break;
|
||
|
||
case TEXTAREA_WRAP_OFF:
|
||
elementToRead = formBigTextScroll;
|
||
break;
|
||
|
||
} // case of wrap property
|
||
|
||
theScroller = (CWhiteScroller *)UReanimator::ReadObjects('PPob', elementToRead);
|
||
ThrowIfNil_(theScroller);
|
||
theScroller->FinishCreate();
|
||
theScroller->PutInside(inHTMLView);
|
||
|
||
theTextView = (CFormBigText*)theScroller->FindPaneByID(formBigTextID);
|
||
Assert_(theTextView != NULL);
|
||
|
||
LModelObject* theSuper = inHTMLView->GetFormElemBaseModel();
|
||
theTextView->InitFormElement(*inNSContext, formElem);
|
||
|
||
// Add the undoer for text actions. This will be on a per-text field basis
|
||
// Let WASTE handle undo
|
||
// LUndoer* theUndoer = new LUndoer;
|
||
// theTextView->AddAttachment(theUndoer);
|
||
|
||
// Resize to proper size
|
||
theTextView->FocusDraw();
|
||
// UTextTraits::SetPortTextTraits( theTextView->GetTextTraits() );
|
||
|
||
// Always use generic application font for form sizing measurements
|
||
short wantedWidth;
|
||
short wantedHeight;
|
||
do
|
||
{
|
||
StTextState textState;
|
||
::TextFont(applFont);
|
||
::TextSize(12);
|
||
::TextFace(0);
|
||
::GetFontInfo(&fontInfo);
|
||
wantedWidth = textAreaData->cols * ::CharWidth('M') + 8; // M is better than space
|
||
wantedHeight = textAreaData->rows * (fontInfo.ascent + fontInfo.descent + fontInfo.leading) + 8;
|
||
} while (0);
|
||
|
||
|
||
// make the image big so there is something to scroll, if necessary....
|
||
if ( textAreaData->auto_wrap == TEXTAREA_WRAP_OFF )
|
||
theTextView->ResizeImageTo(2000, 0, false);
|
||
|
||
theScroller->ResizeFrameTo(wantedWidth + 16 + BigTextLeftIndent + BigTextRightIndent,
|
||
wantedHeight + 16 + BigTextTopIndent + BigTextBottomIndent,
|
||
FALSE);
|
||
|
||
// Set the default values.
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem, theScroller, theTextView, theTextView));
|
||
|
||
theScroller->Show();
|
||
}
|
||
else
|
||
{
|
||
theScroller = (CWhiteScroller*)FEDATAPANE;
|
||
if (!theScroller)
|
||
return NULL;
|
||
theTextView = (CFormBigText*)theScroller->FindPaneByID(formBigTextID);
|
||
theTextView->FocusDraw();
|
||
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
theTextView->SetLayoutElement(formElem);
|
||
::GetFontInfo(&fontInfo);
|
||
}
|
||
|
||
SDimension16 size;
|
||
theScroller->GetFrameSize(size);
|
||
width = size.width + textLeftExtra + textRightExtra;;
|
||
height = size.height + textTopExtra + textBottomExtra;;
|
||
baseline = fontInfo.ascent + 2;
|
||
|
||
return theScroller;
|
||
}
|
||
|
||
// Creates an HTML area
|
||
// htmlAreaData->default_text;
|
||
// htmlAreaData->rows;
|
||
// htmlAreaData->cols;
|
||
LPane* UFormElementFactory::MakeHTMLArea(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CHyperScroller *theScroller = NULL;
|
||
LView *theView = NULL;
|
||
CFormHTMLArea *theHTMLAreaView = NULL;
|
||
FontInfo fontInfo;
|
||
if (!HasFormWidget(formElem)) // If there is no form, create it
|
||
{
|
||
lo_FormElementHTMLareaData * htmlAreaData = (lo_FormElementHTMLareaData *) formElem->element_data;
|
||
|
||
// Create the view
|
||
LCommander::SetDefaultCommander(inHTMLView);
|
||
LView::SetDefaultView(inHTMLView);
|
||
|
||
theView = (LView *)UReanimator::ReadObjects('PPob', formHTMLArea);
|
||
ThrowIfNil_(theView);
|
||
theView->FinishCreate();
|
||
theView->PutInside(inHTMLView);
|
||
|
||
theHTMLAreaView = (CFormHTMLArea*)theView->FindPaneByID(formHTMLAreaID);
|
||
ThrowIfNil_(theHTMLAreaView);
|
||
|
||
URL_Struct* url = 0;
|
||
url = NET_CreateURLStruct ("about:editfilenew", NET_NORMAL_RELOAD );
|
||
|
||
CBrowserContext *nscontext = new CBrowserContext();
|
||
ThrowIfNil_(nscontext);
|
||
theHTMLAreaView->SetContext(nscontext);
|
||
|
||
MWContext *context = *nscontext;
|
||
context->is_editor = true;
|
||
|
||
CURLDispatcher::DispatchURL( url, nscontext, false, false, CEditorWindow::res_ID );
|
||
|
||
LModelObject* theSuper = inHTMLView->GetFormElemBaseModel();
|
||
theHTMLAreaView->InitFormElement(*inNSContext, formElem);
|
||
|
||
// Resize to proper size
|
||
theHTMLAreaView->FocusDraw();
|
||
|
||
// Always use generic application font for form sizing measurements
|
||
short wantedWidth;
|
||
short wantedHeight;
|
||
do
|
||
{
|
||
StTextState textState;
|
||
::TextFont(applFont);
|
||
::TextSize(12);
|
||
::TextFace(0);
|
||
::GetFontInfo(&fontInfo);
|
||
wantedWidth = htmlAreaData->cols * ::CharWidth('M') + 8;
|
||
wantedHeight = htmlAreaData->rows * (fontInfo.ascent + fontInfo.descent + fontInfo.leading) + 8;
|
||
} while (0);
|
||
|
||
theView->ResizeFrameTo(wantedWidth + 16 + BigTextLeftIndent + BigTextRightIndent,
|
||
wantedHeight + 16 + BigTextTopIndent + BigTextBottomIndent,
|
||
FALSE);
|
||
|
||
// Set the default values.
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem, theView, theHTMLAreaView, theHTMLAreaView));
|
||
|
||
theView->Show();
|
||
}
|
||
else
|
||
{
|
||
theView = (LView*)FEDATAPANE;
|
||
if (!theView)
|
||
return NULL;
|
||
theHTMLAreaView = (CFormHTMLArea*)theView->FindPaneByID(formHTMLAreaID);
|
||
theHTMLAreaView->FocusDraw();
|
||
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
theHTMLAreaView->SetLayoutElement(formElem);
|
||
}
|
||
|
||
SDimension16 size;
|
||
theView->GetFrameSize(size);
|
||
width = size.width + textLeftExtra + textRightExtra;;
|
||
height = size.height + textTopExtra + textBottomExtra;;
|
||
baseline = fontInfo.ascent + 2;
|
||
|
||
return theView;
|
||
}
|
||
|
||
// Creates a button
|
||
// buttonData->name; is buttons name
|
||
// Buttons store the form element as the refCon, so that they can broadcast
|
||
// to the window.
|
||
LPane* UFormElementFactory::MakeButton(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
LControl* theControl = nil;
|
||
LPane* thePane = nil;
|
||
LFormElement* theHost = nil;
|
||
lo_FormElementMinimalData * buttonData= (lo_FormElementMinimalData *)formElem->element_data;
|
||
FontInfo info;
|
||
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
// FIX ME?
|
||
LCommander::SetDefaultCommander(LWindow::FetchWindowObject(inHTMLView->GetMacPort()));
|
||
LPane::SetDefaultView(inHTMLView);
|
||
switch (buttonData->type) {
|
||
case FORM_TYPE_SUBMIT:
|
||
{
|
||
XP_Bool useGrayscaleFormControls;
|
||
int prefResult = PREF_GetBoolPref("browser.mac.use_grayscale_form_controls", &useGrayscaleFormControls);
|
||
|
||
if (prefResult == PREF_NOERROR && useGrayscaleFormControls)
|
||
{
|
||
StModifyPPob modifier(formGASubmitButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formGASubmitButton));
|
||
}
|
||
else
|
||
{
|
||
StModifyPPob modifier(formSubmitButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formSubmitButton));
|
||
}
|
||
}
|
||
break;
|
||
case FORM_TYPE_RESET:
|
||
{
|
||
XP_Bool useGrayscaleFormControls;
|
||
int prefResult = PREF_GetBoolPref("browser.mac.use_grayscale_form_controls", &useGrayscaleFormControls);
|
||
|
||
if (prefResult == PREF_NOERROR && useGrayscaleFormControls)
|
||
{
|
||
StModifyPPob modifier(formGAResetButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formGAResetButton));
|
||
}
|
||
else
|
||
{
|
||
StModifyPPob modifier(formResetButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formResetButton));
|
||
}
|
||
}
|
||
break;
|
||
case FORM_TYPE_BUTTON:
|
||
{
|
||
XP_Bool useGrayscaleFormControls;
|
||
int prefResult = PREF_GetBoolPref("browser.mac.use_grayscale_form_controls", &useGrayscaleFormControls);
|
||
|
||
if (prefResult == PREF_NOERROR && useGrayscaleFormControls)
|
||
{
|
||
StModifyPPob modifier(formGAPlainButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formGAPlainButton));
|
||
}
|
||
else
|
||
{
|
||
StModifyPPob modifier(formPlainButton, 0x46, inNSContext->GetWinCSID(), TRUE);
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formPlainButton));
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
Throw_(0);
|
||
}
|
||
|
||
ThrowIfNil_(theHost = dynamic_cast<LFormElement*>(thePane));
|
||
ThrowIfNil_(theControl = dynamic_cast<LControl*>(thePane));
|
||
|
||
thePane->FinishCreate();
|
||
theHost->InitFormElement(*inNSContext, formElem);
|
||
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem,thePane,theHost, NULL));
|
||
// Set up buttons as broadcasters. Store the LO_FormElementStruct * in refCon
|
||
theControl->AddListener(inHTMLView);
|
||
}
|
||
else
|
||
{
|
||
thePane = FEDATAPANE;
|
||
ThrowIfNil_(theHost = dynamic_cast<LFormElement*>(thePane));
|
||
ThrowIfNil_(theControl = dynamic_cast<LControl*>(thePane));
|
||
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
theHost->SetLayoutElement(formElem);
|
||
}
|
||
|
||
thePane->SetUserCon((long)formElem); // Always do this
|
||
|
||
char * name;
|
||
PA_LOCK(name, char*, buttonData->value);
|
||
CStr255 pName(name);
|
||
thePane->SetDescriptor(pName);
|
||
PA_UNLOCK(buttonData->value);
|
||
::GetFontInfo(&info);
|
||
|
||
// Get width/height/baseline
|
||
SDimension16 size;
|
||
thePane->GetFrameSize(size);
|
||
width = size.width + buttomLeftExtra + buttonRightExtra;
|
||
height = size.height + buttonTopExtra + buttonBottomExtra;
|
||
baseline = info.ascent + 2 + buttonTopExtra;
|
||
return thePane;
|
||
}
|
||
|
||
LPane* UFormElementFactory::MakeFilePicker(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CFormFile * filePicker = NULL;
|
||
lo_FormElementTextData * pickerData= (lo_FormElementTextData *)formElem->element_data;
|
||
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
// FIX ME?
|
||
LCommander::SetDefaultCommander(LWindow::FetchWindowObject(inHTMLView->GetMacPort()));
|
||
LPane::SetDefaultView(inHTMLView);
|
||
filePicker = (CFormFile *)UReanimator::ReadObjects('PPob', formFilePicker);
|
||
ThrowIfNil_(filePicker);
|
||
|
||
filePicker->InitFormElement(*inNSContext, formElem);
|
||
|
||
filePicker->FinishCreate();
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem,filePicker,filePicker, filePicker->fEditField));
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
filePicker = (CFormFile *)FEDATAPANE;
|
||
if (!filePicker)
|
||
return NULL;
|
||
filePicker->SetLayoutElement(formElem);
|
||
}
|
||
|
||
|
||
/*
|
||
char * name;
|
||
PA_LOCK(name, char*, pickerData->default_text);
|
||
CStr255 pName(name);
|
||
filePicker->SetDescriptor(pName);
|
||
PA_UNLOCK(pickerData->default_text);
|
||
::GetFontInfo(&info);
|
||
*/
|
||
|
||
// Get width/height/baseline
|
||
filePicker->GetFontInfo(width, height, baseline);
|
||
width = width + buttomLeftExtra + buttonRightExtra;
|
||
height = height + buttonTopExtra + buttonBottomExtra;
|
||
return filePicker;
|
||
}
|
||
|
||
// Creates buttons/checkboxes
|
||
// Boolean toggleData->default_toggle is default on/off
|
||
LPane* UFormElementFactory::MakeToggle(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
|
||
LControl* toggle = nil;
|
||
LPane* thePane;
|
||
LFormElement *host;
|
||
lo_FormElementToggleData * toggleData = (lo_FormElementToggleData *)formElem->element_data;
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
// FIX ME?
|
||
LCommander::SetDefaultCommander(LWindow::FetchWindowObject(inHTMLView->GetMacPort()));
|
||
LPane::SetDefaultView(inHTMLView);
|
||
switch (toggleData->type)
|
||
{
|
||
case FORM_TYPE_RADIO:
|
||
{
|
||
XP_Bool useGrayscaleFormControls;
|
||
int prefResult = PREF_GetBoolPref("browser.mac.use_grayscale_form_controls", &useGrayscaleFormControls);
|
||
|
||
if (prefResult == PREF_NOERROR && useGrayscaleFormControls)
|
||
{
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formGARadio));
|
||
}
|
||
else
|
||
{
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formRadio));
|
||
}
|
||
}
|
||
break;
|
||
case FORM_TYPE_CHECKBOX:
|
||
{
|
||
XP_Bool useGrayscaleFormControls;
|
||
int prefResult = PREF_GetBoolPref("browser.mac.use_grayscale_form_controls", &useGrayscaleFormControls);
|
||
|
||
if (prefResult == PREF_NOERROR && useGrayscaleFormControls)
|
||
{
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formGACheckbox));
|
||
}
|
||
else
|
||
{
|
||
ThrowIfNil_(thePane = (LPane *)UReanimator::ReadObjects('PPob', formCheckbox));
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
Throw_(0);
|
||
}
|
||
|
||
ThrowIfNil_(host = dynamic_cast<LFormElement*>(thePane));
|
||
ThrowIfNil_(toggle = dynamic_cast<LControl*>(thePane));
|
||
|
||
host->InitFormElement(*inNSContext, formElem);
|
||
|
||
thePane->FinishCreate();
|
||
thePane->Enable();
|
||
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem,toggle, host, NULL));
|
||
|
||
// Set up toggles as broadcasters. Store the LO_FormElementStruct * in refCon
|
||
// toggle->AddListener(this);
|
||
|
||
}
|
||
else
|
||
{
|
||
LFormElement* formWidget;
|
||
|
||
lo_FormElementToggleData* toggleData = (lo_FormElementToggleData *)formElem->element_data;
|
||
toggle = dynamic_cast<LControl*>(FEDATAPANE);
|
||
if (!toggle)
|
||
return NULL;
|
||
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
if (toggleData->type == FORM_TYPE_RADIO) // fun with C++ casting
|
||
{
|
||
formWidget = dynamic_cast<LFormElement*>(toggle);
|
||
ThrowIfNil_(formWidget);
|
||
}
|
||
else if (toggleData->type == FORM_TYPE_CHECKBOX)
|
||
{
|
||
formWidget = dynamic_cast<LFormElement*>(toggle);
|
||
ThrowIfNil_(formWidget);
|
||
}
|
||
else
|
||
{
|
||
Assert_(false);
|
||
}
|
||
|
||
formWidget->SetLayoutElement(formElem);
|
||
}
|
||
|
||
toggle->SetUserCon((long)formElem);
|
||
|
||
short extra; // extra space to be left after the control
|
||
switch (toggleData->type) {
|
||
case FORM_TYPE_RADIO:
|
||
extra = 3;
|
||
break;
|
||
case FORM_TYPE_CHECKBOX:
|
||
extra = 5;
|
||
break;
|
||
}
|
||
// width/height/baseline
|
||
SDimension16 size;
|
||
toggle->GetFrameSize(size);
|
||
width = size.width + extra;
|
||
height = size.height;
|
||
baseline = size.height - 2;
|
||
return toggle;
|
||
}
|
||
|
||
LPane* UFormElementFactory::MakePopup (
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
lo_FormElementSelectData * selections = (lo_FormElementSelectData *)formElem->element_data;
|
||
// Create the popup
|
||
LCommander::SetDefaultCommander(inHTMLView);
|
||
LPane::SetDefaultView(inHTMLView);
|
||
|
||
LPane* thePane = (LPane*)(UReanimator::ReadObjects ('PPob', formGAPopup));
|
||
|
||
CGAPopupMenu* popupCtrl = dynamic_cast<CGAPopupMenu*>(thePane);
|
||
ThrowIfNil_(popupCtrl);
|
||
|
||
popupCtrl->SetTextTraits(CPrefs::GetButtonFontTextResIDs(inNSContext->GetWinCSID()));
|
||
|
||
popupCtrl->FinishCreate();
|
||
|
||
// pointer from host widget to layout
|
||
popupCtrl->SetUserCon ((Int32)selections);
|
||
// tell popup what data to display
|
||
FormsPopup * popupText = new FormsPopup (popupCtrl, selections);
|
||
ThrowIfNil_(popupText);
|
||
|
||
popupText->InitFormElement(*inNSContext, formElem);
|
||
|
||
popupCtrl->AddAttachment (popupText);
|
||
// reset values
|
||
|
||
ResetFormElement(formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem,popupCtrl,popupText, NULL)); // Reset the selection
|
||
#if 1 /* POPUP MENU VERTICAL POSITION FIX */
|
||
FontInfo fontInfo;
|
||
GetFontInfo (&fontInfo);
|
||
#endif
|
||
// Resize the popup to max width
|
||
short widgetBaseline;
|
||
Point popupSize = popupText->CalcTargetFrame (widgetBaseline);
|
||
popupCtrl->ResizeFrameTo (popupSize.h, popupSize.v, false);
|
||
width = popupSize.h;
|
||
height = popupSize.v + 1; // add 1 for "leading" between lines in forms
|
||
#if 1 /* POPUP MENU VERTICAL POSITION FIX */
|
||
baseline = fontInfo.ascent + 1;
|
||
#else
|
||
baseline = widgetBaseline;
|
||
#endif
|
||
|
||
popupCtrl->Show();
|
||
popupCtrl->Enable();
|
||
|
||
return popupCtrl;
|
||
}
|
||
else
|
||
{
|
||
LPane* widget = dynamic_cast<LPane*>(FEDATAPANE);
|
||
FormsPopup* popupText = dynamic_cast<FormsPopup*>(FEDATAHOST);
|
||
SDimension16 size;
|
||
|
||
ThrowIfNil_(widget);
|
||
ThrowIfNil_(popupText);
|
||
|
||
#if 1 /* POPUP MENU VERTICAL POSITION FIX */
|
||
FontInfo fontInfo;
|
||
GetFontInfo (&fontInfo);
|
||
#endif
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
if (popupText != NULL)
|
||
popupText->SetLayoutElement(formElem);
|
||
|
||
if (widget != NULL)
|
||
widget->GetFrameSize(size);
|
||
width = size.width;
|
||
height = size.height + 1; // add 1 for "leading" between lines in forms
|
||
#if 1 /* POPUP MENU VERTICAL POSITION FIX */
|
||
baseline = fontInfo.ascent + 1;
|
||
#else
|
||
baseline = 2; // ERROR. Does not get the proper baseline
|
||
#endif
|
||
return widget;
|
||
}
|
||
}
|
||
|
||
LPane* UFormElementFactory::MakeList(
|
||
CHTMLView* inHTMLView,
|
||
CNSContext* inNSContext,
|
||
Int32 &width,
|
||
Int32 &height,
|
||
Int32& baseline,
|
||
LO_FormElementStruct *formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return nil;
|
||
CFormList * myList = NULL; // (CFormList*)FEDATAPANE;
|
||
if (!HasFormWidget(formElem))
|
||
{
|
||
lo_FormElementSelectData* selectData = (lo_FormElementSelectData *)formElem->element_data;
|
||
// Create the form
|
||
LCommander::SetDefaultCommander( inHTMLView );
|
||
LPane::SetDefaultView( inHTMLView );
|
||
StModifyPPob modifier( formScrollingList, 0x3C, inNSContext->GetWinCSID(), false );
|
||
myList = (CFormList *)UReanimator::ReadObjects( 'PPob', formScrollingList );
|
||
ThrowIfNil_( myList );
|
||
|
||
myList->InitFormElement( *inNSContext, formElem );
|
||
myList->FinishCreate();
|
||
|
||
// Initialize the list items from the form data
|
||
myList->SetSelectMultiple( selectData->multiple );
|
||
myList->SyncRows( selectData->option_cnt );
|
||
|
||
ResetFormElement( formElem, FALSE, InitFE_Data((MWContext*)*inNSContext, formElem, myList, myList, myList)); // Reset the selection
|
||
myList->ShrinkToFit( selectData->size );
|
||
}
|
||
else
|
||
{
|
||
myList = (CFormList*)FEDATAPANE;
|
||
if (!myList)
|
||
return NULL;
|
||
myList->FocusDraw();
|
||
|
||
//
|
||
// We've already created a widget for the
|
||
// form element, but layout has gone and
|
||
// reallocated the form element, so we must
|
||
// update our reference to it.
|
||
//
|
||
myList->SetLayoutElement(formElem);
|
||
}
|
||
|
||
FontInfo info;
|
||
SDimension16 size;
|
||
|
||
::GetFontInfo( &info );
|
||
myList->GetFrameSize( size );
|
||
|
||
// +6 to account for the focus ring
|
||
width = size.width + 6;
|
||
height = size.height + 6;
|
||
|
||
baseline = info.ascent;
|
||
return myList;
|
||
}
|
||
|
||
// FreeFormElement is called when eric finally wants to free the FE form data
|
||
void UFormElementFactory::FreeFormElement(
|
||
LO_FormElementData *formElem)
|
||
{
|
||
XP_TRACE(("FreeFormElement, data %d \n", (Int32)formElem->ele_minimal.FE_Data));
|
||
switch (formElem->type) {
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX: // Sets the original text
|
||
case FORM_TYPE_FILE:
|
||
if (formElem->ele_text.current_text)
|
||
PA_FREE(formElem->ele_text.current_text);
|
||
formElem->ele_text.current_text = NULL;
|
||
FormFEData * FEData = (FormFEData *)formElem->ele_text.FE_Data;
|
||
if (FEData)
|
||
{ // don't forget to null out pointer to FEData in fHost
|
||
if (FEData->fHost)
|
||
FEData->fHost->SetFEData(NULL);
|
||
delete FEData;
|
||
}
|
||
formElem->ele_text.FE_Data = NULL;
|
||
break;
|
||
case FORM_TYPE_TEXTAREA:
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
#endif /*ENDER*/
|
||
if (formElem->ele_textarea.current_text) // Free up the old memory
|
||
PA_FREE(formElem->ele_textarea.current_text);
|
||
formElem->ele_textarea.current_text = NULL;
|
||
FEData = (FormFEData *)formElem->ele_textarea.FE_Data;
|
||
if (FEData)
|
||
{ // don't forget to null out pointer to FEData in fHost
|
||
if (FEData->fHost)
|
||
FEData->fHost->SetFEData(NULL);
|
||
delete FEData;
|
||
}
|
||
formElem->ele_textarea.FE_Data = NULL;
|
||
break;
|
||
case FORM_TYPE_RADIO:
|
||
case FORM_TYPE_CHECKBOX:
|
||
FEData = (FormFEData *)formElem->ele_toggle.FE_Data;
|
||
if (FEData)
|
||
{ // don't forget to null out pointer to FEData in fHost
|
||
if (FEData->fHost)
|
||
FEData->fHost->SetFEData(NULL);
|
||
delete FEData;
|
||
}
|
||
formElem->ele_toggle.FE_Data = NULL;
|
||
break;
|
||
case FORM_TYPE_SELECT_ONE:
|
||
case FORM_TYPE_SELECT_MULT:
|
||
FEData = (FormFEData *)formElem->ele_select.FE_Data;
|
||
if ( FEData )
|
||
{ // don't forget to null out pointer to FEData in fHost
|
||
if (FEData->fHost)
|
||
FEData->fHost->SetFEData(NULL);
|
||
delete FEData;
|
||
}
|
||
formElem->ele_select.FE_Data = NULL;
|
||
break;
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
case FORM_TYPE_READONLY:
|
||
FEData = (FormFEData *)formElem->ele_minimal.FE_Data;
|
||
if (FEData)
|
||
{ // don't forget to null out pointer to FEData in fHost
|
||
if (FEData->fHost)
|
||
FEData->fHost->SetFEData(NULL);
|
||
delete FEData;
|
||
}
|
||
formElem->ele_minimal.FE_Data = NULL;
|
||
break;
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
case FORM_TYPE_KEYGEN:
|
||
case FORM_TYPE_OBJECT:
|
||
// no FE_Data for these guys
|
||
break;
|
||
};
|
||
}
|
||
|
||
/*-----------------------------------------------------------------------------
|
||
Forms.
|
||
lo_ele.h
|
||
|
||
Just like in other web clients, size is the size in characters the field should be,
|
||
max_size is the maximum length in characters that can be entered.
|
||
default_text is the text the user wants to have appear in the textfield
|
||
on creation and reset.
|
||
|
||
The layout needs the front end to fill in the width and height fields in the
|
||
LO_FormElementStruct. It also needs the baseline field filled in.
|
||
This may be difficult to impossible on some front ends. baseline is
|
||
the y position from 0 to (height - 1) that should line up with regular text on
|
||
the same line as this form element. If necessary, just punt to
|
||
baseline = (height - 1).
|
||
-----------------------------------------------------------------------------*/
|
||
|
||
// Took out XP_TRACEFORM call, so why use this function?
|
||
|
||
void UFormElementFactory::DisplayFormElement(
|
||
CNSContext* inNSContext,
|
||
LO_FormElementStruct* formElem )
|
||
{
|
||
Rect oldElementFrame, newElementFrame;
|
||
Int32 extraX, extraY;
|
||
LPane *pane;
|
||
|
||
pane = 0;
|
||
|
||
Try_ // Because stupid LNTextEdit does a throw when you resize it too large
|
||
{
|
||
// <20> the x,y passed to us originally may have been adjusted by layout
|
||
// so we have to update the widget. We don't actually need to draw it.
|
||
// It should only be adjusted once I think.
|
||
if ( !XP_CheckElementSpan( *inNSContext,
|
||
formElem->y + formElem->y_offset, formElem->height ) )
|
||
return;
|
||
|
||
if (!formElem->element_data)
|
||
return; // jrm 97/03/21
|
||
|
||
switch ( formElem->element_data->type )
|
||
{
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
case FORM_TYPE_FILE:
|
||
if (GetFEData (formElem)) {
|
||
pane = GetFEDataPane(formElem);
|
||
extraX = buttomLeftExtra; // [sic]
|
||
extraY = buttonTopExtra;
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX:
|
||
case FORM_TYPE_READONLY:
|
||
case FORM_TYPE_TEXTAREA:
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
#endif /*ENDER*/
|
||
if (GetFEData (formElem)) {
|
||
pane = GetFEDataPane(formElem);
|
||
extraX = textLeftExtra;
|
||
extraY = textTopExtra;
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_RADIO:
|
||
case FORM_TYPE_CHECKBOX:
|
||
case FORM_TYPE_SELECT_ONE:
|
||
case FORM_TYPE_SELECT_MULT:
|
||
if (GetFEData (formElem)) {
|
||
pane = GetFEDataPane(formElem);
|
||
extraX = 0;
|
||
extraY = 0;
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_OBJECT:
|
||
break;
|
||
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_KEYGEN:
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
default:
|
||
Assert_(FALSE);
|
||
break;
|
||
}
|
||
|
||
if (pane) {
|
||
if (pane->IsVisible() && formElem->ele_attrmask & LO_ELE_INVISIBLE) {
|
||
pane->Hide();
|
||
}
|
||
pane->CalcPortFrameRect (oldElementFrame);
|
||
pane->PlaceInSuperImageAt (formElem->x + formElem->x_offset + extraX,
|
||
formElem->y + formElem->y_offset + extraY, TRUE);
|
||
pane->CalcPortFrameRect (newElementFrame);
|
||
// if the element had to be moved, invalidate a slightly larger area than its current frame
|
||
// (see notes below)
|
||
if (oldElementFrame.top != newElementFrame.top || oldElementFrame.left != newElementFrame.left) {
|
||
newElementFrame.left--;
|
||
newElementFrame.top--;
|
||
newElementFrame.right++;
|
||
newElementFrame.bottom++;
|
||
pane->InvalPortRect (&newElementFrame);
|
||
}
|
||
if (!pane->IsVisible() && !(formElem->ele_attrmask & LO_ELE_INVISIBLE)) {
|
||
pane->Show();
|
||
pane->Enable();
|
||
}
|
||
pane->Draw(nil);
|
||
}
|
||
}
|
||
Catch_(inErr)
|
||
{}
|
||
EndCatch_
|
||
|
||
/* Why we invalidate a slightly larger rectangle than that occupied by the form element
|
||
pane itself: when generating a page from HTML, the compositor creates a unique layer
|
||
for each form element. This layer is strictly rectangular and slightly larger than
|
||
the form element pane, and is used as a mask to punch out a hole in its background.
|
||
If the new form element happens to be located in a table cell using a background
|
||
color different from that used by the document, the element will have a frame
|
||
of the document background color around it after the document has been created.
|
||
That frame is temporary; it is erased when the document is redrawn, because on
|
||
subsequent draw operations, the element frame is no longer used to punch a hole
|
||
in the cell background. The cell background is rendered in the same pass as the
|
||
document background, before PowerPlant panes (already created form elements) are
|
||
drawn. Invalidating a slightly larger framerect when the form element pane
|
||
is first moved onto the document forces the important part of that redraw to happen
|
||
immediately, erasing the inappropriately colored frame around the pane.
|
||
*/
|
||
}
|
||
|
||
void UFormElementFactory::ResetFormElement(
|
||
LO_FormElementStruct *formElem,
|
||
Boolean redraw,
|
||
Boolean fromDefaults)
|
||
{
|
||
ResetFormElementData(formElem, redraw, fromDefaults, true);
|
||
}
|
||
|
||
void UFormElementFactory::SetFormElementToggle(
|
||
LO_FormElementStruct* formElem,
|
||
Boolean value )
|
||
{
|
||
#ifdef DEBUG
|
||
if ( !formElem->element_data || formElem->element_data->type != FORM_TYPE_RADIO )
|
||
XP_ABORT(("no form radio"));
|
||
#endif
|
||
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
LStdControl* control = (LStdControl*)FEDATAPANE;
|
||
if (!control)
|
||
return;
|
||
|
||
// control->SetValue( value );
|
||
// control->Refresh();
|
||
|
||
// MGY: In order to eliminate flickering, I changed the unenlightened call
|
||
// to Refresh above to be a little more enlightened. TODO: find out why
|
||
// it's here at all and remove it if no one can give a satifactory reason.
|
||
// Before removing it, test both GA and non-GA toggles on a variety of backgfounds
|
||
// to verify that it indeed did not perform any useful service.
|
||
|
||
#if 0
|
||
Int32 oldValue = control->GetValue();
|
||
if (value != oldValue)
|
||
{
|
||
control->SetValue(value);
|
||
control->Refresh();
|
||
}
|
||
#endif
|
||
|
||
// MGY: Do it this way instead
|
||
|
||
control->SetValue(value);
|
||
}
|
||
|
||
void UFormElementFactory::FormTextIsSubmit(
|
||
LO_FormElementStruct * formElem)
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
if (!formElem->element_data)
|
||
return;
|
||
lo_FormElementTextData * textData = (lo_FormElementTextData *) formElem->element_data;
|
||
CFormLittleText* editField = (CFormLittleText*)FEDATAPANE;
|
||
if (editField)
|
||
editField->SetBroadcast(TRUE);
|
||
}
|
||
//
|
||
// We should move this to some utility class
|
||
//
|
||
// To Do: Figure out is this ok for
|
||
// TEXTAREA_WRAP_OFF, TEXTAREA_WRAP_SOFT and TEXTAREA_WRAP_HARD
|
||
//
|
||
static char* ConvertDataInTextEnginToUTF8(CWASTEEdit* engine)
|
||
{
|
||
Handle h = engine->GetTextHandle();
|
||
Int32 offset, theTextSize = engine->GetTextLength();
|
||
ScriptCode script;
|
||
INTL_Encoding_ID encoding;
|
||
WERunInfo runInfo;
|
||
Int32 gatherSize = theTextSize * 3 + 1;
|
||
char* utf8gather = (char*)XP_ALLOC(gatherSize);
|
||
|
||
if(utf8gather) {
|
||
StHandleLocker lock(h);
|
||
*utf8gather = '\0'; // null terminated the beginning
|
||
|
||
for (offset = 0; offset < theTextSize; ) {
|
||
engine->GetRunInfo(offset, &runInfo);
|
||
script = FontToScript(runInfo.runStyle.tsFont);
|
||
encoding = ScriptToEncoding(script);
|
||
|
||
Int32 runLength = runInfo.runEnd - runInfo.runStart;
|
||
char * utftemp = (char*)INTL_ConvertLineWithoutAutoDetect (encoding, CS_UTF8,
|
||
(unsigned char *)((*h) + offset), runLength);
|
||
if(utftemp) {
|
||
XP_STRCAT(utf8gather, utftemp);
|
||
XP_FREE(utftemp);
|
||
}
|
||
offset += runLength;
|
||
}
|
||
|
||
Int32 reallocatedLen = strlen(utf8gather) + 1;
|
||
if(reallocatedLen < (gatherSize - 8))
|
||
{
|
||
// Let's try to allocate a smalle buffer and return that instead if possible
|
||
if(char* reallocated = (char*)XP_ALLOC(reallocatedLen))
|
||
{
|
||
XP_STRCPY(reallocated,utf8gather);
|
||
XP_FREE(utf8gather);
|
||
return reallocated;
|
||
}
|
||
}
|
||
return utf8gather; // otherwise, just return the one we allocated.
|
||
}
|
||
|
||
return "";
|
||
}
|
||
|
||
|
||
void UFormElementFactory::GetFormElementValue(
|
||
LO_FormElementStruct *formElem,
|
||
Boolean hide)
|
||
{
|
||
if (!formElem->element_data)
|
||
return;
|
||
Try_
|
||
{
|
||
switch (formElem->element_data->type)
|
||
{
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX: // Sets the original text
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementTextData* textData = (lo_FormElementTextData*)formElem->element_data;
|
||
if (textData->current_text)
|
||
PA_FREE(textData->current_text);
|
||
textData->current_text = NULL;
|
||
|
||
LEditField * editField = (LEditField*)FEDATAPANE;
|
||
if (!editField)
|
||
return;
|
||
CStr255 text;
|
||
editField->GetDescriptor(text);
|
||
textData->current_text = PA_ALLOC(text.Length() +1);
|
||
char * textPtr;
|
||
PA_LOCK(textPtr, char*, textData->current_text);
|
||
BlockMoveData(&(text[1]), textPtr, text.Length());
|
||
textPtr[text.Length()] = 0;
|
||
PA_UNLOCK(textData->current_text);
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_TEXTAREA:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementTextareaData * textAreaData = (lo_FormElementTextareaData *) formElem->element_data;
|
||
if (textAreaData->current_text) // Free up the old memory
|
||
PA_FREE(textAreaData->current_text);
|
||
textAreaData->current_text = NULL;
|
||
// find the views
|
||
LView * scroller = (LView*)FEDATAPANE;
|
||
if (!scroller)
|
||
return;
|
||
CSimpleTextView* textEdit = (CSimpleTextView*)scroller->FindPaneByID(formBigTextID);
|
||
// Copy the text over
|
||
Handle h = NULL;
|
||
Boolean disposeHandle; // Depending if we are making a copy of the text handle
|
||
if(CS_UTF8 == formElem->text_attr->charset)
|
||
{
|
||
disposeHandle = FALSE;
|
||
textAreaData->current_text =
|
||
(PA_Block) ConvertDataInTextEnginToUTF8(dynamic_cast<CWASTEEdit *>(textEdit));
|
||
|
||
} else {
|
||
Int32 theTextSize;
|
||
switch(textAreaData->auto_wrap)
|
||
{
|
||
case TEXTAREA_WRAP_OFF:
|
||
case TEXTAREA_WRAP_SOFT:
|
||
{
|
||
disposeHandle = FALSE;
|
||
h = textEdit->GetTextHandle();
|
||
theTextSize = textEdit->GetTextLength();
|
||
}
|
||
break;
|
||
case TEXTAREA_WRAP_HARD:
|
||
{
|
||
|
||
disposeHandle = TRUE;
|
||
h = TextHandleToHardLineBreaks( *textEdit );
|
||
theTextSize = ::GetHandleSize(h);
|
||
|
||
}
|
||
break;
|
||
}
|
||
|
||
ThrowIfNULL_(h);
|
||
|
||
// note that in the hard wrapped case we're adding an extra null byte
|
||
// on the end. this wont hurt.
|
||
char* newTextPtr = (char*)XP_ALLOC(theTextSize + 1);
|
||
::BlockMoveData(*h, newTextPtr, theTextSize);
|
||
newTextPtr[theTextSize] = 0;
|
||
|
||
textAreaData->current_text = (PA_Block)newTextPtr;
|
||
}
|
||
|
||
if (disposeHandle)
|
||
DisposeHandle(h);
|
||
}
|
||
break;
|
||
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementHTMLareaData * htmlAreaData = (lo_FormElementHTMLareaData *) formElem->element_data;
|
||
if (htmlAreaData->current_text) // Free up the old memory
|
||
PA_FREE(htmlAreaData->current_text);
|
||
htmlAreaData->current_text = NULL;
|
||
// find the views
|
||
LView * scroller = (LView*)FEDATAPANE;
|
||
if (!scroller)
|
||
return;
|
||
CFormHTMLArea* htmlEdit = (CFormHTMLArea*)scroller->FindPaneByID(formHTMLAreaID);
|
||
Assert_(htmlEdit != NULL);
|
||
// Copy the text over
|
||
char* newTextPtr = 0;
|
||
EDT_SaveToBuffer(*(((CHTMLView*)htmlEdit)->GetContext()), (XP_HUGE_CHAR_PTR*) &newTextPtr);
|
||
htmlAreaData->current_text = (PA_Block)newTextPtr;
|
||
}
|
||
break;
|
||
#endif /*ENDER*/
|
||
|
||
case FORM_TYPE_RADIO:
|
||
case FORM_TYPE_CHECKBOX: // Sets the original check state
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementToggleData * toggleData = (lo_FormElementToggleData*)formElem->element_data;
|
||
LStdControl * toggle = (LStdControl *)FEDATAPANE;
|
||
if (toggle)
|
||
toggleData->toggled = toggle->GetValue();
|
||
break;
|
||
case FORM_TYPE_FILE:
|
||
lo_FormElementTextData * pickData = (lo_FormElementTextData*)formElem->element_data;
|
||
CFormFile * formFile = (CFormFile *)FEDATAPANE;
|
||
FSSpec spec;
|
||
if (formFile && formFile->GetFileSpec(spec))
|
||
{
|
||
char * fileURL = CFileMgr::EncodedPathNameFromFSSpec( spec, TRUE );
|
||
if (fileURL)
|
||
{
|
||
PA_Block newValueBlock = PA_ALLOC(XP_STRLEN(fileURL) + 1);
|
||
char * value;
|
||
PA_LOCK(value, char*, newValueBlock);
|
||
::BlockMoveData(fileURL, value, XP_STRLEN(fileURL) + 1);
|
||
PA_UNLOCK(newValueBlock);
|
||
pickData->current_text = newValueBlock;
|
||
XP_FREE(fileURL);
|
||
}
|
||
else
|
||
pickData->current_text = NULL;
|
||
}
|
||
else
|
||
pickData->current_text = NULL;
|
||
break;
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_KEYGEN:
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
case FORM_TYPE_READONLY:
|
||
break;
|
||
case FORM_TYPE_SELECT_ONE:
|
||
{ // Resets the selects
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementSelectData_struct* selections = &formElem->element_data->ele_select;
|
||
LButton* widget = (LButton*)FEDATAPANE;
|
||
int value = widget ? widget->GetValue() : 0;
|
||
lo_FormElementOptionData_struct* options = (lo_FormElementOptionData_struct*)selections->options;
|
||
for ( int i = 0; i < selections->option_cnt; i++ )
|
||
options[ i ].selected = FALSE;
|
||
if ( value )
|
||
options[ value - 1].selected = TRUE;
|
||
}
|
||
break;
|
||
case FORM_TYPE_SELECT_MULT:
|
||
{
|
||
lo_FormElementSelectData* selectData = (lo_FormElementSelectData *)formElem->element_data;
|
||
CFormList* myList = (CFormList*)FEDATAPANE;
|
||
if (!myList)
|
||
return;
|
||
lo_FormElementOptionData* mother = (lo_FormElementOptionData*)selectData->options;
|
||
for ( int i = 0 ; i < selectData->option_cnt; i++ )
|
||
mother[ i ].selected = myList->IsSelected( i );
|
||
}
|
||
break;
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
case FORM_TYPE_OBJECT:
|
||
break;
|
||
}
|
||
}
|
||
Catch_(inErr){}
|
||
EndCatch_
|
||
if (hide)
|
||
HideFormElement(formElem);
|
||
}
|
||
|
||
void UFormElementFactory::HideFormElement(
|
||
LO_FormElementStruct* formElem)
|
||
{
|
||
if (!formElem->element_data)
|
||
return;
|
||
switch ( formElem->element_data->type )
|
||
{
|
||
case FORM_TYPE_TEXT:
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX:
|
||
case FORM_TYPE_TEXTAREA:
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
#endif /*ENDER*/
|
||
case FORM_TYPE_RADIO:
|
||
case FORM_TYPE_CHECKBOX:
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
case FORM_TYPE_SELECT_ONE:
|
||
case FORM_TYPE_SELECT_MULT:
|
||
case FORM_TYPE_FILE:
|
||
case FORM_TYPE_READONLY:
|
||
|
||
LFormElement* host = FEDATAHOST;
|
||
|
||
// Schedule the form element to be destroyed.
|
||
// We don't do it immediately because we may
|
||
// be in the middle of a JavaScript which could
|
||
// then return to some PowerPlant code which
|
||
// still needs access to the form element widget
|
||
//
|
||
// Read the comments for MarkForDeath for more details
|
||
//
|
||
if (host != NULL) {
|
||
host->MarkForDeath();
|
||
}
|
||
|
||
FEDATAPANE = NULL;
|
||
FEDATAHOST = NULL;
|
||
break;
|
||
|
||
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_KEYGEN:
|
||
// no value to set or reset
|
||
break;
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
case FORM_TYPE_OBJECT:
|
||
break;
|
||
}
|
||
}
|
||
static void ValidateTextByCharset(int csid, char* text)
|
||
{
|
||
if(text && (csid & MULTIBYTE))
|
||
{
|
||
int pos;
|
||
int lastIdx = 0;
|
||
int boundary = strlen(text);
|
||
for(pos = 0 ; pos < boundary ; pos += (INTL_IsLeadByte(csid, text[pos])+1))
|
||
lastIdx = pos;
|
||
if(pos != boundary)
|
||
text[lastIdx] = '\0';
|
||
}
|
||
}
|
||
|
||
|
||
static void PutUnicodeIntoTextEngine( CWASTEEdit* engine, INTL_Unicode* unicode, Int32 len)
|
||
{
|
||
INTL_CompoundStr* cs = INTL_CompoundStrFromUnicode(unicode, len);
|
||
UFontSwitcher* fs= UFixedFontSwitcher::Instance();
|
||
if(cs)
|
||
{
|
||
// Clear the text before insertining text runs.
|
||
engine->SelectAll();
|
||
engine->Delete();
|
||
|
||
INTL_Encoding_ID encoding;
|
||
unsigned char* outtext;
|
||
INTL_CompoundStrIterator iter;
|
||
for(iter = INTL_CompoundStrFirstStr((INTL_CompoundStrIterator)cs, &encoding , &outtext);
|
||
iter != NULL;
|
||
iter = INTL_CompoundStrNextStr(iter, &encoding, &outtext))
|
||
{
|
||
if((outtext) && (*outtext))
|
||
{
|
||
Int32 theTextSize = engine->GetTextLength();
|
||
// Set the Text
|
||
engine->SetSelection(LONG_MAX, LONG_MAX);
|
||
engine->InsertPtr((char*)outtext, XP_STRLEN((char*)outtext), NULL, NULL);
|
||
|
||
CCharSet charset; // Don't move this line since the fontname is point to it.
|
||
unsigned char* fontname;
|
||
switch(encoding)
|
||
{
|
||
case CS_SYMBOL:
|
||
fontname = (unsigned char*)"\pSymbol";
|
||
break;
|
||
case CS_DINGBATS:
|
||
fontname = (unsigned char*)"\pZapf Dingbats";
|
||
break;
|
||
default:
|
||
Boolean gotFont = CPrefs::GetFont(encoding, &charset);
|
||
Assert_(gotFont);
|
||
fontname = &charset.fPropFont[0];//fFixedFont[0];
|
||
break;
|
||
}
|
||
|
||
TextStyle inTextStyle;
|
||
GetFNum(fontname, &inTextStyle.tsFont);
|
||
engine->SetSelection(theTextSize, LONG_MAX);
|
||
engine->SetStyle(weDoFont, &inTextStyle);
|
||
}
|
||
}
|
||
INTL_CompoundStrDestroy(cs);
|
||
}
|
||
}
|
||
|
||
|
||
static void PutUTF8IntoTextEngine( CWASTEEdit* engine, char* text, Int32 len)
|
||
{
|
||
if(len >0)
|
||
{
|
||
uint32 ubuflen = len+1;
|
||
uint32 ucs2len;
|
||
INTL_Unicode* ucs2buf = NULL;
|
||
ucs2buf = new INTL_Unicode[ubuflen];
|
||
if(ucs2buf && (0 != (ucs2len = UUTF8TextHandler::Instance()->UTF8ToUCS2((unsigned char*) text, len, ucs2buf, ubuflen) )))
|
||
PutUnicodeIntoTextEngine(engine, ucs2buf, ucs2len);
|
||
else
|
||
Assert_(FALSE);
|
||
|
||
if(ucs2buf)
|
||
delete ucs2buf;
|
||
}
|
||
}
|
||
|
||
|
||
static void ChangeTextTraitsForSingleScript( CWASTEEdit* engine, unsigned short csid)
|
||
{
|
||
TextTraitsH theTextTraits = UTextTraits::LoadTextTraits(CPrefs::GetTextFieldTextResIDs(csid));
|
||
TextStyle ts;
|
||
|
||
if (theTextTraits != NULL) {
|
||
ts.tsFont = (*theTextTraits)->fontNumber;
|
||
ts.tsSize = (*theTextTraits)->size;
|
||
ts.tsFace = (*theTextTraits)->style;
|
||
ts.tsColor = (*theTextTraits)->color;
|
||
|
||
engine->SetStyle(weDoAll, &ts);
|
||
}
|
||
}
|
||
|
||
|
||
static void SetupTextInTextEngine( CWASTEEdit* engine, int16 csid, char* text, int32 len)
|
||
{
|
||
if(CS_UTF8 == csid)
|
||
{
|
||
PutUTF8IntoTextEngine( engine, text, len );
|
||
} else {
|
||
ChangeTextTraitsForSingleScript(engine, csid );
|
||
if (text != NULL)
|
||
engine->InsertPtr( text, len, NULL, NULL, true );
|
||
else
|
||
{
|
||
engine->SelectAll();
|
||
engine->Delete();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void UFormElementFactory::ResetFormElementData(
|
||
LO_FormElementStruct *formElem,
|
||
Boolean redraw,
|
||
Boolean fromDefaults,
|
||
Boolean reflect)
|
||
{
|
||
if (!formElem->element_data)
|
||
return;
|
||
switch (formElem->element_data->type)
|
||
{
|
||
case FORM_TYPE_TEXT: // Set the text
|
||
case FORM_TYPE_PASSWORD:
|
||
case FORM_TYPE_ISINDEX:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementTextData* textData = & formElem->element_data->ele_text;
|
||
LEditField * editField = (LEditField *)FEDATAPANE;
|
||
if (!editField)
|
||
return;
|
||
char* newText = NULL;
|
||
if ( fromDefaults )
|
||
{
|
||
if ( textData->default_text ) // Eric might be passing us NULL
|
||
{
|
||
newText = (char*)textData->default_text;
|
||
editField->SetDescriptor( CStr255( newText ) );
|
||
}
|
||
else
|
||
editField->SetDescriptor( "\p" );
|
||
}
|
||
else
|
||
{
|
||
newText = (char*)textData->current_text;
|
||
editField->SetDescriptor( CStr255( newText ) );
|
||
}
|
||
if ( redraw )
|
||
{
|
||
editField->Refresh();
|
||
editField->UpdatePort();
|
||
}
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_TEXTAREA:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementTextareaData* textAreaData = (lo_FormElementTextareaData*) formElem->element_data;
|
||
LView* scroller = (LView*)FEDATAPANE;
|
||
if (!scroller)
|
||
return;
|
||
CSimpleTextView* textEdit = (CSimpleTextView*)scroller->FindPaneByID(formBigTextID);
|
||
CWASTEEdit* engine = dynamic_cast<CWASTEEdit *>(textEdit);
|
||
char* default_text;
|
||
if ( fromDefaults )
|
||
{
|
||
if ( textAreaData->default_text )
|
||
{
|
||
default_text = (char*)textAreaData->default_text;
|
||
ValidateTextByCharset(formElem->text_attr->charset, default_text);
|
||
Try_
|
||
{
|
||
SetupTextInTextEngine(engine, formElem->text_attr->charset, default_text, XP_STRLEN((char*)default_text));
|
||
}
|
||
Catch_( inErr )
|
||
{
|
||
}
|
||
EndCatch_
|
||
}
|
||
else // No default value
|
||
{
|
||
Try_
|
||
{
|
||
SetupTextInTextEngine(engine, formElem->text_attr->charset, NULL, 0);
|
||
}
|
||
Catch_( inErr )
|
||
{
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
default_text = (char*)textAreaData->current_text;
|
||
ValidateTextByCharset(formElem->text_attr->charset, default_text);
|
||
Try_
|
||
{
|
||
Int32 length = XP_STRLEN((char*)default_text);
|
||
// Don't want last linefeed
|
||
if ( length && default_text[ length -1 ] == '\r')
|
||
length --; // Strip off the last lf
|
||
|
||
|
||
if( length )
|
||
SetupTextInTextEngine(engine, formElem->text_attr->charset, default_text, length);
|
||
}
|
||
Catch_( inErr )
|
||
{
|
||
}
|
||
}
|
||
if ( redraw )
|
||
textEdit->Refresh();
|
||
}
|
||
break;
|
||
|
||
#ifdef ENDER
|
||
case FORM_TYPE_HTMLAREA:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementHTMLareaData* htmlAreaData = (lo_FormElementHTMLareaData*) formElem->element_data;
|
||
LView* scroller = (LView*)FEDATAPANE;
|
||
if (!scroller)
|
||
return;
|
||
CFormHTMLArea* htmlEdit = (CFormHTMLArea*)scroller->FindPaneByID(formHTMLAreaID);
|
||
if (!htmlEdit)
|
||
return;
|
||
MWContext *pContext = *(((CHTMLView*)htmlEdit)->GetContext());
|
||
if ( fromDefaults )
|
||
{
|
||
EDT_SetDefaultHTML( pContext,(char*)(htmlAreaData->default_text) );
|
||
}
|
||
else
|
||
{
|
||
EDT_SetDefaultHTML( pContext, (char*)(htmlAreaData->current_text) );
|
||
}
|
||
if ( redraw )
|
||
htmlEdit->Refresh();
|
||
}
|
||
break;
|
||
#endif /*ENDER*/
|
||
|
||
case FORM_TYPE_RADIO: // Set the toggle to on or off
|
||
case FORM_TYPE_CHECKBOX:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementToggleData* toggleData = (lo_FormElementToggleData*)formElem->element_data;
|
||
LStdControl* toggle = (LStdControl*)FEDATAPANE;
|
||
if (!toggle)
|
||
return;
|
||
if ( fromDefaults )
|
||
{
|
||
if ( toggle->GetValue() == toggleData->default_toggle ) // Do not change unless we have to
|
||
break;
|
||
toggle->SetValue( toggleData->default_toggle );
|
||
}
|
||
else // use the stored value
|
||
{
|
||
if ( toggle->GetValue() == toggleData->toggled )
|
||
break;
|
||
toggle->SetValue( toggleData->toggled );
|
||
}
|
||
if ( redraw )
|
||
toggle->Refresh();
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_FILE:
|
||
{
|
||
lo_FormElementTextData * pickData = (lo_FormElementTextData*)formElem->element_data;
|
||
CFormFile * formFile = (CFormFile *)FEDATAPANE;
|
||
if (!formFile)
|
||
return;
|
||
formFile->SetVisibleChars(pickData->size);
|
||
if (fromDefaults)
|
||
; // Do nothing
|
||
else
|
||
{
|
||
char * default_text;
|
||
FSSpec spec;
|
||
OSErr err;
|
||
PA_LOCK(default_text, char*, pickData->current_text);
|
||
if (default_text)
|
||
err = CFileMgr::FSSpecFromLocalUnixPath(default_text, &spec);
|
||
else
|
||
err = fnfErr;
|
||
PA_UNLOCK(pickData->current_text);
|
||
if (err == noErr)
|
||
formFile->SetFileSpec(spec);
|
||
}
|
||
if (redraw)
|
||
formFile->Refresh();
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_HIDDEN:
|
||
case FORM_TYPE_KEYGEN:
|
||
case FORM_TYPE_SUBMIT:
|
||
case FORM_TYPE_RESET:
|
||
case FORM_TYPE_BUTTON:
|
||
// no value to set or reset
|
||
break;
|
||
|
||
case FORM_TYPE_SELECT_ONE:
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementSelectData* selectData = (lo_FormElementSelectData*)formElem->element_data;
|
||
int offset = CalcCurrentSelected( selectData, fromDefaults );
|
||
|
||
LButton* widget = (LButton*)FEDATAPANE;
|
||
FormsPopup* popup = (FormsPopup*)FEDATAHOST;
|
||
|
||
if (popup)
|
||
popup->DirtyMenu();
|
||
if (!widget)
|
||
return;
|
||
widget->SetValue( offset + 1 );
|
||
if ( redraw )
|
||
widget->Refresh();
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_SELECT_MULT: // Select/unselect the cells
|
||
{
|
||
if ( !GetFEData( formElem ) )
|
||
return;
|
||
lo_FormElementOptionData* mother;
|
||
lo_FormElementSelectData* selectData = (lo_FormElementSelectData *)formElem->element_data;
|
||
CFormList* myList = (CFormList*)FEDATAPANE;
|
||
|
||
if (!myList)
|
||
return;
|
||
myList->SelectNone();
|
||
myList->FocusDraw();
|
||
|
||
::LSetDrawingMode( FALSE, myList->GetMacListH() );
|
||
|
||
mother = (lo_FormElementOptionData*)selectData->options;
|
||
myList->SyncRows( selectData->option_cnt );
|
||
for ( int i = 0; i < selectData->option_cnt; i++ )
|
||
{
|
||
char* itemName = NULL;
|
||
Boolean select;
|
||
|
||
itemName = (char*)mother[ i ].text_value;
|
||
myList->AddItem( itemName, i );
|
||
|
||
if ( fromDefaults )
|
||
select = mother[ i ].def_selected;
|
||
else
|
||
select = mother[ i ].selected;
|
||
|
||
if (select)
|
||
myList->SetSelect( i, select );
|
||
}
|
||
|
||
::LSetDrawingMode( TRUE, myList->GetMacListH() );
|
||
// <20><>this forces an update of the scrollbar, if there is
|
||
// one
|
||
::LUpdate( NULL, myList->GetMacListH() );
|
||
myList->ShrinkToFit( selectData->size );
|
||
Cell selection = { myList->GetValue(), 0 }; // cells are v, h
|
||
myList->MakeCellVisible ( selection );
|
||
if ( redraw )
|
||
myList->Refresh();
|
||
}
|
||
break;
|
||
|
||
case FORM_TYPE_IMAGE:
|
||
case FORM_TYPE_JOT:
|
||
case FORM_TYPE_OBJECT:
|
||
break;
|
||
}
|
||
|
||
|
||
// immediately reflect our state
|
||
if (reflect)
|
||
FEDATAHOST->ReflectData();
|
||
}
|