]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
Require a buffer on construction of InsetGraphics and InsetExternal. Eventually,...
[lyx.git] / src / BufferView.cpp
index 448d1958574303f0b55505c4fe0211762b01002b..9b3ae322bb3a3eec65c958a8035c6e3506ccfa89 100644 (file)
 #include "TextClass.h"
 #include "TextMetrics.h"
 #include "TexRow.h"
+#include "TocBackend.h"
 #include "VSpace.h"
 #include "WordLangTuple.h"
 
 #include "insets/InsetBibtex.h"
 #include "insets/InsetCommand.h" // ChangeRefs
+#include "insets/InsetExternal.h"
+#include "insets/InsetGraphics.h"
 #include "insets/InsetRef.h"
 #include "insets/InsetText.h"
 
@@ -530,8 +533,7 @@ docstring BufferView::contextMenu(int x, int y) const
        if (covering_inset)
                return covering_inset->contextMenu(*this, x, y);
 
-       // FIXME: Do something more elaborate here.
-       return from_ascii("edit");
+       return buffer_.inset().contextMenu(*this, x, y);
 }
 
 
@@ -846,6 +848,8 @@ 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_PARAGRAPH_GOTO:
        case LFUN_NOTE_NEXT:
        case LFUN_REFERENCE_NEXT:
@@ -858,10 +862,51 @@ 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: {
+               // this is the real function we want to invoke
+               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_TOGGLE, cmd.argument());
+               // if there is an inset at cursor, see whether it
+               // can be modified.
+               Inset * inset = cur.nextInset();
+               if (inset) {
+                       inset->getStatus(cur, tmpcmd, flag);
+                       return flag;
+                       break;
+               }
+               // if it did not work, try the underlying inset.
+               if (!inset || !cur.result().dispatched())
+                       getStatus(tmpcmd);
+
+               if (!cur.result().dispatched())
+                       // else disable
+                       flag.enabled(false);
+               break;
+       }
+
+       case LFUN_NEXT_INSET_MODIFY: {
+               // this is the real function we want to invoke
+               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_MODIFY, cmd.argument());
+               // if there is an inset at cursor, see whether it
+               // can be modified.
+               Inset * inset = cur.nextInset();
+               if (inset) {
+                       inset->getStatus(cur, tmpcmd, flag);
+                       return flag;
+                       break;
+               }
+               // if it did not work, try the underlying inset.
+               if (!inset || !cur.result().dispatched())
+                       getStatus(tmpcmd);
+
+               if (!cur.result().dispatched())
+                       // else disable
+                       flag.enabled(false);
+               break;
+       }
+
        case LFUN_LABEL_GOTO: {
                flag.enabled(!cmd.argument().empty()
                    || getInsetByCode<InsetRef>(cur, REF_CODE));
@@ -902,14 +947,9 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN:
        case LFUN_SCROLL:
-               flag.enabled(true);
-               break;
-
-       // FIXME: LFUN_SCREEN_DOWN_SELECT should be removed from
-       // everywhere else before this can enabled:
        case LFUN_SCREEN_UP_SELECT:
        case LFUN_SCREEN_DOWN_SELECT:
-               flag.enabled(false);
+               flag.enabled(true);
                break;
 
        case LFUN_LAYOUT_TABULAR:
@@ -917,37 +957,29 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd)
                break;
 
        case LFUN_LAYOUT:
+               flag.enabled(!cur.inset().forceEmptyLayout(cur.idx()));
+               break;
+
        case LFUN_LAYOUT_PARAGRAPH:
                flag.enabled(cur.inset().allowParagraphCustomization(cur.idx()));
                break;
 
        case LFUN_INSET_SETTINGS: {
                InsetCode code = cur.inset().lyxCode();
+               if (cur.nextInset())
+                       code = cur.nextInset()->lyxCode();
                bool enable = false;
                switch (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(code));
                                break;
                        default:
                                break;
@@ -1032,6 +1064,25 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                        gotoLabel(label);
                break;
        }
+       
+       case LFUN_EXTERNAL_EDIT: {
+               FuncRequest fr(cmd);
+               InsetExternal * inset = getInsetByCode<InsetExternal>(d->cursor_,
+                       EXTERNAL_CODE);
+               if (inset)
+                       inset->dispatch(d->cursor_, fr);
+               break;
+       }
+
+
+       case LFUN_GRAPHICS_EDIT: {
+               FuncRequest fr(cmd);
+               InsetGraphics * inset = getInsetByCode<InsetGraphics>(d->cursor_,
+                       GRAPHICS_CODE);
+               if (inset)
+                       inset->dispatch(d->cursor_, fr);
+               break;
+       }
 
        case LFUN_PARAGRAPH_GOTO: {
                int const id = convert<int>(to_utf8(cmd.argument()));
@@ -1254,7 +1305,7 @@ bool BufferView::dispatch(FuncRequest const & cmd)
        case LFUN_BUFFER_TOGGLE_EMBEDDING: {
                // turn embedding on/off
                try {
-                       buffer_.embeddedFiles().enable(!buffer_.params().embedded, buffer_);
+                       buffer_.embeddedFiles().enable(!buffer_.params().embedded, buffer_, true);
                } catch (ExceptionMessage const & message) {
                        Alert::error(message.title_, message.details_);
                }
@@ -1280,7 +1331,7 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                        }
                }
                // 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())
@@ -1291,6 +1342,26 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                break;
        }
 
+       case LFUN_NEXT_INSET_MODIFY: {
+               // this is the real function we want to invoke
+               FuncRequest tmpcmd = FuncRequest(LFUN_INSET_MODIFY, cmd.argument());
+               // 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.
+               if (!inset || !cur.result().dispatched())
+                       cur.dispatch(tmpcmd);
+
+               if (!cur.result().dispatched())
+                       // It did not work too; no action needed.
+                       break;
+               cur.clearSelection();
+               processUpdateFlags(Update::Force | Update::FitCursor);
+               break;
+       }
+
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN: {
                Point p = getPos(cur, cur.boundary());
@@ -1311,26 +1382,37 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                lfunScroll(cmd);
                break;
 
-       case LFUN_SCREEN_UP_SELECT:
-       case LFUN_SCREEN_DOWN_SELECT: {
-               // Those two are not ready yet for consumption.
-               return false;
-
+       case LFUN_SCREEN_UP_SELECT: {
                cur.selHandle(true);
-               size_t initial_depth = cur.depth();
-               Point const p = getPos(cur, cur.boundary());
-               scroll(cmd.action == LFUN_SCREEN_UP_SELECT? - height_ : height_);
-               // FIXME: We need to verify if the cursor stayed within an inset...
-               //cur.reset(buffer_.inset());
-               d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
+               if (isTopScreen()) {
+                       lyx::dispatch(FuncRequest(LFUN_BUFFER_BEGIN_SELECT));
+                       cur.finishUndo();
+                       break;
+               }
+               int y = getPos(cur, cur.boundary()).y_;
+               int const ymin = y - height_ + defaultRowHeight();
+               while (y > ymin && cur.up())
+                       y = getPos(cur, cur.boundary()).y_;
+
                cur.finishUndo();
-               while (cur.depth() > initial_depth) {
-                       cur.forwardInset();
+               processUpdateFlags(Update::SinglePar | Update::FitCursor);
+               break;
+       }
+
+       case LFUN_SCREEN_DOWN_SELECT: {
+               cur.selHandle(true);
+               if (isBottomScreen()) {
+                       lyx::dispatch(FuncRequest(LFUN_BUFFER_END_SELECT));
+                       cur.finishUndo();
+                       break;
                }
-               // FIXME: we need to do a redraw again because of the selection
-               // But no screen update is needed.
-               d->update_strategy_ = NoScreenUpdate;
-               buffer_.changed();
+               int y = getPos(cur, cur.boundary()).y_;
+               int const ymax = y + height_ - defaultRowHeight();
+               while (y < ymax && cur.down())
+                       y = getPos(cur, cur.boundary()).y_;
+
+               cur.finishUndo();
+               processUpdateFlags(Update::SinglePar | Update::FitCursor);
                break;
        }
 
@@ -1488,7 +1570,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
@@ -1603,15 +1685,15 @@ void BufferView::setCursorFromRow(int row)
 
 void BufferView::gotoLabel(docstring const & label)
 {
-       for (InsetIterator it = inset_iterator_begin(buffer_.inset()); it; ++it) {
-               vector<docstring> labels;
-               it->getLabelList(labels);
-               if (std::find(labels.begin(), labels.end(), label) != labels.end()) {
-                       setCursor(it);
-                       showCursor();
-                       return;
-               }
+       Toc & toc = buffer().tocBackend().toc("label");
+       TocIterator toc_it = toc.begin();
+       TocIterator end = toc.end();
+       for (; toc_it != end; ++toc_it) {
+               if (label == toc_it->str())
+                       dispatch(toc_it->action());
        }
+       //FIXME: We could do a bit more searching thanks to this:
+       //InsetLabel const * inset = buffer_.insetLabel(label);
 }