]> git.lyx.org Git - features.git/commitdiff
Clean-up FileFilterList API.
authorAngus Leeming <leeming@lyx.org>
Fri, 26 Nov 2004 12:31:39 +0000 (12:31 +0000)
committerAngus Leeming <leeming@lyx.org>
Fri, 26 Nov 2004 12:31:39 +0000 (12:31 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9311 a592a061-630c-0410-9148-cb99ea01b6c8

src/frontends/qt2/ChangeLog
src/frontends/qt2/FileDialog.C
src/frontends/qt2/FileDialog_private.C
src/frontends/xforms/ChangeLog
src/frontends/xforms/FileDialog.C
src/frontends/xforms/FormFiledialog.C
src/support/ChangeLog
src/support/filefilterlist.C
src/support/filefilterlist.h
src/support/globbing.C
src/support/globbing.h

index f37cdd4904e3f277b50ce977144c3b9b1b14910b..f5ab8852f2c9c1e4b47ef4cd0398a43dfa2f6a7e 100644 (file)
@@ -1,3 +1,8 @@
+2004-11-26  Angus Leeming  <leeming@lyx.org>
+
+       * FileDialog.C:
+       * FileDialog_private.C: changes due to the changed FileFilterList API.
+
 2004-11-25  Angus Leeming  <leeming@lyx.org>
 
        * FileDialog.C:
index 90e92d8c87c3837813c7082a27178610cd66446c..bd8460b33d12f6b1e1233fbb8417791e8da0ed4a 100644 (file)
@@ -72,7 +72,7 @@ FileDialog::Result const FileDialog::save(string const & path,
                                          string const & suggested)
 {
        lyxerr[Debug::GUI] << "Select with path \"" << path
-                          << "\", mask \"" << filters.str(false)
+                          << "\", mask \"" << filters.as_string()
                           << "\", suggested \"" << suggested << '"' << endl;
        FileDialog::Result result;
        result.first = FileDialog::Chosen;
@@ -81,7 +81,7 @@ FileDialog::Result const FileDialog::save(string const & path,
        string const startsWith = MakeAbsPath(suggested, path);
        result.second = fromqstr(
                QFileDialog::getSaveFileName(toqstr(startsWith),
-                                            toqstr(filters.str(true)),
+                                            toqstr(filters.as_string()),
                                             qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(),
                                             title_.c_str()));
 #else
@@ -107,7 +107,7 @@ FileDialog::Result const FileDialog::open(string const & path,
                                          string const & suggested)
 {
        lyxerr[Debug::GUI] << "Select with path \"" << path
-                          << "\", mask \"" << filters.str(false)
+                          << "\", mask \"" << filters.as_string()
                           << "\", suggested \"" << suggested << '"' << endl;
        FileDialog::Result result;
        result.first = FileDialog::Chosen;
@@ -116,7 +116,7 @@ FileDialog::Result const FileDialog::open(string const & path,
        string const startsWith = MakeAbsPath(suggested, path);
        result.second = fromqstr(
                QFileDialog::getOpenFileName(toqstr(startsWith),
-                                            toqstr(filters.str(true)),
+                                            toqstr(filters.as_string()),
                                             qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(),
                                             title_.c_str()));
 #else
index bad9d561c05eec915eeaa423a7e325220cae3dd4..1d665f5e75a3053b36f4818b8e409e266471f029 100644 (file)
@@ -47,7 +47,7 @@ LyXFileDialog::LyXFileDialog(string const & p,
                             string const & t,
                             FileDialog::Button const & b1,
                             FileDialog::Button const & b2)
-       : QFileDialog(toqstr(p), toqstr(filters.str(true)),
+       : QFileDialog(toqstr(p), toqstr(filters.as_string()),
                      qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(), toqstr(t), true),
          b1_(0), b2_(0)
 {
index 4a187c0dee3ba94c66ae038b25c1c83bbe93cd82..0eb91a053f7fb2453d40849f5ebfdc05541165fa 100644 (file)
@@ -1,3 +1,11 @@
+2004-11-26  Angus Leeming  <leeming@lyx.org>
+
+       * FileDialog.C:
+       * FormFiledialog.C: changes due to the changed FileFilterList API.
+
+       * FormFiledialog.C (expand_globs): moved here from
+       support/globbing.[Ch].
+
 2004-11-25  Angus Leeming  <leeming@lyx.org>
 
        * FileDialog.C: s/globbing.h/filefilterlist.h/ in #includes.
index 9402b5d72816f8ad119d78c2bdbd3d43e93d6865..4ee22b27ba9795593df381f9c693f69ffd0ab223 100644 (file)
@@ -71,7 +71,7 @@ FileDialog::Result const FileDialog::open(string const & path,
                                          string const & suggested)
 {
        lyxerr[Debug::GUI] << "filedialog open  with path \"" << path
-                          << "\", mask \"" << filters.str(false)
+                          << "\", mask \"" << filters.as_string()
                           << "\", suggested \"" << suggested << '"' << endl;
 
        // no support for asynchronous selection yet
index e75b9f3e1901919dd8907188f29b81bf3ba87da5..b0fbdb48502e9994c73b0b9089a8eee2c7953685 100644 (file)
 #include "support/globbing.h"
 #include "support/lstrings.h"
 #include "support/lyxlib.h"
+#include "support/path.h"
 #include "support/tostr.h"
 
 #include "lyx_forms.h"
 
 #include <boost/bind.hpp>
 #include <boost/regex.hpp>
+#include <boost/tokenizer.hpp>
 
 #include <algorithm>
 #include <map>
+#include <sstream>
+
 #include <grp.h>
 #include <pwd.h>
 
@@ -66,6 +70,7 @@ using lyx::support::GetEnvPath;
 using lyx::support::LyXReadLink;
 using lyx::support::MakeAbsPath;
 using lyx::support::OnlyFilename;
+using lyx::support::Path;
 using lyx::support::split;
 using lyx::support::subst;
 using lyx::support::suffixIs;
@@ -73,6 +78,7 @@ using lyx::support::trim;
 
 using std::max;
 using std::sort;
+using std::ostringstream;
 using std::string;
 using std::map;
 using std::vector;
@@ -81,6 +87,36 @@ using namespace lyx::frontend;
 
 namespace {
 
+/** Given a string "<glob> <glob> <glob>", expand each glob in turn.
+ *  Any glob that cannot be expanded is ignored silently.
+ *  Invokes \c convert_brace_glob and \c glob internally, so use only
+ *  on systems supporting the Posix function 'glob'.
+ *  \param mask the string "<glob> <glob> <glob>".
+ *  \param directory the current working directory from
+ *  which \c glob is invoked.
+ *  \returns a vector of all matching file names.
+ */
+vector<string> const expand_globs(string const & mask,
+                                 string const & directory)
+{
+       Path p(directory);
+
+       // Split into individual globs and then call 'glob' on each one.
+       typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
+       boost::char_separator<char> const separator(" ");
+
+       vector<string> matches;
+       Tokenizer const tokens(mask, separator);
+       Tokenizer::const_iterator it = tokens.begin();
+       Tokenizer::const_iterator const end = tokens.end();
+       for (; it != end; ++it) {
+               vector<string> const tmp = lyx::support::glob(*it);
+               matches.insert(matches.end(), tmp.begin(), tmp.end());
+       }
+       return matches;
+}
+
+
 // six months, in seconds
 long const SIX_MONTH_SEC = 6L * 30L * 24L * 60L * 60L;
 //static
@@ -241,8 +277,7 @@ void FileDialog::Private::Reread()
                ++depth_;
        }
 
-       vector<string> const glob_matches =
-               lyx::support::expand_globs(mask_, directory_);
+       vector<string> const glob_matches = expand_globs(mask_, directory_);
 
        time_t curTime = time(0);
        rewinddir(dir);
@@ -404,8 +439,24 @@ void FileDialog::Private::SetFilters(string const & mask)
 
 void FileDialog::Private::SetFilters(FileFilterList const & filters)
 {
+       if (filters.empty())
+               return;
+
        // Just take the first one for now.
-       mask_ = filters.filters()[0].globs();
+       typedef FileFilterList::Filter::glob_iterator glob_iterator;
+       glob_iterator const begin = filters[0].begin();
+       glob_iterator const end = filters[0].end();
+       if (begin == end)
+               return;
+
+       ostringstream ss;
+       for (glob_iterator it = begin; it != end; ++it) {
+               if (it != begin)
+                       ss << ' ';
+               ss << *it;
+       }
+               
+       mask_ = ss.str();
        fl_set_input(file_dlg_form_->PatBox, mask_.c_str());
 }
 
index 5e5a357c05351594262ba4ea0f9c4b762d9f93bf..a63249d18f67819cdcd11bdb4f342e077c85b24e 100644 (file)
@@ -1,3 +1,13 @@
+2004-11-26  Angus Leeming  <leeming@lyx.org>
+
+       * filefilterlist.C (convert_brace_glob): moved here from
+       globbing.[Ch].
+
+       * filefilterlist.[Ch]: clean-up FileFilterList API.
+
+       * globbing.[Ch] (convert_brace_glob): moved to filefilterlist.C.
+       (expand_globs): moved to xforms/FormFiledialog.C.
+
 2004-11-25  Angus Leeming  <leeming@lyx.org>
 
        * filefilterlist.[Ch]:
index 168a95eeb5cf9f0ae2a4923a39a86276211e1b4a..109a045e0264a9e8196b243ea471645838fd2dbf 100644 (file)
 #include <config.h>
 
 #include "support/filefilterlist.h"
-#include "support/globbing.h"
 #include "support/lstrings.h"
 
 // FIXME Interface violation
 #include "gettext.h"
 
 #include <boost/regex.hpp>
-
-#include </usr/include/glob.h>
+#include <boost/tokenizer.hpp>
 
 #include <sstream>
 
@@ -29,9 +27,78 @@ using std::string;
 using std::vector;
 
 
+namespace {
+
+/** Given a string such as
+ *      "<glob> <glob> ... *.{abc,def} <glob>",
+ *  convert the csh-style brace expresions:
+ *      "<glob> <glob> ... *.abc *.def <glob>".
+ *  Requires no system support, so should work equally on Unix, Mac, Win32.
+ */
+string const convert_brace_glob(string const & glob)
+{
+       // Matches " *.{abc,def,ghi}", storing "*." as group 1 and
+       // "abc,def,ghi" as group 2.
+       static boost::regex const glob_re(" *([^ {]*)\\{([^ }]+)\\}");
+       // Matches "abc" and "abc,", storing "abc" as group 1.
+       static boost::regex const block_re("([^,}]+),?");
+
+       string pattern;
+
+       string::const_iterator it = glob.begin();
+       string::const_iterator const end = glob.end();
+       while (true) {
+               boost::match_results<string::const_iterator> what;
+               if (!boost::regex_search(it, end, what, glob_re)) {
+                       // Ensure that no information is lost.
+                       pattern += string(it, end);
+                       break;
+               }
+
+               // Everything from the start of the input to
+               // the start of the match.
+               pattern += string(what[-1].first, what[-1].second);
+
+               // Given " *.{abc,def}", head == "*." and tail == "abc,def".
+               string const head = string(what[1].first, what[1].second);
+               string const tail = string(what[2].first, what[2].second);
+
+               // Split the ','-separated chunks of tail so that
+               // $head{$chunk1,$chunk2} becomes "$head$chunk1 $head$chunk2".
+               string const fmt = " " + head + "$1";
+               pattern += boost::regex_merge(tail, block_re, fmt);
+
+               // Increment the iterator to the end of the match.
+               it += distance(it, what[0].second);
+       }
+
+       return pattern;
+}
+} // namespace anon
+
+
 namespace lyx {
 namespace support {
 
+FileFilterList::Filter::Filter(std::string const & description,
+                              std::string const & globs)
+       : desc_(description)
+{
+       typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
+       boost::char_separator<char> const separator(" ");
+
+       // Given "<glob> <glob> ... *.{abc,def} <glob>", expand to
+       //       "<glob> <glob> ... *.abc *.def <glob>"
+       string const expanded_globs = convert_brace_glob(globs);
+
+       // Split into individual globs.
+       vector<string> matches;
+       Tokenizer const tokens(expanded_globs, separator);
+       globs_ = vector<string>(tokens.begin(), tokens.end());
+}
+
+               
 FileFilterList::FileFilterList(string const & qt_style_filter)
 {
        string const filter = qt_style_filter
@@ -80,22 +147,31 @@ void FileFilterList::parse_filter(string const & filter)
 }
 
 
-string const FileFilterList::str(bool expand) const
+string const FileFilterList::as_string() const
 {
        ostringstream ss;
 
-       vector<Filter>::const_iterator const begin = filters_.begin();
-       vector<Filter>::const_iterator const end = filters_.end();
-       vector<Filter>::const_iterator it = begin;
-       for (; it != end; ++it) {
-               string const globs = expand ?
-                       convert_brace_glob(it->globs()) : it->globs();
-               if (it != begin)
+       vector<Filter>::const_iterator fit = filters_.begin();
+       vector<Filter>::const_iterator const fend = filters_.end();
+       for (; fit != fend; ++fit) {
+               Filter::glob_iterator const gbegin = fit->begin();
+               Filter::glob_iterator const gend = fit->end();
+               if (gbegin == gend)
+                       continue;
+
+               if (ss.tellp() > 0)
                        ss << ";;";
-               bool const has_description = !it->description().empty();
+
+               bool const has_description = !fit->description().empty();
                if (has_description)
-                       ss << it->description() << " (";
-               ss << globs;
+                       ss << fit->description() << " (";
+
+               for (Filter::glob_iterator git = gbegin; git != gend; ++git) {
+                       if (git != gbegin)
+                               ss << ' ';
+                       ss << *git;
+               }
+               
                if (has_description)
                        ss << ')';
        }
index 984d1398f87de91b82b439995390430609633cba..bb4197778b21852a409725b87cdb602dee2630e7 100644 (file)
@@ -28,25 +28,41 @@ class FileFilterList {
 public:
        class Filter {
                std::string desc_;
-               std::string globs_;
+               std::vector<std::string> globs_;
        public:
-               Filter(std::string const & d, std::string const & g)
-                       : desc_(d), globs_(g) {}
+               /* \param description text describing the filters.
+                * \param one or more wildcard patterns, separated by
+                * whitespace.
+                */
+               Filter(std::string const & description,
+                      std::string const & globs);
+
                std::string const & description() const { return desc_; }
-               std::string const & globs() const { return globs_; }
+
+               typedef std::vector<std::string>::const_iterator glob_iterator;
+               glob_iterator begin() const { return globs_.begin(); }
+               glob_iterator end() const { return globs_.end(); }
        };
 
        /** \param qt_style_filter a list of available file filters.
         *  Eg. "TeX documents (*.tex);;LyX Documents (*.lyx)".
         *  The "All files (*)" filter is always added to the list.
         */
-       explicit FileFilterList(std::string const & qt_style_filter = std::string());
-       std::vector<Filter> const & filters() const { return filters_; }
+       explicit FileFilterList(std::string const & qt_style_filter =
+                               std::string());
+
+       typedef std::vector<Filter>::size_type size_type;
+
+       bool empty() const { return filters_.empty(); }
+       size_type size() const { return filters_.size(); }
+       Filter & operator[](size_type i) { return filters_[i]; }
+       Filter const & operator[](size_type i) const { return filters_[i]; }
 
-       /** \param expand pass each glob through \c convert_brace_glob.
-        *  \returns the equivalent of the string passed to the c-tor.
+       /** \returns the equivalent of the string passed to the c-tor
+        *  although any brace expressions are expanded.
+        *  (E.g. "*.{png,jpg}" -> "*.png *.jpg")
         */
-       std::string const str(bool expand) const;
+       std::string const as_string() const;
 
 private:
        void parse_filter(std::string const & filter);
index 8e663a0cc319dbebc001ce1bfbca963d949a7a4e..0000f34e3a1b665111214f9ab512d3a1dccb97d1 100644 (file)
 #include <config.h>
 
 #include "support/globbing.h"
-#include "support/lstrings.h"
-#include "support/path.h"
-
-#include <boost/regex.hpp>
-#include <boost/tokenizer.hpp>
 
 #include <glob.h>
 
-using std::distance;
 using std::string;
 using std::vector;
 
@@ -27,47 +21,6 @@ using std::vector;
 namespace lyx {
 namespace support {
 
-string const convert_brace_glob(string const & glob)
-{
-       // Matches " *.{abc,def,ghi}", storing "*." as group 1 and
-       // "abc,def,ghi" as group 2.
-       static boost::regex const glob_re(" *([^ {]*)\\{([^ }]+)\\}");
-       // Matches "abc" and "abc,", storing "abc" as group 1.
-       static boost::regex const block_re("([^,}]+),?");
-
-       string pattern;
-
-       string::const_iterator it = glob.begin();
-       string::const_iterator const end = glob.end();
-       while (true) {
-               boost::match_results<string::const_iterator> what;
-               if (!boost::regex_search(it, end, what, glob_re)) {
-                       // Ensure that no information is lost.
-                       pattern += string(it, end);
-                       break;
-               }
-
-               // Everything from the start of the input to
-               // the start of the match.
-               pattern += string(what[-1].first, what[-1].second);
-
-               // Given " *.{abc,def}", head == "*." and tail == "abc,def".
-               string const head = string(what[1].first, what[1].second);
-               string const tail = string(what[2].first, what[2].second);
-
-               // Split the ','-separated chunks of tail so that
-               // $head{$chunk1,$chunk2} becomes "$head$chunk1 $head$chunk2".
-               string const fmt = " " + head + "$1";
-               pattern += boost::regex_merge(tail, block_re, fmt);
-
-               // Increment the iterator to the end of the match.
-               it += distance(it, what[0].second);
-       }
-
-       return pattern;
-}
-
-
 vector<string> const glob(string const & pattern, int flags)
 {
        glob_t glob_buffer;
@@ -80,30 +33,5 @@ vector<string> const glob(string const & pattern, int flags)
        return matches;
 }
 
-
-vector<string> const expand_globs(string const & mask,
-                                 string const & directory)
-{
-       typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
-       boost::char_separator<char> const separator(" ");
-
-       // Given "<glob> <glob> ... *.{abc,def} <glob>", expand to
-       //       "<glob> <glob> ... *.abc *.def <glob>"
-       string const converted_glob = convert_brace_glob(mask);
-
-       Path p(directory);
-
-       // Split into individual globs and then call 'glob' on each one.
-       vector<string> matches;
-       Tokenizer const tokens(converted_glob, separator);
-       Tokenizer::const_iterator it = tokens.begin();
-       Tokenizer::const_iterator const end = tokens.end();
-       for (; it != end; ++it) {
-               vector<string> const tmp = glob(*it);
-               matches.insert(matches.end(), tmp.begin(), tmp.end());
-       }
-       return matches;
-}
-
 } // namespace support
 } // namespace lyx
index 0ee11415124c9e69814a20e241080bd5f69c9408..e4c53c808b2393a6e4a6dfc314b5fe701203eb9f 100644 (file)
 namespace lyx {
 namespace support {
 
-/** Given a string such as
- *      "<glob> <glob> ... *.{abc,def} <glob>",
- *  convert the csh-style brace expresions:
- *      "<glob> <glob> ... *.abc *.def <glob>".
- *  Requires no system support, so should work equally on Unix, Mac, Win32.
- */
-std::string const convert_brace_glob(std::string const & glob);
-
-
 /** A wrapper for the Posix function 'glob'.
  *  \param pattern the glob to be expanded. Eg "*.[Ch]".
  *  \param flags flags to be passed to the system function. See 'man glob'.
@@ -34,20 +25,6 @@ std::string const convert_brace_glob(std::string const & glob);
  */
 std::vector<std::string> const glob(std::string const & pattern, int flags = 0);
 
-
-/** Given a string "<glob> <glob> <glob>", expand each glob in turn.
- *  Any glob that cannot be expanded is ignored silently.
- *  Invokes \c convert_brace_glob and \c glob internally, so use only
- *  on systems supporting the Posix function 'glob'.
- *  \param mask the string "<glob> <glob> <glob>".
- *  \param directory (if not empty) the current working directory from
- *  which \c glob is invoked.
- *  \returns a vector of all matching file names.
- */
-std::vector<std::string> const
-expand_globs(std::string const & mask,
-            std::string const & directory = std::string());
-
 } // namespace support
 } // namespace lyx