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;
}

Reply via email to