Fix bug #8459, #6989 Can't move cursor within IME composition string.

This commit is contained in:
tague%netscape.com 1999-07-14 20:05:25 +00:00
Родитель 589d934040
Коммит a6a76c7c7b
5 изменённых файлов: 142 добавлений и 54 удалений

Просмотреть файл

@ -224,12 +224,14 @@ NS_IMETHODIMP IMETextTxn::GetData(nsString& aResult,nsIDOMTextRangeList** aTextR
NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
{
nsresult result;
PRBool haveSelectedRange;
PRBool haveSelectedRange, haveCaretPosition;
PRUint16 textRangeListLength,selectionStart,selectionEnd,
textRangeType, i;
textRangeType, caretPosition, i;
nsIDOMTextRange* textRange;
haveSelectedRange = PR_FALSE;
haveCaretPosition = PR_FALSE;
#ifdef DEBUG_tague
PRUint16 listlen,start,stop,type;
@ -266,6 +268,11 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
textRange->GetRangeStart(&selectionStart);
textRange->GetRangeEnd(&selectionEnd);
}
if (textRangeType==nsIDOMTextRange::TEXTRANGE_CARETPOSITION)
{
haveCaretPosition = PR_TRUE;
textRange->GetRangeStart(&caretPosition);
}
}
}
}
@ -275,9 +282,12 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
if (NS_SUCCEEDED(result) && selection){
if (haveSelectedRange) {
result = selection->Collapse(mElement,mOffset+selectionStart);
result = selection->Extend(mElement,mOffset+selectionEnd+1);
result = selection->Extend(mElement,mOffset+selectionEnd);
} else {
result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
if (haveCaretPosition)
result = selection->Collapse(mElement,mOffset+caretPosition);
else
result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
}
}

Просмотреть файл

@ -224,12 +224,14 @@ NS_IMETHODIMP IMETextTxn::GetData(nsString& aResult,nsIDOMTextRangeList** aTextR
NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
{
nsresult result;
PRBool haveSelectedRange;
PRBool haveSelectedRange, haveCaretPosition;
PRUint16 textRangeListLength,selectionStart,selectionEnd,
textRangeType, i;
textRangeType, caretPosition, i;
nsIDOMTextRange* textRange;
haveSelectedRange = PR_FALSE;
haveCaretPosition = PR_FALSE;
#ifdef DEBUG_tague
PRUint16 listlen,start,stop,type;
@ -266,6 +268,11 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
textRange->GetRangeStart(&selectionStart);
textRange->GetRangeEnd(&selectionEnd);
}
if (textRangeType==nsIDOMTextRange::TEXTRANGE_CARETPOSITION)
{
haveCaretPosition = PR_TRUE;
textRange->GetRangeStart(&caretPosition);
}
}
}
}
@ -275,9 +282,12 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
if (NS_SUCCEEDED(result) && selection){
if (haveSelectedRange) {
result = selection->Collapse(mElement,mOffset+selectionStart);
result = selection->Extend(mElement,mOffset+selectionEnd+1);
result = selection->Extend(mElement,mOffset+selectionEnd);
} else {
result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
if (haveCaretPosition)
result = selection->Collapse(mElement,mOffset+caretPosition);
else
result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
}
}

Просмотреть файл

@ -1108,16 +1108,18 @@ PRBool nsMacEventHandler::HandleOffsetToPosition(long offset,Point* thePoint)
// HandleUpdate Event
//
//-------------------------------------------------------------------------
nsMacEventHandler::HandleUpdate(Handle textHandle,ScriptCode script,long fixedLength)
nsMacEventHandler::HandleUpdateInputArea(char* text,Size text_size, ScriptCode textScript,long fixedLength,TextRangeArray* textRangeList)
{
TextToUnicodeInfo textToUnicodeInfo;
TextEncoding textEncodingFromScript;
ByteCount text_size, source_read;
ByteCount source_read;
ByteOffset sourceOffset[2], destinationOffset[2];
ItemCount destinationLength;
nsTextRangeArray xpTextRangeArray;
PRBool rv;
int i;
OSErr err;
HLock(textHandle);
//
// if we aren't in composition mode alredy, signal the backing store w/ the mode change
//
@ -1129,47 +1131,89 @@ PRBool nsMacEventHandler::HandleOffsetToPosition(long offset,Point* thePoint)
//
// convert our script code (smKeyScript) to a TextEncoding
//
err = ::UpgradeScriptInfoToTextEncoding(script,kTextLanguageDontCare,kTextRegionDontCare,nsnull,
err = ::UpgradeScriptInfoToTextEncoding(textScript,kTextLanguageDontCare,kTextRegionDontCare,nsnull,
&textEncodingFromScript);
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: UpgradeScriptInfoToTextEncoding failed.");
if (err!=noErr) { ::HUnlock(textHandle); return PR_FALSE; }
NS_ASSERTION(err==noErr,"nsMacEventHandler::UpdateInputArea: UpgradeScriptInfoToTextEncoding failed.");
if (err!=noErr) { return PR_FALSE; }
err = ::CreateTextToUnicodeInfoByEncoding(textEncodingFromScript,&textToUnicodeInfo);
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: CreateUnicodeToTextInfoByEncoding failed.");
if (err!=noErr) { ::HUnlock(textHandle); return PR_FALSE; }
NS_ASSERTION(err==noErr,"nsMacEventHandler::UpdateInputArea: CreateUnicodeToTextInfoByEncoding failed.");
if (err!=noErr) { return PR_FALSE; }
text_size = ::GetHandleSize(textHandle);
if (mIMECompositionStringSize < (text_size+1)*3) {
mIMECompositionStringSize = (text_size+1)*3;
if (mIMECompositionStringSize < text_size+32) {
mIMECompositionStringSize = text_size+32;
if (mIMECompositionString!=nsnull) delete [] mIMECompositionString;
mIMECompositionString = new PRUnichar[(text_size+1)*3];
mIMECompositionString = new PRUnichar[mIMECompositionStringSize];
}
//
// convert the text from the Update event into Unicode
// build up the nsGUIEvent text range array and convert the destination string to Unicode
//
err = ::ConvertFromTextToUnicode(textToUnicodeInfo,
text_size,*textHandle,
kUnicodeLooseMappingsMask,
0,NULL,NULL,NULL,
mIMECompositionStringSize*sizeof(PRUnichar),&source_read,
&mIMECompositionStringLength,mIMECompositionString);
NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleUpdate: ConverFromTextToUnicode failed.");
if (err!=noErr) { ::HUnlock(textHandle); ::DisposeTextToUnicodeInfo(&textToUnicodeInfo); return PR_FALSE; }
if (textRangeList!=NULL) {
xpTextRangeArray = new nsTextRange[textRangeList->fNumOfRanges];
NS_ASSERTION(xpTextRangeArray!=NULL,"nsMacEventHandler::UpdateInputArea: xpTextRangeArray memory allocation failed.");
if (xpTextRangeArray==NULL) { ::DisposeTextToUnicodeInfo(&textToUnicodeInfo); return PR_FALSE; }
//
// the TEC offset mapping capabilities won't work here because you need to have unique, ordered offsets
// so instead we iterate over the range list and map each range individually. it's probably faster than
// trying to do collapse all the ranges into a single offset list
//
for(i=0;i<textRangeList->fNumOfRanges;i++) {
sourceOffset[0] = textRangeList->fRange[i].fStart;
sourceOffset[1] = textRangeList->fRange[i].fEnd;
err = ::ConvertFromTextToUnicode(textToUnicodeInfo,text_size,text,kUnicodeLooseMappingsMask,
2,sourceOffset,&destinationLength,destinationOffset,
mIMECompositionStringSize*sizeof(PRUnichar),
&source_read,&mIMECompositionStringLength,mIMECompositionString);
NS_ASSERTION(err==noErr,"nsMacEventHandler::UpdateInputArea: ConvertFromTextToUnicode failed.\n");
if (err!=noErr) { ::DisposeTextToUnicodeInfo(&textToUnicodeInfo); return PR_FALSE; }
if (destinationLength==2) {
xpTextRangeArray[i].mStartOffset = destinationOffset[0]/sizeof(PRUnichar);
xpTextRangeArray[i].mEndOffset = destinationOffset[1]/sizeof(PRUnichar);
xpTextRangeArray[i].mRangeType = textRangeList->fRange[i].fHiliteStyle;
} else {
xpTextRangeArray[i].mStartOffset = destinationOffset[0]/sizeof(PRUnichar);
xpTextRangeArray[i].mEndOffset = destinationOffset[0]/sizeof(PRUnichar);
xpTextRangeArray[i].mRangeType = textRangeList->fRange[i].fHiliteStyle;
}
}
} else {
err = ::ConvertFromTextToUnicode(textToUnicodeInfo,text_size,text,kUnicodeLooseMappingsMask,
0,NULL,NULL,NULL,
mIMECompositionStringSize*sizeof(PRUnichar),
&source_read,&mIMECompositionStringLength,mIMECompositionString);
NS_ASSERTION(err==noErr,"nsMacEventHandler::UpdateInputArea: ConvertFromTextToUnicode failed.\n");
if (err!=noErr) { ::DisposeTextToUnicodeInfo(&textToUnicodeInfo); return PR_FALSE; }
xpTextRangeArray = new nsTextRange[1];
xpTextRangeArray[0].mStartOffset = 0;
xpTextRangeArray[0].mEndOffset = (mIMECompositionStringLength/sizeof(PRUnichar));
xpTextRangeArray[0].mRangeType = NS_TEXTRANGE_RAWINPUT;
}
//
// null terminate the string for the XP-stuff
//
mIMECompositionString[mIMECompositionStringLength/sizeof(PRUnichar)] = (PRUnichar)0;
rv = HandleTextEvent();
::HUnlock(textHandle);
::DisposeTextToUnicodeInfo(&textToUnicodeInfo);
if (fixedLength==-1 || fixedLength==text_size) {
if (textRangeList==NULL)
rv = HandleTextEvent(1,xpTextRangeArray);
else
rv = HandleTextEvent(textRangeList->fNumOfRanges,xpTextRangeArray);
::DisposeTextToUnicodeInfo(&textToUnicodeInfo);
//
// text_size incldues the null-terminator which isn't included in the fixedLength
//
if (fixedLength==-1 || fixedLength==text_size-1) {
HandleEndComposition();
mIMEIsComposing = PR_FALSE;
}
@ -1264,7 +1308,7 @@ PRBool nsMacEventHandler::HandleEndComposition(void)
// HandleTextEvent
//
//-------------------------------------------------------------------------
PRBool nsMacEventHandler::HandleTextEvent(void)
PRBool nsMacEventHandler::HandleTextEvent(PRUint32 textRangeCount, nsTextRangeArray textRangeArray)
{
//
// get the focused widget [tague: may need to rethink this later]
@ -1291,11 +1335,8 @@ PRBool nsMacEventHandler::HandleTextEvent(void)
textEvent.point.y = 0;
textEvent.time = PR_IntervalNow();
textEvent.theText = mIMECompositionString;
textEvent.rangeCount = 1;
textEvent.rangeArray = new nsTextRange[1];
textEvent.rangeArray[0].mStartOffset = 0;
textEvent.rangeArray[0].mEndOffset = 1;
textEvent.rangeArray[0].mRangeType = 0x01;
textEvent.rangeCount = textRangeCount;
textEvent.rangeArray = textRangeArray;
//
// nsGUIEvent parts

Просмотреть файл

@ -48,7 +48,7 @@ public:
//
virtual long HandlePositionToOffset(Point aPoint,short* regionClass);
virtual PRBool HandleOffsetToPosition(long offset,Point* position);
virtual PRBool HandleUpdate(Handle textHandle,ScriptCode script,long fixedLength);
virtual PRBool HandleUpdateInputArea(char* text,Size text_size, ScriptCode textScript,long fixedLength,TextRangeArray* textRangeArray);
protected:
#if 1
@ -70,7 +70,7 @@ protected:
PRUint32 aMessage);
virtual PRBool HandleStartComposition(void);
virtual PRBool HandleEndComposition(void);
virtual PRBool HandleTextEvent(void);
virtual PRBool HandleTextEvent(PRUint32 textRangeCount, nsTextRangeArray textRangeArray);
public:
virtual void NotifyDelete(void* aDeletedObject);

Просмотреть файл

@ -187,11 +187,12 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
DescType returnedType;
nsMacEventHandler* eventHandler;
Size actualSize;
AEDesc text;
AEDesc text, hiliteRangeArray;
ScriptCode textScript;
long fixLength;
PRBool rv;
TextRangeArray* hiliteRangePtr;
//
// refcon stores the nsMacEventHandler
//
@ -218,21 +219,47 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
&fixLength,sizeof(fixLength),&actualSize);
NS_ASSERTION(err==noErr,"nsMacTSMMessagePump::UpdateHandler: AEGetParamPtr[fixlen] failed.");
if (err!=noErr) return err;
//
// extract the hilite ranges (optional param)
//
err = AEGetParamDesc(theAppleEvent,keyAEHiliteRange,typeTextRangeArray,&hiliteRangeArray);
NS_ASSERTION(err==noErr||err==errAEDescNotFound,"nsMacTSMMessagePump::UpdateHandler: AEGetParamPtr[fixlen] failed.");
if (err==errAEDescNotFound) hiliteRangePtr=NULL;
else if (err==noErr) { ::HLock(hiliteRangeArray.dataHandle); hiliteRangePtr=(TextRangeArray*)*(hiliteRangeArray.dataHandle);}
else return err;
#if TARGET_CARBON
void* textPtr;
err = AEGetDescData(&text,(unsigned long)typeChar,textPtr,fixLength);
if (err!=noErr) return err;
rv = eventHandler->HandleUpdate((char**)&textPtr,textScript,fixLength);
#else
rv = eventHandler->HandleUpdate(text.dataHandle,textScript,fixLength);
// ¥¥¥ Fix Me !!!!!
rv = eventHandler->HandleUpdateInputArea((char*)textPtr,textScript,fixLength,hiliteRangePtr);
#else
::HLock(text.dataHandle);
Size text_size = GetHandleSize(text.dataHandle);
char* mbcsText = new char[text_size+1];
strncpy(mbcsText,*(text.dataHandle),text_size);
mbcsText[text_size]=0;
//
// must pass HandleUpdateInputArea a null-terminated multibyte string, the text size must include the terminator
//
rv = eventHandler->HandleUpdateInputArea(mbcsText,text_size+1,textScript,fixLength,hiliteRangePtr);
#endif
NS_ASSERTION(rv==PR_TRUE,"nsMAcMessagePump::UpdateHandler: HandleUpdated failed.");
NS_ASSERTION(rv==PR_TRUE,"nsMacMessagePump::UpdateHandler: HandleUpdated failed.");
if (rv!=PR_TRUE) return paramErr;
//
// clean up
//
#if !TARGET_CARBON
::HUnlock(text.dataHandle);
::HUnlock(hiliteRangeArray.dataHandle);
delete [] mbcsText;
#endif
(void)AEDisposeDesc(&text);
(void)AEDisposeDesc(&hiliteRangeArray);
return noErr;
}