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