- Timestamp:
- 06/23/11 12:12:43 (14 years ago)
- Location:
- ps/trunk
- Files:
-
- 5 edited
-
binaries/data/config/default.cfg (modified) (2 diffs)
-
source/gui/CInput.cpp (modified) (30 diffs)
-
source/gui/CInput.h (modified) (1 diff)
-
source/lib/sysdep/clipboard.h (modified) (2 diffs)
-
source/lib/sysdep/os/win/wclipboard.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/binaries/data/config/default.cfg
r9443 r9646 130 130 hotkey.console.copy = "Ctrl+C" ; Copy from console to clipboard 131 131 hotkey.console.paste = "Ctrl+V" ; Paste clipboard to console 132 hotkey.console.cut = "Ctrl+X" ; Cut the selected text and copy it to the clipboard 132 133 133 134 ; > ENTITY SELECTION … … 187 188 hotkey.chat = Return ; Toggle chat window 188 189 190 ; > GUI TEXTBOX HOTKEYS 191 hotkey.text.delete.word.left = "Ctrl+Backspace" ; Used in text input boxes to delete word to the left of cursor 192 hotkey.text.delete.word.right = "Ctrl+Del" ; Used in text input boxes to delete word to the right of cursor 193 hotkey.text.move.word.left = "Ctrl+LeftArrow" ; Move cursor to start of word to the left of cursor 194 hotkey.text.move.word.right = "Ctrl+RightArrow" ; Move cursor to start of word to the left of cursor 195 189 196 ; > PROFILER 190 197 hotkey.profile.toggle = "F11" ; Enable/disable real-time profiler -
ps/trunk/source/gui/CInput.cpp
r9362 r9646 35 35 #include "ps/Globals.h" 36 36 37 #include <sstream> 37 38 38 39 //------------------------------------------------------------------- … … 71 72 ENSURE(m_iBufferPos != -1); 72 73 73 // Since the GUI framework doesn't handle to set settings74 // in Unicode (CStrW), we'll simply retrieve the actual75 // pointer and edit that.76 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting;77 78 74 if (ev->ev.type == SDL_HOTKEYDOWN) 79 75 { 80 std::string hotkey = static_cast<const char*>(ev->ev.user.data1); 81 if (hotkey == "console.paste") 82 { 83 wchar_t* text = sys_clipboard_get(); 84 if (text) 85 { 86 if (m_iBufferPos == (int)pCaption->length()) 87 *pCaption += text; 88 else 89 *pCaption = pCaption->Left(m_iBufferPos) + text + 90 pCaption->Right((long) pCaption->length()-m_iBufferPos); 91 92 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 93 94 m_iBufferPos += (int)wcslen(text); 95 96 sys_clipboard_free(text); 97 } 98 99 return IN_HANDLED; 100 } 76 return(ManuallyHandleHotkeyEvent(ev)); 101 77 } 102 78 else if (ev->ev.type == SDL_KEYDOWN) 103 79 { 80 // Since the GUI framework doesn't handle to set settings 81 // in Unicode (CStrW), we'll simply retrieve the actual 82 // pointer and edit that. 83 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 84 bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; 85 104 86 int szChar = ev->ev.key.keysym.sym; 105 87 wchar_t cooked = (wchar_t)ev->ev.key.keysym.unicode; … … 107 89 switch (szChar) 108 90 { 109 case '\t':91 case SDLK_TAB: // '\t' 110 92 /* Auto Complete */ 111 93 // TODO Gee: (2004-09-07) What to do with tab? 112 94 break; 113 95 114 case '\b':115 m_WantedX=0. f;96 case SDLK_BACKSPACE: // '\b' 97 m_WantedX=0.0f; 116 98 117 99 if (SelectingText()) … … 121 103 m_iBufferPos_Tail = -1; 122 104 123 if (pCaption->empty() || 124 m_iBufferPos == 0)105 if (pCaption->empty() || m_iBufferPos == 0) 106 { 125 107 break; 126 127 if (m_iBufferPos == (int)pCaption->length()) 128 *pCaption = pCaption->Left( (long) pCaption->length()-1); 108 } 129 109 else 130 *pCaption = pCaption->Left( m_iBufferPos-1 ) + 131 pCaption->Right( (long) pCaption->length()-m_iBufferPos ); 132 133 --m_iBufferPos; 110 { 111 if (m_iBufferPos == (int)pCaption->length()) 112 *pCaption = pCaption->Left( (long) pCaption->length()-1); 113 else 114 *pCaption = pCaption->Left( m_iBufferPos-1 ) + 115 pCaption->Right( (long) pCaption->length()-m_iBufferPos ); 116 117 --m_iBufferPos; 134 118 135 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 119 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 120 } 136 121 } 137 122 … … 140 125 141 126 case SDLK_DELETE: 142 m_WantedX=0. f;127 m_WantedX=0.0f; 143 128 // If selection: 144 129 if (SelectingText()) … … 148 133 else 149 134 { 150 if (pCaption->empty() || 151 m_iBufferPos == (int)pCaption->length())135 if (pCaption->empty() || m_iBufferPos == (int)pCaption->length()) 136 { 152 137 break; 153 154 *pCaption = pCaption->Left( m_iBufferPos ) + 155 pCaption->Right( (long) pCaption->length()-(m_iBufferPos+1) ); 156 157 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 138 } 139 else 140 { 141 *pCaption = pCaption->Left( m_iBufferPos ) + 142 pCaption->Right( (long) pCaption->length()-(m_iBufferPos+1) ); 143 144 UpdateText(m_iBufferPos, m_iBufferPos+1, m_iBufferPos); 145 } 158 146 } 159 147 … … 163 151 case SDLK_HOME: 164 152 // If there's not a selection, we should create one now 165 if (! g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])153 if (!shiftKeyPressed) 166 154 { 167 155 // Make sure a selection isn't created. … … 175 163 176 164 m_iBufferPos = 0; 177 m_WantedX=0. f;165 m_WantedX=0.0f; 178 166 179 167 UpdateAutoScroll(); … … 182 170 case SDLK_END: 183 171 // If there's not a selection, we should create one now 184 if (! g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT])172 if (!shiftKeyPressed) 185 173 { 186 174 // Make sure a selection isn't created. … … 194 182 195 183 m_iBufferPos = (long) pCaption->length(); 196 m_WantedX=0. f;184 m_WantedX=0.0f; 197 185 198 186 UpdateAutoScroll(); … … 222 210 **/ 223 211 case SDLK_LEFT: 224 // reset m_WantedX, very important225 212 m_WantedX=0.f; 226 213 227 if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] || 228 !SelectingText()) 229 { 230 // If there's not a selection, we should create one now 231 if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 232 { 233 // Make sure a selection isn't created. 214 if (shiftKeyPressed || !SelectingText()) 215 { 216 if (!shiftKeyPressed) 217 { 234 218 m_iBufferPos_Tail = -1; 235 219 } 236 220 else if (!SelectingText()) 237 221 { 238 // Place tail at the current point:239 222 m_iBufferPos_Tail = m_iBufferPos; 240 223 } 241 224 242 if (m_iBufferPos )225 if (m_iBufferPos > 0) 243 226 --m_iBufferPos; 244 227 } … … 255 238 256 239 case SDLK_RIGHT: 257 m_WantedX=0.f; 258 259 if (g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT] || 260 !SelectingText()) 261 { 262 // If there's not a selection, we should create one now 263 if (!SelectingText() && !g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 264 { 265 // Make sure a selection isn't created. 240 m_WantedX=0.0f; 241 242 if (shiftKeyPressed || !SelectingText()) 243 { 244 if (!shiftKeyPressed) 245 { 266 246 m_iBufferPos_Tail = -1; 267 247 } 268 248 else if (!SelectingText()) 269 249 { 270 // Place tail at the current point:271 250 m_iBufferPos_Tail = m_iBufferPos; 272 251 } 273 252 274 275 if (m_iBufferPos != (int)pCaption->length()) 253 if (m_iBufferPos < (int)pCaption->length()) 276 254 ++m_iBufferPos; 277 255 } … … 309 287 case SDLK_UP: 310 288 { 311 // If there's not a selection, we should create one now 312 if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 313 { 314 // Make sure a selection isn't created. 289 if (!shiftKeyPressed) 290 { 315 291 m_iBufferPos_Tail = -1; 316 292 } 317 293 else if (!SelectingText()) 318 294 { 319 // Place tail at the current point:320 295 m_iBufferPos_Tail = m_iBufferPos; 321 296 } … … 357 332 case SDLK_DOWN: 358 333 { 359 // If there's not a selection, we should create one now 360 if (!g_keys[SDLK_RSHIFT] && !g_keys[SDLK_LSHIFT]) 361 { 362 // Make sure a selection isn't created. 334 if (!shiftKeyPressed) 335 { 363 336 m_iBufferPos_Tail = -1; 364 337 } 365 338 else if (!SelectingText()) 366 339 { 367 // Place tail at the current point:368 340 m_iBufferPos_Tail = m_iBufferPos; 369 341 } … … 429 401 default: //Insert a character 430 402 { 431 // If there's a selection, delete if first.432 403 if (cooked == 0) 433 404 return IN_PASS; // Important, because we didn't use any key … … 439 410 break; 440 411 441 m_WantedX=0. f;412 m_WantedX=0.0f; 442 413 443 414 if (SelectingText()) … … 466 437 } 467 438 439 440 InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) 441 { 442 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 443 bool shiftKeyPressed = g_keys[SDLK_RSHIFT] || g_keys[SDLK_LSHIFT]; 444 445 std::string hotkey = static_cast<const char*>(ev->ev.user.data1); 446 if (hotkey == "console.paste") 447 { 448 m_WantedX=0.0f; 449 450 wchar_t* text = sys_clipboard_get(); 451 if (text) 452 { 453 if (m_iBufferPos == (int)pCaption->length()) 454 *pCaption += text; 455 else 456 *pCaption = pCaption->Left(m_iBufferPos) + text + 457 pCaption->Right((long) pCaption->length()-m_iBufferPos); 458 459 UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1); 460 461 m_iBufferPos += (int)wcslen(text); 462 463 sys_clipboard_free(text); 464 } 465 466 return IN_HANDLED; 467 } 468 else if (hotkey == "console.copy" || hotkey == "console.cut") 469 { 470 m_WantedX=0.0f; 471 472 if (SelectingText()) 473 { 474 int virtualFrom; 475 int virtualTo; 476 477 if (m_iBufferPos_Tail >= m_iBufferPos) 478 { 479 virtualFrom = m_iBufferPos; 480 virtualTo = m_iBufferPos_Tail; 481 } 482 else 483 { 484 virtualFrom = m_iBufferPos_Tail; 485 virtualTo = m_iBufferPos; 486 } 487 488 CStrW text = (pCaption->Left(virtualTo)).Right(virtualTo - virtualFrom); 489 490 sys_clipboard_set(&text[0]); 491 492 if (hotkey == "console.cut") 493 { 494 DeleteCurSelection(); 495 } 496 } 497 498 return IN_HANDLED; 499 } 500 else if (hotkey == "text.delete.word.left") 501 { 502 m_WantedX=0.0f; 503 504 if (SelectingText()) 505 { 506 DeleteCurSelection(); 507 } 508 if (!pCaption->empty() && !m_iBufferPos == 0) 509 { 510 m_iBufferPos_Tail = m_iBufferPos; 511 CStrW searchString = pCaption->Left( m_iBufferPos ); 512 513 // If we are starting in whitespace, adjust position until we get a non whitespace 514 while (m_iBufferPos > 0) 515 { 516 if (!iswspace(searchString[m_iBufferPos - 1])) 517 break; 518 519 m_iBufferPos--; 520 } 521 522 // If we end up on a puctuation char we just delete it (treat punct like a word) 523 if (iswpunct(searchString[m_iBufferPos - 1])) 524 m_iBufferPos--; 525 else 526 { 527 // Now we are on a non white space character, adjust position to char after next whitespace char is found 528 while (m_iBufferPos > 0) 529 { 530 if (iswspace(searchString[m_iBufferPos - 1]) || iswpunct(searchString[m_iBufferPos - 1])) 531 break; 532 533 m_iBufferPos--; 534 } 535 } 536 537 DeleteCurSelection(); 538 } 539 return IN_HANDLED; 540 } 541 else if (hotkey == "text.delete.word.right") 542 { 543 m_WantedX=0.0f; 544 545 if (SelectingText()) 546 { 547 DeleteCurSelection(); 548 } 549 if (!pCaption->empty() && m_iBufferPos < (int)pCaption->length()) 550 { 551 // Delete the word to the right of the cursor 552 m_iBufferPos_Tail = m_iBufferPos; 553 554 // Delete chars to the right unit we hit whitespace 555 while (++m_iBufferPos < (int)pCaption->length()) 556 { 557 if (iswspace((*pCaption)[m_iBufferPos]) || iswpunct((*pCaption)[m_iBufferPos])) 558 break; 559 } 560 561 // Eliminate any whitespace behind the word we just deleted 562 while (m_iBufferPos < (int)pCaption->length()) 563 { 564 if (!iswspace((*pCaption)[m_iBufferPos])) 565 break; 566 567 m_iBufferPos++; 568 } 569 DeleteCurSelection(); 570 } 571 return IN_HANDLED; 572 } 573 else if (hotkey == "text.move.word.left") 574 { 575 m_WantedX=0.0f; 576 577 if (shiftKeyPressed || !SelectingText()) 578 { 579 if (!shiftKeyPressed) 580 { 581 m_iBufferPos_Tail = -1; 582 } 583 else if (!SelectingText()) 584 { 585 m_iBufferPos_Tail = m_iBufferPos; 586 } 587 588 if (!pCaption->empty() && !m_iBufferPos == 0) 589 { 590 CStrW searchString = pCaption->Left( m_iBufferPos ); 591 592 // If we are starting in whitespace, adjust position until we get a non whitespace 593 while (m_iBufferPos > 0) 594 { 595 if (!iswspace(searchString[m_iBufferPos - 1])) 596 break; 597 598 m_iBufferPos--; 599 } 600 601 // If we end up on a puctuation char we just select it (treat punct like a word) 602 if (iswpunct(searchString[m_iBufferPos - 1])) 603 m_iBufferPos--; 604 else 605 { 606 // Now we are on a non white space character, adjust position to char after next whitespace char is found 607 while (m_iBufferPos > 0) 608 { 609 if (iswspace(searchString[m_iBufferPos - 1]) || iswpunct(searchString[m_iBufferPos - 1])) 610 break; 611 612 m_iBufferPos--; 613 } 614 } 615 } 616 } 617 else 618 { 619 if (m_iBufferPos_Tail < m_iBufferPos) 620 m_iBufferPos = m_iBufferPos_Tail; 621 622 m_iBufferPos_Tail = -1; 623 } 624 625 UpdateAutoScroll(); 626 627 return IN_HANDLED; 628 } 629 else if (hotkey == "text.move.word.right") 630 { 631 m_WantedX=0.0f; 632 633 if (shiftKeyPressed || !SelectingText()) 634 { 635 if (!shiftKeyPressed) 636 { 637 m_iBufferPos_Tail = -1; 638 } 639 else if (!SelectingText()) 640 { 641 m_iBufferPos_Tail = m_iBufferPos; 642 } 643 644 if (!pCaption->empty() && m_iBufferPos < (int)pCaption->length()) 645 { 646 CStrW searchString = *pCaption; 647 648 // Select chars to the right until we hit whitespace 649 while (++m_iBufferPos < (int)pCaption->length()) 650 { 651 if (iswspace((*pCaption)[m_iBufferPos]) || iswpunct((*pCaption)[m_iBufferPos])) 652 break; 653 } 654 655 // Also select any whitespace following the word we just selected 656 while (m_iBufferPos < (int)pCaption->length()) 657 { 658 if (!iswspace((*pCaption)[m_iBufferPos])) 659 break; 660 661 m_iBufferPos++; 662 } 663 } 664 } 665 else 666 { 667 if (m_iBufferPos_Tail > m_iBufferPos) 668 m_iBufferPos = m_iBufferPos_Tail; 669 670 m_iBufferPos_Tail = -1; 671 } 672 673 UpdateAutoScroll(); 674 675 return IN_HANDLED; 676 } 677 else 678 { 679 return IN_PASS; 680 } 681 } 682 683 468 684 void CInput::HandleMessage(SGUIMessage &Message) 469 685 { … … 481 697 // TODO Gee: (2004-09-01) Is this really updated each time it should? 482 698 if (scrollbar && 483 (Message.value == CStr("size") ||699 (Message.value == CStr("size") || 484 700 Message.value == CStr("z") || 485 701 Message.value == CStr("absolute"))) … … 565 781 566 782 }break; 783 784 case GUIM_MOUSE_DBLCLICK_LEFT: 785 { 786 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 787 m_iBufferPos = m_iBufferPos_Tail = GetMouseHoveringTextPosition(); 788 789 // See if we are clicking over whitespace 790 if (iswspace((*pCaption)[m_iBufferPos])) 791 { 792 // see if we are in a section of whitespace greater than one character 793 if ((m_iBufferPos + 1 < (int) pCaption->length() && iswspace((*pCaption)[m_iBufferPos + 1])) || 794 (m_iBufferPos - 1 > 0 && iswspace((*pCaption)[m_iBufferPos - 1]))) 795 { 796 // 797 // We are clicking in an area with more than one whitespace character 798 // so we select both the word to the left and then the word to the right 799 // 800 // [1] First the left 801 // skip the whitespace 802 while (m_iBufferPos > 0) 803 { 804 if (!iswspace((*pCaption)[m_iBufferPos - 1])) 805 break; 806 807 m_iBufferPos--; 808 } 809 // now go until we hit white space or punctuation 810 while (m_iBufferPos > 0) 811 { 812 if (iswspace((*pCaption)[m_iBufferPos - 1])) 813 break; 814 815 m_iBufferPos--; 816 817 if (iswpunct((*pCaption)[m_iBufferPos])) 818 break; 819 } 820 821 // [2] Then the right 822 // go right until we are not in whitespace 823 while (++m_iBufferPos_Tail < (int)pCaption->length()) 824 { 825 if (!iswspace((*pCaption)[m_iBufferPos_Tail])) 826 break; 827 } 828 // now go to the right until we hit whitespace or punctuation 829 while (++m_iBufferPos_Tail < (int)pCaption->length()) 830 { 831 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 832 break; 833 } 834 } 835 else 836 { 837 // single whitespace so select word to the right 838 while (++m_iBufferPos_Tail < (int)pCaption->length()) 839 { 840 if (!iswspace((*pCaption)[m_iBufferPos_Tail])) 841 break; 842 } 843 844 // Don't include the leading whitespace 845 m_iBufferPos = m_iBufferPos_Tail; 846 847 // now go to the right until we hit whitespace or punctuation 848 while (++m_iBufferPos_Tail < (int)pCaption->length()) 849 { 850 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 851 break; 852 } 853 } 854 } 855 else 856 { 857 // clicked on non-whitespace so select current word 858 // go until we hit white space or punctuation 859 while (m_iBufferPos > 0) 860 { 861 if (iswspace((*pCaption)[m_iBufferPos - 1])) 862 break; 863 864 m_iBufferPos--; 865 866 if (iswpunct((*pCaption)[m_iBufferPos])) 867 break; 868 } 869 // go to the right until we hit whitespace or punctuation 870 while (++m_iBufferPos_Tail < (int)pCaption->length()) 871 { 872 if (iswspace((*pCaption)[m_iBufferPos_Tail]) || iswpunct((*pCaption)[m_iBufferPos_Tail])) 873 break; 874 } 875 } 876 } 877 break; 567 878 568 879 case GUIM_MOUSE_RELEASE_LEFT: … … 922 1233 923 1234 if (i < (int)it->m_ListOfX.size()) 924 x_pointer += (float)font.GetCharacterWidth((*pCaption)[it->m_ListStart + i]);1235 x_pointer += (float)font.GetCharacterWidth((*pCaption)[it->m_ListStart + i]); 925 1236 } 926 1237 … … 954 1265 if (multiline) 955 1266 { 956 if (buffered_y + buffer_zone > m_CachedActualSize.GetHeight())1267 if (buffered_y + buffer_zone > m_CachedActualSize.GetHeight()) 957 1268 break; 958 1269 } … … 962 1273 // Text must always be drawn in integer values. So we have to convert scroll 963 1274 if (multiline) 964 glTranslatef(0.f, -(float)(int)scroll, 0.f);1275 glTranslatef(0.f, -(float)(int)scroll, 0.f); 965 1276 else 966 1277 glTranslatef(-(float)(int)m_HorizontalScroll, 0.f, 0.f); … … 1170 1481 if (destroy_row_to_used == false) 1171 1482 { 1172 destroy_row_to = m_CharacterPositions.end();1483 destroy_row_to = m_CharacterPositions.end(); 1173 1484 check_point_row_start = -1; 1174 1485 … … 1181 1492 1182 1493 if (destroy_row_to != m_CharacterPositions.end()) 1183 to = destroy_row_to->m_ListStart; // notice it will iterate [from, to), so it will never reach to.1494 to = destroy_row_to->m_ListStart; // notice it will iterate [from, to), so it will never reach to. 1184 1495 else 1185 1496 to = (int)caption.length(); … … 1429 1740 1430 1741 // Return position 1431 int RetPosition;1742 int retPosition; 1432 1743 1433 1744 float buffer_zone; … … 1494 1805 1495 1806 //m_iBufferPos = m_CharacterPositions.get.m_ListStart; 1496 RetPosition = current->m_ListStart;1807 retPosition = current->m_ListStart; 1497 1808 1498 1809 // Okay, now loop through the glyphs to find the appropriate X position 1499 1810 float dummy; 1500 RetPosition += GetXTextPosition(current, mouse.x, dummy);1501 1502 return RetPosition;1811 retPosition += GetXTextPosition(current, mouse.x, dummy); 1812 1813 return retPosition; 1503 1814 } 1504 1815 … … 1506 1817 int CInput::GetXTextPosition(const std::list<SRow>::iterator ¤t, const float &x, float &wanted) 1507 1818 { 1508 int Ret=0; 1509 1819 int ret=0; 1510 1820 float previous=0.f; 1511 1821 int i=0; … … 1518 1828 { 1519 1829 if (x - previous >= *it - x) 1520 Ret += i+1;1830 ret += i+1; 1521 1831 else 1522 Ret += i;1832 ret += i; 1523 1833 1524 1834 break; … … 1530 1840 if (i == (int)current->m_ListOfX.size()) 1531 1841 { 1532 Ret += i;1842 ret += i; 1533 1843 wanted = x; 1534 1844 } 1535 1845 else wanted = 0.f; 1536 1846 1537 return Ret;1847 return ret; 1538 1848 } 1539 1849 … … 1542 1852 CStrW *pCaption = (CStrW*)m_Settings["caption"].m_pSetting; 1543 1853 1544 int VirtualFrom, VirtualTo; 1854 int virtualFrom; 1855 int virtualTo; 1545 1856 1546 1857 if (m_iBufferPos_Tail >= m_iBufferPos) 1547 1858 { 1548 VirtualFrom = m_iBufferPos;1549 VirtualTo = m_iBufferPos_Tail;1859 virtualFrom = m_iBufferPos; 1860 virtualTo = m_iBufferPos_Tail; 1550 1861 } 1551 1862 else 1552 1863 { 1553 VirtualFrom = m_iBufferPos_Tail;1554 VirtualTo = m_iBufferPos;1555 } 1556 1557 *pCaption = pCaption->Left( VirtualFrom ) +1558 pCaption->Right( (long) pCaption->length() -(VirtualTo) );1559 1560 UpdateText( VirtualFrom, VirtualTo, VirtualFrom);1864 virtualFrom = m_iBufferPos_Tail; 1865 virtualTo = m_iBufferPos; 1866 } 1867 1868 *pCaption = pCaption->Left( virtualFrom ) + 1869 pCaption->Right( (long) pCaption->length() - (virtualTo) ); 1870 1871 UpdateText(virtualFrom, virtualTo, virtualFrom); 1561 1872 1562 1873 // Remove selection 1563 1874 m_iBufferPos_Tail = -1; 1564 m_iBufferPos = VirtualFrom;1875 m_iBufferPos = virtualFrom; 1565 1876 } 1566 1877 -
ps/trunk/source/gui/CInput.h
r9340 r9646 98 98 99 99 /** 100 * Handle hotkey events (called by ManuallyHandleEvent) 101 */ 102 virtual InReaction ManuallyHandleHotkeyEvent(const SDL_Event_* ev); 103 104 /** 100 105 * @see IGUIObject#UpdateCachedSize() 101 106 */ -
ps/trunk/source/lib/sysdep/clipboard.h
r9410 r9646 1 /* Copyright (c) 201 0Wildfire Games1 /* Copyright (c) 2011 Wildfire Games 2 2 * 3 3 * Permission is hereby granted, free of charge, to any person obtaining … … 21 21 */ 22 22 23 #ifndef INCLUDED_SYSDEP_CLIPBOARD 24 #define INCLUDED_SYSDEP_CLIPBOARD 25 23 26 // "copy" text into the clipboard. replaces previous contents. 24 27 extern Status sys_clipboard_set(const wchar_t* text); 25 28 26 // allow "pasting" from clipboard. returns the current contents if they 27 // can be represented as text, otherwise 0. 28 // when it is no longer needed, the returned pointer must be freed via 29 // sys_clipboard_free. (NB: not necessary if zero, but doesn't hurt) 29 // allow "pasting" from clipboard. 30 // @return current clipboard text or 0 if not representable as text. 31 // callers are responsible for passing this pointer to sys_clipboard_free. 30 32 extern wchar_t* sys_clipboard_get(); 31 33 32 // free s memory used by <copy>, which must have been returned by33 // sys_clipboard_get. see note above.34 // free memory returned by sys_clipboard_get. 35 // @param copy is ignored if 0. 34 36 extern Status sys_clipboard_free(wchar_t* copy); 37 38 #endif // #ifndef INCLUDED_SYSDEP_CLIPBOARD -
ps/trunk/source/lib/sysdep/os/win/wclipboard.cpp
r9410 r9646 27 27 #include "lib/sysdep/os/win/wutil.h" 28 28 29 // caller is responsible for freeing *hMem. 30 static Status SetClipboardText(const wchar_t* text, HGLOBAL* hMem) 29 30 // caller is responsible for freeing hMem. 31 static Status SetClipboardText(const wchar_t* text, HGLOBAL& hMem) 31 32 { 32 33 const size_t numChars = wcslen(text); 33 *hMem = GlobalAlloc(GMEM_MOVEABLE, (numChars+1) * sizeof(wchar_t));34 if(! *hMem)34 hMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, (numChars + 1) * sizeof(wchar_t)); 35 if(!hMem) 35 36 WARN_RETURN(ERR::NO_MEM); 36 37 37 wchar_t* lockedText = (wchar_t*)GlobalLock( *hMem);38 wchar_t* lockedText = (wchar_t*)GlobalLock(hMem); 38 39 if(!lockedText) 39 40 WARN_RETURN(ERR::NO_MEM); 40 41 wcscpy_s(lockedText, numChars+1, text); 41 GlobalUnlock( *hMem);42 GlobalUnlock(hMem); 42 43 43 HANDLE hData = SetClipboardData(CF_UNICODETEXT, *hMem);44 HANDLE hData = SetClipboardData(CF_UNICODETEXT, hMem); 44 45 if(!hData) // failed 45 46 WARN_RETURN(ERR::FAIL); … … 48 49 } 49 50 50 // "copy" text into the clipboard. replaces previous contents. 51 52 // @return INFO::OK iff text has been assigned a pointer (which the 53 // caller must free via sys_clipboard_free) to the clipboard text. 54 static Status GetClipboardText(wchar_t*& text) 55 { 56 // NB: Windows NT/2000+ auto convert CF_UNICODETEXT <-> CF_TEXT. 57 58 if(!IsClipboardFormatAvailable(CF_UNICODETEXT)) 59 return INFO::CANNOT_HANDLE; 60 61 HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); 62 if(!hMem) 63 WARN_RETURN(ERR::FAIL); 64 65 const wchar_t* lockedText = (const wchar_t*)GlobalLock(hMem); 66 if(!lockedText) 67 WARN_RETURN(ERR::NO_MEM); 68 69 const size_t size = GlobalSize(hMem); 70 text = (wchar_t*)malloc(size); 71 if(!text) 72 WARN_RETURN(ERR::NO_MEM); 73 wcscpy_s(text, size/sizeof(wchar_t), lockedText); 74 75 (void)GlobalUnlock(hMem); 76 77 return INFO::OK; 78 } 79 80 81 // OpenClipboard parameter. 82 // NB: using wutil_AppWindow() causes GlobalLock to fail. 83 static const HWND hWndNewOwner = 0; // MSDN: associate with "current task" 84 51 85 Status sys_clipboard_set(const wchar_t* text) 52 86 { 53 // note: MSDN claims that the window handle must not be 0; 54 // that does actually work on WinXP, but we'll play it safe. 55 if(!OpenClipboard(wutil_AppWindow())) 87 if(!OpenClipboard(hWndNewOwner)) 56 88 WARN_RETURN(ERR::FAIL); 57 EmptyClipboard();58 89 90 WARN_IF_FALSE(EmptyClipboard()); 91 92 // NB: to enable copy/pasting something other than text, add 93 // message handlers for WM_RENDERFORMAT and WM_RENDERALLFORMATS. 59 94 HGLOBAL hMem; 60 Status ret = SetClipboardText(text, &hMem);95 Status ret = SetClipboardText(text, hMem); 61 96 62 CloseClipboard();97 WARN_IF_FALSE(CloseClipboard()); // must happen before GlobalFree 63 98 64 // note: MSDN's SetClipboardData documentation says hMem must not be 65 // freed until after CloseClipboard. however, GlobalFree still fails 66 // after the successful completion of both. we'll leave it in to avoid 67 // memory leaks, but ignore its return value. 68 (void)GlobalFree(hMem); 99 ENSURE(GlobalFree(hMem) == 0); // (0 indicates success) 69 100 70 101 return ret; … … 72 103 73 104 74 static wchar_t* CopyClipboardContents()105 wchar_t* sys_clipboard_get() 75 106 { 76 // Windows NT/2000+ auto convert UNICODETEXT <-> TEXT 77 HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); 78 if(!hMem) 107 if(!OpenClipboard(hWndNewOwner)) 79 108 return 0; 80 109 81 const wchar_t* lockedText = (const wchar_t*)GlobalLock(hMem); 82 if(!lockedText) 83 return 0; 110 wchar_t* text; 111 Status ret = GetClipboardText(text); 84 112 85 const size_t numChars = GlobalSize(hMem)/sizeof(wchar_t) - 1; 86 wchar_t* text = new wchar_t[numChars+1]; 87 wcscpy_s(text, numChars+1, lockedText); 113 WARN_IF_FALSE(CloseClipboard()); 88 114 89 GlobalUnlock(hMem); 90 91 return text; 92 } 93 94 // allow "pasting" from clipboard. returns the current contents if they 95 // can be represented as text, otherwise 0. 96 // when it is no longer needed, the returned pointer must be freed via 97 // sys_clipboard_free. (NB: not necessary if zero, but doesn't hurt) 98 wchar_t* sys_clipboard_get() 99 { 100 if(!OpenClipboard(wutil_AppWindow())) 101 return 0; 102 wchar_t* const ret = CopyClipboardContents(); 103 CloseClipboard(); 104 return ret; 115 return (ret == INFO::OK)? text : 0; 105 116 } 106 117 107 118 108 // frees memory used by <copy>, which must have been returned by109 // sys_clipboard_get. see note above.110 119 Status sys_clipboard_free(wchar_t* text) 111 120 { 112 delete[] text;121 free(text); 113 122 return INFO::OK; 114 123 }
Note:
See TracChangeset
for help on using the changeset viewer.
