X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=34b5a478e357034a93c92d4a0ff62c214eb557a7;hb=498f06d43a0f2000c3f704db1ea39fda3c819fe6;hp=b0bac3161019d4a7eefc5c2bd5a99d70768e13f0;hpb=2a0909f47bb7e211c335b3253372102d92714b05;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index b0bac31610..34b5a478e3 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -8,10 +8,6 @@ #include -#ifdef __GNUG__ -#pragma implementation -#endif - #include "BufferView_pimpl.h" #include "frontends/WorkArea.h" #include "frontends/screen.h" @@ -20,6 +16,7 @@ #include "frontends/Dialogs.h" #include "frontends/Alert.h" #include "frontends/FileDialog.h" +#include "frontends/mouse_state.h" #include "lyxtext.h" #include "lyxrow.h" #include "paragraph.h" @@ -40,22 +37,19 @@ #include "ParagraphParameters.h" #include "undo_funcs.h" #include "funcrequest.h" -#include "factory.h" +#include "iterators.h" +#include "lyxfind.h" #include "insets/insetbib.h" #include "insets/insettext.h" -#include "insets/inseturl.h" #include "insets/insetlatexaccent.h" #include "insets/insettoc.h" -#include "insets/insetref.h" -#include "insets/insetparent.h" #include "insets/insetindex.h" +#include "insets/insetref.h" #include "insets/insetinclude.h" #include "insets/insetcite.h" #include "insets/insetgraphics.h" #include "insets/insetmarginal.h" -#include "insets/insettabular.h" -#include "insets/insetcaption.h" #include "insets/insetfloatlist.h" #include "mathed/formulabase.h" @@ -65,25 +59,14 @@ #include "support/LAssert.h" #include "support/lstrings.h" #include "support/filetools.h" -#include "support/lyxfunctional.h" #include #include +#include "BoostFormat.h" -#include -#include #include #include -#include - -#ifndef CXX_GLOBAL_CSTD -using std::tm; -using std::localtime; -using std::time; -using std::setlocale; -using std::strftime; -#endif using std::vector; using std::find_if; @@ -94,16 +77,8 @@ using std::make_pair; using std::min; using lyx::pos_type; -using lyx::textclass_type; - -/* the selection possible is needed, that only motion events are - * used, where the bottom press event was on the drawing area too */ -bool selection_possible = false; extern BufferList bufferlist; -extern char ascii_type; - -extern int bibitemMaxWidth(BufferView *, LyXFont const &); namespace { @@ -115,18 +90,15 @@ unsigned int const saved_positions_num = 20; // to these connections we avoid a segfault upon startup, and also at exit. // (Lgb) +boost::signals::connection dispatchcon; boost::signals::connection timecon; boost::signals::connection doccon; boost::signals::connection resizecon; -boost::signals::connection bpresscon; -boost::signals::connection breleasecon; -boost::signals::connection motioncon; -boost::signals::connection doublecon; -boost::signals::connection triplecon; boost::signals::connection kpresscon; boost::signals::connection selectioncon; boost::signals::connection lostcon; + } // anon namespace @@ -143,16 +115,8 @@ BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner, .connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); resizecon = workarea().workAreaResize .connect(boost::bind(&BufferView::Pimpl::workAreaResize, this)); - bpresscon = workarea().workAreaButtonPress - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonPress, this, _1, _2, _3)); - breleasecon = workarea().workAreaButtonRelease - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonRelease, this, _1, _2, _3)); - motioncon = workarea().workAreaMotionNotify - .connect(boost::bind(&BufferView::Pimpl::workAreaMotionNotify, this, _1, _2, _3)); - doublecon = workarea().workAreaDoubleClick - .connect(boost::bind(&BufferView::Pimpl::doubleClick, this, _1, _2, _3)); - triplecon = workarea().workAreaTripleClick - .connect(boost::bind(&BufferView::Pimpl::tripleClick, this, _1, _2, _3)); + dispatchcon = workarea().dispatch + .connect(boost::bind(&BufferView::Pimpl::dispatch, this, _1)); kpresscon = workarea().workAreaKeyPress .connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2)); selectioncon = workarea().selectionRequested @@ -188,7 +152,7 @@ Painter & BufferView::Pimpl::painter() const void BufferView::Pimpl::buffer(Buffer * b) { lyxerr[Debug::INFO] << "Setting buffer in BufferView (" - << b << ")" << endl; + << b << ')' << endl; if (buffer_) { buffer_->delUser(bv_); @@ -206,7 +170,9 @@ void BufferView::Pimpl::buffer(Buffer * b) // set current buffer buffer_ = b; - if (bufferlist.getState() == BufferList::CLOSING) return; + // if we're quitting lyx, don't bother updating stuff + if (quitting) + return; // if we are closing the buffer, use the first buffer as current if (!buffer_) { @@ -299,8 +265,8 @@ int BufferView::Pimpl::resizeCurrentBuffer() bool selection = false; bool mark_set = false; - owner_->prohibitInput(); - + owner_->busy(true); + owner_->message(_("Formatting document...")); if (bv_->text) { @@ -332,6 +298,8 @@ int BufferView::Pimpl::resizeCurrentBuffer() // bv_->text->owner(bv_); if (lyxerr.debugging()) textcache.show(lyxerr, "resizeCurrentBuffer"); + + buffer_->resizeInsets(bv_); } else { bv_->text = new LyXText(bv_); bv_->text->init(bv_); @@ -362,7 +330,7 @@ int BufferView::Pimpl::resizeCurrentBuffer() bv_->text->first_y = screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); switchKeyMap(); - owner_->allowInput(); + owner_->busy(false); updateScrollbar(); @@ -388,9 +356,9 @@ void BufferView::Pimpl::updateScrollbar() LyXText const & t = *bv_->text; lyxerr[Debug::GUI] << "Updating scrollbar: h " << t.height << ", first_y " - << t.first_y << ", default height " << t.defaultHeight() << endl; + << t.first_y << ", default height " << defaultRowHeight() << endl; - workarea().setScrollbarParams(t.height, t.first_y, t.defaultHeight()); + workarea().setScrollbarParams(t.height, t.first_y, defaultRowHeight()); } @@ -398,17 +366,17 @@ void BufferView::Pimpl::scrollDocView(int value) { lyxerr[Debug::GUI] << "scrollDocView of " << value << endl; - if (!buffer_) return; + if (!buffer_) + return; screen().draw(bv_->text, bv_, value); - if (!lyxrc.cursor_follows_scrollbar) { + if (!lyxrc.cursor_follows_scrollbar) return; - } LyXText * vbt = bv_->text; - int const height = vbt->defaultHeight(); + int const height = defaultRowHeight(); int const first = static_cast((bv_->text->first_y + height)); int const last = static_cast((bv_->text->first_y + workarea().workHeight() - height)); @@ -419,253 +387,33 @@ void BufferView::Pimpl::scrollDocView(int value) } -int BufferView::Pimpl::scroll(long time) -{ - if (!buffer_) - return 0; - - LyXText const * t = bv_->text; - - double const diff = t->defaultHeight() - + double(time) * double(time) * 0.125; - - scrollDocView(int(diff)); - workarea().setScrollbarParams(t->height, t->first_y, t->defaultHeight()); - return 0; -} - - -void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, - key_modifier::state state) -{ - bv_->owner()->getLyXFunc().processKeySym(key, state); -} - - -void BufferView::Pimpl::workAreaMotionNotify(int x, int y, mouse_button::state state) -{ - // Only use motion with button 1 - if (!(state & mouse_button::button1)) - return; - - if (!buffer_) - return; - - // Check for inset locking - if (bv_->theLockingInset()) { - LyXCursor cursor = bv_->text->cursor; - LyXFont font = bv_->text->getFont(buffer_, - cursor.par(), cursor.pos()); - int width = bv_->theLockingInset()->width(bv_, font); - int inset_x = font.isVisibleRightToLeft() - ? cursor.ix() - width : cursor.ix(); - int start_x = inset_x + bv_->theLockingInset()->scroll(); - - FuncRequest cmd(bv_, LFUN_MOUSE_MOTION, - x - start_x, y - cursor.iy() + bv_->text->first_y, state); - bv_->theLockingInset()->localDispatch(cmd); - return; - } - - // The test for not selection possible is needed, that only motion - // events are used, where the bottom press event was on - // the drawing area too - if (!selection_possible) - return; - - screen().hideCursor(); - - Row * cursorrow = bv_->text->cursor.row(); - bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_y); -#if 0 - // sorry for this but I have a strange error that the y value jumps at - // a certain point. This seems like an error in my xforms library or - // in some other local environment, but I would like to leave this here - // for the moment until I can remove this (Jug 20020418) - if (y_before < bv_->text->cursor.y()) - lyxerr << y_before << ":" << bv_->text->cursor.y() << endl; -#endif - // This is to allow jumping over large insets - if (cursorrow == bv_->text->cursor.row()) { - if (y >= int(workarea().workHeight())) { - bv_->text->cursorDown(bv_, false); - } else if (y < 0) { - bv_->text->cursorUp(bv_, false); - } - } - - if (!bv_->text->selection.set()) - update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted - - bv_->text->setSelection(bv_); - screen().toggleToggle(bv_->text, bv_); - fitCursor(); - showCursor(); -} - - -// Single-click on work area -void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, - mouse_button::state button) +void BufferView::Pimpl::scroll(int lines) { - if (!buffer_) - return; - - // ok ok, this is a hack (for xforms) - if (button == mouse_button::button4) { - scroll(-lyxrc.wheel_jump); - // We shouldn't go further down as we really should only do the - // scrolling and be done with this. Otherwise we may open some - // dialogs (Jug 20020424). - return; - } else if (button == mouse_button::button5) { - scroll(lyxrc.wheel_jump); - // We shouldn't go further down as we really should only do the - // scrolling and be done with this. Otherwise we may open some - // dialogs (Jug 20020424). - return; - } - - Inset * inset_hit = checkInsetHit(bv_->text, xpos, 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 == mouse_button::button2 && bv_->getLyXText()->selection.set()) { - owner_->dispatch(FuncRequest(LFUN_COPY)); - paste_internally = true; - } - - int const screen_first = bv_->text->first_y; - - if (bv_->theLockingInset()) { - // We are in inset locking mode - - // Check whether the inset was hit. If not reset mode, - // otherwise give the event to the inset - if (inset_hit == bv_->theLockingInset()) { - FuncRequest cmd(bv_, LFUN_MOUSE_PRESS, xpos, ypos, button); - bv_->theLockingInset()->localDispatch(cmd); - return; - } - bv_->unlockInset(bv_->theLockingInset()); - } - - if (!inset_hit) - selection_possible = true; - screen().hideCursor(); - - // Clear the selection - screen().toggleSelection(bv_->text, bv_); - bv_->text->clearSelection(); - bv_->text->fullRebreak(bv_); - update(); - updateScrollbar(); - - // Single left click in math inset? - if (isHighlyEditableInset(inset_hit)) { - // Highly editable inset, like math - UpdatableInset * inset = static_cast(inset_hit); - selection_possible = false; - owner_->updateLayoutChoice(); - owner_->message(inset->editMessage()); - //inset->edit(bv_, xpos, ypos, button); - // We just have to lock the inset before calling a PressEvent on it! - // we don't need the edit() call here! (Jug20020329) - if (!bv_->lockInset(inset)) { - lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; - } - FuncRequest cmd(bv_, LFUN_MOUSE_PRESS, xpos, ypos, button); - inset->localDispatch(cmd); - return; - } - // I'm not sure we should continue here if we hit an inset (Jug20020403) - - // Right click on a footnote flag opens float menu - if (button == mouse_button::button3) { - selection_possible = false; - return; - } - - if (!inset_hit) // otherwise it was already set in checkInsetHit(...) - bv_->text->setCursorFromCoordinates(bv_, xpos, ypos + screen_first); - finishUndo(); - bv_->text->selection.cursor = bv_->text->cursor; - bv_->text->cursor.x_fix(bv_->text->cursor.x()); - - owner_->updateLayoutChoice(); - if (fitCursor()) { - selection_possible = false; - } - - // Insert primary selection with middle mouse - // if there is a local selection in the current buffer, - // insert this - if (button == mouse_button::button2) { - if (paste_internally) - owner_->dispatch(FuncRequest(LFUN_PASTE)); - else - owner_->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph")); - selection_possible = false; + if (!buffer_) { return; } -} + LyXText const * t = bv_->text; + int const line_height = defaultRowHeight(); -void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, mouse_button::state button) -{ - if (!buffer_) - return; + // The new absolute coordinate + int new_first_y = t->first_y + lines * line_height; - LyXText * text = bv_->getLyXText(); + // Restrict to a valid value + new_first_y = std::min(t->height - 4 * line_height, new_first_y); + new_first_y = std::max(0, new_first_y); - if (text->bv_owner && bv_->theLockingInset()) - return; + scrollDocView(new_first_y); - if (button == mouse_button::button1) { - 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); - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } + // Update the scrollbar. + workarea().setScrollbarParams(t->height, t->first_y, defaultRowHeight()); } -void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, mouse_button::state button) +void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, + key_modifier::state state) { - if (!buffer_) - return; - - LyXText * text = bv_->getLyXText(); - - if (text->bv_owner && bv_->theLockingInset()) - return; - - if (button == mouse_button::button1) { - if (text->bv_owner) { - screen().hideCursor(); - screen().toggleSelection(text, bv_); - } - text->cursorHome(bv_); - text->selection.cursor = text->cursor; - text->cursorEnd(bv_); - text->setSelection(bv_); - 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); - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } + bv_->owner()->getLyXFunc().processKeySym(key, state); } @@ -707,207 +455,6 @@ void BufferView::Pimpl::selectionLost() } -void BufferView::Pimpl::workAreaButtonRelease(int x, int y, - mouse_button::state button) -{ - // do nothing if we used the mouse wheel - if (!buffer_ || button == mouse_button::button4 || button == mouse_button::button5) - return; - - // 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); - - if (bv_->theLockingInset()) { - // We are in inset locking mode. - - // LyX does a kind of work-area grabbing for insets. - // Only a ButtonPress FuncRequest outside the inset will - // force a insetUnlock. - FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button); - bv_->theLockingInset()->localDispatch(cmd); - return; - } - - selection_possible = false; - - if (button == mouse_button::button2) - return; - - // finish selection - if (button == mouse_button::button1) { - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } - - switchKeyMap(); - owner_->view_state_changed(); - owner_->updateMenubar(); - owner_->updateToolbar(); - - // Did we hit an editable inset? - if (inset_hit) { - selection_possible = false; - - // if we reach this point with a selection, it - // must mean we are currently selecting. - // But we don't want to open the inset - // because that is annoying for the user. - // So just pretend we didn't hit it. - // this is OK because a "kosher" ButtonRelease - // will follow a ButtonPress that clears - // the selection. - // Note this also fixes selection drawing - // problems if we end up opening an inset - if (bv_->getLyXText()->selection.set()) - return; - - // CHECK fix this proper in 0.13 - // well, maybe 13.0 !!!!!!!!! - - // Following a ref shouldn't issue - // a push on the undo-stack - // anylonger, now that we have - // keybindings for following - // references and returning from - // references. IMHO though, it - // should be the inset's own business - // to push or not push on the undo - // stack. They don't *have* to - // alter the document... - // (Joacim) - // ...or maybe the SetCursorParUndo() - // below isn't necessary at all anylonger? - if (inset_hit->lyxCode() == Inset::REF_CODE) { - setCursorParUndo(bv_); - } - - owner_->message(inset_hit->editMessage()); - - if (isHighlyEditableInset(inset_hit)) { - // Highly editable inset, like math - UpdatableInset *inset = (UpdatableInset *)inset_hit; - FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button); - inset->localDispatch(cmd); - } else { - FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button); - inset_hit->localDispatch(cmd); - // IMO this is a grosshack! Inset's should be changed so that - // they call the actions they have to do with the insetButtonRel. - // function and not in the edit(). This should be changed - // (Jug 20020329) -#ifdef WITH_WARNINGS -#warning Please remove donot call inset->edit() here (Jug 20020812) -#endif - inset_hit->edit(bv_, x, y, button); - } - return; - } - - // Maybe we want to edit a bibitem ale970302 - if (bv_->text->cursor.par()->bibkey) { - bool const is_rtl = bv_->text->cursor.par()->isRightToLeftPar(buffer_->params); - int const width = bibitemMaxWidth(bv_, buffer_->params.getLyXTextClass().defaultfont()); - if ((is_rtl && x > bv_->text->workWidth(bv_)-20-width) || - (!is_rtl && x < 20+width)) { - bv_->text->cursor.par()->bibkey->edit(bv_, 0, 0, mouse_button::none); - } - } - - return; -} - - -Box BufferView::Pimpl::insetDimensions(LyXText const & text, - LyXCursor const & cursor) const -{ - 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.ix() - width) : cursor.ix(); - - return Box( - inset_x + inset.scroll(), - inset_x + width, - cursor.iy() - inset.ascent(bv_, font), - cursor.iy() + 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.iy(); - - return inset; -} - - -Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y) -{ - int y_tmp = y + text->first_y; - - LyXCursor cursor; - text->setCursorFromCoordinates(bv_, cursor, x, y_tmp); - - Inset * inset = checkInset(*text, cursor, x, y_tmp); - - if (inset) { - y = y_tmp; - return inset; - } - - // look at previous position - - if (cursor.pos() == 0) { - return 0; - } - - // move back one - text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true); - - inset = checkInset(*text, cursor, x, y_tmp); - if (inset) { - y = y_tmp; - } - return inset; -} - - void BufferView::Pimpl::workAreaResize() { static int work_area_width; @@ -1059,10 +606,6 @@ void BufferView::Pimpl::cursorToggle() return; } - /* FIXME */ - extern void reapSpellchecker(void); - reapSpellchecker(); - if (!bv_->theLockingInset()) { screen().cursorToggle(bv_); } else { @@ -1081,6 +624,21 @@ bool BufferView::Pimpl::available() const } +Change const BufferView::Pimpl::getCurrentChange() +{ + if (!bv_->buffer()->params.tracking_changes) + return Change(Change::UNCHANGED); + + LyXText * t(bv_->getLyXText()); + + if (!t->selection.set()) + return Change(Change::UNCHANGED); + + LyXCursor const & cur(t->selection.start); + return cur.par()->lookupChangeFull(cur.pos()); +} + + void BufferView::Pimpl::beforeChange(LyXText * text) { toggleSelection(); @@ -1097,8 +655,12 @@ void BufferView::Pimpl::savePosition(unsigned int i) bv_->text->cursor.pos()); if (i > 0) { ostringstream str; - str << _("Saved bookmark") << ' ' << i; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Saved bookmark %1$d")) % i; +#else + str << _("Saved bookmark ") << i; +#endif + owner_->message(STRCONV(str.str())); } } @@ -1129,8 +691,12 @@ void BufferView::Pimpl::restorePosition(unsigned int i) update(bv_->text, BufferView::SELECT | BufferView::FITCUR); if (i > 0) { ostringstream str; - str << _("Moved to bookmark") << ' ' << i; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Moved to bookmark %1$d")) % i; +#else + str << _("Moved to bookmark ") << i; +#endif + owner_->message(STRCONV(str.str())); } } @@ -1242,36 +808,6 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const */ -void BufferView::Pimpl::moveCursorUpdate(bool selecting, bool fitcur) -{ - LyXText * lt = bv_->getLyXText(); - - if (selecting || lt->selection.mark()) { - lt->setSelection(bv_); - if (lt->bv_owner) - toggleToggle(); - else - updateInset(lt->inset_owner, false); - } - if (lt->bv_owner) { - if (fitcur) - update(lt, BufferView::SELECT|BufferView::FITCUR); - else - update(lt, BufferView::SELECT); - showCursor(); - } else if (bv_->text->status() != LyXText::UNCHANGED) { - bv_->theLockingInset()->hideInsetCursor(bv_); - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); - showCursor(); - } - - if (!lt->selection.set()) - workarea().haveSelection(false); - - switchKeyMap(); -} - - Inset * BufferView::Pimpl::getInsetByCode(Inset::Code code) { #if 0 @@ -1345,7 +881,7 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) string(AddPath(system_lyxdir, "examples")))); FileDialog::Result result = - fileDlg.Select(initpath, + fileDlg.open(initpath, _("*.lyx| LyX Documents (*.lyx)")); if (result.first == FileDialog::Later) @@ -1367,43 +903,88 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) string const disp_fn(MakeDisplayPath(filename)); ostringstream s1; - s1 << _("Inserting document") << ' ' - << disp_fn << " ..."; - owner_->message(s1.str().c_str()); +#if USE_BOOST_FORMAT + s1 << boost::format(_("Inserting document %1$s...")) % disp_fn; +#else + s1 << _("Inserting document ") << disp_fn << _("..."); +#endif + owner_->message(STRCONV(s1.str())); bool const res = bv_->insertLyXFile(filename); if (res) { ostringstream str; - str << _("Document") << ' ' << disp_fn - << ' ' << _("inserted."); - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Document %1$s inserted.")) % disp_fn; +#else + str << _("Document ") << disp_fn << _(" inserted."); +#endif + owner_->message(STRCONV(str.str())); } else { ostringstream str; - str << _("Could not insert document") << ' ' - << disp_fn; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Could not insert document %1$s")) % disp_fn; +#else + str << _("Could not insert document ") << disp_fn; +#endif + owner_->message(STRCONV(str.str())); } } +void BufferView::Pimpl::trackChanges() +{ + Buffer * buf(bv_->buffer()); + bool const tracking(buf->params.tracking_changes); + + if (!tracking) { + ParIterator const end = buf->par_iterator_end(); + for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) { + (*it)->trackChanges(); + } + buf->params.tracking_changes = true; + + // we cannot allow undos beyond the freeze point + buf->undostack.clear(); + } else { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*buf->paragraphs.begin()), 0); +#warning changes FIXME + //moveCursorUpdate(false); + + bool found = lyxfind::findNextChange(bv_); + if (found) { + owner_->getDialogs().showMergeChanges(); + return; + } + + ParIterator const end = buf->par_iterator_end(); + for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) { + (*it)->untrackChanges(); + } + buf->params.tracking_changes = false; + } + + buf->redostack.clear(); +} + + bool BufferView::Pimpl::dispatch(FuncRequest const & ev) { - lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action[" - << ev.action <<"] arg[" << ev.argument << "]" << endl; + lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:" + << " action[" << ev.action << ']' + << " arg[" << ev.argument << ']' + << " x[" << ev.x << ']' + << " y[" << ev.y << ']' + << " button[" << ev.button() << ']' + << endl; + + // e.g. Qt mouse press when no buffer + if (!buffer_) + return false; LyXTextClass const & tclass = buffer_->params.getLyXTextClass(); switch (ev.action) { - case LFUN_TOC_INSERT: - { - InsetCommandParams p; - p.setCmdName("tableofcontents"); - Inset * inset = new InsetTOC(p); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - break; - } - case LFUN_SCROLL_INSET: // this is not handled here as this function is only active // if we have a locking_inset and that one is (or contains) @@ -1561,107 +1142,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) } break; - case LFUN_HTMLURL: - case LFUN_URL: - { - InsetCommandParams p; - if (ev.action == LFUN_HTMLURL) - p.setCmdName("htmlurl"); - else - p.setCmdName("url"); - owner_->getDialogs().createUrl(p.getAsString()); - } - break; - - case LFUN_INSERT_URL: - { - InsetCommandParams p; - p.setFromString(ev.argument); - - InsetUrl * inset = new InsetUrl(p); - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; - -#if 0 - case LFUN_INSET_LIST: - case LFUN_INSET_THEOREM: -#endif - case LFUN_INSERT_NOTE: - case LFUN_INSET_ERT: - case LFUN_INSET_EXTERNAL: - case LFUN_INSET_FLOAT: - case LFUN_INSET_FOOTNOTE: - case LFUN_INSET_MARGINAL: - case LFUN_INSET_MINIPAGE: - case LFUN_INSET_OPTARG: - case LFUN_INSET_WIDE_FLOAT: - { - FuncRequest cmd = ev; - cmd.setView(bv_); - Inset * inset = createInset(cmd); - if (inset) { - bool gotsel = false; - - if (bv_->getLyXText()->selection.set()) { - bv_->getLyXText()->cutSelection(bv_, true, false); - gotsel = true; - } - - if (insertInset(inset)) { - inset->edit(bv_); - if (gotsel) - owner_->dispatch(FuncRequest(LFUN_PASTESELECTION)); - } - else - delete inset; - } - break; - } - - case LFUN_INSET_CAPTION: - { - // Do we have a locking inset... - if (bv_->theLockingInset()) { - lyxerr << "Locking inset code: " - << static_cast(bv_->theLockingInset()->lyxCode()); - InsetCaption * new_inset = - new InsetCaption(buffer_->params); - new_inset->setOwner(bv_->theLockingInset()); - new_inset->setAutoBreakRows(true); - new_inset->setDrawFrame(0, InsetText::LOCKED); - new_inset->setFrameColor(0, LColor::captionframe); - if (insertInset(new_inset)) - new_inset->edit(bv_); - else - delete new_inset; - } - } - break; - - case LFUN_TABULAR_INSERT: - { - if (ev.argument.empty()) { - owner_->getDialogs().showTabularCreate(); - break; - } - - int r = 2; - int c = 2; - ::sscanf(ev.argument.c_str(),"%d%d", &r, &c); - InsetTabular * new_inset = - new InsetTabular(*buffer_, r, c); - bool const rtl = - bv_->getLyXText()->real_current_font.isRightToLeft(); - if (!open_new_inset(new_inset, rtl)) - delete new_inset; - } - break; - - // --- accented characters --------------------------- case LFUN_UMLAUT: @@ -1714,8 +1194,11 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) InsetCitation * inset = new InsetCitation(p); if (!insertInset(inset)) delete inset; - else + else { + inset->setLoadingBuffer(bv_->buffer(), false); updateInset(inset, true); + } + } break; @@ -1755,9 +1238,8 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) { InsetBibtex * inset = static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { + if (inset) inset->delDatabase(ev.argument); - } } break; @@ -1765,56 +1247,16 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) { InsetBibtex * inset = static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { + if (inset) inset->setOptions(ev.argument); - } } break; - case LFUN_INDEX_INSERT: - { - string entry = ev.argument; - if (entry.empty()) - entry = bv_->getLyXText()->getStringToIndex(bv_); - - if (entry.empty()) { - owner_->getDialogs().createIndex(); - break; - } - - InsetIndex * inset = new InsetIndex(InsetCommandParams("index", entry)); - - if (!insertInset(inset)) { - delete inset; - } else { - updateInset(inset, true); - } - } - break; - - case LFUN_INDEX_PRINT: - { - InsetCommandParams p("printindex"); - Inset * inset = new InsetPrintIndex(p); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - } - break; - - case LFUN_PARENTINSERT: - { - InsetCommandParams p("lyxparent", ev.argument); - Inset * inset = new InsetParent(p, *buffer_); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - } - - break; - case LFUN_CHILD_INSERT: { InsetInclude::Params p; - p.cparams.setFromString(ev.argument); + if (!ev.argument.empty()) + p.cparams.setFromString(ev.argument); p.masterFilename_ = buffer_->fileName(); InsetInclude * inset = new InsetInclude(p); @@ -1828,7 +1270,7 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) break; case LFUN_FLOAT_LIST: - if (floatList.typeExist(ev.argument)) { + if (tclass.floats().typeExist(ev.argument)) { Inset * inset = new InsetFloatList(ev.argument); if (!insertInset(inset, tclass.defaultLayoutName())) delete inset; @@ -1859,72 +1301,75 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) } break; - case LFUN_DATE_INSERT: // jdblair: date-insert cmd - { - time_t now_time_t = time(NULL); - struct tm * now_tm = localtime(&now_time_t); - setlocale(LC_TIME, ""); - string arg; - if (!ev.argument.empty()) - arg = ev.argument; - else - arg = lyxrc.date_insert_format; - char datetmp[32]; - int const datetmp_len = - ::strftime(datetmp, 32, arg.c_str(), now_tm); - - LyXText * lt = bv_->getLyXText(); - - for (int i = 0; i < datetmp_len; i++) { - lt->insertChar(bv_, datetmp[i]); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); + case LFUN_TRACK_CHANGES: + trackChanges(); + break; + + case LFUN_MERGE_CHANGES: + owner_->getDialogs().showMergeChanges(); + break; + + case LFUN_ACCEPT_ALL_CHANGES: { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0); +#warning FIXME changes + //moveCursorUpdate(false); + + while (lyxfind::findNextChange(bv_)) { + bv_->getLyXText()->acceptChange(bv_); } + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; + } + + case LFUN_REJECT_ALL_CHANGES: { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0); +#warning FIXME changes + //moveCursorUpdate(false); - lt->selection.cursor = lt->cursor; - moveCursorUpdate(false); + while (lyxfind::findNextChange(bv_)) { + bv_->getLyXText()->rejectChange(bv_); + } + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; + } + + case LFUN_ACCEPT_CHANGE: { + bv_->getLyXText()->acceptChange(bv_); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; } - break; + case LFUN_REJECT_CHANGE: { + bv_->getLyXText()->rejectChange(bv_); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; + } + case LFUN_UNKNOWN_ACTION: ev.errorMessage(N_("Unknown function!")); break; default: - FuncRequest cmd = ev; - cmd.setView(bv_); - return bv_->getLyXText()->dispatch(cmd); + return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_)); } // end of switch return true; } -// Open and lock an updatable inset -bool BufferView::Pimpl::open_new_inset(UpdatableInset * new_inset, bool behind) -{ - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - finishUndo(); - if (!insertInset(new_inset)) { - delete new_inset; - return false; - } - new_inset->edit(bv_, !behind); - return true; -} - - bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) { // if we are in a locking inset we should try to insert the // inset there otherwise this is a illegal function now if (bv_->theLockingInset()) { if (bv_->theLockingInset()->insetAllowed(inset)) - return bv_->theLockingInset()->insertInset(bv_, inset); + return bv_->theLockingInset()->insertInset(bv_, inset); return false; }