aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui
diff options
context:
space:
mode:
authorMcCabe Maxsted2010-09-15 03:33:05 -0700
committerMcCabe Maxsted2010-09-15 03:33:05 -0700
commitd14cf874b7b09ed9d845d7176f0c406a2e79f203 (patch)
tree2bdfdcf2aee411407789ba4726a8a2b155864129 /linden/indra/llui
parentUpdated CannotBuyLandMaturity notification with info on how to fix the problem (diff)
downloadmeta-impy-d14cf874b7b09ed9d845d7176f0c406a2e79f203.zip
meta-impy-d14cf874b7b09ed9d845d7176f0c406a2e79f203.tar.gz
meta-impy-d14cf874b7b09ed9d845d7176f0c406a2e79f203.tar.bz2
meta-impy-d14cf874b7b09ed9d845d7176f0c406a2e79f203.tar.xz
First commit in the long overhaul of making spell check consistent and workable. Contains code cleanup and a change in logic. Spell check is now only available on text/line editors that have spell_check set to true in xml
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/lllineeditor.cpp207
-rw-r--r--linden/indra/llui/lllineeditor.h4
-rw-r--r--linden/indra/llui/lltexteditor.cpp267
-rw-r--r--linden/indra/llui/lltexteditor.h4
4 files changed, 260 insertions, 222 deletions
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp
index c1d8efa..e95af79 100644
--- a/linden/indra/llui/lllineeditor.cpp
+++ b/linden/indra/llui/lllineeditor.cpp
@@ -171,7 +171,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
171 mHaveHistory(FALSE), 171 mHaveHistory(FALSE),
172 mImage( sImage ), 172 mImage( sImage ),
173 mReplaceNewlinesWithSpaces( TRUE ), 173 mReplaceNewlinesWithSpaces( TRUE ),
174 mOverRideAndShowMisspellings( FALSE ) 174 mShowMisspellings( FALSE )
175{ 175{
176 llassert( max_length_bytes > 0 ); 176 llassert( max_length_bytes > 0 );
177 177
@@ -546,19 +546,19 @@ void LLLineEditor::spell_show(void * data)
546 SpellMenuBind* tempBind = (SpellMenuBind*)data; 546 SpellMenuBind* tempBind = (SpellMenuBind*)data;
547 LLLineEditor* line = tempBind->origin; 547 LLLineEditor* line = tempBind->origin;
548 548
549 if(tempBind && line) 549 if( tempBind && line)
550 { 550 {
551 if(tempBind->word=="Show Misspellings") 551 if (tempBind->word=="Show Misspellings")
552 { 552 {
553 line->setOverRideAndShowMisspellings(TRUE); 553 line->setShowMisspellings(TRUE);
554 }else 554 }
555 else
555 { 556 {
556 line->setOverRideAndShowMisspellings(FALSE); 557 line->setShowMisspellings(FALSE);
557 } 558 }
558 } 559 }
559
560
561} 560}
561
562std::vector<S32> LLLineEditor::getMisspelledWordsPositions() 562std::vector<S32> LLLineEditor::getMisspelledWordsPositions()
563{ 563{
564 std::vector<S32> thePosesOfBadWords; 564 std::vector<S32> thePosesOfBadWords;
@@ -604,25 +604,29 @@ std::vector<S32> LLLineEditor::getMisspelledWordsPositions()
604 } 604 }
605 return thePosesOfBadWords; 605 return thePosesOfBadWords;
606} 606}
607
607void LLLineEditor::spell_add(void* data) 608void LLLineEditor::spell_add(void* data)
608{ 609{
609 SpellMenuBind* tempBind = (SpellMenuBind*)data; 610 SpellMenuBind* tempBind = (SpellMenuBind*)data;
610 if(tempBind) 611 if (tempBind)
611 { 612 {
612 glggHunSpell->addWordToCustomDictionary(tempBind->word); 613 glggHunSpell->addWordToCustomDictionary(tempBind->word);
613 tempBind->origin->mPrevSpelledText="";//make it update 614 tempBind->origin->mPrevSpelledText="";//make it update
614 } 615 }
615} 616}
617
616void LLLineEditor::context_paste(void* data) 618void LLLineEditor::context_paste(void* data)
617{ 619{
618 LLLineEditor* line = (LLLineEditor*)data; 620 LLLineEditor* line = (LLLineEditor*)data;
619 if(line)line->paste(); 621 if(line)line->paste();
620} 622}
623
621void LLLineEditor::context_delete(void* data) 624void LLLineEditor::context_delete(void* data)
622{ 625{
623 LLLineEditor* line = (LLLineEditor*)data; 626 LLLineEditor* line = (LLLineEditor*)data;
624 if(line)line->doDelete(); 627 if(line)line->doDelete();
625} 628}
629
626void LLLineEditor::context_selectall(void* data) 630void LLLineEditor::context_selectall(void* data)
627{ 631{
628 LLLineEditor* line = (LLLineEditor*)data; 632 LLLineEditor* line = (LLLineEditor*)data;
@@ -728,16 +732,17 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
728 S32 wordStart = 0; 732 S32 wordStart = 0;
729 S32 wordEnd = calculateCursorFromMouse(x); 733 S32 wordEnd = calculateCursorFromMouse(x);
730 734
731
732 LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); 735 LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
733 if (menu) 736 if (menu)
734 { 737 {
735 if(menu->isOpen()) 738 if(menu->isOpen())
739 {
736 menu->setVisible(FALSE); 740 menu->setVisible(FALSE);
737 for(int i = 0;i<(int)suggestionMenuItems.size();i++) 741 }
742 for (int i = 0;i<(int)suggestionMenuItems.size();i++)
738 { 743 {
739 SpellMenuBind * tempBind = suggestionMenuItems[i]; 744 SpellMenuBind * tempBind = suggestionMenuItems[i];
740 if(tempBind) 745 if (tempBind)
741 { 746 {
742 menu->remove((LLMenuItemCallGL *)tempBind->menuItem); 747 menu->remove((LLMenuItemCallGL *)tempBind->menuItem);
743 ((LLMenuItemCallGL *)tempBind->menuItem)->die(); 748 ((LLMenuItemCallGL *)tempBind->menuItem)->die();
@@ -748,69 +753,74 @@ BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
748 } 753 }
749 suggestionMenuItems.clear(); 754 suggestionMenuItems.clear();
750 755
751 menu->setItemVisible("Translate To",!mReadOnly); 756 menu->setItemVisible("Translate To", !mReadOnly);
752 menu->setItemVisible("Transep",!mReadOnly); 757 menu->setItemVisible("Transep", !mReadOnly);
753 758
754 const LLWString& text = mText.getWString(); 759 // spell_check="true" in xui
755 if(( LLTextEditor::isPartOfWord( text[wordEnd] ) ) 760 if (!mReadOnly && mShowMisspellings)
756 &&(!mReadOnly))
757 { 761 {
758 // Select word the cursor is over 762 const LLWString& text = mText.getWString();
759 while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1]))
760 {
761 wordEnd--;
762 }
763 wordStart=wordEnd;
764 //startSelection();
765 763
766 while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) ) 764 // search for word matches
765 if (LLTextEditor::isPartOfWord(text[wordEnd]))
767 { 766 {
768 wordEnd++; 767 // Select word the cursor is over
769 } 768 while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1]))
770 std::string selectedWord(std::string(text.begin(), 769 {
771 text.end()).substr(wordStart,wordEnd-wordStart)); 770 wordEnd--;
772 if(!glggHunSpell->isSpelledRight(selectedWord)) 771 }
773 { 772 wordStart = wordEnd;
774 //misspelled word here, and you have just right clicked on it! 773 //startSelection();
775 std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
776 //menu->setItemVisible("Transep",(suggs.size()>0));
777 774
778 for(int i = 0;i<(int)suggs.size();i++) 775 while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) )
779 { 776 {
777 wordEnd++;
778 }
779 std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart));
780
781 if (!glggHunSpell->isSpelledRight(selectedWord))
782 {
783 //misspelled word here, and you have just right clicked on it!
784 std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
785 //menu->setItemVisible("Transep",(suggs.size()>0));
786
787 for (int i = 0; i<(int)suggs.size() ;i++)
788 {
789 SpellMenuBind * tempStruct = new SpellMenuBind;
790 tempStruct->origin = this;
791 tempStruct->word = suggs[i];
792 tempStruct->wordPositionEnd = wordEnd;
793 tempStruct->wordPositionStart=wordStart;
794 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
795 tempStruct->word, spell_correct, NULL, tempStruct);
796 //new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
797 tempStruct->menuItem = suggMenuItem;
798 suggestionMenuItems.push_back(tempStruct);
799 menu->append(suggMenuItem);
800 }
780 SpellMenuBind * tempStruct = new SpellMenuBind; 801 SpellMenuBind * tempStruct = new SpellMenuBind;
781 tempStruct->origin = this; 802 tempStruct->origin = this;
782 tempStruct->word = suggs[i]; 803 tempStruct->word = selectedWord;
783 tempStruct->wordPositionEnd = wordEnd; 804 tempStruct->wordPositionEnd = wordEnd;
784 tempStruct->wordPositionStart=wordStart; 805 tempStruct->wordPositionStart=wordStart;
785 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( 806 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
786 tempStruct->word, spell_correct, NULL, tempStruct); 807 "Add Word", spell_add, NULL, tempStruct);
787 //new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
788 tempStruct->menuItem = suggMenuItem; 808 tempStruct->menuItem = suggMenuItem;
789 suggestionMenuItems.push_back(tempStruct); 809 suggestionMenuItems.push_back(tempStruct);
790 menu->append(suggMenuItem); 810 menu->append(suggMenuItem);
791 } 811 }
792 SpellMenuBind * tempStruct = new SpellMenuBind;
793 tempStruct->origin = this;
794 tempStruct->word = selectedWord;
795 tempStruct->wordPositionEnd = wordEnd;
796 tempStruct->wordPositionStart=wordStart;
797 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
798 "Add Word", spell_add, NULL, tempStruct);
799 tempStruct->menuItem = suggMenuItem;
800 suggestionMenuItems.push_back(tempStruct);
801 menu->append(suggMenuItem);
802 } 812 }
803 813
804 }
805 if((!mReadOnly)&&((!glggHunSpell->highlightInRed)
806 ||(mOverRideAndShowMisspellings)))
807 {
808 SpellMenuBind * tempStruct = new SpellMenuBind; 814 SpellMenuBind * tempStruct = new SpellMenuBind;
809 tempStruct->origin = this; 815 tempStruct->origin = this;
810 if(mOverRideAndShowMisspellings) 816 if (glggHunSpell->mSpellCheckHighlight)
817 {
811 tempStruct->word = "Hide Misspellings"; 818 tempStruct->word = "Hide Misspellings";
819 }
812 else 820 else
821 {
813 tempStruct->word = "Show Misspellings"; 822 tempStruct->word = "Show Misspellings";
823 }
814 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( 824 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
815 tempStruct->word, spell_show, NULL, tempStruct); 825 tempStruct->word, spell_show, NULL, tempStruct);
816 tempStruct->menuItem = suggMenuItem; 826 tempStruct->menuItem = suggMenuItem;
@@ -1838,36 +1848,43 @@ void LLLineEditor::doDelete()
1838 } 1848 }
1839 } 1849 }
1840} 1850}
1851
1841void LLLineEditor::autoCorrectText() 1852void LLLineEditor::autoCorrectText()
1842{ 1853{
1843 static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true); 1854 static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true);
1844 if( (!mReadOnly) && (*doAnything) && (isSpellDirty())) 1855 if (!mReadOnly && *doAnything && isSpellDirty())
1845 { 1856 {
1846 S32 wordStart = 0; 1857 S32 wordStart = 0;
1847 S32 wordEnd = mCursorPos-1; 1858 S32 wordEnd = mCursorPos-1;
1848 //llinfos <<"Checking Word, Cursor is at "<<mCursorPos<<" and text is "<<mText.getString().c_str()<<llendl; 1859 //llinfos <<"Checking Word, Cursor is at "<<mCursorPos<<" and text is "<<mText.getString().c_str()<<llendl;
1849 if(wordEnd<1)return; 1860 if (wordEnd < 1)
1861 {
1862 return;
1863 }
1850 const LLWString& text = mText.getWString(); 1864 const LLWString& text = mText.getWString();
1851 if(text.size()<1)return; 1865 if (text.size() < 1 || LLTextEditor::isPartOfWord(text[wordEnd]))
1852 if( LLTextEditor::isPartOfWord( text[wordEnd] )) return;//we only check on word breaks 1866 {
1867 return;//we only check on word breaks
1868 }
1869
1853 wordEnd--; 1870 wordEnd--;
1854 if( LLTextEditor::isPartOfWord( text[wordEnd] ) ) 1871 if (LLTextEditor::isPartOfWord(text[wordEnd]))
1855 { 1872 {
1856 while ((wordEnd > 0) && (' '!=text[wordEnd-1])) 1873 while ((wordEnd > 0) && (' '!=text[wordEnd-1]))
1857 { 1874 {
1858 wordEnd--; 1875 wordEnd--;
1859 } 1876 }
1860 wordStart=wordEnd; 1877 wordStart = wordEnd;
1861 while ((wordEnd < (S32)text.length()) && (' '!=text[wordEnd] ) ) 1878 while ((wordEnd < (S32)text.length()) && (' '!=text[wordEnd] ) )
1862 { 1879 {
1863 wordEnd++; 1880 wordEnd++;
1864 } 1881 }
1865 std::string lastTypedWord(std::string(text.begin(), 1882 std::string lastTypedWord(std::string(text.begin(),
1866 text.end()).substr(wordStart,wordEnd-wordStart)); 1883 text.end()).substr(wordStart, wordEnd-wordStart));
1867 //llinfos << " The last typed word has been chosen, it is "<<lastTypedWord.c_str()<<llendl; 1884 //llinfos << " The last typed word has been chosen, it is "<<lastTypedWord.c_str()<<llendl;
1868 1885
1869 std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord)); 1886 std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord));
1870 if(correctedWord!=lastTypedWord) 1887 if(correctedWord != lastTypedWord)
1871 { 1888 {
1872 int dif = correctedWord.length()-lastTypedWord.length(); 1889 int dif = correctedWord.length()-lastTypedWord.length();
1873 std::string regText(mText); 1890 std::string regText(mText);
@@ -1879,53 +1896,56 @@ void LLLineEditor::autoCorrectText()
1879 } 1896 }
1880 } 1897 }
1881} 1898}
1899
1882void LLLineEditor::drawMisspelled(LLRect background) 1900void LLLineEditor::drawMisspelled(LLRect background)
1883{ 1901{
1884 if((glggHunSpell->highlightInRed || mOverRideAndShowMisspellings) 1902 if (!mReadOnly && mShowMisspellings)
1885 &&(!mReadOnly))
1886 { 1903 {
1887 S32 newStartSpellHere =mScrollHPos; 1904 S32 newStartSpellHere = mScrollHPos;
1888 S32 cursorloc =calculateCursorFromMouse(mMaxHPixels); 1905 S32 cursorloc = calculateCursorFromMouse(mMaxHPixels);
1889 S32 newStopSpellHere = ( ((S32)mText.length())>cursorloc)?cursorloc:(S32)mText.length(); 1906 S32 newStopSpellHere = (((S32)mText.length())>cursorloc) ? cursorloc : (S32)mText.length();
1890 1907
1891 F32 elapsed = mSpellTimer.getElapsedTimeF32(); 1908 F32 elapsed = mSpellTimer.getElapsedTimeF32();
1892 if(S32(elapsed / 1) & 1) 1909 if (S32(elapsed / 1) & 1)
1893 { 1910 {
1894 if(isSpellDirty()||(newStartSpellHere!=mStartSpellHere)||(newStopSpellHere!=mEndSpellHere)) 1911 if (isSpellDirty() || (newStartSpellHere != mStartSpellHere) || ( newStopSpellHere != mEndSpellHere))
1895 { 1912 {
1896 mStartSpellHere=newStartSpellHere; 1913 mStartSpellHere = newStartSpellHere;
1897 mEndSpellHere= newStopSpellHere; 1914 mEndSpellHere = newStopSpellHere;
1898 resetSpellDirty(); 1915 resetSpellDirty();
1899 misspellLocations=getMisspelledWordsPositions(); 1916 misspellLocations=getMisspelledWordsPositions();
1900 } 1917 }
1901 } 1918 }
1902 for(int i =0;i<(int)misspellLocations.size();i++)
1903 {
1904 S32 wstart =findPixelNearestPos( misspellLocations[i]-getCursor());
1905 S32 wend = findPixelNearestPos(misspellLocations[++i]-getCursor());
1906 S32 maxw = getRect().getWidth();
1907 1919
1908 if(wend > maxw) 1920 if (glggHunSpell->mSpellCheckHighlight)
1909 { 1921 {
1910 wend=maxw; 1922 for (int i =0; i<(int)misspellLocations.size(); i++)
1911 }
1912 if(wstart > maxw)
1913 {
1914 wstart=maxw;
1915 }
1916 gGL.color4ub(255,0,0,200);
1917 //3 line zig zags..
1918 while(wstart<wend)
1919 { 1923 {
1920 gl_line_2d(wstart,background.mBottom-1,wstart+3,background.mBottom+2); 1924 S32 wstart =findPixelNearestPos( misspellLocations[i]-getCursor());
1921 gl_line_2d(wstart+3,background.mBottom+2,wstart+6,background.mBottom-1); 1925 S32 wend = findPixelNearestPos(misspellLocations[++i]-getCursor());
1922 wstart+=6; 1926 S32 maxw = getRect().getWidth();
1923 }
1924 1927
1928 if (wend > maxw)
1929 {
1930 wend = maxw;
1931 }
1932 if (wstart > maxw)
1933 {
1934 wstart = maxw;
1935 }
1936 gGL.color4ub(255,0,0,200);
1937 //3 line zig zags..
1938 while (wstart < wend)
1939 {
1940 gl_line_2d(wstart, background.mBottom-1, wstart+3, background.mBottom+2);
1941 gl_line_2d(wstart+3, background.mBottom+2, wstart+6, background.mBottom-1);
1942 wstart+=6;
1943 }
1944 }
1925 } 1945 }
1926 } 1946 }
1927
1928} 1947}
1948
1929void LLLineEditor::draw() 1949void LLLineEditor::draw()
1930{ 1950{
1931 autoCorrectText(); 1951 autoCorrectText();
@@ -2797,6 +2817,11 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
2797 { 2817 {
2798 line_editor->setCommitOnFocusLost(commit_on_focus_lost); 2818 line_editor->setCommitOnFocusLost(commit_on_focus_lost);
2799 } 2819 }
2820 BOOL show_misspellings = FALSE;
2821 if (node->getAttributeBOOL("spell_check", show_misspellings))
2822 {
2823 line_editor->setShowMisspellings(show_misspellings);
2824 }
2800 2825
2801 line_editor->setColorParameters(node); 2826 line_editor->setColorParameters(node);
2802 2827
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h
index 6de57ec..1d24803 100644
--- a/linden/indra/llui/lllineeditor.h
+++ b/linden/indra/llui/lllineeditor.h
@@ -198,7 +198,7 @@ public:
198 void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } 198 void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; }
199 void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } 199 void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; }
200 void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } 200 void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; }
201 void setOverRideAndShowMisspellings(BOOL b) { mOverRideAndShowMisspellings =b;} 201 void setShowMisspellings(BOOL b) { mShowMisspellings = b;}
202 202
203 const LLColor4& getFgColor() const { return mFgColor; } 203 const LLColor4& getFgColor() const { return mFgColor; }
204 const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } 204 const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; }
@@ -293,7 +293,7 @@ protected:
293 std::vector<S32> misspellLocations; // where all the mispelled words are 293 std::vector<S32> misspellLocations; // where all the mispelled words are
294 S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update 294 S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update
295 S32 mEndSpellHere; // the location of the last char on the screen 295 S32 mEndSpellHere; // the location of the last char on the screen
296 BOOL mOverRideAndShowMisspellings; 296 BOOL mShowMisspellings;
297 LLFrameTimer mSpellTimer; 297 LLFrameTimer mSpellTimer;
298 //to keep track of what we have to remove before showing menu 298 //to keep track of what we have to remove before showing menu
299 std::vector<SpellMenuBind* > suggestionMenuItems; 299 std::vector<SpellMenuBind* > suggestionMenuItems;
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp
index 6e5cdc4..d2469c3 100644
--- a/linden/indra/llui/lltexteditor.cpp
+++ b/linden/indra/llui/lltexteditor.cpp
@@ -323,7 +323,7 @@ LLTextEditor::LLTextEditor(
323 mLastSelectionY(-1), 323 mLastSelectionY(-1),
324 mReflowNeeded(FALSE), 324 mReflowNeeded(FALSE),
325 mScrollNeeded(FALSE), 325 mScrollNeeded(FALSE),
326 mOverRideAndShowMisspellings(FALSE) 326 mShowMisspellings(FALSE)
327{ 327{
328 mSourceID.generate(); 328 mSourceID.generate();
329 329
@@ -490,10 +490,10 @@ void LLTextEditor::spell_show(void * data)
490 { 490 {
491 if(tempBind->word=="Show Misspellings") 491 if(tempBind->word=="Show Misspellings")
492 { 492 {
493 line->setOverRideAndShowMisspellings(TRUE); 493 line->setShowMisspellings(TRUE);
494 }else 494 }else
495 { 495 {
496 line->setOverRideAndShowMisspellings(FALSE); 496 line->setShowMisspellings(FALSE);
497 } 497 }
498 } 498 }
499} 499}
@@ -1426,7 +1426,6 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
1426} 1426}
1427BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) 1427BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
1428{ 1428{
1429
1430 setFocus(TRUE); 1429 setFocus(TRUE);
1431 1430
1432 //setCursorAtLocalPos( x, y, TRUE ); 1431 //setCursorAtLocalPos( x, y, TRUE );
@@ -1450,69 +1449,73 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
1450 } 1449 }
1451 suggestionMenuItems.clear(); 1450 suggestionMenuItems.clear();
1452 1451
1453 menu->setItemVisible("Translate To",!mReadOnly); 1452 menu->setItemVisible("Translate To", !mReadOnly);
1454 menu->setItemVisible("Transep",!mReadOnly); 1453 menu->setItemVisible("Transep", !mReadOnly);
1455
1456 const LLWString &text = mWText;
1457 1454
1458 if(( isPartOfWord( text[wordEnd] ) )&&(!mReadOnly)) 1455 // spell_check="true" in xui
1456 if (!mReadOnly && mShowMisspellings)
1459 { 1457 {
1460 // Select word the cursor is over 1458 const LLWString &text = mWText;
1461 while ((wordEnd > 0) && isPartOfWord(text[wordEnd-1])) 1459
1462 { 1460 if (isPartOfWord(text[wordEnd]) && !mReadOnly)
1463 wordEnd--;
1464 }
1465 wordStart=wordEnd;
1466 //startSelection();
1467
1468 while ((wordEnd < (S32)text.length()) && isPartOfWord( text[wordEnd] ) )
1469 {
1470 wordEnd++;
1471 }
1472 std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart));
1473 if(!glggHunSpell->isSpelledRight(selectedWord))
1474 { 1461 {
1475 //misspelled word here, and you have just right clicked on it! 1462 // Select word the cursor is over
1476 std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); 1463 while ((wordEnd > 0) && isPartOfWord(text[wordEnd-1]))
1464 {
1465 wordEnd--;
1466 }
1467 wordStart = wordEnd;
1468 //startSelection();
1477 1469
1478 //menu->setItemVisible("Transep",(suggs.size()>0)); 1470 while ((wordEnd < (S32)text.length()) && isPartOfWord( text[wordEnd] ) )
1479 for(int i = 0;i<(int)suggs.size();i++) 1471 {
1472 wordEnd++;
1473 }
1474 std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordEnd-wordStart));
1475 if (!glggHunSpell->isSpelledRight(selectedWord))
1480 { 1476 {
1477 //misspelled word here, and you have just right clicked on it!
1478 std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
1479
1480 //menu->setItemVisible("Transep",(suggs.size()>0));
1481 for (int i = 0; i<(int)suggs.size(); i++)
1482 {
1483 SpellMenuBind * tempStruct = new SpellMenuBind;
1484 tempStruct->origin = this;
1485 tempStruct->word = suggs[i];
1486 tempStruct->wordPositionEnd = wordEnd;
1487 tempStruct->wordPositionStart=wordStart;
1488 tempStruct->wordY=y;
1489 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
1490 tempStruct->word, spell_correct, NULL, tempStruct);
1491 tempStruct->menuItem = suggMenuItem;
1492 suggestionMenuItems.push_back(tempStruct);
1493 menu->append(suggMenuItem);
1494 }
1481 SpellMenuBind * tempStruct = new SpellMenuBind; 1495 SpellMenuBind * tempStruct = new SpellMenuBind;
1482 tempStruct->origin = this; 1496 tempStruct->origin = this;
1483 tempStruct->word = suggs[i]; 1497 tempStruct->word = selectedWord;
1484 tempStruct->wordPositionEnd = wordEnd; 1498 tempStruct->wordPositionEnd = wordEnd;
1485 tempStruct->wordPositionStart=wordStart; 1499 tempStruct->wordPositionStart=wordStart;
1486 tempStruct->wordY=y; 1500 tempStruct->wordY=y;
1487 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( 1501 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
1488 tempStruct->word, spell_correct, NULL, tempStruct); 1502 "Add Word", spell_add, NULL, tempStruct);
1489 tempStruct->menuItem = suggMenuItem; 1503 tempStruct->menuItem = suggMenuItem;
1490 suggestionMenuItems.push_back(tempStruct); 1504 suggestionMenuItems.push_back(tempStruct);
1491 menu->append(suggMenuItem); 1505 menu->append(suggMenuItem);
1492 } 1506 }
1493 SpellMenuBind * tempStruct = new SpellMenuBind;
1494 tempStruct->origin = this;
1495 tempStruct->word = selectedWord;
1496 tempStruct->wordPositionEnd = wordEnd;
1497 tempStruct->wordPositionStart=wordStart;
1498 tempStruct->wordY=y;
1499 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
1500 "Add Word", spell_add, NULL, tempStruct);
1501 tempStruct->menuItem = suggMenuItem;
1502 suggestionMenuItems.push_back(tempStruct);
1503 menu->append(suggMenuItem);
1504 } 1507 }
1505 1508
1506 }
1507 if((!mReadOnly)&&((!glggHunSpell->highlightInRed)
1508 ||(mOverRideAndShowMisspellings)||(mShowLineNumbers)))
1509 {
1510 SpellMenuBind * tempStruct = new SpellMenuBind; 1509 SpellMenuBind * tempStruct = new SpellMenuBind;
1511 tempStruct->origin = this; 1510 tempStruct->origin = this;
1512 if(mOverRideAndShowMisspellings) 1511 if (glggHunSpell->mSpellCheckHighlight)
1512 {
1513 tempStruct->word = "Hide Misspellings"; 1513 tempStruct->word = "Hide Misspellings";
1514 }
1514 else 1515 else
1516 {
1515 tempStruct->word = "Show Misspellings"; 1517 tempStruct->word = "Show Misspellings";
1518 }
1516 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( 1519 LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
1517 tempStruct->word, spell_show, NULL, tempStruct); 1520 tempStruct->word, spell_show, NULL, tempStruct);
1518 tempStruct->menuItem = suggMenuItem; 1521 tempStruct->menuItem = suggMenuItem;
@@ -3077,51 +3080,57 @@ void LLTextEditor::drawSelectionBackground()
3077 } 3080 }
3078 } 3081 }
3079} 3082}
3083
3080void LLTextEditor::autoCorrectText() 3084void LLTextEditor::autoCorrectText()
3081{ 3085{
3082
3083 static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true); 3086 static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true);
3084 if( (!mReadOnly) && (*doAnything) && (isSpellDirty()) ) 3087 if (!mReadOnly && *doAnything && isSpellDirty())
3085 { 3088 {
3086 S32 wordStart = 0; 3089 S32 wordStart = 0;
3087 S32 wordEnd = mCursorPos-1; 3090 S32 wordEnd = mCursorPos-1;
3088 if(wordEnd<1)return; 3091 if (wordEnd < 1)
3092 {
3093 return;
3094 }
3089 LLWString& text = mWText; 3095 LLWString& text = mWText;
3090 if(text.size()<1)return; 3096 if (text.size() < 1 || LLTextEditor::isPartOfWord(text[wordEnd]))
3091 if( LLTextEditor::isPartOfWord( text[wordEnd] )) return;//we only check on word breaks 3097 {
3098 return;//we only check on word breaks
3099 }
3100
3092 wordEnd--; 3101 wordEnd--;
3093 if( LLTextEditor::isPartOfWord( text[wordEnd] ) ) 3102 if (LLTextEditor::isPartOfWord(text[wordEnd]))
3094 { 3103 {
3095 while ((wordEnd > 0) && (text[wordEnd-1]!=' ')) 3104 while ((wordEnd > 0) && (text[wordEnd-1]!=' '))
3096 { 3105 {
3097 wordEnd--; 3106 wordEnd--;
3098 } 3107 }
3099 wordStart=wordEnd; 3108 wordStart = wordEnd;
3100 while ((wordEnd < (S32)text.length()) && (' '!= text[wordEnd] ) ) 3109 while ((wordEnd < (S32)text.length()) && (' '!= text[wordEnd] ) )
3101 { 3110 {
3102 wordEnd++; 3111 wordEnd++;
3103 } 3112 }
3104 std::string lastTypedWord(std::string(text.begin(), 3113 std::string lastTypedWord(std::string(text.begin(),
3105 text.end()).substr(wordStart,wordEnd-wordStart)); 3114 text.end()).substr(wordStart, wordEnd-wordStart));
3106 3115
3107 std::string regText(text.begin(),text.end()); 3116 std::string regText(text.begin(), text.end());
3108 3117
3109 std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord)); 3118 std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord));
3110 if(correctedWord!=lastTypedWord) 3119 if (correctedWord != lastTypedWord)
3111 { 3120 {
3112 int dif = correctedWord.length()-lastTypedWord.length(); 3121 int dif = correctedWord.length() - lastTypedWord.length();
3113 regText.replace(wordStart,lastTypedWord.length(),correctedWord); 3122 regText.replace(wordStart, lastTypedWord.length(), correctedWord);
3114 mWText=utf8str_to_wstring(regText); 3123 mWText = utf8str_to_wstring(regText);
3115 mCursorPos+=dif; 3124 mCursorPos += dif;
3116 needsReflow(); 3125 needsReflow();
3117 } 3126 }
3118 } 3127 }
3119 } 3128 }
3120} 3129}
3130
3121void LLTextEditor::drawMisspelled() 3131void LLTextEditor::drawMisspelled()
3122{ 3132{
3123 if(mReadOnly)return; 3133 if (!mReadOnly && mShowMisspellings)
3124 if(glggHunSpell->highlightInRed || mOverRideAndShowMisspellings)
3125 { 3134 {
3126 if( 3135 if(
3127 ( ((getLength()<400)||(false)) &&( (S32(mSpellTimer.getElapsedTimeF32() / 1) & 1) )) 3136 ( ((getLength()<400)||(false)) &&( (S32(mSpellTimer.getElapsedTimeF32() / 1) & 1) ))
@@ -3132,80 +3141,86 @@ void LLTextEditor::drawMisspelled()
3132 S32 newSpellStart = getLineStart(mScrollbar->getDocPos());//start at the scroll start 3141 S32 newSpellStart = getLineStart(mScrollbar->getDocPos());//start at the scroll start
3133 S32 newSpellEnd = getLineStart(mScrollbar->getDocPos() + 1 + mScrollbar->getDocSize()-mScrollbar->getDocPosMax());//end at the end o.o 3142 S32 newSpellEnd = getLineStart(mScrollbar->getDocPos() + 1 + mScrollbar->getDocSize()-mScrollbar->getDocPosMax());//end at the end o.o
3134 3143
3135 if(mScrollbar->getDocPos() == mScrollbar->getDocPosMax()) 3144 if (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())
3136 { 3145 {
3137 newSpellEnd=(S32)mWText.length(); 3146 newSpellEnd = (S32)mWText.length();
3138 } 3147 }
3139 if((isSpellDirty())||(newSpellEnd!=spellEnd || newSpellStart!=spellStart)) 3148 if (isSpellDirty() || (newSpellEnd!=spellEnd || newSpellStart!=spellStart))
3140 { 3149 {
3141 spellEnd = newSpellEnd; 3150 spellEnd = newSpellEnd;
3142 spellStart = newSpellStart; 3151 spellStart = newSpellStart;
3143 misspellLocations=getMisspelledWordsPositions(); 3152 misspellLocations = getMisspelledWordsPositions();
3144 } 3153 }
3145 } 3154 }
3146 //draw 3155 //draw
3147 for(int i =0;i<(int)misspellLocations.size();i++) 3156 if (glggHunSpell->mSpellCheckHighlight)
3148 { 3157 {
3149 S32 wstart = misspellLocations[i]; 3158 for (int i = 0; i<(int)misspellLocations.size() ;i++)
3150 S32 wend = misspellLocations[++i];
3151 //start curor code mod
3152 const LLWString &text = mWText;
3153 const S32 text_len = getLength();
3154 // Skip through the lines we aren't drawing.
3155 S32 search_pos = mScrollbar->getDocPos();
3156 S32 num_lines = getLineCount();
3157 if (search_pos >= num_lines)return;
3158 S32 line_start = getLineStart(search_pos);
3159 F32 line_height = mGLFont->getLineHeight();
3160 F32 text_y = (F32)(mTextRect.mTop) - line_height;
3161
3162 F32 word_left = 0.f;
3163 F32 word_right = 0.f;
3164 F32 word_bottom = 0.f;
3165 BOOL word_visible = FALSE;
3166
3167 S32 line_end = 0;
3168 // Determine if the cursor is visible and if so what its coordinates are.
3169 while( (mTextRect.mBottom <= llround(text_y)) && (search_pos < num_lines))
3170 { 3159 {
3171 line_end = text_len + 1; 3160 S32 wstart = misspellLocations[i];
3172 S32 next_line = -1; 3161 S32 wend = misspellLocations[++i];
3173 3162 //start curor code mod
3174 if ((search_pos + 1) < num_lines) 3163 const LLWString &text = mWText;
3164 const S32 text_len = getLength();
3165 // Skip through the lines we aren't drawing.
3166 S32 search_pos = mScrollbar->getDocPos();
3167 S32 num_lines = getLineCount();
3168 if (search_pos >= num_lines)
3175 { 3169 {
3176 next_line = getLineStart(search_pos + 1); 3170 return;
3177 line_end = next_line - 1;
3178 } 3171 }
3179 const llwchar* line = text.c_str() + line_start; 3172 S32 line_start = getLineStart(search_pos);
3180 // Find the cursor and selection bounds 3173 F32 line_height = mGLFont->getLineHeight();
3181 if( line_start <= wstart && wend <= line_end ) 3174 F32 text_y = (F32)(mTextRect.mTop) - line_height;
3175
3176 F32 word_left = 0.f;
3177 F32 word_right = 0.f;
3178 F32 word_bottom = 0.f;
3179 BOOL word_visible = FALSE;
3180
3181 S32 line_end = 0;
3182 // Determine if the cursor is visible and if so what its coordinates are.
3183 while( (mTextRect.mBottom <= llround(text_y)) && (search_pos < num_lines))
3182 { 3184 {
3183 word_visible = TRUE; 3185 line_end = text_len + 1;
3184 word_left = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wstart - line_start, mAllowEmbeddedItems )-1.f; 3186 S32 next_line = -1;
3185 word_right = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wend - line_start, mAllowEmbeddedItems )+1.f; 3187
3186 word_bottom = text_y; 3188 if ((search_pos + 1) < num_lines)
3187 break; 3189 {
3190 next_line = getLineStart(search_pos + 1);
3191 line_end = next_line - 1;
3192 }
3193 const llwchar* line = text.c_str() + line_start;
3194 // Find the cursor and selection bounds
3195 if( line_start <= wstart && wend <= line_end )
3196 {
3197 word_visible = TRUE;
3198 word_left = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wstart - line_start, mAllowEmbeddedItems )-1.f;
3199 word_right = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wend - line_start, mAllowEmbeddedItems )+1.f;
3200 word_bottom = text_y;
3201 break;
3202 }
3203 // move down one line
3204 text_y -= line_height;
3205 line_start = next_line;
3206 search_pos++;
3188 } 3207 }
3189 // move down one line 3208 if (mShowLineNumbers)
3190 text_y -= line_height;
3191 line_start = next_line;
3192 search_pos++;
3193 }
3194 if(mShowLineNumbers)
3195 {
3196 word_left += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
3197 word_right += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
3198 }
3199 // Draw the cursor
3200 if( word_visible )
3201 {
3202 //end cursos code mod
3203 gGL.color4ub(255,0,0,200);
3204 while(word_left<word_right)
3205 { 3209 {
3206 gl_line_2d(word_left,word_bottom-2,word_left+3,word_bottom+1); 3210 word_left += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
3207 gl_line_2d(word_left+3,word_bottom+1,word_left+6,word_bottom-2); 3211 word_right += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
3208 word_left+=6; 3212 }
3213 // Draw the cursor
3214 if (word_visible)
3215 {
3216 //end cursor code mod
3217 gGL.color4ub(255,0,0,200);
3218 while (word_left<word_right)
3219 {
3220 gl_line_2d(word_left,word_bottom-2, word_left+3,word_bottom+1);
3221 gl_line_2d(word_left+3,word_bottom+1, word_left+6,word_bottom-2);
3222 word_left += 6;
3223 }
3209 } 3224 }
3210 } 3225 }
3211 } 3226 }
@@ -3214,8 +3229,7 @@ void LLTextEditor::drawMisspelled()
3214 3229
3215void LLTextEditor::drawCursor() 3230void LLTextEditor::drawCursor()
3216{ 3231{
3217 if( gFocusMgr.getKeyboardFocus() == this 3232 if (!mReadOnly && gFocusMgr.getKeyboardFocus() == this && gShowTextEditCursor)
3218 && gShowTextEditCursor && !mReadOnly)
3219 { 3233 {
3220 const LLWString &text = mWText; 3234 const LLWString &text = mWText;
3221 const S32 text_len = getLength(); 3235 const S32 text_len = getLength();
@@ -3696,10 +3710,7 @@ void LLTextEditor::draw()
3696 drawPreeditMarker(); 3710 drawPreeditMarker();
3697 drawText(); 3711 drawText();
3698 drawCursor(); 3712 drawCursor();
3699 if(!mShowLineNumbers || mOverRideAndShowMisspellings) 3713 drawMisspelled();
3700 {
3701 drawMisspelled();
3702 }
3703 resetSpellDirty(); 3714 resetSpellDirty();
3704 unbindEmbeddedChars(mGLFont); 3715 unbindEmbeddedChars(mGLFont);
3705 3716
@@ -4879,6 +4890,8 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node)
4879 4890
4880 node->getAttributeBOOL("track_bottom", mTrackBottom); 4891 node->getAttributeBOOL("track_bottom", mTrackBottom);
4881 4892
4893 node->getAttributeBOOL("spell_check", mShowMisspellings);
4894
4882 LLColor4 color; 4895 LLColor4 color;
4883 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) 4896 if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
4884 { 4897 {
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h
index 6b372d7..c5c3af8 100644
--- a/linden/indra/llui/lltexteditor.h
+++ b/linden/indra/llui/lltexteditor.h
@@ -229,7 +229,7 @@ public:
229 void setThumbColor( const LLColor4& color ); 229 void setThumbColor( const LLColor4& color );
230 void setHighlightColor( const LLColor4& color ); 230 void setHighlightColor( const LLColor4& color );
231 void setShadowColor( const LLColor4& color ); 231 void setShadowColor( const LLColor4& color );
232 void setOverRideAndShowMisspellings(BOOL b){ mOverRideAndShowMisspellings =b;} 232 void setShowMisspellings(BOOL b) { mShowMisspellings = b; }
233 233
234 // Hacky methods to make it into a word-wrapping, potentially scrolling, 234 // Hacky methods to make it into a word-wrapping, potentially scrolling,
235 // read-only text box. 235 // read-only text box.
@@ -526,7 +526,7 @@ private:
526 S32 spellStart; 526 S32 spellStart;
527 S32 spellEnd; 527 S32 spellEnd;
528 std::vector<S32> misspellLocations; // where all the mispelled words are 528 std::vector<S32> misspellLocations; // where all the mispelled words are
529 BOOL mOverRideAndShowMisspellings; 529 BOOL mShowMisspellings; // set in xui as "spell_check". Default value for a field
530 530
531 S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes 531 S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
532 532