]> git.lyx.org Git - features.git/commitdiff
Implemented the "Current Buffer" & "Current (Master) Document" scopes in the Advanced...
authorTommaso Cucinotta <tommaso@lyx.org>
Wed, 30 Dec 2009 18:40:18 +0000 (18:40 +0000)
committerTommaso Cucinotta <tommaso@lyx.org>
Wed, 30 Dec 2009 18:40:18 +0000 (18:40 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32678 a592a061-630c-0410-9148-cb99ea01b6c8

src/Buffer.cpp
src/Buffer.h
src/frontends/LyXView.h
src/frontends/qt4/FindAndReplace.cpp
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/GuiView.h
src/lyxfind.cpp
src/lyxfind.h

index aa12dbed6783bc7f2d82ee69c111259b98830d50..794c2e29d48c019e5fea8ef8a393dddc7cb457ac 100644 (file)
@@ -2331,9 +2331,8 @@ DocIterator Buffer::firstChildPosition(Buffer const * child)
 }
 
 
-std::vector<Buffer *> Buffer::getChildren(bool grand_children) const
+void Buffer::getChildren(std::vector<Buffer *> & clist, bool grand_children) const
 {
-       std::vector<Buffer *> clist;
        // loop over children
        Impl::BufferPositionMap::iterator it = d->children_positions.begin();
        Impl::BufferPositionMap::iterator end = d->children_positions.end();
@@ -2348,7 +2347,14 @@ std::vector<Buffer *> Buffer::getChildren(bool grand_children) const
                                clist.push_back(*git);
                }
        }
-       return clist;
+}
+
+
+std::vector<Buffer *> Buffer::getChildren(bool grand_children) const
+{
+       std::vector<Buffer *> v;
+       getChildren(v, grand_children);
+       return v;
 }
 
 
index 926a20de6ce5f625b8bad3e6654d606b38b99c74..59ee44480595f527f0c7d2daf2598980b14dd00c 100644 (file)
@@ -321,6 +321,9 @@ public:
        /// return a vector with all children (and grandchildren)
        std::vector<Buffer *> getChildren(bool grand_children = true) const;
 
+       /// Add all children (and grandchildren) to supplied vector
+       void getChildren(std::vector<Buffer *> & children, bool grand_children = true) const;
+
        /// Is buffer read-only?
        bool isReadonly() const;
 
index 6813d759bd6f6bc7b2158241cb9ee7f8e9436c39..342e4dd820f24dfe8f76f263e2564606d6dff0fb 100644 (file)
@@ -57,6 +57,10 @@ public:
        virtual BufferView const * documentBufferView() const = 0;
        //@}
 
+       /// Find or create buffer view and WorkArea for supplied document
+       /// buffer, and make it current.
+       virtual void selectDocumentBuffer(Buffer const * p_buf) = 0;
+
        /// display a message in the view
        virtual void message(docstring const &) = 0;
 
index 817a1d5b59526849d2b3054927d5fb1c7780b12e..ca5e23f27dc0853bdd928ad8ea367cfb1a8d61fe 100644 (file)
@@ -162,6 +162,13 @@ void FindAndReplaceWidget::findAndReplace(
        } else {
                replaceString = from_utf8(LYX_FR_NULL_STRING);
        }
+       FindAndReplaceOptions::SearchScope scope = FindAndReplaceOptions::S_BUFFER;
+       if (CurrentDocument->isChecked())
+               scope = FindAndReplaceOptions::S_BUFFER;
+       else if (MasterDocument->isChecked())
+               scope = FindAndReplaceOptions::S_DOCUMENT;
+       else
+               LASSERT(false, /**/);
        LYXERR(Debug::FIND, "FindAndReplaceOptions: "
               << "searchstring=" << searchString
               << ", casesensitiv=" << casesensitive
@@ -171,9 +178,10 @@ void FindAndReplaceWidget::findAndReplace(
               << ", ignoreformat=" << ignoreformat
               << ", regexp=" << regexp
               << ", replaceString" << replaceString
-              << ", keep_case=" << keep_case);
+              << ", keep_case=" << keep_case
+              << ", scope=" << scope);
        FindAndReplaceOptions opt(searchString, casesensitive, matchword, ! backwards,
-                 expandmacros, ignoreformat, regexp, replaceString, keep_case);
+               expandmacros, ignoreformat, regexp, replaceString, keep_case, scope);
        LYXERR(Debug::FIND, "Dispatching LFUN_WORD_FINDADV");
        std::ostringstream oss;
        oss << opt;
index f6d38e216fd148af524d0c11fcc7843b8864a3b8..0644c7c0bc816da70f4880af395eb90f6aac1d0b 100644 (file)
@@ -3542,6 +3542,11 @@ Dialog * GuiView::build(string const & name)
 }
 
 
+void GuiView::selectDocumentBuffer(Buffer const * p_buf) {
+       setBuffer(const_cast<Buffer *>(p_buf));
+}
+
+
 } // namespace frontend
 } // namespace lyx
 
index 44d491e80cc12dc990dc9f0c17bfc16bd9d384f9..19f6b57051aacc2bdd8d4c1e98eda78d7f19d772 100644 (file)
@@ -283,6 +283,10 @@ public:
        ///
        void disconnectDialog(std::string const & name);
 
+       /// Find or create buffer view and WorkArea for supplied document
+       /// buffer and make it current.
+       void selectDocumentBuffer(Buffer const * p_buf);
+
 private:
        ///
        void saveLayout() const;
index ed700f7da4f0b563ebca5b35c452fc0693263df3..ba28ad4be0170d352b40940a51c3bd216937f68d 100644 (file)
@@ -47,6 +47,9 @@
 #include "support/lstrings.h"
 #include "support/lassert.h"
 
+#include "frontends/Application.h"
+#include "frontends/LyXView.h"
+
 #include <boost/regex.hpp>
 #include <boost/next_prior.hpp>
 
@@ -601,7 +604,7 @@ bool braces_match(string::const_iterator const & beg,
  **/
 class MatchStringAdv {
 public:
-       MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt);
+       MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & opt);
 
        /** Tests if text starting at the supplied position matches with the one provided to the MatchStringAdv
         ** constructor as opt.search, under the opt.* options settings.
@@ -617,7 +620,9 @@ public:
 
 public:
        /// buffer
-       lyx::Buffer const & buf;
+       lyx::Buffer * p_buf;
+       /// first buffer on which search was started
+       lyx::Buffer * const p_first_buf;
        /// options
        FindAndReplaceOptions const & opt;
 
@@ -650,8 +655,8 @@ private:
 };
 
 
-MatchStringAdv::MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt)
-  : buf(buf), opt(opt)
+MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & opt)
+       : p_buf(&buf), p_first_buf(&buf), opt(opt)
 {
        par_as_string = normalize(opt.search);
        open_braces = 0;
@@ -889,6 +894,7 @@ docstring latexifyFromCursor(DocIterator const & cur, int len)
        return ods.str();
 }
 
+
 /** Finalize an advanced find operation, advancing the cursor to the innermost
  ** position that matches, plus computing the length of the matching text to
  ** be selected
@@ -929,8 +935,78 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match)
 }
 
 
+/** Switch p_buf to point to next document buffer.
+ **
+ ** Return true if restarted from master-document buffer.
+ **
+ ** @note
+ ** Not using p_buf->allRelatives() here, because I'm not sure
+ ** whether or not the returned order is independent of p_buf.
+ **/
+bool next_document_buffer(Buffer * & p_buf) {
+       Buffer *p_master = p_buf;
+       Buffer *p_old;
+       do {
+               p_old = p_master;
+               p_master = const_cast<Buffer *>(p_master->masterBuffer());
+               LYXERR(Debug::FIND, "p_old=" << p_old << ", p_master=" << p_master);
+       } while (p_master != p_old);
+       LASSERT(p_master != NULL, /**/);
+       std::vector<Buffer *> v_children;
+       /* Root master added as first buffer in the vector */
+       v_children.push_back(p_master);
+       p_master->getChildren(v_children, true);
+       LYXERR(Debug::FIND, "v_children.size()=" << v_children.size());
+       std::vector<Buffer *>::const_iterator it = std::find(v_children.begin(), v_children.end(), p_buf);
+       LASSERT(it != v_children.end(), /**/)
+       ++it;
+       if (it == v_children.end()) {
+               p_buf = *v_children.begin();
+               return true;
+       }
+       p_buf = *it;
+       return false;
+}
+
+
+/** Switch p_buf to point to previous document buffer.
+ **
+ ** Return true if restarted from last child buffer.
+ **
+ ** @note
+ ** Not using p_buf->allRelatives() here, because I'm not sure
+ ** whether or not the returned order is independent of p_buf.
+ **/
+bool prev_document_buffer(Buffer * & p_buf) {
+       Buffer *p_master = p_buf;
+       Buffer *p_old;
+       do {
+               p_old = p_master;
+               p_master = const_cast<Buffer *>(p_master->masterBuffer());
+               LYXERR(Debug::FIND, "p_old=" << p_old << ", p_master=" << p_master);
+       } while (p_master != p_old);
+       LASSERT(p_master != NULL, /**/);
+       std::vector<Buffer *> v_children;
+       /* Root master added as first buffer in the vector */
+       v_children.push_back(p_master);
+       p_master->getChildren(v_children, true);
+       LYXERR(Debug::FIND, "v_children.size()=" << v_children.size());
+       std::vector<Buffer *>::const_iterator it = std::find(v_children.begin(), v_children.end(), p_buf);
+       LASSERT(it != v_children.end(), /**/)
+       if (it == v_children.begin()) {
+               it = v_children.end();
+               --it;
+               p_buf = *it;
+               return true;
+       }
+       --it;
+       p_buf = *it;
+       return false;
+}
+
+
 /// Finds forward
-int findForwardAdv(DocIterator & cur, MatchStringAdv const & match)
+int findForwardAdv(DocIterator & cur, MatchStringAdv & match)
 {
        if (!cur)
                return 0;
@@ -947,17 +1023,29 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv const & match)
                        if (match(cur))
                                return findAdvFinalize(cur, match);
                }
-               if (wrap_answer != -1)
-                       break;
-               wrap_answer = frontend::Alert::prompt(
-                       _("Wrap search?"),
-                       _("End of document reached while searching forward.\n"
-                               "\n"
-                               "Continue searching from beginning?"),
-                       0, 1, _("&Yes"), _("&No"));
+               // No match has been found in current buffer
+               bool prompt = false;
+               if (match.opt.scope == FindAndReplaceOptions::S_BUFFER) {
+                       prompt = true;
+               } else if (match.opt.scope == FindAndReplaceOptions::S_DOCUMENT) {
+                       prompt = next_document_buffer(match.p_buf);
+               } else {
+                       /* Unimplemented scope */
+                       LASSERT(false, /**/);
+               }
+               if (prompt) {
+                       if (wrap_answer != -1)
+                               break;
+                       wrap_answer = frontend::Alert::prompt(
+                               _("Wrap search?"),
+                               _("End of document/scope reached while searching forward.\n"
+                                       "\n"
+                                       "Continue searching from beginning?"),
+                               0, 1, _("&Yes"), _("&No"));
+               }
                cur.clear();
-               cur.push_back(CursorSlice(match.buf.inset()));
-       } while (wrap_answer == 0);
+               cur.push_back(CursorSlice(match.p_buf->inset()));
+       } while (wrap_answer != 1);
        return 0;
 }
 
@@ -986,7 +1074,7 @@ void findMostBackwards(DocIterator & cur, MatchStringAdv const & match, int & le
 }
 
 /// Finds backwards
-int findBackwardsAdv(DocIterator & cur, MatchStringAdv const & match) {
+int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) {
        if (! cur)
                return 0;
        // Backup of original position (for restoring it in case match not found)
@@ -1047,13 +1135,25 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv const & match) {
                                cur.backwardPos();
                        };
                }
-               wrap_answer = frontend::Alert::prompt(
-                       _("Wrap search?"),
-                       _("Beginning of document reached while searching backwards\n"
-                         "\n"
-                         "Continue searching from end?"),
-                       0, 1, _("&Yes"), _("&No"));
-               cur = doc_iterator_end(&match.buf);
+               // No match has been found in current buffer
+               bool prompt = false;
+               if (match.opt.scope == FindAndReplaceOptions::S_BUFFER) {
+                       prompt = true;
+               } else if (match.opt.scope == FindAndReplaceOptions::S_DOCUMENT) {
+                       prompt = prev_document_buffer(match.p_buf);
+               } else {
+                       /* Unimplemented scope */
+                       LASSERT(false, /**/);
+               }
+               if (prompt) {
+                       wrap_answer = frontend::Alert::prompt(
+                               _("Wrap search?"),
+                               _("Beginning of document/scope reached while searching backwards\n"
+                                 "\n"
+                                 "Continue searching from end?"),
+                               0, 1, _("&Yes"), _("&No"));
+               }
+               cur = doc_iterator_end(match.p_buf);
                cur.backwardPos();
                LYXERR(Debug::FIND, "findBackAdv5: cur: " << cur);
                cur_orig2 = cur;
@@ -1062,6 +1162,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv const & match) {
        return 0;
 }
 
+
 } // anonym namespace
 
 
@@ -1077,10 +1178,11 @@ docstring stringifyFromForSearch(FindAndReplaceOptions const & opt,
 
 FindAndReplaceOptions::FindAndReplaceOptions(docstring const & search, bool casesensitive,
        bool matchword, bool forward, bool expandmacros, bool ignoreformat,
-       bool regexp, docstring const & replace, bool keep_case)
+       bool regexp, docstring const & replace, bool keep_case,
+       SearchScope scope)
        : search(search), casesensitive(casesensitive), matchword(matchword),
        forward(forward), expandmacros(expandmacros), ignoreformat(ignoreformat),
-       regexp(regexp), replace(replace), keep_case(keep_case)
+       regexp(regexp), replace(replace), keep_case(keep_case), scope(scope)
 {
 }
 
@@ -1153,8 +1255,8 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt)
 //             return false;
 //     }
 
+       MatchStringAdv matchAdv(bv->buffer(), opt);
        try {
-               MatchStringAdv const matchAdv(bv->buffer(), opt);
                if (opt.forward)
                                match_len = findForwardAdv(cur, matchAdv);
                else
@@ -1170,7 +1272,12 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt)
                return false;
        }
 
-       LYXERR(Debug::FIND, "Putting selection at " << cur << " with len: " << match_len);
+       LYXERR(Debug::FIND, "Putting selection at buf=" << matchAdv.p_buf
+               << "cur=" << cur << " with len: " << match_len);
+
+       theApp()->currentWindow()->selectDocumentBuffer(matchAdv.p_buf);
+       bv = theApp()->currentWindow()->documentBufferView();
+
        bv->putSelectionAt(cur, match_len, ! opt.forward);
        if (opt.replace == docstring(from_utf8(LYX_FR_NULL_STRING))) {
                bv->message(_("Match found !"));
@@ -1248,7 +1355,8 @@ ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const
           << opt.ignoreformat << ' '
           << opt.regexp << ' '
           << to_utf8(opt.replace) << "\nEOSS\n"
-          << opt.keep_case;
+          << opt.keep_case << ' '
+          << int(opt.scope);
 
        LYXERR(Debug::FIND, "built: " << os.str());
 
@@ -1284,6 +1392,9 @@ istringstream & operator>>(istringstream & is, lyx::FindAndReplaceOptions & opt)
                getline(is, line);
        }
        is >> opt.keep_case;
+       int i;
+       is >> i;
+       opt.scope = FindAndReplaceOptions::SearchScope(i);
        LYXERR(Debug::FIND, "parsed: " << opt.casesensitive << ' ' << opt.matchword << ' ' << opt.forward << ' '
                   << opt.expandmacros << ' ' << opt.ignoreformat << ' ' << opt.regexp << ' ' << opt.keep_case);
        LYXERR(Debug::FIND, "replacing with: '" << s << "'");
index f8a77494f05dc608ecd1ca769af763d5325b690c..3a3e91013e05328164c57310b62a6dec0a294c55 100644 (file)
@@ -78,6 +78,12 @@ bool findChange(BufferView * bv, bool next);
 
 class FindAndReplaceOptions {
 public:
+       typedef enum {
+               S_BUFFER,
+               S_DOCUMENT,
+               S_OPEN_BUFFERS,
+               S_ALL_MANUALS
+       } SearchScope;
        FindAndReplaceOptions(
                docstring const & search,
                bool casesensitive,
@@ -87,7 +93,8 @@ public:
                bool ignoreformat,
                bool regexp,
                docstring const & replace,
-               bool keep_case
+               bool keep_case,
+               SearchScope scope = S_BUFFER
        );
        FindAndReplaceOptions() {  }
        docstring search;
@@ -99,6 +106,7 @@ public:
        bool regexp;
        docstring replace;
        bool keep_case;
+       SearchScope scope;
 };
 
 /// Write a FindAdvOptions instance to a stringstream