]> git.lyx.org Git - lyx.git/blob - src/BufferView2.C
a4d3325fb08d703b04258c20ceffb87c65aac4b8
[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
201 bool BufferView::insertInset(Inset * inset, string const & lout,
202                              bool /*no_table*/)
203 {
204         // if we are in a locking inset we should try to insert the
205         // inset there otherwise this is a illegal function now
206         if (theLockingInset()) {
207                 if (theLockingInset()->InsertInsetAllowed(inset))
208                     return theLockingInset()->InsertInset(this, inset);
209                 return false;
210         }
211
212         // not quite sure if we want this...
213         text->SetCursorParUndo(buffer());
214         text->FreezeUndo();
215         
216         beforeChange();
217         if (!lout.empty()) {
218                 update(BufferView::SELECT|BufferView::FITCUR);
219                 text->BreakParagraph(this);
220                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
221                 
222                 if (text->cursor.par()->Last()) {
223                         text->CursorLeft(this);
224                         
225                         text->BreakParagraph(this);
226                         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
227                 }
228
229                 pair<bool, LyXTextClass::size_type> lres =
230                         textclasslist.NumberOfLayout(buffer()->params
231                                                      .textclass, lout);
232                 LyXTextClass::size_type lay;
233                 if (lres.first != false) {
234                         // layout found
235                         lay = lres.second;
236                 } else {
237                         // layout not fount using default "Standard" (0)
238                         lay = 0;
239                 }
240                  
241                 text->SetLayout(this, lay);
242                 
243                 text->SetParagraph(this, 0, 0,
244                                    0, 0,
245                                    VSpace(VSpace::NONE), VSpace(VSpace::NONE),
246                                    LYX_ALIGN_LAYOUT, 
247                                    string(),
248                                    0);
249                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
250                 
251                 text->current_font.setLatex(LyXFont::OFF);
252         }
253         
254         text->InsertInset(this, inset);
255         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
256
257         text->UnFreezeUndo();
258         return true;
259 }
260
261
262 // Open and lock an updatable inset
263 bool BufferView::open_new_inset(UpdatableInset * new_inset)
264 {
265         beforeChange();
266         text->FinishUndo();
267         if (!insertInset(new_inset))
268                 return false;
269         text->CursorLeft(this);
270         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
271         new_inset->Edit(this, 0, 0, 0);
272         return true;
273 }
274
275 /* This is also a buffer property (ale) */
276 // Not so sure about that. a goto Label function can not be buffer local, just
277 // think how this will work in a multiwindo/buffer environment, all the
278 // cursors in all the views showing this buffer will move. (Lgb)
279 // OK, then no cursor action should be allowed in buffer. (ale)
280 bool BufferView::gotoLabel(string const & label)
281
282 {
283         for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
284              it != buffer()->inset_iterator_end(); ++it) {
285                 vector<string> labels = (*it)->getLabelList();
286                 if ( find(labels.begin(),labels.end(),label)
287                      != labels.end()) {
288                         beforeChange();
289                         text->SetCursor(this, it.getPar(), it.getPos());
290                         text->sel_cursor = text->cursor;
291                         update(BufferView::SELECT|BufferView::FITCUR);
292                         return true;
293                 }
294         }
295         return false;
296 }
297
298
299 #ifndef NEW_INSETS
300 void BufferView::allFloats(char flag, char figmar)
301 {
302         if (!available()) return;
303
304         LyXCursor cursor = text->cursor;
305
306         if (!flag
307             && cursor.par()->footnoteflag != LyXParagraph::NO_FOOTNOTE
308             && ((figmar 
309                  && cursor.par()->footnotekind != LyXParagraph::FOOTNOTE 
310                  && cursor.par()->footnotekind != LyXParagraph::MARGIN
311                     )
312                 || (!figmar
313                     && cursor.par()->footnotekind != LyXParagraph::FIG 
314                     && cursor.par()->footnotekind != LyXParagraph::TAB
315                     && cursor.par()->footnotekind != LyXParagraph::WIDE_FIG 
316                     && cursor.par()->footnotekind != LyXParagraph::WIDE_TAB
317                     && cursor.par()->footnotekind != LyXParagraph::ALGORITHM)))
318                 toggleFloat();
319         else
320                 beforeChange();
321
322         LyXCursor tmpcursor = cursor;
323         cursor.par(tmpcursor.par()->ParFromPos(tmpcursor.pos()));
324         cursor.pos(tmpcursor.par()->PositionInParFromPos(tmpcursor.pos()));
325
326         LyXParagraph *par = buffer()->paragraph;
327         while (par) {
328                 if (flag) {
329                         if (par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
330                             && ((figmar 
331                                  && par->footnotekind != LyXParagraph::FOOTNOTE 
332                                  && par->footnotekind !=  LyXParagraph::MARGIN)
333                                 || (!figmar
334                                     && par->footnotekind != LyXParagraph::FIG 
335                                     && par->footnotekind != LyXParagraph::TAB
336                                     && par->footnotekind != LyXParagraph::WIDE_FIG 
337                                     && par->footnotekind != LyXParagraph::WIDE_TAB
338                                     && par->footnotekind != LyXParagraph::ALGORITHM
339                                         )
340                                     )
341                                 ) {
342                                 if (par->previous
343                                     && par->previous->footnoteflag != 
344                                     LyXParagraph::CLOSED_FOOTNOTE){ /* should be */ 
345                                         text->SetCursorIntern(this, 
346                                                               par->previous,
347                                                               0);
348                                         text->OpenFootnote(this);
349                                 }
350                         }
351                 } else {
352                         if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
353                             && (
354                                     (figmar 
355                                      &&
356                                      par->footnotekind != LyXParagraph::FOOTNOTE 
357                                      &&
358                                      par->footnotekind !=  LyXParagraph::MARGIN
359                                             )
360                                     ||
361                                     (!figmar
362                                      &&
363                                      par->footnotekind != LyXParagraph::FIG 
364                                      &&
365                                      par->footnotekind != LyXParagraph::TAB
366                                      &&
367                                      par->footnotekind != LyXParagraph::WIDE_FIG 
368                                      &&
369                                      par->footnotekind != LyXParagraph::WIDE_TAB
370                                      &&
371                                      par->footnotekind != LyXParagraph::ALGORITHM
372                                             )
373                                     )
374                                 ) {
375                                 text->SetCursorIntern(this, par, 0);
376                                 text->CloseFootnote(this);
377                         }
378                 }
379                 par = par->next;
380         }
381
382         text->SetCursorIntern(this, cursor.par(), cursor.pos());
383         redraw();
384         fitCursor(text);
385 }
386 #endif
387
388
389 void BufferView::insertNote()
390 {
391         InsetInfo * new_inset = new InsetInfo();
392         insertInset(new_inset);
393         new_inset->Edit(this, 0, 0, 0);
394 }
395
396
397 #ifndef NEW_INSETS
398 void BufferView::openStuff()
399 {
400         if (available()) {
401                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
402                 hideCursor();
403                 beforeChange();
404                 update(BufferView::SELECT|BufferView::FITCUR);
405                 text->OpenStuff(this);
406                 update(BufferView::SELECT|BufferView::FITCUR);
407                 setState();
408         }
409 }
410
411
412 void BufferView::toggleFloat()
413 {
414         if (available()) {
415                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
416                 hideCursor();
417                 beforeChange();
418                 update(BufferView::SELECT|BufferView::FITCUR);
419                 text->ToggleFootnote(this);
420                 update(BufferView::SELECT|BufferView::FITCUR);
421                 setState();
422         }
423 }
424 #endif
425
426 void BufferView::menuUndo()
427 {
428         if (available()) {
429                 owner()->getMiniBuffer()->Set(_("Undo"));
430                 hideCursor();
431                 beforeChange();
432                 update(BufferView::SELECT|BufferView::FITCUR);
433                 if (!text->TextUndo(this))
434                         owner()->getMiniBuffer()->Set(_("No further undo information"));
435                 else
436                         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
437                 setState();
438         }
439 }
440
441
442 void BufferView::menuRedo()
443 {
444         if (theLockingInset()) {
445                 owner()->getMiniBuffer()->Set(_("Redo not yet supported in math mode"));
446                 return;
447         }    
448    
449         if (available()) {
450                 owner()->getMiniBuffer()->Set(_("Redo"));
451                 hideCursor();
452                 beforeChange();
453                 update(BufferView::SELECT|BufferView::FITCUR);
454                 if (!text->TextRedo(this))
455                         owner()->getMiniBuffer()->Set(_("No further redo information"));
456                 else
457                         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
458                 setState();
459         }
460 }
461
462
463 void BufferView::hyphenationPoint()
464 {
465         if (available()) {
466                 hideCursor();
467                 update(BufferView::SELECT|BufferView::FITCUR);
468                 InsetSpecialChar * new_inset = 
469                         new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
470                 insertInset(new_inset);
471         }
472 }
473
474
475 void BufferView::ldots()
476 {
477         if (available())  {
478                 hideCursor();
479                 update(BufferView::SELECT|BufferView::FITCUR);
480                 InsetSpecialChar * new_inset = 
481                         new InsetSpecialChar(InsetSpecialChar::LDOTS);
482                 insertInset(new_inset);
483         }
484 }
485
486
487 void BufferView::endOfSentenceDot()
488 {
489         if (available()) {
490                 hideCursor();
491                 update(BufferView::SELECT|BufferView::FITCUR);
492                 InsetSpecialChar * new_inset = 
493                         new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
494                 insertInset(new_inset);
495         }
496 }
497
498
499 void BufferView::menuSeparator()
500 {
501         if (available()) {
502                 hideCursor();
503                 update(BufferView::SELECT|BufferView::FITCUR);
504                 InsetSpecialChar * new_inset = 
505                         new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
506                 insertInset(new_inset);
507         }
508 }
509
510
511 void BufferView::newline()
512 {
513         if (available()) {
514                 hideCursor();
515                 update(BufferView::SELECT|BufferView::FITCUR);
516                 text->InsertChar(this, LyXParagraph::META_NEWLINE);
517                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
518         }
519 }
520
521
522 void BufferView::protectedBlank()
523 {
524         if (available()) {
525                 hideCursor();
526                 update(BufferView::SELECT|BufferView::FITCUR);
527                 InsetSpecialChar * new_inset =
528                         new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
529                 insertInset(new_inset);
530         }
531 }
532
533
534 void BufferView::hfill()
535 {
536         if (available()) {
537                 hideCursor();
538                 update(BufferView::SELECT|BufferView::FITCUR);
539                 text->InsertChar(this, LyXParagraph::META_HFILL);
540                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
541         }
542 }
543
544 void BufferView::copyEnvironment()
545 {
546         if (available()) {
547                 text->copyEnvironmentType();
548                 // clear the selection, even if mark_set
549                 toggleSelection();
550                 text->ClearSelection();
551                 update(BufferView::SELECT|BufferView::FITCUR);
552                 owner()->getMiniBuffer()->Set(_("Paragraph environment type copied"));
553         }
554 }
555
556
557 void BufferView::pasteEnvironment()
558 {
559         if (available()) {
560                 text->pasteEnvironmentType(this);
561                 owner()->getMiniBuffer()->Set(_("Paragraph environment type set"));
562                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
563         }
564 }
565
566
567 void BufferView::copy()
568 {
569         if (available()) {
570                 text->CopySelection(this);
571                 // clear the selection, even if mark_set
572                 toggleSelection();
573                 text->ClearSelection();
574                 update(BufferView::SELECT|BufferView::FITCUR);
575                 owner()->getMiniBuffer()->Set(_("Copy"));
576         }
577 }
578
579 void BufferView::cut()
580 {
581         if (available()) {
582                 hideCursor();
583                 update(BufferView::SELECT|BufferView::FITCUR);
584                 text->CutSelection(this);
585                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
586                 owner()->getMiniBuffer()->Set(_("Cut"));
587         }
588 }
589
590
591 void BufferView::paste()
592 {
593         if (!available()) return;
594         
595         owner()->getMiniBuffer()->Set(_("Paste"));
596         hideCursor();
597         // clear the selection
598         toggleSelection();
599         text->ClearSelection();
600         update(BufferView::SELECT|BufferView::FITCUR);
601         
602         // paste
603         text->PasteSelection(this);
604         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
605         
606         // clear the selection 
607         toggleSelection();
608         text->ClearSelection();
609         update(BufferView::SELECT|BufferView::FITCUR);
610 }
611
612
613 void BufferView::gotoNote()
614 {
615         if (!available()) return;
616    
617         hideCursor();
618         beforeChange();
619         update(BufferView::SELECT|BufferView::FITCUR);
620         LyXCursor tmp;
621    
622         if (!text->GotoNextNote(this)) {
623                 if (text->cursor.pos() 
624                     || text->cursor.par() != text->FirstParagraph()) {
625                                 tmp = text->cursor;
626                                 text->cursor.par(text->FirstParagraph());
627                                 text->cursor.pos(0);
628                                 if (!text->GotoNextNote(this)) {
629                                         text->cursor = tmp;
630                                         owner()->getMiniBuffer()->Set(_("No more notes"));
631                                         LyXBell();
632                                 }
633                         } else {
634                                 owner()->getMiniBuffer()->Set(_("No more notes"));
635                                 LyXBell();
636                         }
637         }
638         update(BufferView::SELECT|BufferView::FITCUR);
639         text->sel_cursor = text->cursor;
640 }
641
642
643 void BufferView::insertCorrectQuote()
644 {
645         char c;
646
647         if (text->cursor.pos())
648                 c = text->cursor.par()->GetChar(text->cursor.pos() - 1);
649         else 
650                 c = ' ';
651
652         insertInset(new InsetQuotes(c, buffer()->params));
653 }
654
655
656 /* these functions are for the spellchecker */ 
657 string const BufferView::nextWord(float & value)
658 {
659         if (!available()) {
660                 value = 1;
661                 return string();
662         }
663
664         return text->SelectNextWord(this, value);
665 }
666
667   
668 void BufferView::selectLastWord()
669 {
670         if (!available()) return;
671    
672         hideCursor();
673         beforeChange();
674         text->SelectSelectedWord(this);
675         toggleSelection(false);
676         update(BufferView::SELECT|BufferView::FITCUR);
677 }
678
679
680 void BufferView::endOfSpellCheck()
681 {
682         if (!available()) return;
683    
684         hideCursor();
685         beforeChange();
686         text->SelectSelectedWord(this);
687         text->ClearSelection();
688         update(BufferView::SELECT|BufferView::FITCUR);
689 }
690
691
692 void BufferView::replaceWord(string const & replacestring)
693 {
694         if (!available()) return;
695
696         hideCursor();
697         update(BufferView::SELECT|BufferView::FITCUR);
698    
699         /* clear the selection (if there is any) */ 
700         toggleSelection(false);
701         update(BufferView::SELECT|BufferView::FITCUR);
702    
703         /* clear the selection (if there is any) */ 
704         toggleSelection(false);
705         text->ReplaceSelectionWithString(this, replacestring);
706    
707         text->SetSelectionOverString(this, replacestring);
708
709         // Go back so that replacement string is also spellchecked
710         for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
711                 text->CursorLeft(this);
712         }
713         update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
714 }
715 // End of spellchecker stuff
716
717
718 bool BufferView::lockInset(UpdatableInset * inset)
719 {
720         if (!theLockingInset() && inset) {
721                 theLockingInset(inset);
722                 return true;
723         } else if (inset) {
724             return theLockingInset()->LockInsetInInset(this, inset);
725         }
726         return false;
727 }
728
729
730 void BufferView::showLockedInsetCursor(int x, int y, int asc, int desc)
731 {
732         if (theLockingInset() && available()) {
733                 LyXCursor cursor = text->cursor;
734                 if ((cursor.pos() - 1 >= 0) &&
735                     (cursor.par()->GetChar(cursor.pos() - 1) ==
736                      LyXParagraph::META_INSET) &&
737                     (cursor.par()->GetInset(cursor.pos() - 1) ==
738                      theLockingInset()->GetLockingInset()))
739                         text->SetCursor(this, cursor,
740                                         cursor.par(), cursor.pos() - 1);
741                 y += cursor.y() + theLockingInset()->InsetInInsetY();
742                 pimpl_->screen_->ShowManualCursor(text, x, y, asc, desc,
743                                                   LyXScreen::BAR_SHAPE);
744         }
745 }
746
747
748 void BufferView::hideLockedInsetCursor()
749 {
750         if (theLockingInset() && available()) {
751                 pimpl_->screen_->HideCursor();
752         }
753 }
754
755
756 void BufferView::fitLockedInsetCursor(int x, int y, int asc, int desc)
757 {
758         if (theLockingInset() && available()){
759                 y += text->cursor.y() + theLockingInset()->InsetInInsetY();
760                 if (pimpl_->screen_->FitManualCursor(text, x, y, asc, desc))
761                         updateScrollbar();
762         }
763 }
764
765
766 int BufferView::unlockInset(UpdatableInset * inset)
767 {
768         if (inset && theLockingInset() == inset) {
769                 inset->InsetUnlock(this);
770                 theLockingInset(0);
771                 text->FinishUndo();
772                 return 0;
773         } else if (inset && theLockingInset() &&
774                    theLockingInset()->UnlockInsetInInset(this, inset)) {
775                 text->FinishUndo();
776                 return 0;
777         }
778         return bufferlist.unlockInset(inset);
779 }
780
781
782 void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind)
783 {
784         if (!theLockingInset())
785                 return; // shouldn't happen
786         if (kind == Undo::EDIT) // in this case insets would not be stored!
787                 kind = Undo::FINISH;
788         text->SetUndo(buffer(), kind,
789 #ifndef NEW_INSETS
790                       text->cursor.par()->
791                       ParFromPos(text->cursor.pos())->previous, 
792                       text->cursor.par()->
793                       ParFromPos(text->cursor.pos())->next
794 #else
795                       text->cursor.par()->previous, 
796                       text->cursor.par()->next
797 #endif
798                 );
799 }
800
801
802 void BufferView::updateInset(Inset * inset, bool mark_dirty)
803 {
804         if (!inset)
805                 return;
806
807         // first check for locking insets
808         if (theLockingInset()) {
809                 if (theLockingInset() == inset) {
810                         if (text->UpdateInset(this, inset)){
811                                 update();
812                                 if (mark_dirty){
813                                         if (buffer()->isLyxClean())
814                                                 owner()->getMiniBuffer()->
815                                                         setTimer(4);
816                                         buffer()->markDirty();
817                                 }
818                                 updateScrollbar();
819                                 return;
820                         }
821                 } else if (theLockingInset()->UpdateInsetInInset(this,inset)) {
822                         if (text->UpdateInset(this, theLockingInset())) {
823                                 update();
824                                 if (mark_dirty){
825                                         if (buffer()->isLyxClean())
826                                                 owner()->getMiniBuffer()->
827                                                         setTimer(4);
828                                         buffer()->markDirty();
829                                 }
830                                 updateScrollbar();
831                                 return;
832                         }
833                 }
834         }
835   
836         // then check the current buffer
837         if (available()) {
838                 hideCursor();
839                 update(BufferView::UPDATE);
840                 if (text->UpdateInset(this, inset)){
841                         if (mark_dirty)
842                                 update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
843                         else 
844                                 update(SELECT);
845                         return;
846                 }
847         }
848 }
849
850 bool BufferView::ChangeRefs(string const & from, string const & to)
851 {
852         bool flag = false;
853         LyXParagraph * par = buffer()->paragraph;
854         LyXCursor cursor = text->cursor;
855         LyXCursor tmpcursor = cursor;
856 #ifndef NEW_INSETS
857         cursor.par(tmpcursor.par()->ParFromPos(tmpcursor.pos()));
858         cursor.pos(tmpcursor.par()->PositionInParFromPos(tmpcursor.pos()));
859 #else
860         cursor.par(tmpcursor.par());
861         cursor.pos(tmpcursor.pos());
862 #endif
863
864         while (par) {
865                 bool flag2 = false;
866                 for (LyXParagraph::inset_iterator it = par->inset_iterator_begin();
867                      it != par->inset_iterator_end(); ++it) {
868                         if ((*it)->LyxCode() == Inset::REF_CODE) {
869                                 InsetCommand * inset = static_cast<InsetCommand *>(*it);
870                                 if (inset->getContents() == from) {
871                                         inset->setContents(to);
872                                         flag2 = true;
873                                 }
874                         }
875                 }
876                 if (flag2) {
877                         flag = true;
878 #ifndef NEW_INSETS
879                         if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
880 #endif
881                                 // this is possible now, since SetCursor takes
882                                 // care about footnotes
883                                 text->SetCursorIntern(this, par, 0);
884                                 text->RedoParagraphs(this, text->cursor,
885                                                      text->cursor.par()->Next());
886                                 text->FullRebreak(this);
887 #ifndef NEW_INSETS
888                         }
889 #endif
890                 }
891                 par = par->next;
892         }
893         text->SetCursorIntern(this, cursor.par(), cursor.pos());
894         return flag;
895 }
896
897
898 UpdatableInset * BufferView::theLockingInset() const
899 {
900     return text->the_locking_inset;
901 }
902
903
904 void BufferView::theLockingInset(UpdatableInset * inset)
905 {
906     text->the_locking_inset = inset;
907 }