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