1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ 2 3 /* AbiSource Application Framework 4 * Copyright (C) 2003 Hubert Figuiere 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 * 02110-1301 USA. 20 */ 21 /* 22 Implements the text view that supports the NSTextInput protocol 23 */ 24 25 #include "ut_assert.h" 26 #include "ut_debugmsg.h" 27 28 #include "ev_CocoaKeyboard.h" 29 #include "ev_EditMethod.h" 30 #include "ev_NamedVirtualKey.h" 31 32 #include "xap_App.h" 33 #import "xap_CocoaCompat.h" 34 #include "xap_CocoaTextView.h" 35 #include "xap_CocoaToolPalette.h" 36 #include "xap_Frame.h" 37 #include "xav_View.h" 38 39 #include "fv_View.h" 40 41 #include "pd_Document.h" 42 43 @implementation XAP_CocoaTextView 44 45 - (id)initWith:(XAP_Frame *)frame andFrame:(NSRect)windowFrame 46 { 47 if (![super initWith:frame andFrame:windowFrame]) { 48 return nil; 49 } 50 m_hasMarkedText = NO; 51 return self; 52 } 53 54 /* standard methods */ 55 56 - (BOOL)resignFirstResponder 57 { 58 return YES; 59 } 60 61 62 /*! 63 Invoke an Abi method 64 */ 65 - (void)invokeEditMethod:(const char*)method 66 { 67 EV_EditMethod* pEM; 68 pEM = XAP_App::getApp()->getEditMethodContainer()->findEditMethodByName(method); 69 AV_View * pView = m_pFrame->getCurrentView(); 70 EV_Keyboard * pCocoaKeyboard = m_pFrame->getKeyboard(); 71 pCocoaKeyboard->invokeKeyboardMethod(pView,pEM,0,0); 72 } 73 74 75 /* NSResponder methods */ 76 - (void)insertNewline:(id)sender 77 { 78 UT_UNUSED(sender); 79 [self invokeEditMethod:"insertParagraphBreak"]; 80 } 81 82 - (void)insertTab:(id)sender 83 { 84 UT_UNUSED(sender); 85 [self invokeEditMethod:"insertTab"]; 86 } 87 88 - (void)deleteBackward:(id)sender 89 { 90 UT_UNUSED(sender); 91 [self invokeEditMethod:"delLeft"]; 92 } 93 94 - (void)deleteForward:(id)sender 95 { 96 UT_UNUSED(sender); 97 [self invokeEditMethod:"delRight"]; 98 } 99 100 - (void)deleteToEndOfParagraph:(id)sender 101 { 102 UT_UNUSED(sender); 103 [self invokeEditMethod:"delEOL"]; 104 } 105 106 - (void)moveForward:(id)sender; 107 { 108 UT_UNUSED(sender); 109 [self invokeEditMethod:"warpInsPtRight"]; 110 } 111 112 - (void)moveRight:(id)sender; 113 { 114 UT_UNUSED(sender); 115 [self invokeEditMethod:"warpInsPtRight"]; 116 } 117 118 - (void)moveBackward:(id)sender; 119 { 120 UT_UNUSED(sender); 121 [self invokeEditMethod:"warpInsPtLeft"]; 122 } 123 124 - (void)moveLeft:(id)sender; 125 { 126 UT_UNUSED(sender); 127 [self invokeEditMethod:"warpInsPtLeft"]; 128 } 129 130 - (void)moveUp:(id)sender; 131 { 132 UT_UNUSED(sender); 133 [self invokeEditMethod:"warpInsPtPrevLine"]; 134 } 135 136 - (void)moveDown:(id)sender; 137 { 138 UT_UNUSED(sender); 139 [self invokeEditMethod:"warpInsPtNextLine"]; 140 } 141 - (void)moveWordForward:(id)sender 142 { 143 UT_UNUSED(sender); 144 [self invokeEditMethod:"warpInsPtEOW"]; 145 } 146 - (void)moveWordBackward:(id)sender 147 { 148 UT_UNUSED(sender); 149 [self invokeEditMethod:"warpInsPtBOW"]; 150 } 151 152 - (void)moveWordRight:(id)sender 153 { 154 UT_UNUSED(sender); 155 [self invokeEditMethod:"warpInsPtEOW"]; 156 } 157 158 - (void)moveWordLeft:(id)sender 159 { 160 UT_UNUSED(sender); 161 [self invokeEditMethod:"warpInsPtBOW"]; 162 } 163 164 - (void)moveToBeginningOfLine:(id)sender 165 { 166 UT_UNUSED(sender); 167 [self invokeEditMethod:"warpInsPtBOL"]; 168 } 169 170 - (void)moveToEndOfLine:(id)sender 171 { 172 UT_UNUSED(sender); 173 [self invokeEditMethod:"warpInsPtEOL"]; 174 } 175 - (void)moveToBeginningOfParagraph:(id)sender 176 { 177 UT_UNUSED(sender); 178 [self invokeEditMethod:"warpInsPtBOP"]; 179 } 180 - (void)moveToEndOfParagraph:(id)sender 181 { 182 UT_UNUSED(sender); 183 [self invokeEditMethod:"warpInsPtEOP"]; 184 } 185 #if 0 186 // implement the Edit method first 187 - (void)moveParagraphBackwardAndModifySelection:(id)sender 188 { 189 UT_UNUSED(sender); 190 [self invokeEditMethod:"extSelBOP"]; 191 } 192 - (void)moveParagraphForwardAndModifySelection:(id)sender 193 { 194 UT_UNUSED(sender); 195 [self invokeEditMethod:"extSelEOP"]; 196 } 197 #endif 198 199 - (void)moveToEndOfDocument:(id)sender 200 { 201 UT_UNUSED(sender); 202 [self invokeEditMethod:"warpInsPtEOD"]; 203 } 204 205 - (void)moveToBeginningOfDocument:(id)sender 206 { 207 UT_UNUSED(sender); 208 [self invokeEditMethod:"warpInsPtBOD"]; 209 } 210 211 - (void)moveToEndOfDocumentAndModifySelection:(id)sender 212 { 213 UT_UNUSED(sender); 214 [self invokeEditMethod:"extSelEOD"]; 215 } 216 - (void)moveToBeginningOfDocumentAndModifySelection:(id)sender 217 { 218 UT_UNUSED(sender); 219 [self invokeEditMethod:"extSelBOD"]; 220 } 221 222 - (void)pageDown:(id)sender; 223 { 224 UT_UNUSED(sender); 225 [self invokeEditMethod:"warpInsPtNextScreen"]; 226 } 227 - (void)pageUp:(id)sender; 228 { 229 UT_UNUSED(sender); 230 [self invokeEditMethod:"warpInsPtPrevScreen"]; 231 } 232 233 - (void)moveLeftAndModifySelection:(id)sender 234 { 235 UT_UNUSED(sender); 236 [self invokeEditMethod:"extSelLeft"]; 237 } 238 - (void)moveRightAndModifySelection:(id)sender 239 { 240 UT_UNUSED(sender); 241 [self invokeEditMethod:"extSelRight"]; 242 } 243 244 - (void)moveBackwardAndModifySelection:(id)sender 245 { 246 UT_UNUSED(sender); 247 [self invokeEditMethod:"extSelLeft"]; 248 } 249 - (void)moveForwardAndModifySelection:(id)sender 250 { 251 UT_UNUSED(sender); 252 [self invokeEditMethod:"extSelRight"]; 253 } 254 255 - (void)moveWordForwardAndModifySelection:(id)sender 256 { 257 UT_UNUSED(sender); 258 [self invokeEditMethod:"extSelEOW"]; 259 } 260 - (void)moveWordRightAndModifySelection:(id)sender 261 { 262 UT_UNUSED(sender); 263 [self invokeEditMethod:"extSelEOW"]; 264 } 265 266 - (void)moveWordBackwardAndModifySelection:(id)sender 267 { 268 UT_UNUSED(sender); 269 [self invokeEditMethod:"extSelBOW"]; 270 } 271 - (void)moveWordLeftAndModifySelection:(id)sender 272 { 273 UT_UNUSED(sender); 274 [self invokeEditMethod:"extSelBOW"]; 275 } 276 277 - (void)moveUpAndModifySelection:(id)sender 278 { 279 UT_UNUSED(sender); 280 [self invokeEditMethod:"extSelPrevLine"]; 281 } 282 - (void)moveDownAndModifySelection:(id)sender 283 { 284 UT_UNUSED(sender); 285 [self invokeEditMethod:"extSelNextLine"]; 286 } 287 - (void)moveToBeginningOfLineAndModifySelection:(id)sender 288 { 289 UT_UNUSED(sender); 290 [self invokeEditMethod:"extSelBOL"]; 291 } 292 - (void)moveToEndOfLineAndModifySelection:(id)sender 293 { 294 UT_UNUSED(sender); 295 [self invokeEditMethod:"extSelEOL"]; 296 } 297 298 - (void)scrollPageUp:(id)sender 299 { 300 UT_UNUSED(sender); 301 [self invokeEditMethod:"scrollPageUp"]; 302 } 303 - (void)scrollPageDown:(id)sender 304 { 305 UT_UNUSED(sender); 306 [self invokeEditMethod:"scrollPageDown"]; 307 } 308 - (void)scrollLineUp:(id)sender 309 { 310 UT_UNUSED(sender); 311 [self invokeEditMethod:"scrollLineUp"]; 312 } 313 - (void)scrollLineDown:(id)sender 314 { 315 UT_UNUSED(sender); 316 [self invokeEditMethod:"scrollLineDown"]; 317 } 318 - (void)scrollToBeginningOfDocument:(id)sender 319 { 320 UT_UNUSED(sender); 321 [self invokeEditMethod:"scrollToTop"]; 322 } 323 - (void)scrollToEndOfDocument:(id)sender 324 { 325 UT_UNUSED(sender); 326 [self invokeEditMethod:"scrollToBottom"]; 327 } 328 329 330 /* NSTextInput protocol */ 331 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange 332 { 333 UT_UNUSED(theRange); 334 UT_ASSERT_NOT_REACHED(); 335 return nil; 336 } 337 338 339 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint 340 { 341 UT_UNUSED(thePoint); 342 UT_ASSERT_NOT_REACHED(); 343 return NSNotFound; 344 } 345 346 347 - (long)conversationIdentifier 348 { 349 return (long)self; 350 } 351 352 - (void)doCommandBySelector:(SEL)aSelector 353 { 354 if ([self respondsToSelector:aSelector]) { 355 [self performSelector:aSelector withObject:self]; 356 return; 357 } 358 UT_DEBUGMSG(("Unrecognized selector:%s\n", [NSStringFromSelector(aSelector) UTF8String])); 359 // UT_ASSERT_NOT_REACHED(); 360 } 361 362 363 - (NSRect)firstRectForCharacterRange:(NSRange)theRange 364 { 365 // UT_ASSERT_NOT_REACHED(); 366 UT_DEBUG_ONLY_ARG(theRange); 367 UT_DEBUGMSG(("characterRange=(location=%u,length=%u)\n",theRange.location,theRange.length)); 368 return NSZeroRect; 369 } 370 371 372 - (BOOL)hasMarkedText 373 { 374 UT_DEBUGMSG(("m_hasMarkedText=%s\n",m_hasMarkedText ? "YES" : "NO")); 375 return m_hasMarkedText; 376 } 377 378 379 - (void)insertText:(id)aString 380 { 381 /* UT_DEBUGMSG(("insertText '%s' in window '%s'\n", [str UTF8String], [[[self window] title] UTF8String])); 382 */ 383 UT_DEBUGMSG(("insertText: length=%u\n", [(NSString *)aString length])); 384 // pFrame->setTimeOfLastEvent([theEvent timestamp]); 385 AV_View * pView = m_pFrame->getCurrentView(); 386 ev_CocoaKeyboard * pCocoaKeyboard = static_cast<ev_CocoaKeyboard *> 387 (m_pFrame->getKeyboard()); 388 389 if (pView) 390 pCocoaKeyboard->insertTextEvent(pView, aString); 391 392 [XAP_CocoaToolPalette setPreviewText:@""]; 393 394 m_selectedRange = NSMakeRange(NSNotFound, 0); 395 m_hasMarkedText = NO; 396 } 397 398 399 - (NSRange)markedRange 400 { 401 // UT_ASSERT_NOT_REACHED(); 402 UT_DEBUGMSG(("markedRange (m_hasMarkedText=%s)\n",m_hasMarkedText ? "YES" : "NO")); 403 404 /* This method gets called when you delete the current character sequence to 0 length, 405 * so let's clear the preview... 406 */ 407 [XAP_CocoaToolPalette setPreviewText:@""]; 408 409 m_selectedRange = NSMakeRange(NSNotFound, 0); 410 m_hasMarkedText = NO; 411 412 return m_selectedRange; 413 } 414 415 - (NSRange)selectedRange 416 { 417 UT_DEBUGMSG(("selectedRange=(location=%u,length=%u)\n",m_selectedRange.location,m_selectedRange.length)); 418 return m_selectedRange; 419 } 420 421 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange 422 { 423 [XAP_CocoaToolPalette setPreviewText:aString]; 424 425 m_selectedRange = selRange; 426 m_hasMarkedText = (selRange.length != 0 ? YES : NO); 427 428 UT_DEBUGMSG(("range=(location=%u,length=%u) [aString length]=%u\n", selRange.location, selRange.length, [(NSString*)aString length])); 429 /* 430 Steal code from the selection handling code in XP land. We have the AV_View 431 so everything is here. 432 */ 433 434 if (FV_View * pView = static_cast<FV_View *>(m_pFrame->getCurrentView())) { 435 NSString * str = 0; 436 437 if ([aString isKindOfClass:[NSString class]]) { 438 str = (NSString *) aString; 439 } 440 else if ([aString isKindOfClass:[NSAttributedString class]]) { 441 NSAttributedString * attr_str = (NSAttributedString *) aString; 442 str = [attr_str string]; 443 } 444 if (str) { 445 if ([str length]) { 446 UT_UCS4String ucs4([str UTF8String], [str length]); 447 448 PT_DocPosition oldPos = pView->getPoint(); 449 450 if (!pView->isSelectionEmpty()) 451 oldPos = pView->getSelectionAnchor(); 452 453 ev_CocoaKeyboard * pCocoaKeyboard = static_cast<ev_CocoaKeyboard *>(m_pFrame->getKeyboard()); 454 pCocoaKeyboard->insertTextEvent(pView, str); 455 456 // pView->cmdCharInsert(ucs4.ucs4_str(), ucs4.length()); 457 pView->cmdSelect(oldPos, pView->getPoint()); 458 } 459 } 460 } 461 } 462 463 - (void)unmarkText 464 { 465 m_hasMarkedText = NO; 466 UT_DEBUGMSG(("Hub TODO: handle -[XAP_CocoaTextView unmarkText]\n")); 467 } 468 469 - (NSArray*)validAttributesForMarkedText 470 { 471 return [NSArray array]; 472 } 473 474 @end 475