]> git.lyx.org Git - lyx.git/blob - src/BufferView2.C
some small stuff before the meeting begins for real
[lyx.git] / src / BufferView2.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *        
7  *           Copyright 1995 Matthias Ettrich
8  *           Copyright 1995-2000 The LyX Team.
9  *
10  * ====================================================== */
11
12 #include <config.h>
13
14 #include <fstream>
15 #include <algorithm>
16
17 #include "BufferView.h"
18 #include "buffer.h"
19 #include "lyxcursor.h"
20 #include "lyxtext.h"
21 #include "insets/inseterror.h"
22 #include "insets/insetinfo.h"
23 #include "insets/insetspecialchar.h"
24 #include "LyXView.h"
25 #include "minibuffer.h"
26 #include "bufferlist.h"
27 #include "support/FileInfo.h"
28 #include "lyxscreen.h"
29 #include "support/filetools.h"
30 #include "lyx_gui_misc.h"
31 #include "LaTeX.h"
32 #include "BufferView_pimpl.h"
33 #include "insets/insetcommand.h" //ChangeRefs
34
35 extern BufferList bufferlist;
36
37 using std::pair;
38 using std::endl;
39 using std::ifstream;
40 using std::vector;
41 using std::find;
42
43 // Inserts a file into current document
44 bool BufferView::insertLyXFile(string const & filen)
45         //
46         // Copyright CHT Software Service GmbH
47         // Uwe C. Schroeder
48         //
49         // Insert a Lyxformat - file into current buffer
50         //
51         // Moved from lyx_cb.C (Lgb)
52 {
53         if (filen.empty()) return false;
54
55         string fname = MakeAbsPath(filen);
56
57         // check if file exist
58         FileInfo fi(fname);
59
60         if (!fi.readable()) {
61                 WriteAlert(_("Error!"),
62                            _("Specified file is unreadable: "),
63                            MakeDisplayPath(fname, 50));
64                 return false;
65         }
66         
67         beforeChange();
68
69         ifstream ifs(fname.c_str());
70         if (!ifs) {
71                 WriteAlert(_("Error!"),
72                            _("Cannot open specified file: "),
73                            MakeDisplayPath(fname, 50));
74                 return false;
75         }
76         LyXLex lex(0, 0);
77         lex.setStream(ifs);
78         char c; ifs.get(c);
79         ifs.putback(c);
80
81         bool res = true;
82
83         if (c == '#') {
84                 lyxerr.debug() << "Will insert file with header" << endl;
85                 res = buffer()->readFile(lex, text->cursor.par());
86         } else {
87                 lyxerr.debug() << "Will insert file without header" << endl;
88                 res = buffer()->readLyXformat2(lex, text->cursor.par());
89         }
90
91         resize();
92         return res;
93 }
94
95 bool BufferView::removeAutoInsets()
96 {
97         LyXParagraph * par = buffer()->paragraph;
98
99         LyXCursor tmpcursor = text->cursor;
100         LyXCursor cursor;
101
102         bool a = false;
103         while (par) {
104                 // this has to be done before the delete
105                 if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
106                         text->SetCursor(cursor, par, 0);
107                 if (par->AutoDeleteInsets()){
108                         a = true;
109                         if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
110                                 text->RedoParagraphs(cursor,
111                                                      cursor.par()->Next());
112                                 text->FullRebreak();
113                         }
114                 }
115                 par = par->next;
116         }
117         // avoid forbidden cursor positions caused by error removing
118         if (tmpcursor.pos() > tmpcursor.par()->Last())
119                 tmpcursor.pos(tmpcursor.par()->Last());
120         text->SetCursorIntern(tmpcursor.par(), tmpcursor.pos());
121
122         return a;
123 }
124
125
126 void BufferView::insertErrors(TeXErrors & terr)
127 {
128         // Save the cursor position
129         LyXCursor cursor = text->cursor;
130
131         // This is drastic, but it's the only fix, I could find. (Asger)
132         allFloats(1, 0);
133         allFloats(1, 1);
134
135         for (TeXErrors::Errors::const_iterator cit = terr.begin();
136              cit != terr.end();
137              ++cit) {
138                 string desctext((*cit).error_desc);
139                 string errortext((*cit).error_text);
140                 string msgtxt = desctext + '\n' + errortext;
141                 int errorrow = (*cit).error_in_line;
142
143                 // Insert error string for row number
144                 int tmpid = -1; 
145                 int tmppos = -1;
146
147                 buffer()->texrow.getIdFromRow(errorrow, tmpid, tmppos);
148
149                 LyXParagraph * texrowpar = 0;
150
151                 if (tmpid == -1) {
152                         texrowpar = text->FirstParagraph();
153                         tmppos = 0;
154                 } else {
155                         texrowpar = text->GetParFromID(tmpid);
156                 }
157
158                 if (texrowpar == 0)
159                         continue;
160
161                 InsetError * new_inset = new InsetError(msgtxt);
162                 text->SetCursorIntern(texrowpar, tmppos);
163                 text->InsertInset(new_inset);
164                 text->FullRebreak();
165         }
166         // Restore the cursor position
167         text->SetCursorIntern(cursor.par(), cursor.pos());
168 }
169
170
171 void BufferView::setCursorFromRow(int row)
172 {
173         int tmpid = -1; 
174         int tmppos = -1;
175
176         buffer()->texrow.getIdFromRow(row, tmpid, tmppos);
177
178         LyXParagraph * texrowpar;
179
180         if (tmpid == -1) {
181                 texrowpar = text->FirstParagraph();
182                 tmppos = 0;
183         } else {
184                 texrowpar = text->GetParFromID(tmpid);
185         }
186         text->SetCursor(texrowpar, tmppos);
187 }
188
189 bool BufferView::insertInset(Inset * inset, string const & lout,
190                          bool no_table)
191 {
192         // if we are in a locking inset we should try to insert the
193         // inset there otherwise this is a illegal function now
194         if (the_locking_inset) {
195                 if (the_locking_inset->InsertInsetAllowed(inset) &&
196                     the_locking_inset->InsertInset(this, inset))
197                         return true;
198                 return false;
199         }
200
201 #ifndef NEW_TABULAR
202         // check for table/list in tables
203         if (no_table && text->cursor.par()->table){
204                 WriteAlert(_("Impossible Operation!"),
205                            _("Cannot insert table/list in table."),
206                            _("Sorry."));
207                 return false;
208         }
209 #endif
210
211         // not quite sure if we want this...
212         text->SetCursorParUndo();
213         text->FreezeUndo();
214         
215         beforeChange();
216         if (!lout.empty()) {
217                 update(-2);
218                 text->BreakParagraph();
219                 update(-1);
220                 
221                 if (text->cursor.par()->Last()) {
222                         text->CursorLeft();
223                         
224                         text->BreakParagraph();
225                         update(-1);
226                 }
227
228                 pair<bool, LyXTextClass::size_type> lres =
229                         textclasslist.NumberOfLayout(buffer()->params
230                                                      .textclass, lout);
231                 LyXTextClass::size_type lay;
232                 if (lres.first != false) {
233                         // layout found
234                         lay = lres.second;
235                 } else {
236                         // layout not fount using default "Standard" (0)
237                         lay = 0;
238                 }
239                  
240                 text->SetLayout(lay);
241                 
242                 text->SetParagraph(0, 0,
243                                    0, 0,
244                                    VSpace(VSpace::NONE), VSpace(VSpace::NONE),
245                                    LYX_ALIGN_LAYOUT, 
246                                    string(),
247                                    0);
248                 update(-1);
249                 
250                 text->current_font.setLatex(LyXFont::OFF);
251         }
252         
253         text->InsertInset(inset);
254 #if 1
255         // if we enter a text-inset the cursor should be to the left side
256         // of it! This couldn't happen before as Undo was not handled inside
257         // inset now after the Undo LyX tries to call inset->Edit(...) again
258         // and cannot do this as the cursor is behind the inset and GetInset
259         // does not return the inset!
260         if (inset->IsTextInset()) {
261                 if (text->cursor.par()->isRightToLeftPar(buffer()->params))
262                         text->CursorRight();
263                 else
264                         text->CursorLeft();
265         }
266 #endif
267         update(-1);
268
269         text->UnFreezeUndo();
270         return true;
271 }
272
273
274 // Open and lock an updatable inset
275 void BufferView::open_new_inset(UpdatableInset * new_inset)
276 {
277         beforeChange();
278         text->FinishUndo();
279         insertInset(new_inset);
280         text->CursorLeft();
281         update(1);
282         new_inset->Edit(this, 0, 0, 0);
283 }
284
285 /* This is also a buffer property (ale) */
286 // Not so sure about that. a goto Label function can not be buffer local, just
287 // think how this will work in a multiwindo/buffer environment, all the
288 // cursors in all the views showing this buffer will move. (Lgb)
289 // OK, then no cursor action should be allowed in buffer. (ale)
290 bool BufferView::gotoLabel(string const & label)
291
292 {
293         for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
294              it != buffer()->inset_iterator_end(); ++it) {
295                 vector<string> labels = (*it)->getLabelList();
296                 if ( find(labels.begin(),labels.end(),label)
297                      != labels.end()) {
298                         beforeChange();
299                         text->SetCursor(it.getPar(), it.getPos());
300                         text->sel_cursor = text->cursor;
301                         update(0);
302                         return true;
303                 }
304         }
305         return false;
306 }
307
308 void BufferView::allFloats(char flag, char figmar)
309 {
310         if (!available()) return;
311
312         LyXCursor cursor = text->cursor;
313
314         if (!flag && cursor.par()->footnoteflag != LyXParagraph::NO_FOOTNOTE
315             && ((figmar 
316                  && cursor.par()->footnotekind != LyXParagraph::FOOTNOTE 
317                  && cursor.par()->footnotekind != LyXParagraph::MARGIN)
318                 || (!figmar
319                     && cursor.par()->footnotekind != LyXParagraph::FIG 
320                     && cursor.par()->footnotekind != LyXParagraph::TAB
321                     && cursor.par()->footnotekind != LyXParagraph::WIDE_FIG 
322                     && cursor.par()->footnotekind != LyXParagraph::WIDE_TAB
323                     && cursor.par()->footnotekind != LyXParagraph::ALGORITHM)))
324                 toggleFloat();
325         else
326                 beforeChange();
327
328         LyXCursor tmpcursor = cursor;
329         cursor.par(tmpcursor.par()->ParFromPos(tmpcursor.pos()));
330         cursor.pos(tmpcursor.par()->PositionInParFromPos(tmpcursor.pos()));
331
332         LyXParagraph *par = buffer()->paragraph;
333         while (par) {
334                 if (flag) {
335                         if (par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
336                             && ((figmar 
337                                  && par->footnotekind != LyXParagraph::FOOTNOTE 
338                                  && par->footnotekind !=  LyXParagraph::MARGIN)
339                                 || (!figmar
340                                     && par->footnotekind != LyXParagraph::FIG 
341                                     && par->footnotekind != LyXParagraph::TAB
342                                     && par->footnotekind != LyXParagraph::WIDE_FIG 
343                                     && par->footnotekind != LyXParagraph::WIDE_TAB
344                                     && par->footnotekind != LyXParagraph::ALGORITHM
345                                         )
346                                     )
347                                 ) {
348                                 if (par->previous
349                                     && par->previous->footnoteflag != 
350                                     LyXParagraph::CLOSED_FOOTNOTE){ /* should be */ 
351                                         text->SetCursorIntern(par->previous,
352                                                               0);
353                                         text->OpenFootnote();
354                                 }
355                         }
356                 } else {
357                         if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
358                             && (
359                                     (figmar 
360                                      &&
361                                      par->footnotekind != LyXParagraph::FOOTNOTE 
362                                      &&
363                                      par->footnotekind !=  LyXParagraph::MARGIN
364                                             )
365                                     ||
366                                     (!figmar
367                                      &&
368                                      par->footnotekind != LyXParagraph::FIG 
369                                      &&
370                                      par->footnotekind != LyXParagraph::TAB
371                                      &&
372                                      par->footnotekind != LyXParagraph::WIDE_FIG 
373                                      &&
374                                      par->footnotekind != LyXParagraph::WIDE_TAB
375                                      &&
376                                      par->footnotekind != LyXParagraph::ALGORITHM
377                                             )
378                                     )
379                                 ) {
380                                 text->SetCursorIntern(par, 0);
381                                 text->CloseFootnote();
382                         }
383                 }
384                 par = par->next;
385         }
386
387         text->SetCursorIntern(cursor.par(), cursor.pos());
388         redraw();
389         fitCursor();
390         //updateScrollbar();
391 }
392
393
394 void BufferView::insertNote()
395 {
396         InsetInfo * new_inset = new InsetInfo();
397         insertInset(new_inset);
398         new_inset->Edit(this, 0, 0, 0);
399 }
400
401
402 void BufferView::openStuff()
403 {
404         if (available()) {
405                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
406                 hideCursor();
407                 beforeChange();
408                 update(-2);
409                 text->OpenStuff();
410                 update(0);
411                 setState();
412         }
413 }
414
415
416 void BufferView::toggleFloat()
417 {
418         if (available()) {
419                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
420                 hideCursor();
421                 beforeChange();
422                 update(-2);
423                 text->ToggleFootnote();
424                 update(0);
425                 setState();
426         }
427 }
428
429 void BufferView::menuUndo()
430 {
431         if (available()) {
432                 owner()->getMiniBuffer()->Set(_("Undo"));
433                 hideCursor();
434                 beforeChange();
435                 update(-2);
436                 if (!text->TextUndo())
437                         owner()->getMiniBuffer()->Set(_("No further undo information"));
438                 else
439                         update(-1);
440                 setState();
441         }
442 }
443
444
445 void BufferView::menuRedo()
446 {
447         if (the_locking_inset) {
448                 owner()->getMiniBuffer()->Set(_("Redo not yet supported in math mode"));
449                 return;
450         }    
451    
452         if (available()) {
453                 owner()->getMiniBuffer()->Set(_("Redo"));
454                 hideCursor();
455                 beforeChange();
456                 update(-2);
457                 if (!text->TextRedo())
458                         owner()->getMiniBuffer()->Set(_("No further redo information"));
459                 else
460                         update(-1);
461                 setState();
462         }
463 }
464
465
466 void BufferView::hyphenationPoint()
467 {
468         if (available()) {
469                 hideCursor();
470                 update(-2);
471                 InsetSpecialChar * new_inset = 
472                         new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
473                 insertInset(new_inset);
474         }
475 }
476
477
478 void BufferView::ldots()
479 {
480         if (available())  {
481                 hideCursor();
482                 update(-2);
483                 InsetSpecialChar * new_inset = 
484                         new InsetSpecialChar(InsetSpecialChar::LDOTS);
485                 insertInset(new_inset);
486         }
487 }
488
489
490 void BufferView::endOfSentenceDot()
491 {
492         if (available()) {
493                 hideCursor();
494                 update(-2);
495                 InsetSpecialChar * new_inset = 
496                         new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
497                 insertInset(new_inset);
498         }
499 }
500
501
502 void BufferView::menuSeparator()
503 {
504         if (available()) {
505                 hideCursor();
506                 update(-2);
507                 InsetSpecialChar * new_inset = 
508                         new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
509                 insertInset(new_inset);
510         }
511 }
512
513
514 void BufferView::newline()
515 {
516         if (available()) {
517                 hideCursor();
518                 update(-2);
519                 text->InsertChar(LyXParagraph::META_NEWLINE);
520                 update(-1);
521         }
522 }
523
524
525 void BufferView::protectedBlank()
526 {
527         if (available()) {
528                 hideCursor();
529                 update(-2);
530                 InsetSpecialChar * new_inset =
531                         new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
532                 insertInset(new_inset);
533         }
534 }
535
536
537 void BufferView::hfill()
538 {
539         if (available()) {
540                 hideCursor();
541                 update(-2);
542                 text->InsertChar(LyXParagraph::META_HFILL);
543                 update(-1);
544         }
545 }
546
547 void BufferView::copyEnvironment()
548 {
549         if (available()) {
550                 text->copyEnvironmentType();
551                 // clear the selection, even if mark_set
552                 toggleSelection();
553                 text->ClearSelection();
554                 update(-2);
555                 owner()->getMiniBuffer()->Set(_("Paragraph environment type copied"));
556         }
557 }
558
559
560 void BufferView::pasteEnvironment()
561 {
562         if (available()) {
563                 text->pasteEnvironmentType();
564                 owner()->getMiniBuffer()->Set(_("Paragraph environment type set"));
565                 update(1);
566         }
567 }
568
569
570 void BufferView::copy()
571 {
572         if (available()) {
573                 text->CopySelection();
574                 // clear the selection, even if mark_set
575                 toggleSelection();
576                 text->ClearSelection();
577                 update(-2);
578                 owner()->getMiniBuffer()->Set(_("Copy"));
579         }
580 }
581
582 void BufferView::cut()
583 {
584         if (available()) {
585                 hideCursor();
586                 update(-2);
587                 text->CutSelection();
588                 update(1);
589                 owner()->getMiniBuffer()->Set(_("Cut"));
590         }
591 }
592
593
594 void BufferView::paste()
595 {
596         if (!available()) return;
597         
598         owner()->getMiniBuffer()->Set(_("Paste"));
599         hideCursor();
600         // clear the selection
601         toggleSelection();
602         text->ClearSelection();
603         update(-2);
604         
605         // paste
606         text->PasteSelection();
607         update(1);
608         
609         // clear the selection 
610         toggleSelection();
611         text->ClearSelection();
612         update(-2);
613 }
614
615
616 void BufferView::gotoNote()
617 {
618         if (!available()) return;
619    
620         hideCursor();
621         beforeChange();
622         update(-2);
623         LyXCursor tmp;
624    
625         if (!text->GotoNextNote()) {
626                 if (text->cursor.pos() 
627                     || text->cursor.par() != text->FirstParagraph()) {
628                                 tmp = text->cursor;
629                                 text->cursor.par(text->FirstParagraph());
630                                 text->cursor.pos(0);
631                                 if (!text->GotoNextNote()) {
632                                         text->cursor = tmp;
633                                         owner()->getMiniBuffer()->Set(_("No more notes"));
634                                         LyXBell();
635                                 }
636                         } else {
637                                 owner()->getMiniBuffer()->Set(_("No more notes"));
638                                 LyXBell();
639                         }
640         }
641         update(0);
642         text->sel_cursor = text->cursor;
643 }
644
645
646 void BufferView::insertCorrectQuote()
647 {
648         char c;
649
650         if (text->cursor.pos())
651                 c = text->cursor.par()->GetChar(text->cursor.pos() - 1);
652         else 
653                 c = ' ';
654
655         insertInset(new InsetQuotes(c, buffer()->params));
656 }
657
658
659 /* these functions are for the spellchecker */ 
660 char * BufferView::nextWord(float & value)
661 {
662         if (!available()) {
663                 value = 1;
664                 return 0;
665         }
666
667         char * string = text->SelectNextWord(value);
668
669         return string;
670 }
671
672   
673 void BufferView::selectLastWord()
674 {
675         if (!available()) return;
676    
677         hideCursor();
678         beforeChange();
679         text->SelectSelectedWord();
680         toggleSelection(false);
681         update(0);
682 }
683
684
685 void BufferView::endOfSpellCheck()
686 {
687         if (!available()) return;
688    
689         hideCursor();
690         beforeChange();
691         text->SelectSelectedWord();
692         text->ClearSelection();
693         update(0);
694 }
695
696
697 void BufferView::replaceWord(string const & replacestring)
698 {
699         if (!available()) return;
700
701         hideCursor();
702         update(-2);
703    
704         /* clear the selection (if there is any) */ 
705         toggleSelection(false);
706         update(-2);
707    
708         /* clear the selection (if there is any) */ 
709         toggleSelection(false);
710         text->ReplaceSelectionWithString(replacestring.c_str());
711    
712         text->SetSelectionOverString(replacestring.c_str());
713
714         // Go back so that replacement string is also spellchecked
715         for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
716                 text->CursorLeftIntern();
717         }
718         update(1);
719 }
720 // End of spellchecker stuff
721
722
723 bool BufferView::lockInset(UpdatableInset * inset)
724 {
725         if (!the_locking_inset && inset) {
726                 the_locking_inset = inset;
727                 return true;
728         } else if (inset) {
729             return the_locking_inset->LockInsetInInset(this, inset);
730         }
731         return false;
732 }
733
734
735 void BufferView::showLockedInsetCursor(long x, long y, int asc, int desc)
736 {
737         if (the_locking_inset && available()) {
738                 LyXCursor cursor = text->cursor;
739                 if ((cursor.pos() - 1 >= 0) &&
740                     (cursor.par()->GetChar(cursor.pos() - 1) ==
741                      LyXParagraph::META_INSET) &&
742                     (cursor.par()->GetInset(cursor.pos() - 1) ==
743                      the_locking_inset->GetLockingInset()))
744                         text->SetCursor(cursor,
745                                         cursor.par(), cursor.pos() - 1);
746                 y += cursor.y() + the_locking_inset->InsetInInsetY();
747                 pimpl_->screen->ShowManualCursor(x, y, asc, desc,
748                                          LyXScreen::BAR_SHAPE);
749         }
750 }
751
752
753 void BufferView::hideLockedInsetCursor()
754 {
755         if (the_locking_inset && available()) {
756                 pimpl_->screen->HideCursor();
757         }
758 }
759
760
761 void BufferView::fitLockedInsetCursor(long x, long y, int asc, int desc)
762 {
763         if (the_locking_inset && available()){
764                 y += text->cursor.y() + the_locking_inset->InsetInInsetY();
765                 if (pimpl_->screen->FitManualCursor(x, y, asc, desc))
766                         updateScrollbar();
767         }
768 }
769
770
771 int BufferView::unlockInset(UpdatableInset * inset)
772 {
773         if (inset && the_locking_inset == inset) {
774                 inset->InsetUnlock(this);
775                 the_locking_inset = 0;
776                 text->FinishUndo();
777                 return 0;
778         } else if (inset && the_locking_inset &&
779                    the_locking_inset->UnlockInsetInInset(this, inset)) {
780                 text->FinishUndo();
781                 return 0;
782         }
783         return bufferlist.unlockInset(inset);
784 }
785
786
787 void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind)
788 {
789         if (!the_locking_inset)
790                 return; // shouldn't happen
791         if (kind == Undo::EDIT) // in this case insets would not be stored!
792                 kind = Undo::FINISH;
793         text->SetUndo(kind,
794                       text->cursor.par()->
795                       ParFromPos(text->cursor.pos())->previous, 
796                       text->cursor.par()->
797                       ParFromPos(text->cursor.pos())->next);
798 }
799
800
801 void BufferView::updateInset(Inset * inset, bool mark_dirty)
802 {
803         if (!inset)
804                 return;
805
806         // first check for locking insets
807         if (the_locking_inset) {
808                 if (the_locking_inset == inset) {
809                         if (text->UpdateInset(inset)){
810                                 update();
811                                 if (mark_dirty){
812                                         if (buffer()->isLyxClean())
813                                                 owner()->getMiniBuffer()->
814                                                         setTimer(4);
815                                         buffer()->markDirty();
816                                 }
817                                 updateScrollbar();
818                                 return;
819                         }
820                 } else if (the_locking_inset->UpdateInsetInInset(this,inset)) {
821                         if (text->UpdateInset(the_locking_inset)) {
822                                 update();
823                                 if (mark_dirty){
824                                         if (buffer()->isLyxClean())
825                                                 owner()->getMiniBuffer()->
826                                                         setTimer(4);
827                                         buffer()->markDirty();
828                                 }
829                                 updateScrollbar();
830                                 return;
831                         }
832                 }
833         }
834   
835         // then check the current buffer
836         if (available()) {
837                 hideCursor();
838                 update(-3);
839                 if (text->UpdateInset(inset)){
840                         if (mark_dirty)
841                                 update(1);
842                         else 
843                                 update(3);
844                         return;
845                 }
846         }
847 }
848
849 bool BufferView::ChangeRefs(string const & from, string const & to)
850 {
851         bool flag = false;
852         LyXParagraph * par = buffer()->paragraph;
853         LyXCursor cursor = text->cursor;
854         LyXCursor tmpcursor = cursor;
855         cursor.par(tmpcursor.par()->ParFromPos(tmpcursor.pos()));
856         cursor.pos(tmpcursor.par()->PositionInParFromPos(tmpcursor.pos()));
857
858         while (par) {
859                 bool flag2 = false;
860                 for (LyXParagraph::inset_iterator it = par->inset_iterator_begin();
861                      it != par->inset_iterator_end(); ++it) {
862                         if ((*it)->LyxCode() == Inset::REF_CODE) {
863                                 InsetCommand * inset = static_cast<InsetCommand *>(*it);
864                                 if (inset->getContents() == from) {
865                                         inset->setContents(to);
866                                         flag2 = true;
867                                 }
868                         }
869                 }
870                 if (flag2) {
871                         flag = true;
872                         if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
873                                 // this is possible now, since SetCursor takes
874                                 // care about footnotes
875                                 text->SetCursorIntern(par, 0);
876                                 text->RedoParagraphs(text->cursor,
877                                                      text->cursor.par()->Next());
878                                 text->FullRebreak();
879                         }
880                 }
881                 par = par->next;
882         }
883         text->SetCursorIntern(cursor.par(), cursor.pos());
884         return flag;
885 }