]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfunc.C
Fix bug 2195: Slowness in rendering inside insets, especially on the Mac
[lyx.git] / src / lyxfunc.C
index 3edf1984304f46154160bf91f881ea3085a61d7b..7a7882d85f4688cfea484db224cccb1dfbddb5fe 100644 (file)
@@ -182,7 +182,7 @@ bool getStatus(LCursor cursor,
  */
 Change::Type lookupChange(DocIterator const & dit, bool outer = false)
 {
-       size_t const depth = dit.depth() - outer ? 1 : 0;
+       size_t const depth = dit.depth() - (outer ? 1 : 0);
 
        for (size_t i = 0 ; i < depth ; ++i) {
                CursorSlice const & slice = dit[i];
@@ -307,7 +307,8 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state)
                // by a binding
                if (keysym->isText() && keyseq.length() == 1) {
                        lyxerr[Debug::KEY] << "isText() is true, inserting." << endl;
-                       func = FuncRequest(LFUN_SELFINSERT);
+                       func = FuncRequest(LFUN_SELFINSERT, 
+                                          FuncRequest::KEYBOARD);
                } else {
                        lyxerr[Debug::KEY] << "Unknown, !isText() - giving up" << endl;
                        owner->message(_("Unknown function."));
@@ -318,7 +319,8 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state)
        if (func.action == LFUN_SELFINSERT) {
                if (encoded_last_key != 0) {
                        string const arg(1, encoded_last_key);
-                       dispatch(FuncRequest(LFUN_SELFINSERT, arg));
+                       dispatch(FuncRequest(LFUN_SELFINSERT, arg, 
+                                            FuncRequest::KEYBOARD));
                        lyxerr[Debug::KEY]
                                << "SelfInsert arg[`" << arg << "']" << endl;
                }
@@ -338,6 +340,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
           application can still be accessed without giving focus to
           the main window. In this case, we want to disable the menu
           entries that are buffer-related.
+
+          Note that this code is not perfect, as bug 1941 attests:
+          http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
        */
        Buffer * buf;
        if (cmd.origin == FuncRequest::UI && !owner->hasFocus())
@@ -408,10 +413,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
                enable = cmd.argument == "custom"
                        || Exporter::IsExportable(*buf, cmd.argument);
                break;
-       case LFUN_CUT:
-       case LFUN_COPY:
-               enable = cur.selection();
-               break;
 
        case LFUN_RUNCHKTEX:
                enable = buf->isLatex() && lyxrc.chktex_command != "none";
@@ -427,7 +428,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
 
        case LFUN_LAYOUT:
        case LFUN_LAYOUT_PARAGRAPH:
-               enable = !cur.inset().forceDefaultParagraphs(&cur.inset());
+               enable = !cur.inset().forceDefaultParagraphs(cur.idx());
                break;
 
        case LFUN_VC_REGISTER:
@@ -533,6 +534,12 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
                break;
        }
 
+       case LFUN_INSERT_CITATION: {
+               FuncRequest fr(LFUN_INSET_INSERT, "citation");
+               enable = getStatus(fr).enabled();
+               break;
+       }
+
        // this one is difficult to get right. As a half-baked
        // solution, we consider only the first action of the sequence
        case LFUN_SEQUENCE: {
@@ -1243,6 +1250,30 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                        owner->getDialogs().disconnect(argument);
                        break;
 
+               
+               case LFUN_INSERT_CITATION: {
+                       if (!argument.empty()) {
+                               // we can have one optional argument, delimited by '|'
+                               // citation-insert <key>|<text_before>
+                               // this should be enhanced to also support text_after 
+                               // and citation style
+                               string arg = argument;
+                               string opt1;
+                               if (contains(argument, "|")) {
+                                       arg = token(argument, '|', 0);
+                                       opt1 = '[' + token(argument, '|', 1) + ']';
+                               }
+                               std::ostringstream os;
+                               os << "citation LatexCommand\n"
+                                  << "\\cite" << opt1 << "{" << arg << "}\n"
+                                  << "\\end_inset";
+                               FuncRequest fr(LFUN_INSET_INSERT, os.str());
+                               dispatch(fr);
+                       } else
+                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, "citation"));
+                       break;
+               }
+
                case LFUN_CHILDOPEN: {
                        string const filename =
                                MakeAbsPath(argument, owner->buffer()->filePath());
@@ -1405,9 +1436,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                        InsetIterator const end = inset_iterator_end(inset);
                        for (; it != end; ++it) {
                                if (inset_code == InsetBase::NO_CODE
-                                   || inset_code == it->lyxCode())
-                                       it->dispatch(cur, fr);
+                                   || inset_code == it->lyxCode()) {
+                                       LCursor tmpcur = cur;
+                                       tmpcur.pushLeft(*it);
+                                       it->dispatch(tmpcur, fr);
+                               }
                        }
+                       update = true;
                        break;
                }
 
@@ -1484,7 +1519,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                }
 
                case LFUN_TEXTCLASS_APPLY: {
-                       recordUndoFullDocument(view());
                        Buffer * buffer = owner->buffer();
 
                        lyx::textclass_type const old_class =
@@ -1504,6 +1538,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                                break;
 
                        owner->message(_("Converting document to new document class..."));
+                       recordUndoFullDocument(view());
+                       buffer->params().textclass = new_class;
                        StableDocIterator backcur(view()->cursor());
                        ErrorList el;
                        lyx::cap::SwitchBetweenClasses(
@@ -1558,10 +1594,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                                view()->update(Update::FitCursor);
 
                        // if we executed a mutating lfun, mark the buffer as dirty
-                       // FIXME: Why not use flag.enabled() but call getStatus again?
-                       if (getStatus(cmd).enabled()
-                                       && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)
-                                       && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly))
+                       if (flag.enabled()
+                           && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)
+                           && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly))
                                view()->buffer()->markDirty();
                }
 
@@ -1575,8 +1610,15 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
 
 void LyXFunc::sendDispatchMessage(string const & msg, FuncRequest const & cmd)
 {
-       owner->updateMenubar();
-       owner->updateToolbars();
+       /* When an action did not originate from the UI/kbd, it makes
+        * sense to avoid updating the GUI. It turns out that this
+        * fixes bug 1941, for reasons that are described here:
+        * http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4 
+        */
+       if (cmd.origin != FuncRequest::INTERNAL) {
+               owner->updateMenubar();
+               owner->updateToolbars();
+       }
 
        const bool verbose = (cmd.origin == FuncRequest::UI
                              || cmd.origin == FuncRequest::COMMANDBUFFER);