X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=ae3ee5e487429c3d77effd0e07f3701e015d9a5c;hb=ff86a0160192ba7272331034da1510aba7899ff9;hp=8593ebaa5ee5e2c0deb9c6e62a9b65c98b834f3e;hpb=33a28bdc9cdf978601d5d40b693f13924801ad9e;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 8593ebaa5e..ae3ee5e487 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -1,10 +1,5 @@ #include -#include -#include -#include -#include - #ifdef __GNUG__ #pragma implementation #endif @@ -23,22 +18,23 @@ #include "bufferview_funcs.h" #include "TextCache.h" #include "bufferlist.h" -#include "lyx_gui_misc.h" #include "lyxrc.h" #include "intl.h" -#include "support/LAssert.h" -#include "support/lstrings.h" +// added for Dispatch functions +#include "lyx_cb.h" +#include "lyx_main.h" +#include "FloatList.h" +#include "gettext.h" +#include "ParagraphParameters.h" +#include "undo_funcs.h" +#include "lyxtextclasslist.h" + #include "frontends/Dialogs.h" #include "frontends/Alert.h" +#include "frontends/FileDialog.h" + #include "insets/insetbib.h" #include "insets/insettext.h" -/// added for Dispatch functions -#include "lyx_cb.h" -#include "frontends/FileDialog.h" -#include "lyx_main.h" -#include "FloatList.h" -#include "support/filetools.h" -#include "support/lyxfunctional.h" #include "insets/inseturl.h" #include "insets/insetlatexaccent.h" #include "insets/insettoc.h" @@ -63,12 +59,21 @@ #include "insets/insetcaption.h" #include "insets/insetfloatlist.h" #include "insets/insetspecialchar.h" -#include "gettext.h" -#include "ParagraphParameters.h" -#include "undo_funcs.h" + #include "mathed/formulabase.h" -extern lyx::layout_type current_layout; +#include "support/LAssert.h" +#include "support/lstrings.h" +#include "support/filetools.h" +#include "support/lyxfunctional.h" + +#include +#include +#include +#include + + +extern string current_layout; using std::vector; using std::find_if; @@ -80,7 +85,6 @@ using std::min; using SigC::slot; using lyx::pos_type; -using lyx::layout_type; using lyx::textclass_type; /* the selection possible is needed, that only motion events are @@ -90,7 +94,6 @@ bool selection_possible = false; extern BufferList bufferlist; extern char ascii_type; -extern void sigchldchecker(pid_t pid, int * status); extern int bibitemMaxWidth(BufferView *, LyXFont const &); @@ -109,7 +112,7 @@ void SetXtermCursor(Window win) { static Cursor cursor; static bool cursor_undefined = true; - if (cursor_undefined){ + if (cursor_undefined) { cursor = XCreateFontCursor(fl_get_display(), XC_xterm); XFlush(fl_get_display()); cursor_undefined = false; @@ -149,6 +152,10 @@ BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o, .connect(slot(this, &BufferView::Pimpl::tripleClick)); workarea_.workAreaKeyPress .connect(slot(this, &BufferView::Pimpl::workAreaKeyPress)); + workarea_.selectionRequested + .connect(slot(this, &BufferView::Pimpl::selectionRequested)); + workarea_.selectionLost + .connect(slot(this, &BufferView::Pimpl::selectionLost)); cursor_timeout.timeout.connect(slot(this, &BufferView::Pimpl::cursorToggle)); @@ -207,7 +214,7 @@ void BufferView::Pimpl::buffer(Buffer * b) updateScreen(); updateScrollbar(); } - bv_->text->first = screen_->topCursorVisible(bv_->text); + bv_->text->first_y = screen_->topCursorVisible(bv_->text); owner_->updateMenubar(); owner_->updateToolbar(); // Similarly, buffer-dependent dialogs should be updated or @@ -304,7 +311,7 @@ int BufferView::Pimpl::resizeCurrentBuffer() pos_type selendpos = 0; bool selection = false; bool mark_set = false; - + owner_->prohibitInput(); owner_->message(_("Formatting document...")); @@ -322,6 +329,7 @@ int BufferView::Pimpl::resizeCurrentBuffer() delete bv_->text; bv_->text = new LyXText(bv_); bv_->text->init(bv_); + buffer_->resizeInsets(bv_); } else { // See if we have a text in TextCache that fits // the new buffer_ with the correct width. @@ -338,14 +346,16 @@ int BufferView::Pimpl::resizeCurrentBuffer() } else { bv_->text = new LyXText(bv_); bv_->text->init(bv_); + //buffer_->resizeInsets(bv_); } } + updateScreen(); if (par) { bv_->text->selection.set(true); - /* at this point just to avoid the Delete-Empty-Paragraph - * Mechanism when setting the cursor */ + // At this point just to avoid the Delete-Empty-Paragraph- + // Mechanism when setting the cursor. bv_->text->selection.mark(mark_set); if (selection) { bv_->text->setCursor(bv_, selstartpar, selstartpos); @@ -361,8 +371,9 @@ int BufferView::Pimpl::resizeCurrentBuffer() // remake the inset locking bv_->theLockingInset(the_locking_inset); } - bv_->text->first = screen_->topCursorVisible(bv_->text); - buffer_->resizeInsets(bv_); + + bv_->text->first_y = screen_->topCursorVisible(bv_->text); + // this will scroll the screen such that the cursor becomes visible updateScrollbar(); redraw(); @@ -395,26 +406,35 @@ void BufferView::Pimpl::updateScrollbar() } long const text_height = bv_->text->height; + long const work_height = workarea_.height(); + if (text_height <= work_height) { + workarea_.setScrollbarBounds(0.0, 0.0); + current_scrollbar_value = bv_->text->first_y; + workarea_.setScrollbar(current_scrollbar_value, 1.0); + return; + } + double const lineh = bv_->text->defaultHeight(); double const slider_size = (text_height == 0) ? 1.0 : 1.0 / double(text_height); - - static long old_text_height = 0; - static double old_lineh = 0; - static double old_slider_size = 0; + + static long old_text_height; + static double old_lineh; + static double old_slider_size; if (text_height != old_text_height) { - workarea_.setScrollbarBounds(0, text_height - workarea_.height()); + workarea_.setScrollbarBounds(0.0, + text_height - work_height); old_text_height = text_height; } if (lineh != old_lineh) { workarea_.setScrollbarIncrements(lineh); old_lineh = lineh; } - if (current_scrollbar_value != bv_->text->first + if (current_scrollbar_value != bv_->text->first_y || slider_size != old_slider_size) { - current_scrollbar_value = bv_->text->first; + current_scrollbar_value = bv_->text->first_y; workarea_.setScrollbar(current_scrollbar_value, slider_size); old_slider_size = slider_size; } @@ -427,6 +447,7 @@ void BufferView::Pimpl::scrollCB(double value) if (!buffer_) return; current_scrollbar_value = long(value); + if (current_scrollbar_value < 0) current_scrollbar_value = 0; @@ -443,8 +464,8 @@ void BufferView::Pimpl::scrollCB(double value) LyXText * vbt = bv_->text; int const height = vbt->defaultHeight(); - int const first = static_cast((bv_->text->first + height)); - int const last = static_cast((bv_->text->first + workarea_.height() - height)); + int const first = static_cast((bv_->text->first_y + height)); + int const last = static_cast((bv_->text->first_y + workarea_.height() - height)); if (vbt->cursor.y() < first) vbt->setCursorFromCoordinates(bv_, 0, first); @@ -539,7 +560,7 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state) bv_->theLockingInset()-> insetMotionNotify(bv_, x - start_x, - y - cursor.y() + bv_->text->first, + y - cursor.y() + bv_->text->first_y, state); return; } @@ -552,7 +573,7 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state) screen_->hideCursor(); - bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first); + bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_y); if (!bv_->text->selection.set()) update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted @@ -560,11 +581,7 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state) bv_->text->setSelection(bv_); screen_->toggleToggle(bv_->text, bv_); fitCursor(); -#if 0 - screen_->showCursor(bv_->text, bv_); -#else showCursor(); -#endif } @@ -572,9 +589,10 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state) void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, unsigned int button) { - if (!buffer_ || !screen_.get()) return; + if (!buffer_ || !screen_.get()) + return; - Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos, button); + Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos); // ok ok, this is a hack. if (button == 4 || button == 5) { @@ -588,6 +606,16 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, } } + // Middle button press pastes if we have a selection + // We do this here as if the selection was inside an inset + // it could get cleared on the unlocking of the inset so + // we have to check this first + bool paste_internally = false; + if (button == 2 && bv_->getLyXText()->selection.set()) { + owner_->getLyXFunc()->dispatch(LFUN_COPY); + paste_internally = true; + } + if (bv_->theLockingInset()) { // We are in inset locking mode @@ -606,25 +634,13 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, selection_possible = true; screen_->hideCursor(); - int const screen_first = bv_->text->first; - - // Middle button press pastes if we have a selection - bool paste_internally = false; - if (button == 2 - && bv_->text->selection.set()) { - owner_->getLyXFunc()->dispatch(LFUN_COPY); - paste_internally = true; - } + int const screen_first = bv_->text->first_y; // Clear the selection screen_->toggleSelection(bv_->text, bv_); bv_->text->clearSelection(); bv_->text->fullRebreak(bv_); -#if 0 - screen_->update(bv_->text, bv_); -#else update(); -#endif updateScrollbar(); // Single left click in math inset? @@ -634,8 +650,10 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, selection_possible = false; owner_->updateLayoutChoice(); owner_->message(inset->editMessage()); + // IMO the inset has to be first in edit-mode and then we send the + // button press. (Jug 20020222) + inset->edit(bv_); //, xpos, ypos, button); inset->insetButtonPress(bv_, xpos, ypos, button); - inset->edit(bv_, xpos, ypos, button); return; } @@ -664,7 +682,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, owner_->getLyXFunc()->dispatch(LFUN_PASTE); else owner_->getLyXFunc()->dispatch(LFUN_PASTESELECTION, - "paragraph"); + "paragraph"); selection_possible = false; return; } @@ -675,25 +693,25 @@ void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button) { // select a word if (!buffer_) - return; + return; LyXText * text = bv_->getLyXText(); if (text->bv_owner && bv_->theLockingInset()) - return; + return; if (screen_.get() && button == 1) { - if (text->bv_owner) { - screen_->hideCursor(); - screen_->toggleSelection(text, bv_); - text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); - screen_->toggleSelection(text, bv_, false); - } else { - text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); - } - /* This will fit the cursor on the screen - * if necessary */ - update(text, BufferView::SELECT|BufferView::FITCUR); + if (text->bv_owner) { + screen_->hideCursor(); + screen_->toggleSelection(text, bv_); + text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); + screen_->toggleSelection(text, bv_, false); + } else { + text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); + } + /* This will fit the cursor on the screen + * if necessary */ + update(text, BufferView::SELECT|BufferView::FITCUR); } } @@ -710,13 +728,17 @@ void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, unsigned int button) return; if (screen_.get() && (button == 1)) { - screen_->hideCursor(); - screen_->toggleSelection(text, bv_); + if (text->bv_owner) { + screen_->hideCursor(); + screen_->toggleSelection(text, bv_); + } text->cursorHome(bv_); text->selection.cursor = text->cursor; text->cursorEnd(bv_); text->setSelection(bv_); - screen_->toggleSelection(text, bv_, false); + if (text->bv_owner) { + screen_->toggleSelection(text, bv_, false); + } /* This will fit the cursor on the screen * if necessary */ update(text, BufferView::SELECT|BufferView::FITCUR); @@ -724,6 +746,30 @@ void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, unsigned int button) } +void BufferView::Pimpl::selectionRequested() +{ + if (!available()) + return; + + string const sel(bv_->getLyXText()->selectionAsString(bv_->buffer(), + false)); + if (!sel.empty()) { + workarea_.putClipboard(sel); + } +} + + +void BufferView::Pimpl::selectionLost() +{ + if (active() && available()) { + hideCursor(); + toggleSelection(); + bv_->getLyXText()->clearSelection(); + showCursor(); + } +} + + void BufferView::Pimpl::enterView() { if (active() && available()) { @@ -750,7 +796,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, // If we hit an inset, we have the inset coordinates in these // and inset_hit points to the inset. If we do not hit an // inset, inset_hit is 0, and inset_x == x, inset_y == y. - Inset * inset_hit = checkInsetHit(bv_->text, x, y, button); + Inset * inset_hit = checkInsetHit(bv_->text, x, y); if (bv_->theLockingInset()) { // We are in inset locking mode. @@ -768,12 +814,18 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, if (button == 2) return; + // finish selection + if (button == 1) { + workarea_.haveSelection(bv_->getLyXText()->selection.set()); + } + setState(); owner_->showState(); + owner_->updateMenubar(); + owner_->updateToolbar(); // Did we hit an editable inset? if (inset_hit) { - // Inset like error, notes and figures selection_possible = false; // if we reach this point with a selection, it @@ -822,34 +874,9 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, return; } -#ifdef WITH_WARNINGS -#warning variable c is set but never used. What is it good for?? (JMarc) -#warning isnt this code dead ?? "open a float" ??? (jbl) -#endif - // check whether we want to open a float - if (bv_->text) { - bool hit = false; - char c = ' '; - if (bv_->text->cursor.pos() < - bv_->text->cursor.par()->size()) { - c = bv_->text->cursor.par()-> - getChar(bv_->text->cursor.pos()); - } - if (bv_->text->cursor.pos() - 1 >= 0) { - c = bv_->text->cursor.par()-> - getChar(bv_->text->cursor.pos() - 1); - } - if (hit == true) { - selection_possible = false; - return; - } - } - // Maybe we want to edit a bibitem ale970302 if (bv_->text->cursor.par()->bibkey && x < 20 + - bibitemMaxWidth(bv_, textclasslist. - TextClass(buffer_-> - params.textclass).defaultfont())) { + bibitemMaxWidth(bv_, textclasslist[buffer_->params.textclass].defaultfont())) { bv_->text->cursor.par()->bibkey->edit(bv_, 0, 0, 0); } @@ -857,63 +884,96 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, } -/* - * Returns an inset if inset was hit. 0 otherwise. - * If hit, the coordinates are changed relative to the inset. - * Otherwise coordinates are not changed, and false is returned. - */ -Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, - unsigned int /* button */) +Box BufferView::Pimpl::insetDimensions(LyXText const & text, + LyXCursor const & cursor) const { - if (!screen_.get()) + Paragraph /*const*/ & par = *cursor.par(); + pos_type const pos = cursor.pos(); + + lyx::Assert(par.getInset(pos)); + + Inset const & inset(*par.getInset(pos)); + + LyXFont const & font = text.getFont(buffer_, &par, pos); + + int const width = inset.width(bv_, font); + int const inset_x = font.isVisibleRightToLeft() + ? (cursor.x() - width) : cursor.x(); + + return Box( + inset_x + inset.scroll(), + inset_x + width, + cursor.y() - inset.ascent(bv_, font), + cursor.y() + inset.descent(bv_, font)); +} + + +Inset * BufferView::Pimpl::checkInset(LyXText const & text, + LyXCursor const & cursor, + int & x, int & y) const +{ + pos_type const pos(cursor.pos()); + Paragraph /*const*/ & par(*cursor.par()); + + if (pos >= par.size() || !par.isInset(pos)) { + return 0; + } + + Inset /*const*/ * inset = par.getInset(pos); + + if (!isEditableInset(inset)) { + return 0; + } + + Box b(insetDimensions(text, cursor)); + + if (!b.contained(x, y)) { + lyxerr[Debug::GUI] << "Missed inset at x,y " << x << "," << y + << " box " << b << endl; return 0; + } + + text.setCursor(bv_, &par, pos, true); + + x -= b.x1; + // The origin of an inset is on the baseline + y -= (text.cursor.y()); - int y_tmp = y + text->first; + return inset; +} + + +Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y) +{ + if (!screen_.get()) + return 0; + int y_tmp = y + text->first_y; + LyXCursor cursor; text->setCursorFromCoordinates(bv_, cursor, x, y_tmp); - text->setCursor(bv_, cursor, cursor.par(),cursor.pos(),true); + + Inset * inset(checkInset(*text, cursor, x, y_tmp)); - lyx::pos_type pos; + if (inset) { + y = y_tmp; + return inset; + } - if (cursor.pos() < cursor.par()->size() - && cursor.par()->isInset(cursor.pos()) - && isEditableInset(cursor.par()->getInset(cursor.pos()))) - { - pos = cursor.pos(); - } else if ((cursor.pos() - 1 >= 0) - && cursor.par()->isInset(cursor.pos() - 1) - && isEditableInset(cursor.par()->getInset(cursor.pos() - 1))) - { - pos = cursor.pos() - 1; - // if the inset takes a full row, then the cursor.y() - // at the end of the inset will be wrong. So step the cursor - // back one - text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true); - } else { + // look at previous position + + if (cursor.pos() == 0) { return 0; } - // Check whether the inset really was hit - Inset * inset = cursor.par()->getInset(pos); - LyXFont const & font = text->getFont(buffer_, cursor.par(), pos); - int const width = inset->width(bv_, font); - int const inset_x = font.isVisibleRightToLeft() - ? cursor.x() - width : cursor.x(); - int const start_x = inset_x + inset->scroll(); - int const end_x = inset_x + width; - int const start_y = cursor.y() - inset->ascent(bv_, font); - int const end_y = cursor.y() + inset->descent(bv_, font); - - if (x > start_x && x < end_x && y_tmp > start_y && y < end_y) { - text->setCursor(bv_, cursor.par(), pos, true); - x = x - start_x; - // The origin of an inset is on the baseline - y = y_tmp - (text->cursor.y()); - return inset; - } + // move back one + text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true); - return 0; + inset = checkInset(*text, cursor, x, y_tmp); + if (inset) { + y = y_tmp; + } + return inset; } @@ -942,6 +1002,7 @@ void BufferView::Pimpl::workAreaExpose() if (lyxerr.debugging()) textcache.show(lyxerr, "Expose delete all"); textcache.clear(); + buffer_->resizeInsets(bv_); } else if (heightChange) { // Rebuild image of current screen updateScreen(); @@ -1060,27 +1121,20 @@ void BufferView::Pimpl::update(LyXText * text, BufferView::UpdateCodes f) // Callback for cursor timer void BufferView::Pimpl::cursorToggle() { - // Quite a nice place for asyncron Inset updating, isn't it? - // Actually no! This is run even if no buffer exist... so (Lgb) if (!buffer_) { cursor_timeout.restart(); return; } - int status = 1; - int const pid = waitpid(static_cast(0), &status, WNOHANG); - if (pid == -1) // error find out what is wrong - ; // ignore it for now. - else if (pid > 0) - sigchldchecker(pid, &status); - - updatelist.update(bv_); - if (!screen_.get()) { cursor_timeout.restart(); return; } + /* FIXME */ + extern void reapSpellchecker(void); + reapSpellchecker(); + if (!bv_->theLockingInset()) { screen_->cursorToggle(bv_); } else { @@ -1096,10 +1150,9 @@ void BufferView::Pimpl::cursorPrevious(LyXText * text) if (!text->cursor.row()->previous()) return; - int y = text->first; - if (text->inset_owner) - y += bv_->text->first; + int y = text->first_y; Row * cursorrow = text->cursor.row(); + text->setCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y); finishUndo(); // This is to allow jumping over large insets @@ -1112,7 +1165,7 @@ void BufferView::Pimpl::cursorPrevious(LyXText * text) text->cursor.y() - text->cursor.row()->baseline() + text->cursor.row()->height() - - workarea_.height() + 1 ); + - workarea_.height() + 1); updateScrollbar(); } @@ -1122,7 +1175,7 @@ void BufferView::Pimpl::cursorNext(LyXText * text) if (!text->cursor.row()->next()) return; - int y = text->first + workarea_.height(); + int y = text->first_y + workarea_.height(); // if (text->inset_owner) // y += bv_->text->first; text->getRowNearY(y); @@ -1144,7 +1197,8 @@ void BufferView::Pimpl::cursorNext(LyXText * text) bool BufferView::Pimpl::available() const { - if (buffer_ && bv_->text) return true; + if (buffer_ && bv_->text) + return true; return false; } @@ -1184,7 +1238,7 @@ void BufferView::Pimpl::restorePosition(unsigned int i) Buffer * b = bufferlist.exists(fname) ? bufferlist.getBuffer(fname) : bufferlist.loadLyXFile(fname); // don't ask, just load it - if (b != 0 ) buffer(b); + if (b != 0) buffer(b); } Paragraph * par = buffer_->getParFromID(saved_positions[i].par_id); @@ -1337,19 +1391,21 @@ void BufferView::Pimpl::center() void BufferView::Pimpl::pasteClipboard(bool asPara) { - if (!buffer_) return; + if (!buffer_) + return; screen_->hideCursor(); beforeChange(bv_->text); string const clip(workarea_.getClipboard()); - if (clip.empty()) return; + if (clip.empty()) + return; if (asPara) { - bv_->text->insertStringAsParagraphs(bv_, clip); + bv_->getLyXText()->insertStringAsParagraphs(bv_, clip); } else { - bv_->text->insertStringAsLines(bv_, clip); + bv_->getLyXText()->insertStringAsLines(bv_, clip); } update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); } @@ -1376,9 +1432,13 @@ void BufferView::Pimpl::moveCursorUpdate(bool selecting) lt->setSelection(bv_); if (lt->bv_owner) toggleToggle(); + else + updateInset(lt->inset_owner, false); + } + if (lt->bv_owner) { + update(lt, BufferView::SELECT|BufferView::FITCUR); + showCursor(); } - update(lt, BufferView::SELECT|BufferView::FITCUR); - showCursor(); /* ---> Everytime the cursor is moved, show the current font state. */ // should this too me moved out of this func? @@ -1408,7 +1468,7 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) string initpath = lyxrc.document_path; if (available()) { - string const trypath = owner_->buffer()->filepath; + string const trypath = owner_->buffer()->filePath(); // If directory is writeable, use this as default. if (IsDirWriteable(trypath)) initpath = trypath; @@ -1417,9 +1477,9 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) FileDialog fileDlg(bv_->owner(), _("Select LyX document to insert"), LFUN_FILE_INSERT, - make_pair(string(_("Documents")), + make_pair(string(_("Documents|#o#O")), string(lyxrc.document_path)), - make_pair(string(_("Examples")), + make_pair(string(_("Examples|#E#e")), string(AddPath(system_lyxdir, "examples")))); FileDialog::Result result = @@ -1493,7 +1553,6 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; } - case LFUN_TABULAR_FEATURE: case LFUN_SCROLL_INSET: // this is not handled here as this funktion is only aktive // if we have a locking_inset and that one is (or contains) @@ -1520,8 +1579,9 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) case LFUN_PASTESELECTION: { - bool asPara = false; - if (argument == "paragraph") asPara = true; + bool asPara = false; + if (argument == "paragraph") + asPara = true; pasteClipboard(asPara); } break; @@ -1584,10 +1644,6 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) hfill(); break; - case LFUN_DEPTH: - changeDepth(bv_, bv_->getLyXText(), 0); - break; - case LFUN_DEPTH_MIN: changeDepth(bv_, bv_->getLyXText(), -1); break; @@ -1620,34 +1676,34 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) // Derive layout number from given argument (string) // and current buffer's textclass (number). */ textclass_type tclass = buffer_->params.textclass; - pair layout = - textclasslist.NumberOfLayout(tclass, argument); + bool hasLayout = + textclasslist[tclass].hasLayout(argument); + string layout = argument; // If the entry is obsolete, use the new one instead. - if (layout.first) { - string obs = textclasslist.Style(tclass, layout.second) + if (hasLayout) { + string const & obs = textclasslist[tclass][layout] .obsoleted_by(); if (!obs.empty()) - layout = textclasslist.NumberOfLayout(tclass, obs); + layout = obs; } - // see if we found the layout number: - if (!layout.first) { + if (!hasLayout) { owner_->getLyXFunc()->setErrorMessage( string(N_("Layout ")) + argument + N_(" not known")); break; } - if (current_layout != layout.second) { + if (current_layout != layout) { LyXText * lt = bv_->getLyXText(); hideCursor(); - current_layout = layout.second; + current_layout = layout; update(lt, BufferView::SELECT | BufferView::FITCUR); - lt->setLayout(bv_, layout.second); - owner_->setLayout(layout.second); + lt->setLayout(bv_, layout); + owner_->setLayout(layout); update(lt, BufferView::SELECT | BufferView::FITCUR @@ -2205,7 +2261,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) case LFUN_ENDSEL: { LyXText * lt = bv_->getLyXText(); - + update(lt, BufferView::SELECT|BufferView::FITCUR); lt->cursorEnd(bv_); finishUndo(); @@ -2292,9 +2348,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) { LyXText * lt = bv_->getLyXText(); - LyXLayout const & style = textclasslist - .Style(buffer_->params.textclass, - lt->cursor.par()->getLayout()); + LyXLayout const & style = textclasslist[buffer_->params.textclass][lt->cursor.par()->layout()]; if (style.free_spacing) { lt->insertChar(bv_, ' '); @@ -2303,7 +2357,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) | BufferView::FITCUR | BufferView::CHANGE); } else { - protectedBlank(lt); + specialChar(InsetSpecialChar::PROTECTED_SEPARATOR); } moveCursorUpdate(false); } @@ -2581,13 +2635,13 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) if (cursor.par()->params().spaceTop() == VSpace(VSpace::NONE)) { lt->setParagraph (bv_, - cursor.par()->params().lineTop(), + cursor.par()->params().lineTop(), cursor.par()->params().lineBottom(), - cursor.par()->params().pagebreakTop(), + cursor.par()->params().pagebreakTop(), cursor.par()->params().pagebreakBottom(), VSpace(VSpace::DEFSKIP), cursor.par()->params().spaceBottom(), - cursor.par()->params().spacing(), - cursor.par()->params().align(), + cursor.par()->params().spacing(), + cursor.par()->params().align(), cursor.par()->params().labelWidthString(), 1); //update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); } @@ -2698,12 +2752,8 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) } break; - case LFUN_INSET_TEXT: - insertAndEditInset(new InsetText); - break; - case LFUN_INSET_ERT: - insertAndEditInset(new InsetERT); + insertAndEditInset(new InsetERT(buffer_->params)); break; case LFUN_INSET_EXTERNAL: @@ -2711,25 +2761,26 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; case LFUN_INSET_FOOTNOTE: - insertAndEditInset(new InsetFoot); + insertAndEditInset(new InsetFoot(buffer_->params)); break; case LFUN_INSET_MARGINAL: - insertAndEditInset(new InsetMarginal); + insertAndEditInset(new InsetMarginal(buffer_->params)); break; case LFUN_INSET_MINIPAGE: - insertAndEditInset(new InsetMinipage); + insertAndEditInset(new InsetMinipage(buffer_->params)); break; case LFUN_INSERT_NOTE: - insertAndEditInset(new InsetNote); + insertAndEditInset(new InsetNote(buffer_->params)); break; case LFUN_INSET_FLOAT: // check if the float type exist if (floatList.typeExist(argument)) { - insertAndEditInset(new InsetFloat(argument)); + insertAndEditInset(new InsetFloat(buffer_->params, + argument)); } else { lyxerr << "Non-existent float type: " << argument << endl; @@ -2740,7 +2791,8 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) { // check if the float type exist if (floatList.typeExist(argument)) { - InsetFloat * new_inset = new InsetFloat(argument); + InsetFloat * new_inset = + new InsetFloat(buffer_->params, argument); new_inset->wide(true); if (insertInset(new_inset)) new_inset->edit(bv_); @@ -2770,7 +2822,8 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) if (bv_->theLockingInset()) { lyxerr << "Locking inset code: " << static_cast(bv_->theLockingInset()->lyxCode()); - InsetCaption * new_inset = new InsetCaption; + InsetCaption * new_inset = + new InsetCaption(buffer_->params); new_inset->setOwner(bv_->theLockingInset()); new_inset->setAutoBreakRows(true); new_inset->setDrawFrame(0, InsetText::LOCKED); @@ -2830,7 +2883,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; case LFUN_GETLAYOUT: - owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.par()->layout)); + owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.par()->layout())); break; case LFUN_GETFONT: @@ -2914,13 +2967,13 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) case LFUN_CITATION_INSERT: { InsetCommandParams p; - p.setFromString( argument ); + p.setFromString(argument); - InsetCitation * inset = new InsetCitation( p ); + InsetCitation * inset = new InsetCitation(p); if (!insertInset(inset)) delete inset; else - updateInset( inset, true ); + updateInset(inset, true); } break; @@ -2932,7 +2985,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) string const db = token(argument, ' ', 0); string const bibstyle = token(argument, ' ', 1); - InsetCommandParams p( "BibTeX", db, bibstyle ); + InsetCommandParams p("BibTeX", db, bibstyle); InsetBibtex * inset = new InsetBibtex(p); if (insertInset(inset)) { @@ -3030,7 +3083,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) case LFUN_PARENTINSERT: { lyxerr << "arg " << argument << endl; - InsetCommandParams p( "lyxparent", argument ); + InsetCommandParams p("lyxparent", argument); Inset * inset = new InsetParent(p, *buffer_); if (!insertInset(inset, "Standard")) delete inset; @@ -3206,27 +3259,6 @@ void BufferView::Pimpl::hfill() } -void BufferView::Pimpl::protectedBlank(LyXText * lt) -{ - if (available()) { - hideCursor(); - update(lt, BufferView::SELECT|BufferView::FITCUR); - InsetSpecialChar * new_inset = - new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR); -#ifdef WITH_WARNINGS -#warning Why is this code different from specialChar() below? (JMarc) -// the code in specialChar is a generic version of what used to exist -// for other special chars. I did not merge this case because of the -// call to updateInset(), but what does it do? -#endif - if (!insertInset(new_inset)) - delete new_inset; - else - updateInset(new_inset, true); - } -} - - void BufferView::Pimpl::specialChar(InsetSpecialChar::Kind kind) { if (available()) { @@ -3236,9 +3268,10 @@ void BufferView::Pimpl::specialChar(InsetSpecialChar::Kind kind) update(lt, BufferView::SELECT|BufferView::FITCUR); InsetSpecialChar * new_inset = new InsetSpecialChar(kind); - insertInset(new_inset); - // Ok, what happens here if we are unable to insert - // the inset? Leak it? + if (!insertInset(new_inset)) + delete new_inset; + else + updateInset(new_inset, true); } } @@ -3260,12 +3293,12 @@ void BufferView::Pimpl::smartQuote() hideCursor(); - LyXLayout const & style = textclasslist.Style( - bv_->buffer()->params.textclass, par->getLayout()); + LyXLayout const & style = + textclasslist[bv_->buffer()->params.textclass][par->layout()]; if (style.pass_thru || (!insertInset(new InsetQuotes(c, bv_->buffer()->params)))) - Dispatch(LFUN_SELFINSERT, "\""); + bv_->owner()->getLyXFunc()->dispatch(LFUN_SELFINSERT, "\""); } @@ -3321,17 +3354,20 @@ bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); } - pair lres = - textclasslist.NumberOfLayout(buffer_->params .textclass, lout); - layout_type lay = 0; - if (lres.first != false) { + string lres = lout; + LyXTextClass const & tclass = + textclasslist[buffer_->params.textclass]; + bool hasLayout = tclass.hasLayout(lres); + string lay = tclass.defaultLayoutName(); + + if (hasLayout != false) { // layout found - lay = lres.second; + lay = lres; } else { - // layout not fount using default "Standard" (0) - lay = 0; + // layout not fount using default + lay = tclass.defaultLayoutName(); } - + bv_->text->setLayout(bv_, lay); bv_->text->setParagraph(bv_, 0, 0, @@ -3354,7 +3390,7 @@ bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) { - if (!inset) + if (!inset || !available()) return; // first check for locking insets @@ -3369,10 +3405,9 @@ void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) return; } } else if (bv_->theLockingInset()->updateInsetInInset(bv_, inset)) { - if (bv_->text->updateInset(bv_, - bv_->theLockingInset())) { + if (bv_->text->updateInset(bv_, bv_->theLockingInset())) { update(); - if (mark_dirty){ + if (mark_dirty) { buffer_->markDirty(); } updateScrollbar(); @@ -3381,9 +3416,14 @@ void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) } } - // then check the current buffer - if (available()) { - hideCursor(); + // then check if the inset is a top_level inset (has no owner) + // if yes do the update as always otherwise we have to update the + // toplevel inset where this inset is inside + Inset * tl_inset = inset; + while(tl_inset->owner()) + tl_inset = tl_inset->owner(); + hideCursor(); + if (tl_inset == inset) { update(bv_->text, BufferView::UPDATE); if (bv_->text->updateInset(bv_, inset)) { if (mark_dirty) { @@ -3396,6 +3436,13 @@ void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) } return; } + } else if (static_cast(tl_inset) + ->updateInsetInInset(bv_, inset)) + { + if (bv_->text->updateInset(bv_, tl_inset)) { + update(); + updateScrollbar(); + } } } @@ -3424,9 +3471,9 @@ void BufferView::Pimpl::gotoInset(vector const & codes, if (!bv_->text->gotoNextInset(bv_, codes, contents)) { if (bv_->text->cursor.pos() - || bv_->text->cursor.par() != bv_->text->firstParagraph()) { + || bv_->text->cursor.par() != bv_->text->ownerParagraph()) { LyXCursor tmp = bv_->text->cursor; - bv_->text->cursor.par(bv_->text->firstParagraph()); + bv_->text->cursor.par(bv_->text->ownerParagraph()); bv_->text->cursor.pos(0); if (!bv_->text->gotoNextInset(bv_, codes, contents)) { bv_->text->cursor = tmp;