1998-03-28 05:44:41 +03:00
|
|
|
|
/* -*- 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:
|
1998-06-23 05:36:59 +04:00
|
|
|
|
//friend class CHyperView; // this class no longer exists
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
|
|
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);
|
1998-06-23 05:36:59 +04:00
|
|
|
|
// Should allow undo
|
|
|
|
|
LUndoer* theUndoer = new LUndoer;
|
|
|
|
|
editField->AddAttachment(theUndoer);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
|
|
// 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
|
1998-06-23 05:36:59 +04:00
|
|
|
|
// - Let WASTE handle undo
|
|
|
|
|
// LUndoer* theUndoer = new LUndoer;
|
|
|
|
|
// theTextView->AddAttachment(theUndoer);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
|
|
// Resize to proper size
|
|
|
|
|
theTextView->FocusDraw();
|
|
|
|
|
::GetFontInfo(&fontInfo);
|
1998-06-23 05:36:59 +04:00
|
|
|
|
// short wantedWidth = textAreaData->cols * fontInfo.widMax + 8;
|
|
|
|
|
short wantedWidth = textAreaData->cols * ::CharWidth('M') + 8;
|
1998-03-28 05:44:41 +03:00
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
// <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:
|
|
|
|
|
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 );
|
1998-06-23 05:36:59 +04:00
|
|
|
|
if (text != NULL)
|
|
|
|
|
engine->InsertPtr( text, len, NULL, NULL, true );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
engine->SelectAll();
|
|
|
|
|
engine->Delete();
|
|
|
|
|
}
|
1998-03-28 05:44:41 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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_
|
|
|
|
|
{
|
1998-06-23 05:36:59 +04:00
|
|
|
|
|
|
|
|
|
// don't want ending linefeed
|
|
|
|
|
Int32 length = XP_STRLEN((char*)default_text)-1;
|
|
|
|
|
if( length )
|
|
|
|
|
SetupTextInTextEngine(engine, formElem->text_attr->charset, default_text, length);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
}
|
|
|
|
|
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() );
|
|
|
|
|
// <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();
|
|
|
|
|
}
|