]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
Attempt to fix bug #13017.
[lyx.git] / src / Buffer.cpp
index 32d3e8955b82a0cc9423c3af7af22ac63fbbc1ad..7522dce4343938d433bf26fed31bada34d1be385 100644 (file)
@@ -802,6 +802,12 @@ Undo & Buffer::undo()
 }
 
 
+Undo const & Buffer::undo() const
+{
+       return d->undo_;
+}
+
+
 void Buffer::setChild(DocIterator const & dit, Buffer * child)
 {
        d->children_positions[child] = dit;
@@ -941,6 +947,7 @@ int Buffer::readHeader(Lexer & lex)
        params().clearRemovedModules();
        params().clearIncludedChildren();
        params().pdfoptions().clear();
+       params().document_metadata.clear();
        params().indiceslist().clear();
        params().backgroundcolor = lyx::rgbFromHexName("#ffffff");
        params().isbackgroundcolor = false;
@@ -2254,9 +2261,7 @@ Buffer::ExportStatus Buffer::writeLyXHTMLSource(odocstream & os,
                os << "<!DOCTYPE html>\n"
                   << "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"" << from_ascii(htmlCode) << "\">\n"
                   << "<head>\n"
-                  << "<meta name=\"GENERATOR\" content=\"" << PACKAGE_STRING << "\" />\n"
-                  // FIXME Presumably need to set this right
-                  << "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />\n";
+                  << "<meta name=\"generator\" content=\"" << PACKAGE_STRING << "\" />\n";
 
                docstring const & doctitle = features.htmlTitle();
                os << "<title>"
@@ -2417,7 +2422,7 @@ void Buffer::validate(LaTeXFeatures & features) const
 }
 
 
-void Buffer::getLabelList(vector<std::pair<docstring, docstring>> & list) const
+void Buffer::getLabelList(vector<std::tuple<docstring, docstring, docstring>> & list) const
 {
        // If this is a child document, use the master's list instead.
        if (parent()) {
@@ -2428,8 +2433,9 @@ void Buffer::getLabelList(vector<std::pair<docstring, docstring>> & list) const
        list.clear();
        shared_ptr<Toc> toc = d->toc_backend.toc("label");
        for (auto const & tocit : *toc) {
-               if (tocit.depth() == 0)
-                       list.push_back(make_pair(tocit.str(), tocit.asString()));
+               if (tocit.depth() == 0) {
+                       list.push_back(make_tuple(tocit.str(), tocit.asString(), tocit.prettyStr()));
+               }
        }
 }
 
@@ -2683,6 +2689,11 @@ bool Buffer::citeLabelsValid() const
 
 void Buffer::removeBiblioTempFiles() const
 {
+       if (theApp()->isBufferBusy(this)) {
+               removeBiblioTemps = true;
+               return;
+       }
+
        // We remove files that contain LaTeX commands specific to the
        // particular bibliographic style being used, in order to avoid
        // LaTeX errors when we switch style.
@@ -2696,6 +2707,7 @@ void Buffer::removeBiblioTempFiles() const
        Buffer const * const pbuf = parent();
        if (pbuf)
                pbuf->removeBiblioTempFiles();
+       removeBiblioTemps = false;
 }
 
 
@@ -2714,6 +2726,24 @@ void Buffer::markDepClean(string const & name)
 }
 
 
+bool Buffer::branchActivationEnabled(FuncCode act, docstring const & branch) const
+{
+       bool const master = act == LFUN_BRANCH_MASTER_ACTIVATE
+                           || act == LFUN_BRANCH_MASTER_DEACTIVATE;
+       bool const activate = act == LFUN_BRANCH_ACTIVATE
+                           || act == LFUN_BRANCH_MASTER_ACTIVATE;
+       Buffer const * buf = master ? masterBuffer() : this;
+       Branch const * our_branch = buf->params().branchlist().find(branch);
+       // Can be disabled if
+       // - this is  a _MASTER_ command and there is no master
+       // - the relevant buffer does not know the branch
+       // - the branch is already in the desired state
+       return ((!master || parent() != nullptr)
+               && !branch.empty() && our_branch
+               && our_branch->isSelected() != activate);
+}
+
+
 bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
 {
        if (isInternal()) {
@@ -2765,15 +2795,12 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
        case LFUN_BRANCH_ACTIVATE:
        case LFUN_BRANCH_DEACTIVATE:
        case LFUN_BRANCH_MASTER_ACTIVATE:
-       case LFUN_BRANCH_MASTER_DEACTIVATE: {
-               bool const master = (cmd.action() == LFUN_BRANCH_MASTER_ACTIVATE
-                                    || cmd.action() == LFUN_BRANCH_MASTER_DEACTIVATE);
-               BranchList const & branchList = master ? masterBuffer()->params().branchlist()
-                       : params().branchlist();
-               docstring const & branchName = cmd.argument();
-               flag.setEnabled(!branchName.empty() && branchList.find(branchName));
+       case LFUN_BRANCH_MASTER_DEACTIVATE:
+               // Let a branch inset handle that
+               if (cmd.argument().empty())
+                       return false;
+               flag.setEnabled(branchActivationEnabled(cmd.action(), cmd.argument()));
                break;
-       }
 
        case LFUN_BRANCH_ADD:
        case LFUN_BRANCHES_RENAME:
@@ -2818,6 +2845,53 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
 }
 
 
+bool Buffer::branchActivationDispatch(FuncCode act, docstring const & branch)
+{
+       bool const master = (act == LFUN_BRANCH_MASTER_ACTIVATE
+                            || act == LFUN_BRANCH_MASTER_DEACTIVATE);
+       bool const activate = (act == LFUN_BRANCH_ACTIVATE
+                              || act == LFUN_BRANCH_MASTER_ACTIVATE);
+       Buffer * buf = master ? const_cast<Buffer *>(masterBuffer()) : this;
+       Branch * our_branch = buf->params().branchlist().find(branch);
+
+       // See comment in branchActivationStatus
+       if ((master && parent() == nullptr)
+            || !our_branch
+            || our_branch->isSelected() == activate)
+               return false;
+
+       if (master && !buf->hasGuiDelegate()
+           && (!theApp() || !theApp()->unhide(buf)))
+               // at least issue a warning for now (ugly, but better than dataloss).
+               frontend::Alert::warning(_("Branch state changes in master document"),
+                   lyx::support::bformat(_("The state of the branch '%1$s' "
+                       "was changed in the master file. "
+                       "Please make sure to save the master."), branch), true);
+
+       UndoGroupHelper ugh(buf);
+       buf->undo().recordUndoBufferParams(CursorData());
+       our_branch->setSelected(activate);
+       // cur.forceBufferUpdate() is not enough)
+       buf->updateBuffer();
+
+       // if branch exists in a descendant, update previews.
+       // TODO: only needed if "Show preview" is enabled in the included inset.
+       bool exists_in_desc = false;
+       for (auto const & it : buf->getDescendants()) {
+               if (it->params().branchlist().find(branch))
+                       exists_in_desc = true;
+       }
+       if (exists_in_desc) {
+               // TODO: ideally we would only update the previews of the
+               // specific children that have this branch directly or
+               // in one of their descendants
+               buf->removePreviews();
+               buf->updatePreviews();
+       }
+       return true;
+}
+
+
 void Buffer::dispatch(string const & command, DispatchResult & result)
 {
        return dispatch(lyxaction.lookupFunc(command), result);
@@ -2829,6 +2903,7 @@ void Buffer::dispatch(string const & command, DispatchResult & result)
 // whether we have a GUI or not. The boolean use_gui holds this information.
 void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
 {
+       LYXERR(Debug::ACTION, "Buffer::dispatch: cmd: " << func);
        if (isInternal()) {
                // FIXME? if there is an Buffer LFUN that can be dispatched even
                // if internal, put a switch '(cmd.action())' here.
@@ -2927,35 +3002,15 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
        case LFUN_BRANCH_DEACTIVATE:
        case LFUN_BRANCH_MASTER_ACTIVATE:
        case LFUN_BRANCH_MASTER_DEACTIVATE: {
-               bool const master = (func.action() == LFUN_BRANCH_MASTER_ACTIVATE
-                                    || func.action() == LFUN_BRANCH_MASTER_DEACTIVATE);
-               Buffer * buf = master ? const_cast<Buffer *>(masterBuffer())
-                                     : this;
-
-               docstring const & branch_name = func.argument();
-               // the case without a branch name is handled elsewhere
-               if (branch_name.empty()) {
-                       dispatched = false;
-                       break;
-               }
-               Branch * branch = buf->params().branchlist().find(branch_name);
-               if (!branch) {
-                       LYXERR0("Branch " << branch_name << " does not exist.");
-                       dr.setError(true);
-                       docstring const msg =
-                               bformat(_("Branch \"%1$s\" does not exist."), branch_name);
-                       dr.setMessage(msg);
-                       break;
+               // Let a branch inset handle that
+               if (func.argument().empty()) {
+                       dr.dispatched(false);
+                       return;
                }
-               bool const activate = (func.action() == LFUN_BRANCH_ACTIVATE
-                                      || func.action() == LFUN_BRANCH_MASTER_ACTIVATE);
-               if (branch->isSelected() != activate) {
-                       buf->undo().recordUndoBufferParams(CursorData());
-                       branch->setSelected(activate);
-                       dr.setError(false);
+               bool const res = branchActivationDispatch(func.action(), func.argument());
+               dr.setError(!res);
+               if (res)
                        dr.screenUpdate(Update::Force);
-                       dr.forceBufferUpdate();
-               }
                break;
        }
 
@@ -4157,6 +4212,7 @@ unique_ptr<TexRow> Buffer::getSourceCode(odocstream & os, string const & format,
                        LaTeXFeatures features(*this, params(), runparams);
                        validate(features);
                        runparams.use_polyglossia = features.usePolyglossia();
+                       runparams.use_babel = features.useBabel();
                        runparams.use_hyperref = features.isRequired("hyperref");
                        // latex or literate
                        otexstream ots(os);
@@ -4466,7 +4522,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir
                                                      translateIfPossible(theFormats().prettyName(format)));
                                if (format == "pdf4")
                                        s += "\n"
-                                         + bformat(_("Hint: use non-TeX fonts or set input encoding "
+                                         + bformat(_("Hint: use non-TeX fonts or set input encoding"
                                                  " to '%1$s'"), from_utf8(encodings.fromLyXName("ascii")->guiName()));
                                Alert::error(_("Couldn't export file"), s);
                        }
@@ -4806,7 +4862,7 @@ Buffer::ReadStatus Buffer::loadEmergency()
                                          "asked about it again the next time you try to load "
                                          "this file, and may over-write your own work."));
                        } else {
-                               Alert::warning(_("Emergency File Renames"),
+                               Alert::warning(_("Emergency File Renamed"),
                                        bformat(_("Emergency file renamed as:\n %1$s"),
                                        from_utf8(newname.onlyFileName())));
                        }
@@ -5292,6 +5348,10 @@ void Buffer::Impl::setLabel(ParIterator & it, UpdateType utype) const
 
 void Buffer::updateBuffer(ParIterator & parit, UpdateType utype, bool const deleted) const
 {
+       // if fomatted references are shown in workarea update buffer accordingly
+       if (params().use_formatted_ref)
+               utype = OutputUpdate;
+
        pushIncludedBuffer(this);
        // LASSERT: Is it safe to continue here, or should we just return?
        LASSERT(parit.pit() == 0, /**/);
@@ -5661,15 +5721,24 @@ void Buffer::Impl::fileExternallyModified(bool const exists)
                       "checksum unchanged: " << filename);
                return;
        }
+       lyx_clean = false;
        // If the file has been deleted, only mark the file as dirty since it is
        // pointless to prompt for reloading. If later a file is moved into this
        // location, then the externally modified warning will appear then.
        if (exists)
-                       externally_modified_ = true;
+               externally_modified_ = true;
        // Update external modification notification.
        // Dirty buffers must be visible at all times.
-       if (wa_ && wa_->unhide(owner_))
+       if (wa_ && wa_->unhide(owner_)) {
                wa_->updateTitles();
+               if (!exists) {
+                       frontend::Alert::warning(
+                               _("File deleted from disk"),
+                               bformat(_("The file\n  %1$s\n"
+                                          "has been deleted from disk!"),
+                                       from_utf8(filename.absFileName())));
+               }
+       }
        else
                // Unable to unhide the buffer (e.g. no GUI or not current View)
                lyx_clean = true;