home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / lyxfr1.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  8KB  |  325 lines

  1. /* This file is part of
  2. * ======================================================
  3. *           LyX, The Document Processor
  4. *      
  5. *        Copyright (C) 1995 Matthias Ettrich,
  6. *           Copyright (C) 1995-1998 The LyX Team.
  7. *
  8. *======================================================*/
  9.  
  10. #include <config.h>
  11.  
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15.  
  16. #ifdef __GNUG__
  17. #pragma implementation
  18. #endif
  19.  
  20. #include "LString.h"
  21. #include "lyx_main.h"
  22. #include FORMS_H_LOCATION
  23. #include "form1.h"
  24. #include "lyxfr0.h"
  25. #include "lyxfr1.h"
  26. #include "lyxfunc.h"
  27. #include "lyxscreen.h"
  28. #include "error.h"
  29. #include "lyxtext.h"
  30. #include "gettext.h"
  31. #include "LyXView.h"
  32. #include "lyx_gui_misc.h"
  33.  
  34. extern BufferView *current_view; // called too many times in this file...
  35.  
  36. // Maximum length copied from the current selection to the search string
  37. const int LYXSEARCH_MAXLEN =  128;
  38.  
  39. // function prototypes
  40.  
  41. bool IsLetterCharOrDigit(char ch);
  42.  
  43. // If nothing selected, select the word at the cursor.
  44. // Returns the current selection
  45. // Note: this function should be in LyXText!
  46. LString const GetSelectionOrWordAtCursor(LyXText *lt);
  47.  
  48. // Returns the current selection. If nothing is selected or if the selection
  49. // spans 2 paragraphs, an empty string is returned.
  50. LString const GetCurrentSelectionAsString(LyXText *lt);
  51.  
  52. // This is a copy of SetSelectionOverString from text.C
  53. // It does the same, but uses only the length as a parameter
  54. void SetSelectionOverLenChars(LyXText *lt, int len);
  55.  
  56. //-------------------------------------------------------------
  57.  
  58. bool IsLetterCharOrDigit(char ch)
  59. {
  60.     return IsLetterChar(ch) || isdigit(ch);
  61. }
  62.  
  63.  
  64. // Returns the current selection. If nothing is selected or if the selection
  65. // spans 2 paragraphs, an empty string is returned.
  66. LString const GetCurrentSelectionAsString(LyXText *lt) 
  67. {
  68.     LyXParagraph     *par;
  69.     int         pos;
  70.     int        endpos;
  71.     int        i;
  72.     char        sz[LYXSEARCH_MAXLEN];
  73.     char        ch;
  74.     bool        fPrevIsSpace;
  75.  
  76.     sz[0] = 0;
  77.     par = lt->cursor.par;
  78.     if (lt->selection && (lt->sel_cursor.par == par)) {
  79.         // (selected) and (begin/end in same paragraph)
  80.         pos = lt->sel_start_cursor.pos;
  81.         endpos = lt->sel_end_cursor.pos;
  82.         i = 0;
  83.         fPrevIsSpace = false;
  84.         while ((i < LYXSEARCH_MAXLEN-2) && 
  85.             (pos < par->Last()) && (pos < endpos)) {
  86.             ch = par->GetChar(pos);
  87.  
  88.             //HB??: Maybe (ch <= ' ') 
  89.             if ((ch == ' ') || ((unsigned char)ch <= LYX_META_INSET)) {
  90.                 // consecutive spaces --> 1 space char
  91.                 if (fPrevIsSpace) {
  92.                     pos++;        // Next text pos
  93.                     continue;    // same search pos
  94.                 }
  95.                 sz[i] = ' ';
  96.                 fPrevIsSpace = true;
  97.             } else {
  98.                 sz[i] = ch;
  99.                 fPrevIsSpace = false;
  100.             }
  101.             pos++;
  102.             i++;
  103.         } 
  104.         sz[i] = 0;
  105.     }
  106.     return LString(sz);
  107. }
  108.  
  109.  
  110. // If nothing selected, select the word at the cursor.
  111. // Returns the current selection
  112. LString const GetSelectionOrWordAtCursor(LyXText *lt) 
  113. {
  114.     lt->SelectWordWhenUnderCursor();
  115.     return GetCurrentSelectionAsString(lt);
  116. }
  117.  
  118.  
  119. // This is a copy of SetSelectionOverString from text.C
  120. // It does the same, but uses only the length as a parameter
  121. void SetSelectionOverLenChars(LyXText *lt, int len)
  122. {
  123.     lt->sel_cursor = lt->cursor;
  124.     int i;
  125.     for (i=0; i < len; i++)
  126.         lt->CursorRight();
  127.     lt->SetSelection();
  128. }
  129.  
  130.  
  131. //------------------------------
  132.  
  133. void LyXFindReplace1::StartSearch()
  134. {
  135.     LyXFindReplace0::StartSearch();
  136.     SetReplaceEnabled(!current_view->currentBuffer()->isReadonly());
  137.  
  138.     if (lsSearch.empty()) 
  139.         SetSearchString(GetSelectionOrWordAtCursor(current_view->currentBuffer()->text));
  140. }    
  141.  
  142.  
  143. void LyXFindReplace1::SearchReplaceCB()
  144. {
  145.     if (!current_view->getScreen())
  146.         return;
  147.     if (current_view->currentBuffer()->isReadonly())
  148.             return;
  149.     if (!current_view->currentBuffer()->text->selection) {
  150.         LyXBell();
  151.         return;
  152.     }
  153.     LString const replacestring = ReplaceString();
  154.  
  155.     current_view->getScreen()->HideCursor();
  156.     current_view->currentBuffer()->update(-2);
  157.  
  158.     // clear the selection (if there is any) 
  159.     current_view->getScreen()->ToggleSelection(false);
  160.     current_view->currentBuffer()->text->
  161.         ReplaceSelectionWithString(replacestring.c_str());
  162.     current_view->currentBuffer()->text->
  163.         SetSelectionOverString(replacestring.c_str());
  164.     current_view->currentBuffer()->update(1); 
  165. }
  166.  
  167.  
  168. void LyXFindReplace1::SearchCB(bool fForward)
  169. {
  170.     LyXText        *ltCur;
  171.  
  172.     if (!current_view->getScreen())
  173.         return;
  174.    
  175.     current_view->getScreen()->HideCursor();
  176.     current_view->currentBuffer()->update(-2);
  177.     ltCur = current_view->currentBuffer()->text;
  178.     if (ltCur->selection) 
  179.         ltCur->cursor = fForward ? ltCur->sel_end_cursor :
  180.                                                  ltCur->sel_start_cursor;
  181.  
  182.     ReInitFromForm();
  183.     iLenSelected = SearchString().length();
  184.    
  185.     if (!ValidSearchData() ||
  186.         (fForward ? SearchForward(ltCur) : SearchBackward(ltCur))) {
  187.         current_view->currentBuffer()->update(-2);
  188.  
  189.         // clear the selection (if there is any) 
  190.         current_view->getScreen()->ToggleSelection();
  191.         current_view->currentBuffer()->text->ClearSelection();
  192.  
  193.         // set the new selection 
  194.         SetSelectionOverLenChars(current_view->currentBuffer()->text, iLenSelected);
  195.         current_view->getScreen()->ToggleSelection(false);
  196.     } else 
  197.         LyXBell();    
  198.    
  199.     if (current_view->getWorkArea()->focus)
  200.         current_view->getScreen()->ShowCursor();
  201. }
  202.  
  203.  
  204. // if the string can be found: return true and set the cursor to
  205. // the new position 
  206. // (was: LyXText::SearchForward(char const* string) in text2.C )
  207. bool LyXFindReplace1::SearchForward(LyXText *lt)
  208. {
  209.     LyXParagraph *par;
  210.     int pos;
  211.  
  212.     par = lt->cursor.par;
  213.     pos = lt->cursor.pos;
  214.  
  215.     while (par && !IsSearchStringInText(par,pos)) {
  216.         if (pos<par->Last()-1)
  217.             pos++;
  218.         else {
  219.             pos = 0;
  220.             par = par->Next();
  221.         }
  222.     }
  223.     if (par) {
  224.         lt->SetCursor(par,pos);
  225.         return true;
  226.     } else
  227.         return false;
  228. }
  229.  
  230.  
  231. // if the string can be found: return true and set the cursor to
  232. // the new position 
  233. // (was: LyXText::SearchBackward(char const* string) in text2.C )
  234. bool LyXFindReplace1::SearchBackward(LyXText *lt)
  235. {
  236.     LyXParagraph *par = lt->cursor.par;
  237.     int pos = lt->cursor.pos;
  238.  
  239.     do {
  240.         if (pos>0)
  241.             pos--;
  242.         else {
  243.             // We skip empty paragraphs (Asger)
  244.             do {
  245.                 par = par->Previous();
  246.                 if (par)
  247.                     pos = par->Last()-1;
  248.             } while (par && pos<0);
  249.         }
  250.     } while (par && !IsSearchStringInText(par,pos));
  251.   
  252.     if (par) {
  253.         lt->SetCursor(par,pos);
  254.         return true;
  255.     } else
  256.         return false;
  257. }
  258.  
  259.  
  260. /* Compares 2 char values. 
  261. return value is
  262.     > 0 if chSearch > ch2
  263.     = 0 if chSearch == ch2
  264.     < 0 if chSearch < ch2
  265. */
  266. int LyXFindReplace1::CompareChars(char chSearch, char chText)
  267. {
  268.     if (CaseSensitive())
  269.         return (chSearch - chText);
  270.     return (toupper((unsigned char) chSearch) - toupper((unsigned char) chText));
  271. }
  272.  
  273.  
  274. // returns true if the search string is at the specified position 
  275. // (Copied from the original "LyXText::IsStringInText" in text2.C )
  276. bool LyXFindReplace1::IsSearchStringInText(LyXParagraph *par, int pos)
  277. {
  278.     const char    *szSearch;
  279.     char        chSrch = 0;
  280.     char        chText;
  281.     bool        fPrevIsSpace;
  282.     int        iText;
  283.     int         iSrch;
  284.  
  285.     szSearch = SearchString().c_str();
  286.  
  287.     if (par) {
  288.         fPrevIsSpace = false;
  289.         iText = 0; iSrch = 0;
  290.         while (pos+iText < par->Last() && 
  291.                        (chSrch = szSearch[iSrch]) != 0) {
  292.             chText = par->GetChar(pos+iText);
  293.             if ((chText == ' ') || 
  294.                             ((unsigned char)chText <= LYX_META_INSET)) 
  295.             {
  296.                 if (fPrevIsSpace) {
  297.                     iText++;  // next Text pos
  298.                     continue; // same search pos
  299.                 }
  300.                 chText = ' ';                
  301.                 fPrevIsSpace = true;
  302.             } else
  303.                 fPrevIsSpace = false;
  304.             if (CompareChars(chSrch, chText) != 0)
  305.                 break;
  306.         
  307.             iSrch++;
  308.             iText++;
  309.         }
  310.  
  311.         if (!szSearch[iSrch]) {
  312.             if ((!MatchWord()) ||
  313.                 (((pos <= 0) || (!IsLetterCharOrDigit(par->GetChar(pos-1)))) &&
  314.                  ((pos+iText >= par->Last()) || 
  315.                   (!IsLetterCharOrDigit(par->GetChar(pos + iText))))))
  316.             {
  317.                 iLenSelected = iText;
  318.                 return true;
  319.             }
  320.         }
  321.     }
  322.     return false;
  323. }
  324.