2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1995 Matthias Ettrich
8 * Copyright 1995-2000 The LyX Team.
10 * ====================================================== */
14 #include "BufferView.h"
16 #include "lyxcursor.h"
18 #include "insets/inseterror.h"
19 #include "insets/insetinfo.h"
20 #include "insets/insetspecialchar.h"
22 #include "minibuffer.h"
23 #include "bufferlist.h"
24 #include "support/FileInfo.h"
26 extern BufferList bufferlist;
28 // Inserts a file into current document
29 bool BufferView::insertLyXFile(string const & filen)
31 // (c) CHT Software Service GmbH
34 // Insert a Lyxformat - file into current buffer
36 // Moved from lyx_cb.C (Lgb)
38 if (filen.empty()) return false;
40 string fname = MakeAbsPath(filen);
42 // check if file exist
46 WriteAlert(_("Error!"),
47 _("Specified file is unreadable: "),
48 MakeDisplayPath(fname, 50));
54 ifstream ifs(fname.c_str());
56 WriteAlert(_("Error!"),
57 _("Cannot open specified file: "),
58 MakeDisplayPath(fname, 50));
69 lyxerr.debug() << "Will insert file with header" << endl;
70 res = buffer()->readFile(lex, text->cursor.par);
72 lyxerr.debug() << "Will insert file without header" << endl;
73 res = buffer()->readLyXformat2(lex, text->cursor.par);
80 bool BufferView::removeAutoInsets()
82 LyXParagraph * par = buffer()->paragraph;
84 LyXCursor cursor = text->cursor;
85 LyXCursor tmpcursor = cursor;
86 cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
87 cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
91 if (par->AutoDeleteInsets()){
93 if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
94 // this is possible now, since SetCursor takes
95 // care about footnotes
96 text->SetCursorIntern(par, 0);
97 text->RedoParagraphs(text->cursor,
98 text->cursor.par->Next());
104 // avoid forbidden cursor positions caused by error removing
105 if (cursor.pos > cursor.par->Last())
106 cursor.pos = cursor.par->Last();
107 text->SetCursorIntern(cursor.par, cursor.pos);
113 void BufferView::insertErrors(TeXErrors & terr)
115 // Save the cursor position
116 LyXCursor cursor = text->cursor;
118 // This is drastic, but it's the only fix, I could find. (Asger)
122 for (TeXErrors::Errors::const_iterator cit = terr.begin();
125 string desctext((*cit).error_desc);
126 string errortext((*cit).error_text);
127 string msgtxt = desctext + '\n' + errortext;
128 int errorrow = (*cit).error_in_line;
130 // Insert error string for row number
134 buffer()->texrow.getIdFromRow(errorrow, tmpid, tmppos);
136 LyXParagraph * texrowpar = 0;
139 texrowpar = text->FirstParagraph();
142 texrowpar = text->GetParFromID(tmpid);
148 InsetError * new_inset = new InsetError(msgtxt);
149 text->SetCursorIntern(texrowpar, tmppos);
150 text->InsertInset(new_inset);
153 // Restore the cursor position
154 text->SetCursorIntern(cursor.par, cursor.pos);
158 void BufferView::setCursorFromRow(int row)
163 buffer()->texrow.getIdFromRow(row, tmpid, tmppos);
165 LyXParagraph * texrowpar;
168 texrowpar = text->FirstParagraph();
171 texrowpar = text->GetParFromID(tmpid);
173 text->SetCursor(texrowpar, tmppos);
176 void BufferView::insertInset(Inset * inset, string const & lout,
179 // check for table/list in tables
180 if (no_table && text->cursor.par->table){
181 WriteAlert(_("Impossible Operation!"),
182 _("Cannot insert table/list in table."),
186 // not quite sure if we want this...
187 text->SetCursorParUndo();
193 text->BreakParagraph();
196 if (text->cursor.par->Last()) {
199 text->BreakParagraph();
203 int lay = textclasslist.NumberOfLayout(buffer()->params.textclass,
205 if (lay == -1) // layout not found
206 // use default layout "Standard" (0)
209 text->SetLayout(lay);
211 text->SetParagraph(0, 0,
213 VSpace(VSpace::NONE), VSpace(VSpace::NONE),
219 text->current_font.setLatex(LyXFont::OFF);
222 text->InsertInset(inset);
225 text->UnFreezeUndo();
229 // Open and lock an updatable inset
230 void BufferView::open_new_inset(UpdatableInset * new_inset)
234 insertInset(new_inset);
237 new_inset->Edit(0, 0);
240 /* This is also a buffer property (ale) */
241 // Not so sure about that. a goto Label function can not be buffer local, just
242 // think how this will work in a multiwindo/buffer environment, all the
243 // cursors in all the views showing this buffer will move. (Lgb)
244 // OK, then no cursor action should be allowed in buffer. (ale)
245 bool BufferView::gotoLabel(string const & label)
248 LyXParagraph * par = buffer()->paragraph;
249 LyXParagraph::size_type pos;
253 while ((inset = par->ReturnNextInsetPointer(pos))){
254 for (int i = 0; i < inset->GetNumberOfLabels(); ++i) {
255 if (label == inset->getLabel(i)) {
257 text->SetCursor(par, pos);
258 text->sel_cursor = text->cursor;
270 void BufferView::allFloats(char flag, char figmar)
272 if (!available()) return;
274 LyXCursor cursor = text->cursor;
276 if (!flag && cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
278 && cursor.par->footnotekind != LyXParagraph::FOOTNOTE
279 && cursor.par->footnotekind != LyXParagraph::MARGIN)
281 && cursor.par->footnotekind != LyXParagraph::FIG
282 && cursor.par->footnotekind != LyXParagraph::TAB
283 && cursor.par->footnotekind != LyXParagraph::WIDE_FIG
284 && cursor.par->footnotekind != LyXParagraph::WIDE_TAB
285 && cursor.par->footnotekind != LyXParagraph::ALGORITHM)))
290 LyXCursor tmpcursor = cursor;
291 cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
292 cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
294 LyXParagraph *par = buffer()->paragraph;
297 if (par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
299 && par->footnotekind != LyXParagraph::FOOTNOTE
300 && par->footnotekind != LyXParagraph::MARGIN)
302 && par->footnotekind != LyXParagraph::FIG
303 && par->footnotekind != LyXParagraph::TAB
304 && par->footnotekind != LyXParagraph::WIDE_FIG
305 && par->footnotekind != LyXParagraph::WIDE_TAB
306 && par->footnotekind != LyXParagraph::ALGORITHM
311 && par->previous->footnoteflag !=
312 LyXParagraph::CLOSED_FOOTNOTE){ /* should be */
313 text->SetCursorIntern(par->previous,
315 text->OpenFootnote();
319 if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
323 par->footnotekind != LyXParagraph::FOOTNOTE
325 par->footnotekind != LyXParagraph::MARGIN
330 par->footnotekind != LyXParagraph::FIG
332 par->footnotekind != LyXParagraph::TAB
334 par->footnotekind != LyXParagraph::WIDE_FIG
336 par->footnotekind != LyXParagraph::WIDE_TAB
338 par->footnotekind != LyXParagraph::ALGORITHM
342 text->SetCursorIntern(par, 0);
343 text->CloseFootnote();
349 text->SetCursorIntern(cursor.par, cursor.pos);
356 void BufferView::insertNote()
358 InsetInfo * new_inset = new InsetInfo();
359 insertInset(new_inset);
360 new_inset->Edit(0, 0);
364 void BufferView::openStuff()
367 owner()->getMiniBuffer()->Set(_("Open/Close..."));
368 getScreen()->HideCursor();
378 void BufferView::toggleFloat()
381 owner()->getMiniBuffer()->Set(_("Open/Close..."));
382 getScreen()->HideCursor();
385 text->ToggleFootnote();
391 void BufferView::menuUndo()
394 owner()->getMiniBuffer()->Set(_("Undo"));
395 getScreen()->HideCursor();
398 if (!text->TextUndo())
399 owner()->getMiniBuffer()->Set(_("No further undo information"));
407 void BufferView::menuRedo()
409 if (the_locking_inset) {
410 owner()->getMiniBuffer()->Set(_("Redo not yet supported in math mode"));
415 owner()->getMiniBuffer()->Set(_("Redo"));
416 getScreen()->HideCursor();
419 if (!text->TextRedo())
420 owner()->getMiniBuffer()->Set(_("No further redo information"));
428 void BufferView::hyphenationPoint()
431 getScreen()->HideCursor();
433 InsetSpecialChar * new_inset =
434 new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
435 insertInset(new_inset);
440 void BufferView::ldots()
443 getScreen()->HideCursor();
445 InsetSpecialChar * new_inset =
446 new InsetSpecialChar(InsetSpecialChar::LDOTS);
447 insertInset(new_inset);
452 void BufferView::endOfSentenceDot()
455 getScreen()->HideCursor();
457 InsetSpecialChar * new_inset =
458 new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
459 insertInset(new_inset);
464 void BufferView::menuSeparator()
467 getScreen()->HideCursor();
469 InsetSpecialChar * new_inset =
470 new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
471 insertInset(new_inset);
476 void BufferView::newline()
479 getScreen()->HideCursor();
481 text->InsertChar(LyXParagraph::META_NEWLINE);
487 void BufferView::protectedBlank()
490 getScreen()->HideCursor();
492 text->InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
498 void BufferView::hfill()
501 getScreen()->HideCursor();
503 text->InsertChar(LyXParagraph::META_HFILL);
508 void BufferView::copyEnvironment()
511 text->copyEnvironmentType();
512 // clear the selection, even if mark_set
513 getScreen()->ToggleSelection();
514 text->ClearSelection();
516 owner()->getMiniBuffer()->Set(_("Paragraph environment type copied"));
521 void BufferView::pasteEnvironment()
524 text->pasteEnvironmentType();
525 owner()->getMiniBuffer()->Set(_("Paragraph environment type set"));
531 void BufferView::copy()
534 text->CopySelection();
535 // clear the selection, even if mark_set
536 getScreen()->ToggleSelection();
537 text->ClearSelection();
539 owner()->getMiniBuffer()->Set(_("Copy"));
543 void BufferView::cut()
546 getScreen()->HideCursor();
548 text->CutSelection();
550 owner()->getMiniBuffer()->Set(_("Cut"));
555 void BufferView::paste()
557 if (!available()) return;
559 owner()->getMiniBuffer()->Set(_("Paste"));
560 getScreen()->HideCursor();
561 // clear the selection
562 getScreen()->ToggleSelection();
563 text->ClearSelection();
567 text->PasteSelection();
570 // clear the selection
571 getScreen()->ToggleSelection();
572 text->ClearSelection();
577 void BufferView::gotoNote()
579 if (!getScreen()) return;
581 getScreen()->HideCursor();
586 if (!text->GotoNextNote()) {
588 || text->cursor.par != text->FirstParagraph()) {
590 text->cursor.par = text->FirstParagraph();
591 text->cursor.pos = 0;
592 if (!text->GotoNextNote()) {
594 owner()->getMiniBuffer()->Set(_("No more notes"));
598 owner()->getMiniBuffer()->Set(_("No more notes"));
603 text->sel_cursor = text->cursor;
607 void BufferView::insertCorrectQuote()
611 if (text->cursor.pos)
612 c = text->cursor.par->GetChar(text->cursor.pos - 1);
616 insertInset(new InsetQuotes(c, buffer()->params));
620 /* these functions are for the spellchecker */
621 char * BufferView::nextWord(float & value)
628 char * string = text->SelectNextWord(value);
634 void BufferView::selectLastWord()
636 if (!available()) return;
638 getScreen()->HideCursor();
640 text->SelectSelectedWord();
641 getScreen()->ToggleSelection(false);
646 void BufferView::endOfSpellCheck()
648 if (!available()) return;
650 getScreen()->HideCursor();
652 text->SelectSelectedWord();
653 text->ClearSelection();
656 void BufferView::replaceWord(string const & replacestring)
658 if (!getScreen()) return;
660 getScreen()->HideCursor();
663 /* clear the selection (if there is any) */
664 getScreen()->ToggleSelection(false);
667 /* clear the selection (if there is any) */
668 getScreen()->ToggleSelection(false);
669 text->ReplaceSelectionWithString(replacestring.c_str());
671 text->SetSelectionOverString(replacestring.c_str());
673 // Go back so that replacement string is also spellchecked
674 for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
675 text->CursorLeftIntern();
679 // End of spellchecker stuff
682 /* these functions return 1 if an error occured,
684 int BufferView::lockInset(UpdatableInset * inset)
686 if (!the_locking_inset && inset){
687 the_locking_inset = inset;
694 void BufferView::showLockedInsetCursor(long x, long y, int asc, int desc)
696 if (the_locking_inset && getScreen()) {
698 getScreen()->ShowManualCursor(x, y,
704 void BufferView::hideLockedInsetCursor(long x, long y, int asc, int desc)
706 if (the_locking_inset && getScreen()) {
708 getScreen()->HideManualCursor(x, y,
714 void BufferView::fitLockedInsetCursor(long x, long y, int asc, int desc)
716 if (the_locking_inset && getScreen()){
718 if (getScreen()->FitManualCursor(x, y, asc, desc))
724 int BufferView::unlockInset(UpdatableInset * inset)
726 if (inset && the_locking_inset == inset) {
727 inset->InsetUnlock();
728 the_locking_inset = 0;
732 return bufferlist.unlockInset(inset);
736 void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind)
738 if (!the_locking_inset)
739 return; // shouldn't happen
740 if (kind == Undo::EDIT) // in this case insets would not be stored!
744 ParFromPos(text->cursor.pos)->previous,
746 ParFromPos(text->cursor.pos)->next);