nsTextWidget is 1-line field and can be done with TextEdit or the Appearance Manager instead of WASTE, while nsTextArea should use WASTE. git-svn-id: svn://10.0.0.236/trunk@14069 18797224-902f-48f8-a5cc-f745e15eee43
578 lines
16 KiB
C++
578 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 2; 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.
|
|
*/
|
|
|
|
#include "nsTextAreaWidget.h"
|
|
#include "nsMacWindow.h"
|
|
#include "nsToolkit.h"
|
|
#include "nsColor.h"
|
|
#include "nsGUIEvent.h"
|
|
#include "nsString.h"
|
|
|
|
|
|
#define DBG 0
|
|
|
|
NS_IMPL_ADDREF(nsTextAreaWidget);
|
|
NS_IMPL_RELEASE(nsTextAreaWidget);
|
|
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* nsTextAreaWidget Constructor
|
|
* @update dc 09/10/98
|
|
*/
|
|
nsTextAreaWidget::nsTextAreaWidget(): nsWindow()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mIsPasswordCallBacksInstalled = PR_FALSE;
|
|
mMakeReadOnly=PR_FALSE;
|
|
mMakePassword=PR_FALSE;
|
|
mTE_Data = nsnull;
|
|
strcpy(gInstanceClassName, "nsTextAreaWidget");
|
|
//mBackground = NS_RGB(124, 124, 124);
|
|
}
|
|
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* The create method for a nsTextAreaWidget, using a nsIWidget as the parent
|
|
* @update dc 09/10/98
|
|
* @param aParent -- the widget which will be this widgets parent in the tree
|
|
* @param aRect -- The bounds in parental coordinates of this widget
|
|
* @param aHandleEventFunction -- Procedures to be executed for this widget
|
|
* @param aContext -- device context to be used by this widget
|
|
* @param aAppShell --
|
|
* @param aToolkit -- toolkit to be used by this widget
|
|
* @param aInitData -- Initialization data used by frames
|
|
* @return -- NS_OK if everything was created correctly
|
|
*/
|
|
NS_IMETHODIMP nsTextAreaWidget::Create(nsIWidget *aParent,const nsRect &aRect,EVENT_CALLBACK aHandleEventFunction,
|
|
nsIDeviceContext *aContext,nsIAppShell *aAppShell,nsIToolkit *aToolkit, nsWidgetInitData *aInitData)
|
|
{
|
|
LongRect destRect,viewRect;
|
|
PRUint32 teFlags=0;
|
|
GrafPtr curport;
|
|
PRInt32 offx,offy;
|
|
|
|
nsWindow::Create(aParent, aRect, aHandleEventFunction,
|
|
aContext, aAppShell, aToolkit, aInitData);
|
|
|
|
mWindowPtr = nsnull;
|
|
if (aParent)
|
|
mWindowPtr = (WindowPtr)aParent->GetNativeData(NS_NATIVE_DISPLAY);
|
|
else if (aAppShell)
|
|
mWindowPtr = (WindowPtr)aAppShell->GetNativeData(NS_NATIVE_SHELL);
|
|
|
|
// Initialize the TE record
|
|
CalcOffset(offx,offy);
|
|
|
|
viewRect.left = aRect.x;
|
|
viewRect.top = aRect.y;
|
|
viewRect.right = aRect.x+aRect.width;
|
|
viewRect.bottom = aRect.y+aRect.height;
|
|
destRect = viewRect;
|
|
::GetPort(&curport);
|
|
::SetPort(mWindowPtr);
|
|
//::SetOrigin(-offx,-offy);
|
|
WENew(&destRect,&viewRect,teFlags,&mTE_Data);
|
|
//::SetOrigin(0,0);
|
|
::SetPort(curport);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Destuctor for the nsTextAreaWidget
|
|
* @update dc 08/31/98
|
|
*/
|
|
nsTextAreaWidget::~nsTextAreaWidget()
|
|
{
|
|
if(mTE_Data!=nsnull)
|
|
WEDispose(mTE_Data);
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID
|
|
* @update dc 08/31/98
|
|
* @param aIID The name of the class implementing the method
|
|
* @param _classiiddef The name of the #define symbol that defines the IID
|
|
* for the class (e.g. NS_ISUPPORTS_IID)
|
|
*/
|
|
nsresult nsTextAreaWidget::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
|
|
|
|
if (aIID.Equals(kITextAreaWidgetIID)) {
|
|
AddRef();
|
|
*aInstancePtr = (void**)(nsITextAreaWidget*)this;
|
|
return NS_OK;
|
|
}
|
|
|
|
return nsWindow::QueryInterface(aIID, aInstancePtr);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
/**
|
|
* The onPaint handler for a nsTextAreaWidget -- this may change, inherited from windows
|
|
* @param aEvent -- The paint event to respond to
|
|
* @return -- PR_TRUE if painted, false otherwise
|
|
*/
|
|
PRBool nsTextAreaWidget::OnPaint(nsPaintEvent & aEvent)
|
|
{
|
|
PRInt32 offx,offy;
|
|
nsRect therect;
|
|
Rect macrect;
|
|
GrafPtr theport;
|
|
RgnHandle thergn;
|
|
|
|
CalcOffset(offx,offy);
|
|
::GetPort(&theport);
|
|
::SetPort(mWindowPtr);
|
|
::SetOrigin(-offx,-offy);
|
|
GetBounds(therect);
|
|
nsRectToMacRect(therect,macrect);
|
|
thergn = ::NewRgn();
|
|
::GetClip(thergn);
|
|
::ClipRect(¯ect);
|
|
::EraseRect(¯ect);
|
|
::PenSize(1,1);
|
|
WEActivate(mTE_Data);
|
|
WEUpdate(nsnull,mTE_Data);
|
|
::FrameRect(¯ect);
|
|
::SetClip(thergn);
|
|
::SetOrigin(0,0);
|
|
::SetPort(theport);
|
|
|
|
return PR_FALSE;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
/**
|
|
* The Keydown handler for a nsTextAreaWidget
|
|
* @param aKey -- the key pressed
|
|
* @param aModifiers -- the modifiers of the key pressed, like command, shift, etc.
|
|
* @return -- PR_TRUE if painted, false otherwise
|
|
*/
|
|
void nsTextAreaWidget::PrimitiveKeyDown(PRInt16 aKey,PRInt16 aModifiers)
|
|
{
|
|
PRBool result=PR_TRUE;
|
|
GrafPtr thePort;
|
|
RgnHandle theRgn;
|
|
nsRect theRect;
|
|
Rect macRect;
|
|
PRInt32 offX,offY;
|
|
|
|
CalcOffset(offX,offY);
|
|
::GetPort(&thePort);
|
|
::SetPort(mWindowPtr);
|
|
|
|
GetBounds(theRect);
|
|
nsRectToMacRect(theRect,macRect);
|
|
theRgn = ::NewRgn();
|
|
::GetClip(theRgn);
|
|
::ClipRect(&macRect);
|
|
WEKey(aKey,aModifiers,mTE_Data);
|
|
::SetClip(theRgn);
|
|
::DisposeRgn(theRgn);
|
|
::SetPort(thePort);
|
|
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* DispatchMouseEvent handle an event for this nsTextAreaWidget
|
|
* @update dc 10/10/98
|
|
* @Param aEvent -- The mouse event to respond to for this button
|
|
* @return -- True if the event was handled, PR_FALSE if we did not handle it.
|
|
*/
|
|
PRBool nsTextAreaWidget::DispatchMouseEvent(nsMouseEvent &aEvent)
|
|
{
|
|
PRBool result=PR_TRUE;
|
|
Point mouseLoc;
|
|
PRInt16 modifiers=0;
|
|
nsRect therect;
|
|
Rect macrect;
|
|
PRInt32 offx,offy;
|
|
GrafPtr theport;
|
|
|
|
switch (aEvent.message){
|
|
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
|
CalcOffset(offx,offy);
|
|
::GetPort(&theport);
|
|
::SetPort(mWindowPtr);
|
|
GetBounds(therect);
|
|
nsRectToMacRect(therect,macrect);
|
|
::ClipRect(¯ect);
|
|
mouseLoc.h = aEvent.point.x;
|
|
mouseLoc.v = aEvent.point.y;
|
|
WEClick(mouseLoc,modifiers,aEvent.time,mTE_Data);
|
|
::SetPort(theport);
|
|
result = PR_FALSE;
|
|
break;
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
break;
|
|
case NS_MOUSE_EXIT:
|
|
break;
|
|
case NS_MOUSE_ENTER:
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
PRBool nsTextAreaWidget::DispatchWindowEvent(nsGUIEvent &event)
|
|
{
|
|
PRBool keyHandled = nsWindow::DispatchWindowEvent(event);
|
|
|
|
if (! keyHandled)
|
|
{
|
|
if (event.eventStructType == NS_KEY_EVENT)
|
|
{
|
|
if (event.message == NS_KEY_DOWN)
|
|
{
|
|
char theChar;
|
|
short theModifiers;
|
|
EventRecord* theOSEvent = (EventRecord*)event.nativeMsg;
|
|
if (theOSEvent)
|
|
{
|
|
theChar = (theOSEvent->message & charCodeMask);
|
|
theModifiers = theOSEvent->modifiers;
|
|
}
|
|
else
|
|
{
|
|
nsKeyEvent* keyEvent = (nsKeyEvent*)&event;
|
|
theChar = keyEvent->keyCode;
|
|
if (keyEvent->isShift)
|
|
theModifiers = shiftKey;
|
|
if (keyEvent->isControl)
|
|
theModifiers |= controlKey;
|
|
if (keyEvent->isAlt)
|
|
theModifiers |= optionKey;
|
|
}
|
|
if (theChar != NS_VK_RETURN) // don't pass Return: nsTextAreaWidget is a single line editor
|
|
{
|
|
PrimitiveKeyDown(theChar, theModifiers);
|
|
keyHandled = PR_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (keyHandled);
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Sets the password flag. If true, asteriks are the onlything displayed
|
|
* @update dc 10/10/98
|
|
* @Param aIsPassword -- if true, password attribute is used.
|
|
* @return -- if everything is ok
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SetPassword(PRBool aIsPassword)
|
|
{
|
|
if ( aIsPassword) {
|
|
mMakePassword = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Sets the readonly flag. If true, you can only read the text
|
|
* @update dc 10/10/98
|
|
* @Param aReadOnlyFlag -- if true, readoly attribute is used.
|
|
* @Param aOldFlag -- the old setting
|
|
* @return -- if everything is ok
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SetReadOnly(PRBool aReadOnlyFlag, PRBool& aOldFlag)
|
|
{
|
|
aOldFlag = mMakeReadOnly;
|
|
mMakeReadOnly = aReadOnlyFlag;
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Sets the maximum number of characters allowed.
|
|
* @update dc 10/10/98
|
|
* @Param aChars -- number of characters allowed
|
|
* @return -- if everything is ok
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SetMaxTextLength(PRUint32 aChars)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Gets the text from this widget
|
|
* @update dc 10/10/98
|
|
* @Param aTextBuffer -- string to fill in
|
|
* @Param aBufferSize -- size of the buffer passed in
|
|
* @Param aSize -- size of the string passed out
|
|
* @return -- if everything is ok
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::GetText(nsString& aTextBuffer, PRUint32 aBufferSize, PRUint32& aSize)
|
|
{
|
|
Handle thetext;
|
|
PRInt32 len,i;
|
|
char *str;
|
|
|
|
thetext = WEGetText(mTE_Data);
|
|
len = WEGetTextLength(mTE_Data);
|
|
|
|
//HLock(thetext);
|
|
str = new char[len+1];
|
|
|
|
for(i=0;i<len;i++)
|
|
str[i] = (*thetext)[i];
|
|
str[len] = 0;
|
|
//HUnlock(thetext);
|
|
|
|
aTextBuffer.SetLength(0);
|
|
aTextBuffer.Append(str);
|
|
aSize = aTextBuffer.Length();
|
|
|
|
delete [] str;
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Resize this widget
|
|
* @update dc 10/01/98
|
|
* @param aWidth -- x offset in widget local coordinates
|
|
* @param aHeight -- y offset in widget local coordinates
|
|
* @param aRepaint -- indicates if a repaint is needed.
|
|
* @return PR_TRUE if the pt is contained in the widget
|
|
*/
|
|
NS_IMETHODIMP nsTextAreaWidget::Resize(PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
|
|
{
|
|
nsSizeEvent event;
|
|
nsEventStatus eventStatus;
|
|
LongRect macRect;
|
|
|
|
mBounds.width = aWidth;
|
|
mBounds.height = aHeight;
|
|
|
|
if(nsnull!=mWindowRegion)
|
|
::DisposeRgn(mWindowRegion);
|
|
mWindowRegion = NewRgn();
|
|
SetRectRgn(mWindowRegion,mBounds.x,mBounds.y,mBounds.x+mBounds.width,mBounds.y+mBounds.height);
|
|
|
|
if(mTE_Data != nsnull){
|
|
macRect.top = mBounds.y;
|
|
macRect.left = mBounds.x;
|
|
macRect.bottom = mBounds.y+mBounds.height;
|
|
macRect.right = mBounds.x+mBounds.width;
|
|
WESetDestRect(&macRect,mTE_Data);
|
|
WESetViewRect(&macRect,mTE_Data);
|
|
}
|
|
|
|
if (aRepaint){
|
|
//¥TODO
|
|
}
|
|
|
|
event.message = NS_SIZE;
|
|
event.point.x = 0;
|
|
event.point.y = 0;
|
|
event.windowSize = &mBounds;
|
|
event.eventStructType = NS_SIZE_EVENT;
|
|
event.widget = this;
|
|
//this->DispatchEvent(&event, eventStatus);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Resize this widget
|
|
* @update dc 10/01/98
|
|
* @param aX -- left part of rectangle
|
|
* @param aY -- top of rectangle
|
|
* @param aWidth -- x offset in widget local coordinates
|
|
* @param aHeight -- y offset in widget local coordinates
|
|
* @param aW
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_IMETHODIMP nsTextAreaWidget::Resize(PRUint32 aX, PRUint32 aY, PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
|
|
{
|
|
nsSizeEvent event;
|
|
nsEventStatus eventStatus;
|
|
LongRect macRect;
|
|
|
|
mBounds.x = aX;
|
|
mBounds.y = aY;
|
|
mBounds.width = aWidth;
|
|
mBounds.height = aHeight;
|
|
if(nsnull!=mWindowRegion)
|
|
::DisposeRgn(mWindowRegion);
|
|
mWindowRegion = NewRgn();
|
|
SetRectRgn(mWindowRegion,mBounds.x,mBounds.y,mBounds.x+mBounds.width,mBounds.y+mBounds.height);
|
|
|
|
if(mTE_Data != nsnull){
|
|
macRect.top = mBounds.y;
|
|
macRect.left = mBounds.x;
|
|
macRect.bottom = mBounds.y+mBounds.height;
|
|
macRect.right = mBounds.x+mBounds.width;
|
|
WESetDestRect(&macRect,mTE_Data);
|
|
WESetViewRect(&macRect,mTE_Data);
|
|
}
|
|
|
|
if (aRepaint){
|
|
//¥TODO
|
|
}
|
|
|
|
event.message = NS_SIZE;
|
|
event.point.x = 0;
|
|
event.point.y = 0;
|
|
event.windowSize = &mBounds;
|
|
event.widget = this;
|
|
event.eventStructType = NS_SIZE_EVENT;
|
|
//this->DispatchEvent(&event, eventStatus);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Set the text for this widget
|
|
* @update dc 10/01/98
|
|
* @param aText -- Text to use in this widget
|
|
* @param aSize -- size of the text to use here
|
|
* @return PR_TRUE
|
|
*/
|
|
PRUint32 nsTextAreaWidget::SetText(const nsString& aText, PRUint32& aSize)
|
|
{
|
|
char buffer[256];
|
|
PRInt32 len;
|
|
PRInt32 offx,offy;
|
|
GrafPtr theport;
|
|
|
|
CalcOffset(offx,offy);
|
|
::GetPort(&theport);
|
|
::SetPort(mWindowPtr);
|
|
//::SetOrigin(-offx,-offy);
|
|
|
|
this->RemoveText();
|
|
aText.ToCString(buffer,255);
|
|
len = strlen(buffer);
|
|
|
|
WEInsert(buffer,len,0,0,mTE_Data);
|
|
|
|
aSize = len;
|
|
//::SetOrigin(0,0);
|
|
::SetPort(theport);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* insert text into this widget
|
|
* @update dc 10/01/98
|
|
* @param aText -- Text to use in this widget
|
|
* @param aStartPos - Starting position
|
|
* @param aEndtPos - Ending position
|
|
* @param aSize -- size of the text to use here
|
|
* @return PR_TRUE
|
|
*/
|
|
PRUint32 nsTextAreaWidget::InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos, PRUint32& aSize)
|
|
{
|
|
char buffer[256];
|
|
PRInt32 len;
|
|
PRInt32 offX,offY;
|
|
GrafPtr thePort;
|
|
|
|
CalcOffset(offX,offY);
|
|
::GetPort(&thePort);
|
|
::SetPort(mWindowPtr);
|
|
//::SetOrigin(-offx,-offy);
|
|
|
|
aText.ToCString(buffer,255);
|
|
len = strlen(buffer);
|
|
|
|
WEInsert(buffer,len,0,0,mTE_Data);
|
|
aSize = len;
|
|
//::SetOrigin(0,0);
|
|
::SetPort(thePort);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Remove all the text for this widget
|
|
* @update dc 10/01/98
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::RemoveText()
|
|
{
|
|
WESetSelection(0, 32000,mTE_Data);
|
|
WEDelete(mTE_Data);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Select all the text for this widget
|
|
* @update dc 10/01/98
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SelectAll()
|
|
{
|
|
WESetSelection(0, 32000,mTE_Data);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Set the text for this widget
|
|
* @update dc 10/01/98
|
|
* @param aStartSel -- start index of the text
|
|
* @param aEndSel -- end index of the text
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SetSelection(PRUint32 aStartSel, PRUint32 aEndSel)
|
|
{
|
|
WESetSelection(aStartSel, aEndSel,mTE_Data);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Get the text for this widget
|
|
* @update dc 10/01/98
|
|
* @param aStartSel -- start index of the text
|
|
* @param aEndSel -- end index of the text
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel)
|
|
{
|
|
WEGetSelection((long*)aStartSel,(long*)aEndSel,mTE_Data);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Set the caret position for this widget
|
|
* @update dc 10/01/98
|
|
* @param aPosition -- postition of text
|
|
* @return PR_TRUE
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::SetCaretPosition(PRUint32 aPosition)
|
|
{
|
|
//mHelper->SetCaretPosition(aPosition);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**-------------------------------------------------------------------------------
|
|
* Get the caret position for this widget
|
|
* @update dc 10/01/98
|
|
* @param aPosition -- postition of text
|
|
* @return PR_TRUE if the pt is contained in the widget
|
|
*/
|
|
NS_METHOD nsTextAreaWidget::GetCaretPosition(PRUint32& aPos)
|
|
{
|
|
//return mHelper->GetCaretPosition();
|
|
return NS_OK;
|
|
}
|
|
|