Alfredo Braunstein wrote:
> on lyx-xforms, File->Open gives me a mask of "*.lyx| LyX Documents
> (*.lyx)" that filters out all .lyx files.
> If I change it to "*.lyx | LyX Documents (*.lyx)" or "*.lyx" all
> goes well.
Thanks for the report, Alfredo.
The problem with the above is that it is a nasty kludge. It is a
half-hearted attempt to support Qt's native syntax:
"LyX Documents (*.lyx);;Pdf Documents (*.pdf)"
Qt would use the above to populate the "File type" combox in the file
browser dialog with two entries
LyX Documents (*.lyx)
Pdf Documents (*.pdf)
and to filter the files on view based on the globbing pattern of
whichever entry was selected (*.lyx or *.pdf).
I think that we should support Qt's native syntax fully, but that will
require us to write a parser for this syntax so that xforms (gtk?)
can be made to understand it too.
So, we need a parser that can handle
"<filter>\(;;<filter>\)*"
where <filter> = "<space separated globs>"
or <filter> = "<descriptive text>(<space separated globs>)"
This parser would generate std::vector<FileFilter> where
struct FileFilter {
std::string descriptive_text;
std::string globbing_list;
};
This could be handled simply enough by the xforms frontend if we
replaced the "Pattern" input widget with a combox, as in the Qt
frontend. However, this prevents the user from modifying the pattern.
Ideally, we'd have an "input combox" here.
It might be fun writing the parser using the boost::spirit library,
but I think it's easiest to use boost::tokenizer. See attached.
$ g++ -Iboost/boost-1.30.2 -o trial2 trial2.C
$ ./trial2 'LyX Documents (*.lyx);;Pdf Documents (*.pdf)'
Description 'LyX Documents ', globbing pattern '*.lyx'
Description 'Pdf Documents ', globbing pattern '*.pdf'
--
Angus
#include <boost/tokenizer.hpp>
#include <iostream>
#include <string>
void parse_input(std::string const & str)
{
if (str.empty())
return;
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
boost::char_separator<char> const filter_separator(";");
boost::char_separator<char> const description_separator("()");
Tokenizer const filter_list_tokens(str, filter_separator);
Tokenizer::const_iterator it = filter_list_tokens.begin();
Tokenizer::const_iterator const end = filter_list_tokens.end();
for (; it != end; ++it) {
std::string description;
std::string globbing_pattern;
Tokenizer const tokens(*it, description_separator);
Tokenizer::const_iterator it2 = tokens.begin();
Tokenizer::const_iterator const end2 = tokens.end();
std::string::size_type const size = std::distance(it2, end2);
if (size == 1)
globbing_pattern = *it2;
else if (size == 2) {
description = *it2++;
globbing_pattern = *it2;
} else {
std::cerr << "Unrecognized pattern "
<< *it << '\n';
continue;
}
std::cout << "Description '" << description
<< "', globbing pattern '" << globbing_pattern
<< "'\n";
}
}
int main(int argc, char const * const argv[])
{
for (int i = 1; i != argc; ++i)
parse_input(argv[i]);
std::flush(std::cout);
return 0;
}