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;
30 // Inserts a file into current document
31 bool BufferView::insertLyXFile(string const & filen)
33 // (c) CHT Software Service GmbH
36 // Insert a Lyxformat - file into current buffer
38 // Moved from lyx_cb.C (Lgb)
40 if (filen.empty()) return false;
42 string fname = MakeAbsPath(filen);
44 // check if file exist
48 WriteAlert(_("Error!"),
49 _("Specified file is unreadable: "),
50 MakeDisplayPath(fname, 50));
56 ifstream ifs(fname.c_str());
58 WriteAlert(_("Error!"),
59 _("Cannot open specified file: "),
60 MakeDisplayPath(fname, 50));
71 lyxerr.debug() << "Will insert file with header" << endl;
72 res = buffer()->readFile(lex, text->cursor.par);
74 lyxerr.debug() << "Will insert file without header" << endl;
75 res = buffer()->readLyXformat2(lex, text->cursor.par);
82 bool BufferView::removeAutoInsets()
84 LyXParagraph * par = buffer()->paragraph;
86 LyXCursor cursor = text->cursor;
87 LyXCursor tmpcursor = cursor;
88 cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
89 cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
93 if (par->AutoDeleteInsets()){
95 if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
96 // this is possible now, since SetCursor takes
97 // care about footnotes
98 text->SetCursorIntern(par, 0);
99 text->RedoParagraphs(text->cursor,
100 text->cursor.par->Next());
106 // avoid forbidden cursor positions caused by error removing
107 if (cursor.pos > cursor.par->Last())
108 cursor.pos = cursor.par->Last();
109 text->SetCursorIntern(cursor.par, cursor.pos);
115 void BufferView::insertErrors(TeXErrors & terr)
117 // Save the cursor position
118 LyXCursor cursor = text->cursor;
120 // This is drastic, but it's the only fix, I could find. (Asger)
124 for (TeXErrors::Errors::const_iterator cit = terr.begin();
127 string desctext((*cit).error_desc);
128 string errortext((*cit).error_text);
129 string msgtxt = desctext + '\n' + errortext;
130 int errorrow = (*cit).error_in_line;
132 // Insert error string for row number
136 buffer()->texrow.getIdFromRow(errorrow, tmpid, tmppos);
138 LyXParagraph * texrowpar = 0;
141 texrowpar = text->FirstParagraph();
144 texrowpar = text->GetParFromID(tmpid);
150 InsetError * new_inset = new InsetError(msgtxt);
151 text->SetCursorIntern(texrowpar, tmppos);
152 text->InsertInset(new_inset);
155 // Restore the cursor position
156 text->SetCursorIntern(cursor.par, cursor.pos);
160 void BufferView::setCursorFromRow(int row)
165 buffer()->texrow.getIdFromRow(row, tmpid, tmppos);
167 LyXParagraph * texrowpar;
170 texrowpar = text->FirstParagraph();
173 texrowpar = text->GetParFromID(tmpid);
175 text->SetCursor(texrowpar, tmppos);
178 void BufferView::insertInset(Inset * inset, string const & lout,
181 // check for table/list in tables
182 if (no_table && text->cursor.par->table){
183 WriteAlert(_("Impossible Operation!"),
184 _("Cannot insert table/list in table."),
188 // not quite sure if we want this...
189 text->SetCursorParUndo();
195 text->BreakParagraph();
198 if (text->cursor.par->Last()) {
201 text->BreakParagraph();
205 int lay = textclasslist.NumberOfLayout(buffer()->params.textclass,
207 if (lay == -1) // layout not found
208 // use default layout "Standard" (0)
211 text->SetLayout(lay);
213 text->SetParagraph(0, 0,
215 VSpace(VSpace::NONE), VSpace(VSpace::NONE),
221 text->current_font.setLatex(LyXFont::OFF);
224 text->InsertInset(inset);
227 text->UnFreezeUndo();
231 // Open and lock an updatable inset
232 void BufferView::open_new_inset(UpdatableInset * new_inset)
236 insertInset(new_inset);
239 new_inset->Edit(0, 0);
242 /* This is also a buffer property (ale) */
243 // Not so sure about that. a goto Label function can not be buffer local, just
244 // think how this will work in a multiwindo/buffer environment, all the
245 // cursors in all the views showing this buffer will move. (Lgb)
246 // OK, then no cursor action should be allowed in buffer. (ale)
247 bool BufferView::gotoLabel(string const & label)
250 LyXParagraph * par = buffer()->paragraph;
251 LyXParagraph::size_type pos;
255 while ((inset = par->ReturnNextInsetPointer(pos))){
256 for (int i = 0; i < inset->GetNumberOfLabels(); ++i) {
257 if (label == inset->getLabel(i)) {
259 text->SetCursor(par, pos);
260 text->sel_cursor = text->cursor;
272 void BufferView::allFloats(char flag, char figmar)
274 if (!available()) return;
276 LyXCursor cursor = text->cursor;
278 if (!flag && cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
280 && cursor.par->footnotekind != LyXParagraph::FOOTNOTE
281 && cursor.par->footnotekind != LyXParagraph::MARGIN)
283 && cursor.par->footnotekind != LyXParagraph::FIG
284 && cursor.par->footnotekind != LyXParagraph::TAB
285 && cursor.par->footnotekind != LyXParagraph::WIDE_FIG
286 && cursor.par->footnotekind != LyXParagraph::WIDE_TAB
287 && cursor.par->footnotekind != LyXParagraph::ALGORITHM)))
292 LyXCursor tmpcursor = cursor;
293 cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
294 cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
296 LyXParagraph *par = buffer()->paragraph;
299 if (par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
301 && par->footnotekind != LyXParagraph::FOOTNOTE
302 && par->footnotekind != LyXParagraph::MARGIN)
304 && par->footnotekind != LyXParagraph::FIG
305 && par->footnotekind != LyXParagraph::TAB
306 && par->footnotekind != LyXParagraph::WIDE_FIG
307 && par->footnotekind != LyXParagraph::WIDE_TAB
308 && par->footnotekind != LyXParagraph::ALGORITHM
313 && par->previous->footnoteflag !=
314 LyXParagraph::CLOSED_FOOTNOTE){ /* should be */
315 text->SetCursorIntern(par->previous,
317 text->OpenFootnote();
321 if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
325 par->footnotekind != LyXParagraph::FOOTNOTE
327 par->footnotekind != LyXParagraph::MARGIN
332 par->footnotekind != LyXParagraph::FIG
334 par->footnotekind != LyXParagraph::TAB
336 par->footnotekind != LyXParagraph::WIDE_FIG
338 par->footnotekind != LyXParagraph::WIDE_TAB
340 par->footnotekind != LyXParagraph::ALGORITHM
344 text->SetCursorIntern(par, 0);
345 text->CloseFootnote();
351 text->SetCursorIntern(cursor.par, cursor.pos);
358 void BufferView::insertNote()
360 InsetInfo * new_inset = new InsetInfo();
361 insertInset(new_inset);
362 new_inset->Edit(0, 0);
366 void BufferView::openStuff()
369 owner()->getMiniBuffer()->Set(_("Open/Close..."));
370 getScreen()->HideCursor();
380 void BufferView::toggleFloat()
383 owner()->getMiniBuffer()->Set(_("Open/Close..."));
384 getScreen()->HideCursor();
387 text->ToggleFootnote();
393 void BufferView::menuUndo()
396 owner()->getMiniBuffer()->Set(_("Undo"));
397 getScreen()->HideCursor();
400 if (!text->TextUndo())
401 owner()->getMiniBuffer()->Set(_("No further undo information"));
409 void BufferView::menuRedo()
411 if (the_locking_inset) {
412 owner()->getMiniBuffer()->Set(_("Redo not yet supported in math mode"));
417 owner()->getMiniBuffer()->Set(_("Redo"));
418 getScreen()->HideCursor();
421 if (!text->TextRedo())
422 owner()->getMiniBuffer()->Set(_("No further redo information"));
430 void BufferView::hyphenationPoint()
433 getScreen()->HideCursor();
435 InsetSpecialChar * new_inset =
436 new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
437 insertInset(new_inset);
442 void BufferView::ldots()
445 getScreen()->HideCursor();
447 InsetSpecialChar * new_inset =
448 new InsetSpecialChar(InsetSpecialChar::LDOTS);
449 insertInset(new_inset);
454 void BufferView::endOfSentenceDot()
457 getScreen()->HideCursor();
459 InsetSpecialChar * new_inset =
460 new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
461 insertInset(new_inset);
466 void BufferView::menuSeparator()
469 getScreen()->HideCursor();
471 InsetSpecialChar * new_inset =
472 new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
473 insertInset(new_inset);
478 void BufferView::newline()
481 getScreen()->HideCursor();
483 text->InsertChar(LyXParagraph::META_NEWLINE);
489 void BufferView::protectedBlank()
492 getScreen()->HideCursor();
494 text->InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
500 void BufferView::hfill()
503 getScreen()->HideCursor();
505 text->InsertChar(LyXParagraph::META_HFILL);
510 void BufferView::copyEnvironment()
513 text->copyEnvironmentType();
514 // clear the selection, even if mark_set
515 getScreen()->ToggleSelection();
516 text->ClearSelection();
518 owner()->getMiniBuffer()->Set(_("Paragraph environment type copied"));
523 void BufferView::pasteEnvironment()
526 text->pasteEnvironmentType();
527 owner()->getMiniBuffer()->Set(_("Paragraph environment type set"));
533 void BufferView::copy()
536 text->CopySelection();
537 // clear the selection, even if mark_set
538 getScreen()->ToggleSelection();
539 text->ClearSelection();
541 owner()->getMiniBuffer()->Set(_("Copy"));
545 void BufferView::cut()
548 getScreen()->HideCursor();
550 text->CutSelection();
552 owner()->getMiniBuffer()->Set(_("Cut"));
557 void BufferView::paste()
559 if (!available()) return;
561 owner()->getMiniBuffer()->Set(_("Paste"));
562 getScreen()->HideCursor();
563 // clear the selection
564 getScreen()->ToggleSelection();
565 text->ClearSelection();
569 text->PasteSelection();
572 // clear the selection
573 getScreen()->ToggleSelection();
574 text->ClearSelection();
579 void BufferView::gotoNote()
581 if (!getScreen()) return;
583 getScreen()->HideCursor();
588 if (!text->GotoNextNote()) {
590 || text->cursor.par != text->FirstParagraph()) {
592 text->cursor.par = text->FirstParagraph();
593 text->cursor.pos = 0;
594 if (!text->GotoNextNote()) {
596 owner()->getMiniBuffer()->Set(_("No more notes"));
600 owner()->getMiniBuffer()->Set(_("No more notes"));
605 text->sel_cursor = text->cursor;
609 void BufferView::insertCorrectQuote()
613 if (text->cursor.pos)
614 c = text->cursor.par->GetChar(text->cursor.pos - 1);
618 insertInset(new InsetQuotes(c, buffer()->params));
622 /* these functions are for the spellchecker */
623 char * BufferView::nextWord(float & value)
630 char * string = text->SelectNextWord(value);
636 void BufferView::selectLastWord()
638 if (!available()) return;
640 getScreen()->HideCursor();
642 text->SelectSelectedWord();
643 getScreen()->ToggleSelection(false);
648 void BufferView::endOfSpellCheck()
650 if (!available()) return;
652 getScreen()->HideCursor();
654 text->SelectSelectedWord();
655 text->ClearSelection();
658 void BufferView::replaceWord(string const & replacestring)
660 if (!getScreen()) return;
662 getScreen()->HideCursor();
665 /* clear the selection (if there is any) */
666 getScreen()->ToggleSelection(false);
669 /* clear the selection (if there is any) */
670 getScreen()->ToggleSelection(false);
671 text->ReplaceSelectionWithString(replacestring.c_str());
673 text->SetSelectionOverString(replacestring.c_str());
675 // Go back so that replacement string is also spellchecked
676 for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
677 text->CursorLeftIntern();
681 // End of spellchecker stuff
684 /* these functions return 1 if an error occured,
686 int BufferView::lockInset(UpdatableInset * inset)
688 if (!the_locking_inset && inset){
689 the_locking_inset = inset;
696 void BufferView::showLockedInsetCursor(long x, long y, int asc, int desc)
698 if (the_locking_inset && getScreen()) {
700 getScreen()->ShowManualCursor(x, y,
706 void BufferView::hideLockedInsetCursor(long x, long y, int asc, int desc)
708 if (the_locking_inset && getScreen()) {
710 getScreen()->HideManualCursor(x, y,
716 void BufferView::fitLockedInsetCursor(long x, long y, int asc, int desc)
718 if (the_locking_inset && getScreen()){
720 if (getScreen()->FitManualCursor(x, y, asc, desc))
726 int BufferView::unlockInset(UpdatableInset * inset)
728 if (inset && the_locking_inset == inset) {
729 inset->InsetUnlock();
730 the_locking_inset = 0;
734 return bufferlist.unlockInset(inset);
738 void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind)
740 if (!the_locking_inset)
741 return; // shouldn't happen
742 if (kind == Undo::EDIT) // in this case insets would not be stored!
746 ParFromPos(text->cursor.pos)->previous,
748 ParFromPos(text->cursor.pos)->next);