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