]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfr1.C
Fix crash when entering unhandled math objects in toolbar
[lyx.git] / src / lyxfr1.C
index 1e4cee8ca241f558cff4906669f29ca915ba1323..ca5e9aa51a0469506b2a6b5fe5fe444fc38eea20 100644 (file)
 /* This file is part of
- * ======================================================
+ * ====================================================== 
  * 
  *           LyX, The Document Processor
  *      
  *           Copyright 1995 Matthias Ettrich,
- *           Copyright 1995-1999 The LyX Team.
+ *           Copyright 1995-2000 The LyX Team.
  *
- * ======================================================*/
+ * ====================================================== */
 
 #include <config.h>
 
-#include <cctype>
-#include <cstring>
-#include <cstdlib>
-
 #ifdef __GNUG__
 #pragma implementation
 #endif
 
-#include "LString.h"
-#include "lyx_main.h"
-#include FORMS_H_LOCATION
-#include "form1.h"
-#include "lyxfr0.h"
 #include "lyxfr1.h"
-#include "lyxfunc.h"
-#include "lyxscreen.h"
-#include "debug.h"
+
 #include "lyxtext.h"
-#include "gettext.h"
 #include "LyXView.h"
-#include "lyx_gui_misc.h"
 #include "minibuffer.h"
+#include "lyx_gui_misc.h"
+#include "support/textutils.h"
 #include "support/lstrings.h"
-
-extern BufferView *current_view; // called too many times in this file...
-extern MiniBuffer *minibuffer;
-
-// Maximum length copied from the current selection to the search string
-const int LYXSEARCH_MAXLEN =  128;
-
-// function prototypes
-
-bool IsLetterCharOrDigit(char ch);
-
-// If nothing selected, select the word at the cursor.
-// Returns the current selection
-// Note: this function should be in LyXText!
-string const GetSelectionOrWordAtCursor(LyXText *lt);
+#include "BufferView.h"
+#include "buffer.h"
 
 // Returns the current selection. If nothing is selected or if the selection
 // spans 2 paragraphs, an empty string is returned.
-string const GetCurrentSelectionAsString(LyXText *lt);
-
-// This is a copy of SetSelectionOverString from text.C
-// It does the same, but uses only the length as a parameter
-void SetSelectionOverLenChars(LyXText *lt, int len);
-
-//-------------------------------------------------------------
-
-bool IsLetterCharOrDigit(char ch)
-{
-       return IsLetterChar(ch) || isdigit(ch);
-}
-
-
-// Returns the current selection. If nothing is selected or if the selection
-// spans 2 paragraphs, an empty string is returned.
-string const GetCurrentSelectionAsString(LyXText * lt) 
+static
+string GetCurrentSelectionAsString(LyXText * lt) 
 {
-       char            sz[LYXSEARCH_MAXLEN];
-
-       sz[0] = 0;
-       LyXParagraph * par = lt->cursor.par;
-       if (lt->selection && (lt->sel_cursor.par == par)) {
+       string sz;
+       
+       LyXParagraph * par = lt->cursor.par();
+       if (lt->selection && lt->sel_cursor.par() == par) {
                // (selected) and (begin/end in same paragraph)
-#ifdef NEW_TEXT
-               LyXParagraph::size_type pos =
-                       lt->sel_start_cursor.pos;
-               LyXParagraph::size_type endpos =
-                       lt->sel_end_cursor.pos;
-#else
-               int pos =
-                       lt->sel_start_cursor.pos;
-               int endpos =
-                       lt->sel_end_cursor.pos;
-#endif
-               int i = 0;
+               LyXParagraph::size_type pos = 
+                       lt->sel_start_cursor.pos();
+               LyXParagraph::size_type endpos = 
+                       lt->sel_end_cursor.pos();
                bool fPrevIsSpace = false;
                char ch;
-               while ((i < LYXSEARCH_MAXLEN-2) && 
-                       (pos < par->Last()) && (pos < endpos)) {
+               while (pos < par->Last() && pos < endpos) {
                        ch = par->GetChar(pos);
-
+                       
                        //HB??: Maybe (ch <= ' ') 
-                       if ((ch == ' ') || (ch <= LYX_META_INSET)) {
+                       if ((ch == ' ') || (ch <= LyXParagraph::META_INSET)) {
                                // consecutive spaces --> 1 space char
                                if (fPrevIsSpace) {
-                                       pos++;          // Next text pos
+                                       ++pos;          // Next text pos
                                        continue;       // same search pos
                                }
-                               sz[i] = ' ';
+                               sz += ' ';
                                fPrevIsSpace = true;
                        } else {
-                               sz[i] = ch;
+                               sz += ch;
                                fPrevIsSpace = false;
                        }
-                       pos++;
-                       i++;
-               } 
-               sz[i] = 0;
+                       ++pos;
+               }
        }
-       return string(sz);
+       return sz;
 }
 
 
 // If nothing selected, select the word at the cursor.
 // Returns the current selection
-string const GetSelectionOrWordAtCursor(LyXText *lt) 
+static inline
+string GetSelectionOrWordAtCursor(BufferView * bv) 
 {
-       lt->SelectWordWhenUnderCursor();
-       return GetCurrentSelectionAsString(lt);
+       bv->text->SelectWordWhenUnderCursor(bv);
+       return GetCurrentSelectionAsString(bv->text);
 }
 
 
 // This is a copy of SetSelectionOverString from text.C
 // It does the same, but uses only the length as a parameter
-void SetSelectionOverLenChars(LyXText *lt, int len)
+static inline
+void SetSelectionOverLenChars(BufferView * bv, int len)
 {
-       lt->sel_cursor = lt->cursor;
-       int i;
-       for (i=0; i < len; i++)
-               lt->CursorRight();
-       lt->SetSelection();
+       bv->text->sel_cursor = bv->text->cursor;
+       for (int i = 0; i < len; ++i)
+               bv->text->CursorRight(bv);
+       bv->text->SetSelection();
 }
 
 
 //------------------------------
 
-void LyXFindReplace1::StartSearch()
+
+LyXFindReplace::LyXFindReplace()
+       : bv(0)
+{}
+
+
+LyXFindReplace::~LyXFindReplace()
+{}
+
+
+void LyXFindReplace::StartSearch(BufferView * b)
 {
-       LyXFindReplace0::StartSearch();
-       SetReplaceEnabled(!current_view->buffer()->isReadonly());
+       bv = b;
+       SF.StartSearch(this);
+       SF.replaceEnabled(!bv->buffer()->isReadonly());
        searchForward = true;
-       if (lsSearch.empty()) 
-               SetSearchString(GetSelectionOrWordAtCursor(current_view->buffer()->text));
+       if (SF.SearchString().empty()) 
+               SF.SetSearchString(GetSelectionOrWordAtCursor(bv));
 }      
 
 
-// TODO?: the user can insert multiple spaces with this routine (1999-01-11, dnaber)
-void LyXFindReplace1::SearchReplaceCB()
+// TODO?: the user can insert multiple spaces with this
+// routine (1999-01-11, dnaber)
+void LyXFindReplace::SearchReplaceCB()
 {
-       LyXText         *ltCur;
-
-       if (!current_view->getScreen())
-               return;
-       if (current_view->buffer()->isReadonly())
-               return;
+       if (!bv->available()) return;
+       if (bv->buffer()->isReadonly()) return;
        
        // CutSelection cannot cut a single space, so we have to stop
        // in order to avoid endless loop :-(
-       ReInitFromForm();
-       if (SearchString().length() == 0 || (SearchString().length() == 1
-                                            && SearchString()[0] == ' ') ) {
+       if (SF.SearchString().length() == 0
+           || (SF.SearchString().length() == 1
+               && SF.SearchString()[0] == ' ') ) {
                WriteAlert(_("Sorry!"), _("You cannot replace a single space, "
                                          "nor an empty character."));
                return;
        }
        
-       string const replacestring = ReplaceString();
+       string const replacestring = SF.ReplaceString();
 
-       current_view->getScreen()->HideCursor();
-       current_view->buffer()->update(-2);
+       bv->hideCursor();
+       bv->update(BufferView::SELECT|BufferView::FITCUR);
 
-       ltCur = current_view->buffer()->text;   
+       LyXText * ltCur = bv->text;     
        if (ltCur->selection) {
                // clear the selection (if there is any) 
-               current_view->getScreen()->ToggleSelection(false);
-               current_view->buffer()->text->
-                       ReplaceSelectionWithString(replacestring.c_str());
-               current_view->buffer()->text->
-                       SetSelectionOverString(replacestring.c_str());
-               current_view->buffer()->update(1);
+               bv->toggleSelection(false);
+               bv->text->
+                       ReplaceSelectionWithString(bv, replacestring);
+               bv->text->
+                       SetSelectionOverString(bv, replacestring);
+               bv->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
        }
        
        // jump to next match:
-       SearchCB( searchForward );
+       SearchCB(searchForward);
 }
 
 
 // replaces all occurences of a string (1999-01-15, dnaber@mini.gt.owl.de)
-void LyXFindReplace1::SearchReplaceAllCB()
+void LyXFindReplace::SearchReplaceAllCB()
 {
-       LyXText         *ltCur;
-
-       if (!current_view->getScreen())
-               return;
-       if (current_view->buffer()->isReadonly())
-               return;
+       if (!bv->available()) return;
+       if (bv->buffer()->isReadonly()) return;
 
        // CutSelection cannot cut a single space, so we have to stop
        // in order to avoid endless loop :-(
-       ReInitFromForm();
-       if (SearchString().length() == 0 || (SearchString().length() == 1
-                                            && SearchString()[0] == ' ') ) {
+       if (SF.SearchString().length() == 0
+           || (SF.SearchString().length() == 1
+               && SF.SearchString()[0] == ' ') ) {
                WriteAlert(_("Sorry!"), _("You cannot replace a single space, "
                                          "nor an empty character."));
-               return;
-       }
+               return;
+       }
 
-       string const replacestring = ReplaceString();
+       string const replacestring = SF.ReplaceString();
 
-       current_view->getScreen()->HideCursor();
+       bv->hideCursor();
 
        // start at top
-       current_view->buffer()->text->ClearSelection();
-       current_view->buffer()->text->CursorTop();
+       bv->text->ClearSelection();
+       bv->text->CursorTop(bv);
 
        int replace_count = 0;
+       LyXText * ltCur;
        do {
-               ltCur = current_view->buffer()->text;   
+               ltCur = bv->text;       
                if (ltCur->selection) {
-                       current_view->buffer()->update(-2);
-                       current_view->getScreen()->ToggleSelection(false);
-                       current_view->buffer()->text->
-                               ReplaceSelectionWithString(replacestring.c_str());
-                       current_view->buffer()->text->
-                               SetSelectionOverString(replacestring.c_str());
-                       current_view->buffer()->update(1); 
-                       replace_count++;
+                       bv->update(BufferView::SELECT|BufferView::FITCUR);
+                       bv->toggleSelection(false);
+                       bv->text->
+                               ReplaceSelectionWithString(bv, replacestring);
+                       bv->text->
+                               SetSelectionOverString(bv, replacestring);
+                       bv->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); 
+                       ++replace_count;
                }
-       } while( SearchCB(true) );
-
+       } while (SearchCB(true));
        if( replace_count == 0 ) {
                LyXBell();      
-               minibuffer->Set(_("String not found!"));
+               bv->owner()->getMiniBuffer()->Set(
+                       _("String not found!"));
        } else {
-               if( replace_count == 1 ) {
-                       minibuffer->Set(_("1 string has been replaced."));
+               if (replace_count == 1) {
+                       bv->owner()->getMiniBuffer()->Set(
+                               _("1 string has been replaced."));
                } else {
                        string str = tostr(replace_count);
                        str += _(" strings have been replaced.");
-                       minibuffer->Set(str);
+                       bv->owner()->getMiniBuffer()->Set(str);
                }
        }
 }
 
 
-bool LyXFindReplace1::SearchCB(bool fForward)
+bool LyXFindReplace::SearchCB(bool fForward)
 {
-       LyXText         *ltCur;
-       bool result;
-
        // store search direction
        searchForward = fForward;
        
-       if (!current_view->getScreen())
-               return(false);
+       if (!bv->available())
+               return false;
    
-       current_view->getScreen()->HideCursor();
-       current_view->buffer()->update(-2);
-       ltCur = current_view->buffer()->text;
+       bv->hideCursor();
+       bv->update(BufferView::SELECT|BufferView::FITCUR);
+       LyXText * ltCur = bv->text;
        if (ltCur->selection) 
                ltCur->cursor = fForward ? ltCur->sel_end_cursor :
-                                                 ltCur->sel_start_cursor;
+               ltCur->sel_start_cursor;
 
-       ReInitFromForm();
-       iLenSelected = SearchString().length();
+       iLenSelected = SF.SearchString().length();
+       bool result;
    
-       if (!ValidSearchData() ||
-           (fForward ? SearchForward(ltCur) : SearchBackward(ltCur))) {
-               current_view->buffer()->update(-2);
+       if (!SF.ValidSearchData() ||
+           (fForward ? SearchForward(bv):SearchBackward(bv))) {
+               bv->update(BufferView::SELECT|BufferView::FITCUR);
 
                // clear the selection (if there is any) 
-               current_view->getScreen()->ToggleSelection();
-               current_view->buffer()->text->ClearSelection();
+               bv->toggleSelection();
+               bv->text->ClearSelection();
 
                // set the new selection 
-               SetSelectionOverLenChars(current_view->buffer()->text, iLenSelected);
-               current_view->getScreen()->ToggleSelection(false);
-               minibuffer->Set(_("Found."));
+               SetSelectionOverLenChars(bv, iLenSelected);
+               bv->toggleSelection(false);
+               bv->owner()->getMiniBuffer()->Set(_("Found."));
                result = true;
        } else {
                LyXBell();
-               minibuffer->Set(_("String not found!"));
+               bv->owner()->getMiniBuffer()->Set(_("String not found!"));
                result = false;
        }
-   
-       if (current_view->getWorkArea()->focus)
-               current_view->getScreen()->ShowCursor();
 
-       return(result);
+       if (bv->focus())
+               bv->showCursor();
+
+       return result;
 }
 
 
 // if the string can be found: return true and set the cursor to
 // the new position 
 // (was: LyXText::SearchForward(char const* string) in text2.C )
-bool LyXFindReplace1::SearchForward(LyXText * lt)
+bool LyXFindReplace::SearchForward(BufferView * bv)
 {
-       LyXParagraph * par = lt->cursor.par;
-#ifdef NEW_TEXT
-       LyXParagraph::size_type pos = lt->cursor.pos;
-#else
-       int pos = lt->cursor.pos;
-#endif
+       LyXParagraph * par = bv->text->cursor.par();
+       LyXParagraph::size_type pos = bv->text->cursor.pos();
 
-       while (par && !IsSearchStringInText(par,pos)) {
-               if (pos<par->Last()-1)
-                       pos++;
+       while (par && !IsSearchStringInText(par, pos)) {
+               if (pos < par->Last() - 1)
+                       ++pos;
                else {
                        pos = 0;
                        par = par->Next();
                }
        }
        if (par) {
-               lt->SetCursor(par,pos);
+               bv->text->SetCursor(bv, par, pos);
                return true;
        } else
                return false;
@@ -325,26 +274,26 @@ bool LyXFindReplace1::SearchForward(LyXText * lt)
 // if the string can be found: return true and set the cursor to
 // the new position 
 // (was: LyXText::SearchBackward(char const* string) in text2.C )
-bool LyXFindReplace1::SearchBackward(LyXText *lt)
+bool LyXFindReplace::SearchBackward(BufferView * bv)
 {
-       LyXParagraph *par = lt->cursor.par;
-       int pos = lt->cursor.pos;
+       LyXParagraph * par = bv->text->cursor.par();
+       int pos = bv->text->cursor.pos();
 
        do {
-               if (pos>0)
-                       pos--;
+               if (pos > 0)
+                       --pos;
                else {
                        // We skip empty paragraphs (Asger)
                        do {
                                par = par->Previous();
                                if (par)
-                                       pos = par->Last()-1;
-                       } while (par && pos<0);
+                                       pos = par->Last() - 1;
+                       } while (par && pos < 0);
                }
-       } while (par && !IsSearchStringInText(par,pos));
+       } while (par && !IsSearchStringInText(par, pos));
   
        if (par) {
-               lt->SetCursor(par,pos);
+               bv->text->SetCursor(bv, par, pos);
                return true;
        } else
                return false;
@@ -357,9 +306,9 @@ return value is
     = 0 if chSearch == ch2
     < 0 if chSearch < ch2
 */
-int LyXFindReplace1::CompareChars(char chSearch, char chText)
+int LyXFindReplace::CompareChars(char chSearch, char chText) const
 {
-       if (CaseSensitive())
+       if (SF.CaseSensitive())
                return (chSearch - chText);
        return (toupper(chSearch) - toupper(chText));
 }
@@ -367,30 +316,23 @@ int LyXFindReplace1::CompareChars(char chSearch, char chText)
 
 // returns true if the search string is at the specified position 
 // (Copied from the original "LyXText::IsStringInText" in text2.C )
-#ifdef NEW_TEXT
-bool LyXFindReplace1::IsSearchStringInText(LyXParagraph * par,
-                                          LyXParagraph::size_type pos)
-#else
-bool LyXFindReplace1::IsSearchStringInText(LyXParagraph * par,
-                                          int pos)
-#endif
+bool LyXFindReplace::IsSearchStringInText(LyXParagraph * par,
+                                         LyXParagraph::size_type pos) const
 {
-       char            chSrch = 0;
-       char            chText;
-
-       if (!par) 
-               return false;
+       if (!par) return false;
 
+       char chSrch = 0;
+       char chText;
        bool fPrevIsSpace = false;
        int iText = 0;
        string::size_type iSrch = 0;
        while (pos + iText < par->Last() && 
-              iSrch < SearchString().length()) {
-               chSrch = SearchString()[iSrch];
+              iSrch < SF.SearchString().length()) {
+               chSrch = SF.SearchString()[iSrch];
                chText = par->GetChar(pos+iText);
                if (chText == ' ') {
                        if (fPrevIsSpace) {
-                               iText++;  // next Text pos
+                               ++iText;  // next Text pos
                                continue; // same search pos
                        }
                        fPrevIsSpace = true;
@@ -403,11 +345,11 @@ bool LyXFindReplace1::IsSearchStringInText(LyXParagraph * par,
                ++iText;
        }
 
-       if (iSrch < SearchString().length())
+       if (iSrch < SF.SearchString().length())
                return false;
 
-       if (!MatchWord() 
-           || ((pos <= 0 || !IsLetterCharOrDigit(par->GetChar(pos-1)))
+       if (!SF.MatchWord() 
+           || ((pos <= 0 || !IsLetterCharOrDigit(par->GetChar(pos - 1)))
                && (pos + iText >= par->Last() 
                    || !IsLetterCharOrDigit(par->GetChar(pos + iText))))) {
                iLenSelected = iText;