+2004-01-05 Angus Leeming <leeming@lyx.org>
+
+ * external_templates: use the valid csh-style glob
+ "*.{gif,png,jpg,bmp,pbm,ppm,tga,tif,xpm,xbm}" to define the
+ RasterImage file filter, rather than the current psuedo-glob,
+ psuedo-regex .
+
2003-12-22 Michael Schmitt <michael.schmitt@teststep.org>
* layouts/g-brief2.layout: more spelling fixes
GuiName "Bitmap: $$Basename"
HelpText
A bitmap file.
- In the parameters box, you can provide optional
- parameters for the ImageMagick convert program.
- E.g., use `-border 10x10 -bordercolor black'
- to surround the picture with a black border
- when you export to LaTeX.
- When you export to Ascii, you can provide a
- number describing how many columns the picture
- should expand to.
This template uses Gimp for editing.
HelpTextEnd
InputFormat "*"
- FileFilter "*.(gif|png|jpg|bmp|pbm|ppm|tga|tif|xpm|xbm)"
+ FileFilter "*.{gif,png,jpg,bmp,pbm,ppm,tga,tif,xpm,xbm}"
EditCommand "gimp $$FName"
AutomaticProduction true
Transform Rotate
Template Date
GuiName "Date"
HelpText
- Todays date.
+ Today's date.
Read 'info date' for more information.
HelpTextEnd
InputFormat date
+2004-01-05 Angus Leeming <leeming@lyx.org>
+
+ * FileDialog_private.C (c-tor): invoke convert_brace_glob to convert
+ a csh-style glob like "*.{abc,def}" to something that
+ Qt can understand.
+
2003-12-30 Juergen Spitzmueller <j.spitzmueller@gmx.de>
* ui/QGraphicsDialogBase.ui: add missing signal/slot (bug 1469).
#include "FileDialog_private.h"
#include "qt_helpers.h"
+#include "support/globbing.h"
#include "support/lstrings.h"
#include <qapplication.h>
#include <qtoolbutton.h>
+using lyx::support::convert_brace_glob;
using lyx::support::split;
using std::string;
LyXFileDialog::LyXFileDialog(string const & p, string const & m,
string const & t,
FileDialog::Button const & b1, FileDialog::Button const & b2)
- : QFileDialog(toqstr(p), toqstr(m),
+ : QFileDialog(toqstr(p), toqstr(convert_brace_glob(m)),
qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(), toqstr(t), true),
b1_(0), b2_(0)
{
+2004-01-05 Angus Leeming <leeming@lyx.org>
+
+ * FormFiledialog.C (glob2regex, globMatch): removed.
+ (Reread): use lyx::support::expand_globs instead.
+
2004-01-02 Angus Leeming <leeming@lyx.org>
* forms/fdfix.sh: no need to assume that the fdfix files are in
#include "frontends/Dialogs.h"
#include "support/FileInfo.h"
-#include "support/lyxlib.h"
+#include "support/filetools.h"
+#include "support/globbing.h"
#include "support/lstrings.h"
+#include "support/lyxlib.h"
#include "support/tostr.h"
-#include "support/filetools.h"
#include "lyx_forms.h"
using std::sort;
using std::string;
using std::map;
+using std::vector;
namespace {
int FileDialog::Private::minh_ = 0;
-namespace {
-
-boost::regex glob2regex(string const & pat)
-{
- // We massage the pattern a bit so that the usual
- // shell pattern we all are used to will work.
- // One nice thing about using a real regex is that
- // things like "*.*[^~]" will work also.
- // build the regex string.
- string pattern = subst(pat, ".", "\\.");
- pattern = subst(pattern, "*", ".*");
-
- boost::regex reg(pattern);
- return reg;
-}
-
-
-bool globMatch(string const & a, boost::regex const & reg)
-{
- // If the glob is invalid then match everything.
- return reg.empty() ? true : boost::regex_match(a, reg);
-}
-
-} // namespace anon
-
-
// Reread: updates dialog list to match class directory
void FileDialog::Private::Reread()
{
++depth_;
}
- // Parses all entries of the given subdirectory
- boost::regex const mask_regex = glob2regex(mask_);
-
+ vector<string> const glob_matches =
+ lyx::support::expand_globs(mask_, directory_);
+
time_t curTime = time(0);
rewinddir(dir);
while (dirent * entry = readdir(dir)) {
buffer += Link;
// This gives the FileType of the file that
- // is really pointed too after resolving all
+ // is really pointed to after resolving all
// symlinks. This is not necessarily the same
// as the type of Link (which could again be a
// link). Is that intended?
|| fileInfo.isChar()
|| fileInfo.isBlock()
|| fileInfo.isFifo()) {
- if (!globMatch(fname, mask_regex))
+ typedef vector<string>::const_iterator viterator;
+ viterator gbegin = glob_matches.begin();
+ viterator const gend = glob_matches.end();
+ if (std::find(gbegin, gend, fname) == gend)
continue;
} else if (!(isDir = fileInfo.isDir()))
continue;
+2004-01-05 Angus Leeming <leeming@lyx.org>
+
+ * globbing.[Ch]: new files containing some globbing utilities.
+
2003-11-05 João Luis M. Assirati <assirati@fma.if.usp.br>
* putenv.C: allocate the string before putting it into the
forkedcontr.C \
forkedcontr.h \
getcwd.C \
+ globbing.C \
+ globbing.h \
$(COMPRESSION) kill.C \
limited_stack.h \
lstrings.C \
--- /dev/null
+/**
+ * \file globbing.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include "globbing.h"
+
+#include "path.h"
+
+#include <boost/regex.hpp>
+#include <boost/tokenizer.hpp>
+
+#include "glob.h"
+
+using std::string;
+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 += std::distance(it, what[0].second);
+ }
+
+ return pattern;
+}
+
+
+vector<string> const glob(string const & pattern, int flags)
+{
+ glob_t glob_buffer = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+ glob(pattern.c_str(), flags, 0, &glob_buffer);
+ vector<string> const matches(glob_buffer.gl_pathv,
+ glob_buffer.gl_pathv +
+ glob_buffer.gl_pathc);
+ globfree(&glob_buffer);
+ return matches;
+}
+
+
+vector<string> const expand_globs(string const & mask,
+ std::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 expanded_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(expanded_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
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file globbing.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef GLOBBING_H
+#define GLOBBING_H
+
+#include <string>
+#include <vector>
+
+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'.
+ * \returns a vector of the files found to match \c pattern.
+ */
+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 expand_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
+
+#endif // NOT GLOBBING_H