home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-08 | 54.7 KB | 1,912 lines |
- /* -*- 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 "CNSContext.h"
- #include "resgui.h"
- #include "uprefd.h"
- #include "mforms.h"
- #include "CConfigActiveScroller.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"
-
- // 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);
- }
-
- // prototypes
- Boolean SetFE_Data(LO_FormElementStruct *formElem, LPane * pane, LFormElement *host, LCommander *commander);
- 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
- Boolean SetFE_Data(
- 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);
- return noFEData;
- }
-
- 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 CConfigActiveScroller
- {
- public:
- friend class CHyperView;
-
- enum { class_ID = 'wscr' };
-
- CWhiteScroller( LStream* inStream );
- virtual Boolean FocusDraw(LPane* inSubPane = nil);
- virtual void DrawSelf();
- };
-
- CWhiteScroller::CWhiteScroller(LStream *inStream)
- : CConfigActiveScroller(inStream)
- {
- }
-
- // The only real routine. Sets background to white
- Boolean CWhiteScroller::FocusDraw(LPane* /*inSubPane*/)
- {
- if (LScroller::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);
-
- LScroller::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_( 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;
-
- 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);
-
- // Reset the value
- ResetFormElement(formElem, FALSE, SetFE_Data(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, SetFE_Data(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
- LUndoer* theUndoer = new LUndoer;
- theTextView->AddAttachment(theUndoer);
-
- // Resize to proper size
- theTextView->FocusDraw();
- ::GetFontInfo(&fontInfo);
- short wantedWidth = textAreaData->cols * fontInfo.widMax + 8;
- short wantedHeight = textAreaData->rows * (fontInfo.ascent + fontInfo.descent + fontInfo.leading) + 8;
-
- // 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, SetFE_Data(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 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, SetFE_Data(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, SetFE_Data(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, SetFE_Data(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, SetFE_Data(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, SetFE_Data( 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:
- 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
- {
- // Ñ 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:
- 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;
-
- 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:
- 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 );
- engine->InsertPtr( text, len, NULL, NULL, true );
- }
- }
-
-
- 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_
- {
- SetupTextInTextEngine(engine, formElem->text_attr->charset, default_text, XP_STRLEN((char*)default_text));
- }
- Catch_( inErr )
- {
- }
- }
- if ( redraw )
- textEdit->Refresh();
- }
- break;
-
- 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() );
- // Ñ╩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();
- }
-