From 6a22af3691d76d06e12adf68ce5030ebb9f055a4 Mon Sep 17 00:00:00 2001 From: "pinkerton%netscape.com" Date: Tue, 19 Jan 1999 17:21:37 +0000 Subject: [PATCH] Added cut/copy to pierre's paste work and sync'd the work done in textWidget to that in textAreaWidget so both now support cut/copy/paste the same way (though the code isn't shared). --- widget/src/mac/nsTextAreaWidget.cpp | 179 +++++++++++++++++++++++----- widget/src/mac/nsTextWidget.cpp | 40 ++++++- 2 files changed, 185 insertions(+), 34 deletions(-) diff --git a/widget/src/mac/nsTextAreaWidget.cpp b/widget/src/mac/nsTextAreaWidget.cpp index 0cf44351defe..e05ed76ee381 100644 --- a/widget/src/mac/nsTextAreaWidget.cpp +++ b/widget/src/mac/nsTextAreaWidget.cpp @@ -23,6 +23,7 @@ #include "nsGUIEvent.h" #include "nsString.h" #include +#include #define DBG 0 @@ -30,6 +31,27 @@ NS_IMPL_ADDREF(nsTextAreaWidget); NS_IMPL_RELEASE(nsTextAreaWidget); +//------------------------------------------------------------------------- +// ¥ NOTE ABOUT MENU HANDLING ¥ +// +// The definitions below, as well as the NS_MENU_SELECTED code in +// DispatchEvent() are temporary hacks only. They require the menu +// resources to be created under Contructor with the standard +// PowerPlant menu IDs. All that will go away because: +// - nsTextWidget will be rewritten as an XP widget by the Editor team. +// - menu handling will be rewritten by the XPApp team. +//------------------------------------------------------------------------- + +#include +#include // for PP standard menu commands +enum +{ + menu_Apple = 128, + menu_File, + menu_Edit +}; + + /**------------------------------------------------------------------------------- * nsTextAreaWidget Constructor * @update dc 09/10/98 @@ -231,43 +253,138 @@ GrafPtr theport; } //------------------------------------------------------------------------- -PRBool nsTextAreaWidget::DispatchWindowEvent(nsGUIEvent &event) +PRBool nsTextAreaWidget::DispatchWindowEvent(nsGUIEvent &aEvent) { - PRBool keyHandled = nsWindow::DispatchWindowEvent(event); + PRBool keyHandled = nsWindow::DispatchWindowEvent(aEvent); if (! keyHandled) { - if (event.eventStructType == NS_KEY_EVENT) - { - if (event.message == NS_KEY_DOWN) + switch ( aEvent.message ) { - char theChar; - short theModifiers; - EventRecord* theOSEvent = (EventRecord*)event.nativeMsg; - if (theOSEvent) + case NS_KEY_DOWN: { - 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; - } - } - } - } + char theChar; + short theModifiers; + EventRecord* theOSEvent = (EventRecord*)aEvent.nativeMsg; + if (theOSEvent) + { + theChar = (theOSEvent->message & charCodeMask); + theModifiers = theOSEvent->modifiers; + } + else + { + nsKeyEvent* keyEvent = (nsKeyEvent*)&aEvent; + 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; + } + break; + } + + case NS_MENU_SELECTED: + { + nsMenuEvent* menuEvent = (nsMenuEvent*)&aEvent; + long menuID = HiWord(menuEvent->mCommand); + long menuItem = LoWord(menuEvent->mCommand); + switch (menuID) + { + case menu_Edit: + { + switch (menuItem) + { +// case cmd_Undo: + + case cmd_Cut: + case cmd_Copy: + { + PRUint32 startSel = 0, endSel = 0; + GetSelection ( &startSel, &endSel ); + if ( startSel != endSel ) { + const Uint32 selectionLen = (endSel - startSel) + 1; + + // extract out the selection into a different nsString so + // we can keep it unicode as long as possible + PRUint32 unused = 0; + nsString str, selection; + GetText ( str, 0, unused ); + str.Mid ( selection, startSel, (endSel-startSel)+1 ); + + // now |selection| holds the current selection in unicode. + // We need to convert it to a c-string for MacOS. + auto_ptr cRepOfSelection ( new char[selection.Length() + 1] ); + selection.ToCString ( cRepOfSelection.get(), selectionLen ); + + // copy it to the scrapMgr + ::ZeroScrap(); + ::PutScrap ( selectionLen, 'TEXT', cRepOfSelection.get() ); + + // if we're cutting, remove the text from the widget + if ( menuItem == cmd_Cut ) { + unused = 0; + str.Cut ( startSel, selectionLen ); + SetText ( str, unused ); + } + } // if there is a selection + break; + } + + case cmd_Paste: + { + long scrapOffset; + Handle scrapH = ::NewHandle(0); + long scrapLen = ::GetScrap(scrapH, 'TEXT', &scrapOffset); + if (scrapLen > 0) + { + ::HLock(scrapH); + + // truncate to the first line + char* cr = strchr((char*)*scrapH, '\r'); + if (cr != nil) + scrapLen = cr - *scrapH; + + // paste text + nsString str; + str.SetString((char*)*scrapH, scrapLen); + PRUint32 startSel, endSel; + GetSelection(&startSel, &endSel); + PRUint32 outSize; + InsertText(str, startSel, endSel, outSize); + + ::HUnlock(scrapH); + } + ::DisposeHandle(scrapH); + break; + } + case cmd_Clear: + { + nsString str; + PRUint32 outSize; + SetText(str, outSize); + break; + } + case cmd_SelectAll: + { + SelectAll(); + break; + } + } + break; + } + } + break; + } // case NS_MENU_SELECTED + + } // switch on which event message + } // if key event not handled return (keyHandled); } diff --git a/widget/src/mac/nsTextWidget.cpp b/widget/src/mac/nsTextWidget.cpp index 7caf1e0ce4ab..bd8889091a0f 100644 --- a/widget/src/mac/nsTextWidget.cpp +++ b/widget/src/mac/nsTextWidget.cpp @@ -171,8 +171,41 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent) switch (menuItem) { // case cmd_Undo: -// case cmd_Cut: //¥TODO -// case cmd_Copy: //¥TODO + + case cmd_Cut: + case cmd_Copy: + { + PRUint32 startSel = 0, endSel = 0; + GetSelection ( &startSel, &endSel ); + if ( startSel != endSel ) { + const Uint32 selectionLen = (endSel - startSel) + 1; + + // extract out the selection into a different nsString so + // we can keep it unicode as long as possible + PRUint32 unused = 0; + nsString str, selection; + GetText ( str, 0, unused ); + str.Mid ( selection, startSel, (endSel-startSel)+1 ); + + // now |selection| holds the current selection in unicode. + // We need to convert it to a c-string for MacOS. + auto_ptr cRepOfSelection ( new char[selection.Length() + 1] ); + selection.ToCString ( cRepOfSelection.get(), selectionLen ); + + // copy it to the scrapMgr + ::ZeroScrap(); + ::PutScrap ( selectionLen, 'TEXT', cRepOfSelection.get() ); + + // if we're cutting, remove the text from the widget + if ( menuItem == cmd_Cut ) { + unused = 0; + str.Cut ( startSel, selectionLen ); + SetText ( str, unused ); + } + } // if there is a selection + break; + } + case cmd_Paste: { long scrapOffset; @@ -197,6 +230,7 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent) ::HUnlock(scrapH); } + ::DisposeHandle(scrapH); break; } case cmd_Clear: @@ -216,7 +250,7 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent) } } break; - } + } // case NS_MENU_SELECTED case NS_GOTFOCUS: {