]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
Add LFUN_BRANCH_ACTIVATE and LFUN_BRANCH_DEACTIVATE, fixing bug 4341.
[lyx.git] / src / BufferView.cpp
index a338a68b103285b51c802d5e900b2a632300055a..a3f3672e5c0996d77813ec0f23e7223b3999c54b 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "BufferView.h"
 
+#include "BranchList.h"
 #include "Buffer.h"
 #include "buffer_funcs.h"
 #include "BufferList.h"
@@ -24,7 +25,6 @@
 #include "Cursor.h"
 #include "CutAndPaste.h"
 #include "DispatchResult.h"
-#include "EmbeddedFiles.h"
 #include "ErrorList.h"
 #include "factory.h"
 #include "FloatList.h"
@@ -214,6 +214,7 @@ struct BufferView::Private
 {
        Private(BufferView & bv): wh_(0), cursor_(bv),
                anchor_pit_(0), anchor_ypos_(0),
+               inlineCompletionUniqueChars_(0),
                last_inset_(0), gui_(0)
        {}
 
@@ -242,11 +243,11 @@ struct BufferView::Private
        vector<int> par_height_;
 
        ///
-       DocIterator inlineCompletionPos;
+       DocIterator inlineCompletionPos_;
        ///
-       docstring inlineCompletion;
+       docstring inlineCompletion_;
        ///
-       size_t inlineCompletionUniqueChars;
+       size_t inlineCompletionUniqueChars_;
 
        /// keyboard mapping object.
        Intl intl_;
@@ -263,6 +264,9 @@ struct BufferView::Private
        /** Not owned, so don't delete.
          */
        frontend::GuiBufferViewDelegate * gui_;
+
+       /// Cache for Find Next
+       FuncRequest search_request_cache_;
 };
 
 
@@ -784,7 +788,7 @@ void BufferView::showCursor(DocIterator const & dit)
 
        if (tm.contains(bot_pit)) {
                ParagraphMetrics const & pm = tm.parMetrics(bot_pit);
-               BOOST_ASSERT(!pm.rows().empty());
+               LASSERT(!pm.rows().empty(), /**/);
                // FIXME: smooth scrolling doesn't work in mathed.
                CursorSlice const & cs = dit.innerTextSlice();
                int offset = coordOffset(dit, dit.boundary()).y_;
@@ -800,8 +804,8 @@ void BufferView::showCursor(DocIterator const & dit)
        }
 
        // fix inline completion position
-       if (d->inlineCompletionPos.fixIfBroken())
-               d->inlineCompletionPos = DocIterator();
+       if (d->inlineCompletionPos_.fixIfBroken())
+               d->inlineCompletionPos_ = DocIterator();
 
        tm.redoParagraph(bot_pit);
        ParagraphMetrics const & pm = tm.parMetrics(bot_pit);
@@ -848,8 +852,7 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
        case LFUN_FONT_STATE:
        case LFUN_LABEL_INSERT:
        case LFUN_INFO_INSERT:
-       case LFUN_EXTERNAL_EDIT:
-       case LFUN_GRAPHICS_EDIT:
+       case LFUN_INSET_EDIT:
        case LFUN_PARAGRAPH_GOTO:
        case LFUN_NOTE_NEXT:
        case LFUN_REFERENCE_NEXT:
@@ -862,30 +865,20 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
        case LFUN_BIBTEX_DATABASE_ADD:
        case LFUN_BIBTEX_DATABASE_DEL:
        case LFUN_STATISTICS:
-       case LFUN_NEXT_INSET_TOGGLE:
                flag.enabled(true);
                break;
 
+       case LFUN_NEXT_INSET_TOGGLE: 
        case LFUN_NEXT_INSET_MODIFY: {
                // this is the real function we want to invoke
-               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_MODIFY, cmd.argument());
+               FuncRequest tmpcmd = cmd;
+               tmpcmd.action = (cmd.action == LFUN_NEXT_INSET_TOGGLE) 
+                       ? LFUN_INSET_TOGGLE : LFUN_INSET_MODIFY;
                // if there is an inset at cursor, see whether it
-               // can be modified.
+               // handles the lfun, other start from scratch
                Inset * inset = cur.nextInset();
-               if (inset) {
-                       inset->getStatus(cur, tmpcmd, flag);
-                       return flag;
-                       break;
-               }
-               // if it did not work, try the underlying inset.
-               inset = &cur.inset();
-               if (inset) {
-                       inset->getStatus(cur, tmpcmd, flag);
-                       return flag;
-                       break;
-               }
-               // else disable
-               flag.enabled(false);
+               if (!inset || !inset->getStatus(cur, tmpcmd, flag))
+                       flag = lyx::getStatus(tmpcmd);
                break;
        }
 
@@ -921,11 +914,6 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
                break;
        }
        
-       case LFUN_BUFFER_TOGGLE_EMBEDDING: {
-               flag.setOnOff(buffer_.params().embedded);
-               break;
-       }
-
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN:
        case LFUN_SCROLL:
@@ -948,33 +936,24 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
 
        case LFUN_INSET_SETTINGS: {
                InsetCode code = cur.inset().lyxCode();
-               if (cur.nextInset())
-                       code = cur.nextInset()->lyxCode();
+               if (cmd.getArg(0) == insetName(code)) {
+                       flag.enabled(true);
+                       break;
+               }
                bool enable = false;
-               switch (code) {
+               InsetCode next_code = cur.nextInset()
+                       ? cur.nextInset()->lyxCode() : NO_CODE;
+               switch (next_code) {
                        case TABULAR_CODE:
-                               enable = cmd.argument() == "tabular";
-                               break;
                        case ERT_CODE:
-                               enable = cmd.argument() == "ert";
-                               break;
                        case FLOAT_CODE:
-                               enable = cmd.argument() == "float";
-                               break;
                        case WRAP_CODE:
-                               enable = cmd.argument() == "wrap";
-                               break;
                        case NOTE_CODE:
-                               enable = cmd.argument() == "note";
-                               break;
                        case BRANCH_CODE:
-                               enable = cmd.argument() == "branch";
-                               break;
                        case BOX_CODE:
-                               enable = cmd.argument() == "box";
-                               break;
                        case LISTINGS_CODE:
-                               enable = cmd.argument() == "listings";
+                               enable = (cmd.argument().empty() ||
+                                         cmd.getArg(0) == insetName(next_code));
                                break;
                        default:
                                break;
@@ -993,6 +972,16 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
                }
                break;
 
+       case LFUN_BRANCH_ACTIVATE: 
+       case LFUN_BRANCH_DEACTIVATE: {
+               bool enable = false;
+               docstring const branchName = cmd.argument();
+               if (!branchName.empty())
+                       enable = buffer_.params().branchlist().find(branchName);
+               flag.enabled(enable);
+               break;
+       }
+
        default:
                flag.enabled(false);
        }
@@ -1060,27 +1049,25 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                break;
        }
        
-       case LFUN_EXTERNAL_EDIT: {
+       case LFUN_INSET_EDIT: {
                FuncRequest fr(cmd);
-               InsetExternal * inset = getInsetByCode<InsetExternal>(d->cursor_,
-                       EXTERNAL_CODE);
+               // if there is an inset at cursor, see whether it
+               // can be modified.
+               Inset * inset = cur.nextInset();
                if (inset)
-                       inset->dispatch(d->cursor_, fr);
-               break;
-       }
-
+                       inset->dispatch(cur, fr);
+               // if it did not work, try the underlying inset.
+               if (!inset || !cur.result().dispatched())
+                       cur.dispatch(cmd);
 
-       case LFUN_GRAPHICS_EDIT: {
-               FuncRequest fr(cmd);
-               InsetGraphics * inset = getInsetByCode<InsetGraphics>(d->cursor_,
-                       GRAPHICS_CODE);
-               if (inset)
-                       inset->dispatch(d->cursor_, fr);
-               break;
+               if (!cur.result().dispatched())
+                       // It did not work too; no action needed.
+                       break;
        }
 
        case LFUN_PARAGRAPH_GOTO: {
-               int const id = convert<int>(to_utf8(cmd.argument()));
+               int const id = convert<int>(cmd.getArg(0));
+               int const pos = convert<int>(cmd.getArg(1));
                int i = 0;
                for (Buffer * b = &buffer_; i == 0 || b != &buffer_;
                        b = theBufferList().next(b)) {
@@ -1097,6 +1084,7 @@ bool BufferView::dispatch(FuncRequest const & cmd)
 
                        if (b == &buffer_) {
                                // Set the cursor
+                               dit.pos() = pos;
                                setCursor(dit);
                                processUpdateFlags(Update::Force | Update::FitCursor);
                        } else {
@@ -1177,12 +1165,17 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                buffer_.text().acceptOrRejectChanges(d->cursor_, Text::REJECT);
                break;
 
-       case LFUN_WORD_FIND:
-               if (find(this, cmd))
+       case LFUN_WORD_FIND: {
+               FuncRequest req = cmd;
+               if (cmd.argument().empty() && !d->search_request_cache_.argument().empty())
+                       req = d->search_request_cache_;
+               if (find(this, req))
                        showCursor();
                else
                        message(_("String not found!"));
+               d->search_request_cache_ = req;
                break;
+       }
 
        case LFUN_WORD_REPLACE: {
                bool has_deleted = false;
@@ -1235,7 +1228,7 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur,
                                                BIBTEX_CODE);
                if (inset) {
-                       if (inset->addDatabase(to_utf8(cmd.argument())))
+                       if (inset->addDatabase(cmd.argument()))
                                buffer_.updateBibfilesCache();
                }
                break;
@@ -1247,7 +1240,7 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur,
                                                BIBTEX_CODE);
                if (inset) {
-                       if (inset->delDatabase(to_utf8(cmd.argument())))
+                       if (inset->delDatabase(cmd.argument()))
                                buffer_.updateBibfilesCache();
                }
                break;
@@ -1297,19 +1290,10 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                buffer_.params().compressed = !buffer_.params().compressed;
                break;
        
-       case LFUN_BUFFER_TOGGLE_EMBEDDING: {
-               // turn embedding on/off
-               try {
-                       buffer_.embeddedFiles().enable(!buffer_.params().embedded, buffer_, true);
-               } catch (ExceptionMessage const & message) {
-                       Alert::error(message.title_, message.details_);
-               }
-               break;
-       }
-
        case LFUN_NEXT_INSET_TOGGLE: {
-               // this is the real function we want to invoke
-               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_TOGGLE, cmd.origin);
+               // create the the real function we want to invoke
+               FuncRequest tmpcmd = cmd;
+               tmpcmd.action = LFUN_INSET_TOGGLE;
                // if there is an inset at cursor, see whether it
                // wants to toggle.
                Inset * inset = cur.nextInset();
@@ -1318,15 +1302,13 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                                Cursor tmpcur = cur;
                                tmpcur.pushBackward(*inset);
                                inset->dispatch(tmpcur, tmpcmd);
-                               if (tmpcur.result().dispatched()) {
+                               if (tmpcur.result().dispatched())
                                        cur.dispatched();
-                               }
-                       } else if (inset->editable() == Inset::IS_EDITABLE) {
-                               inset->edit(cur, true);
-                       }
+                       } else 
+                               inset->dispatch(cur, tmpcmd);
                }
                // if it did not work, try the underlying inset.
-               if (!cur.result().dispatched())
+               if (!inset || !cur.result().dispatched())
                        cur.dispatch(tmpcmd);
 
                if (!cur.result().dispatched())
@@ -1338,17 +1320,19 @@ bool BufferView::dispatch(FuncRequest const & cmd)
        }
 
        case LFUN_NEXT_INSET_MODIFY: {
-               // this is the real function we want to invoke
-               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_MODIFY, cmd.argument());
+               // create the the real function we want to invoke
+               FuncRequest tmpcmd = cmd;
+               tmpcmd.action = LFUN_INSET_MODIFY;
                // if there is an inset at cursor, see whether it
                // can be modified.
                Inset * inset = cur.nextInset();
                if (inset)
                        inset->dispatch(cur, tmpcmd);
                // if it did not work, try the underlying inset.
-               else if (&cur.inset())
-                       cur.inset().dispatch(cur, tmpcmd);
-               else
+               if (!inset || !cur.result().dispatched())
+                       cur.dispatch(tmpcmd);
+
+               if (!cur.result().dispatched())
                        // It did not work too; no action needed.
                        break;
                cur.clearSelection();
@@ -1410,6 +1394,12 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                break;
        }
 
+       case LFUN_BRANCH_ACTIVATE:
+       case LFUN_BRANCH_DEACTIVATE:
+               buffer_.dispatch(cmd);
+               processUpdateFlags(Update::Force);
+               break;
+
        default:
                return false;
        }
@@ -1564,7 +1554,7 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
 
        // Now dispatch to the temporary cursor. If the real cursor should
        // be modified, the inset's dispatch has to do so explicitly.
-       if (!cur.result().dispatched())
+       if (!inset || !cur.result().dispatched())
                cur.dispatch(cmd);
 
        // Notify left insets
@@ -1588,8 +1578,8 @@ void BufferView::lfunScroll(FuncRequest const & cmd)
 {
        string const scroll_type = cmd.getArg(0);
        int const scroll_step = 
-               (scroll_type == "line")? d->scrollbarParameters_.single_step
-               : (scroll_type == "page")? d->scrollbarParameters_.page_step : 0;
+               (scroll_type == "line") ? d->scrollbarParameters_.single_step
+               : (scroll_type == "page") ? d->scrollbarParameters_.page_step : 0;
        if (scroll_step == 0)
                return;
        string const scroll_quantity = cmd.getArg(1);
@@ -1760,7 +1750,7 @@ bool BufferView::checkDepm(Cursor & cur, Cursor & old)
 
 bool BufferView::mouseSetCursor(Cursor & cur, bool select)
 {
-       BOOST_ASSERT(&cur.bv() == this);
+       LASSERT(&cur.bv() == this, /**/);
 
        if (!select)
                // this event will clear selection so we save selection for
@@ -1847,8 +1837,8 @@ bool BufferView::singleParUpdate()
        int old_height = tm.parMetrics(bottom_pit).height();
 
        // make sure inline completion pointer is ok
-       if (d->inlineCompletionPos.fixIfBroken())
-               d->inlineCompletionPos = DocIterator();
+       if (d->inlineCompletionPos_.fixIfBroken())
+               d->inlineCompletionPos_ = DocIterator();
 
        // In Single Paragraph mode, rebreak only
        // the (main text, not inset!) paragraph containing the cursor.
@@ -1887,8 +1877,8 @@ void BufferView::updateMetrics()
        TextMetrics & tm = textMetrics(&buftext);
 
        // make sure inline completion pointer is ok
-       if (d->inlineCompletionPos.fixIfBroken())
-               d->inlineCompletionPos = DocIterator();
+       if (d->inlineCompletionPos_.fixIfBroken())
+               d->inlineCompletionPos_ = DocIterator();
        
        if (d->anchor_pit_ >= npit)
                // The anchor pit must have been deleted...
@@ -1961,7 +1951,7 @@ void BufferView::updateMetrics()
 
 void BufferView::insertLyXFile(FileName const & fname)
 {
-       BOOST_ASSERT(d->cursor_.inTexted());
+       LASSERT(d->cursor_.inTexted(), /**/);
 
        // Get absolute path of file and add ".lyx"
        // to the filename if necessary
@@ -2046,7 +2036,7 @@ Point BufferView::coordOffset(DocIterator const & dit, bool boundary) const
        CursorSlice const & sl = dit[0];
        TextMetrics const & tm = textMetrics(sl.text());
        ParagraphMetrics const & pm = tm.parMetrics(sl.pit());
-       BOOST_ASSERT(!pm.rows().empty());
+       LASSERT(!pm.rows().empty(), /**/);
        y -= pm.rows()[0].ascent();
 #if 1
        // FIXME: document this mess
@@ -2260,19 +2250,19 @@ void BufferView::insertPlaintextFile(FileName const & f, bool asParagraph)
 
 docstring const & BufferView::inlineCompletion() const
 {
-       return d->inlineCompletion;
+       return d->inlineCompletion_;
 }
 
 
 size_t const & BufferView::inlineCompletionUniqueChars() const
 {
-       return d->inlineCompletionUniqueChars;
+       return d->inlineCompletionUniqueChars_;
 }
 
 
 DocIterator const & BufferView::inlineCompletionPos() const
 {
-       return d->inlineCompletionPos;
+       return d->inlineCompletionPos_;
 }
 
 
@@ -2290,16 +2280,16 @@ void BufferView::setInlineCompletion(Cursor & cur, DocIterator const & pos,
        docstring const & completion, size_t uniqueChars)
 {
        uniqueChars = min(completion.size(), uniqueChars);
-       bool changed = d->inlineCompletion != completion
-               || d->inlineCompletionUniqueChars != uniqueChars;
+       bool changed = d->inlineCompletion_ != completion
+               || d->inlineCompletionUniqueChars_ != uniqueChars;
        bool singlePar = true;
-       d->inlineCompletion = completion;
-       d->inlineCompletionUniqueChars = min(completion.size(), uniqueChars);
+       d->inlineCompletion_ = completion;
+       d->inlineCompletionUniqueChars_ = min(completion.size(), uniqueChars);
        
        //lyxerr << "setInlineCompletion pos=" << pos << " completion=" << completion << " uniqueChars=" << uniqueChars << std::endl;
        
        // at new position?
-       DocIterator const & old = d->inlineCompletionPos;
+       DocIterator const & old = d->inlineCompletionPos_;
        if (old != pos) {
                //lyxerr << "inlineCompletionPos changed" << std::endl;
                // old or pos are in another paragraph?
@@ -2308,7 +2298,7 @@ void BufferView::setInlineCompletion(Cursor & cur, DocIterator const & pos,
                        singlePar = false;
                        //lyxerr << "different paragraph" << std::endl;
                }
-               d->inlineCompletionPos = pos;
+               d->inlineCompletionPos_ = pos;
        }
        
        // set update flags