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