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