2 * \file frontend_helpers.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
9 * Full author contact details are available in file CREDITS.
14 #include "frontend_helpers.h"
17 #include "BufferParams.h"
24 #include "frontends/FileDialog.h"
25 #include "frontends/alert.h"
27 #include "support/filetools.h"
28 #include "support/lstrings.h"
29 #include "support/Package.h"
30 #include "support/filetools.h"
31 #include "support/lstrings.h"
32 #include "support/lyxalgo.h"
33 #include "support/os.h"
34 #include "support/Package.h"
35 #include "support/Path.h"
36 #include "support/Systemcall.h"
38 #include <boost/cregex.hpp>
39 #include <boost/regex.hpp>
53 vector<FamilyPair> const getFamilyData()
55 vector<FamilyPair> family(5);
59 pr.first = _("No change");
60 pr.second = Font::IGNORE_FAMILY;
63 pr.first = _("Roman");
64 pr.second = Font::ROMAN_FAMILY;
67 pr.first = _("Sans Serif");
68 pr.second = Font::SANS_FAMILY;
71 pr.first = _("Typewriter");
72 pr.second = Font::TYPEWRITER_FAMILY;
75 pr.first = _("Reset");
76 pr.second = Font::INHERIT_FAMILY;
83 vector<SeriesPair> const getSeriesData()
85 vector<SeriesPair> series(4);
89 pr.first = _("No change");
90 pr.second = Font::IGNORE_SERIES;
93 pr.first = _("Medium");
94 pr.second = Font::MEDIUM_SERIES;
98 pr.second = Font::BOLD_SERIES;
101 pr.first = _("Reset");
102 pr.second = Font::INHERIT_SERIES;
109 vector<ShapePair> const getShapeData()
111 vector<ShapePair> shape(6);
115 pr.first = _("No change");
116 pr.second = Font::IGNORE_SHAPE;
119 pr.first = _("Upright");
120 pr.second = Font::UP_SHAPE;
123 pr.first = _("Italic");
124 pr.second = Font::ITALIC_SHAPE;
127 pr.first = _("Slanted");
128 pr.second = Font::SLANTED_SHAPE;
131 pr.first = _("Small Caps");
132 pr.second = Font::SMALLCAPS_SHAPE;
135 pr.first = _("Reset");
136 pr.second = Font::INHERIT_SHAPE;
143 vector<SizePair> const getSizeData()
145 vector<SizePair> size(14);
149 pr.first = _("No change");
150 pr.second = Font::IGNORE_SIZE;
153 pr.first = _("Tiny");
154 pr.second = Font::SIZE_TINY;
157 pr.first = _("Smallest");
158 pr.second = Font::SIZE_SCRIPT;
161 pr.first = _("Smaller");
162 pr.second = Font::SIZE_FOOTNOTE;
165 pr.first = _("Small");
166 pr.second = Font::SIZE_SMALL;
169 pr.first = _("Normal");
170 pr.second = Font::SIZE_NORMAL;
173 pr.first = _("Large");
174 pr.second = Font::SIZE_LARGE;
177 pr.first = _("Larger");
178 pr.second = Font::SIZE_LARGER;
181 pr.first = _("Largest");
182 pr.second = Font::SIZE_LARGEST;
185 pr.first = _("Huge");
186 pr.second = Font::SIZE_HUGE;
189 pr.first = _("Huger");
190 pr.second = Font::SIZE_HUGER;
193 pr.first = _("Increase");
194 pr.second = Font::INCREASE_SIZE;
197 pr.first = _("Decrease");
198 pr.second = Font::DECREASE_SIZE;
201 pr.first = _("Reset");
202 pr.second = Font::INHERIT_SIZE;
209 vector<BarPair> const getBarData()
211 vector<BarPair> bar(5);
215 pr.first = _("No change");
219 pr.first = _("Emph");
220 pr.second = EMPH_TOGGLE;
223 pr.first = _("Underbar");
224 pr.second = UNDERBAR_TOGGLE;
227 pr.first = _("Noun");
228 pr.second = NOUN_TOGGLE;
231 pr.first = _("Reset");
239 vector<ColorPair> const getColorData()
241 vector<ColorPair> color(11);
245 pr.first = _("No change");
246 pr.second = Color::ignore;
249 pr.first = _("No color");
250 pr.second = Color::none;
253 pr.first = _("Black");
254 pr.second = Color::black;
257 pr.first = _("White");
258 pr.second = Color::white;
262 pr.second = Color::red;
265 pr.first = _("Green");
266 pr.second = Color::green;
269 pr.first = _("Blue");
270 pr.second = Color::blue;
273 pr.first = _("Cyan");
274 pr.second = Color::cyan;
277 pr.first = _("Magenta");
278 pr.second = Color::magenta;
281 pr.first = _("Yellow");
282 pr.second = Color::yellow;
285 pr.first = _("Reset");
286 pr.second = Color::inherit;
297 : public std::binary_function<LanguagePair,
301 bool operator()(LanguagePair const & lhs,
302 LanguagePair const & rhs) const {
303 return lhs.first < rhs.first;
311 bool operator()(Color::color const & lhs,
312 Color::color const & rhs) const {
313 return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs);
320 vector<LanguagePair> const getLanguageData(bool character_dlg)
322 vector<LanguagePair>::size_type const size = character_dlg ?
323 languages.size() + 2 : languages.size();
325 vector<LanguagePair> langs(size);
328 langs[0].first = _("No change");
329 langs[0].second = "ignore";
330 langs[1].first = _("Reset");
331 langs[1].second = "reset";
334 vector<string>::size_type i = character_dlg ? 2 : 0;
335 for (Languages::const_iterator cit = languages.begin();
336 cit != languages.end(); ++cit) {
337 langs[i].first = _(cit->second.display());
338 langs[i].second = cit->second.lang();
342 // Don't sort "ignore" and "reset"
343 vector<LanguagePair>::iterator begin = character_dlg ?
344 langs.begin() + 2 : langs.begin();
346 std::sort(begin, langs.end(), Sorter());
352 vector<Color_color> const getSortedColors(vector<Color_color> colors)
355 std::sort(colors.begin(), colors.end(), ColorSorter());
359 } // namespace frontend
361 using support::addName;
362 using support::FileFilterList;
363 using support::getExtension;
364 using support::libFileSearch;
365 using support::makeAbsPath;
366 using support::makeRelPath;
367 using support::onlyFilename;
368 using support::onlyPath;
369 using support::package;
370 using support::prefixIs;
371 using support::removeExtension;
376 docstring const browseFile(docstring const & filename,
377 docstring const & title,
378 FileFilterList const & filters,
380 pair<docstring,docstring> const & dir1,
381 pair<docstring,docstring> const & dir2)
383 docstring lastPath = from_ascii(".");
384 if (!filename.empty())
385 lastPath = from_utf8(onlyPath(to_utf8(filename)));
387 FileDialog fileDlg(title, LFUN_SELECT_FILE_SYNC, dir1, dir2);
389 FileDialog::Result result;
392 result = fileDlg.save(lastPath, filters,
393 from_utf8(onlyFilename(to_utf8(filename))));
395 result = fileDlg.open(lastPath, filters,
396 from_utf8(onlyFilename(to_utf8(filename))));
398 return result.second;
402 docstring const browseRelFile(docstring const & filename,
403 docstring const & refpath,
404 docstring const & title,
405 FileFilterList const & filters,
407 pair<docstring,docstring> const & dir1,
408 pair<docstring,docstring> const & dir2)
410 docstring const fname = from_utf8(makeAbsPath(
411 to_utf8(filename), to_utf8(refpath)).absFilename());
413 docstring const outname = browseFile(fname, title, filters, save,
415 docstring const reloutname = makeRelPath(outname, refpath);
416 if (prefixIs(reloutname, from_ascii("../")))
424 docstring const browseLibFile(docstring const & dir,
425 docstring const & name,
426 docstring const & ext,
427 docstring const & title,
428 FileFilterList const & filters)
431 pair<docstring, docstring> const dir1(_("System files|#S#s"),
432 from_utf8(addName(package().system_support().absFilename(), to_utf8(dir))));
434 pair<docstring, docstring> const dir2(_("User files|#U#u"),
435 from_utf8(addName(package().user_support().absFilename(), to_utf8(dir))));
437 docstring const result = browseFile(from_utf8(
438 libFileSearch(to_utf8(dir), to_utf8(name), to_utf8(ext)).absFilename()),
439 title, filters, false, dir1, dir2);
441 // remove the extension if it is the default one
442 docstring noextresult;
443 if (from_utf8(getExtension(to_utf8(result))) == ext)
444 noextresult = from_utf8(removeExtension(to_utf8(result)));
446 noextresult = result;
448 // remove the directory, if it is the default one
449 docstring const file = from_utf8(onlyFilename(to_utf8(noextresult)));
450 if (from_utf8(libFileSearch(to_utf8(dir), to_utf8(file), to_utf8(ext)).absFilename()) == result)
457 docstring const browseDir(docstring const & pathname,
458 docstring const & title,
459 pair<docstring,docstring> const & dir1,
460 pair<docstring,docstring> const & dir2)
462 docstring lastPath = from_ascii(".");
463 if (!pathname.empty())
464 lastPath = from_utf8(onlyPath(to_utf8(pathname)));
466 FileDialog fileDlg(title, LFUN_SELECT_FILE_SYNC, dir1, dir2);
468 FileDialog::Result const result =
469 fileDlg.opendir(lastPath, from_utf8(onlyFilename(to_utf8(pathname))));
471 return result.second;
475 vector<docstring> const getLatexUnits()
477 vector<docstring> units;
479 char const * str = stringFromUnit(i);
480 for (; str != 0; ++i, str = stringFromUnit(i))
481 units.push_back(from_ascii(str));
486 } // namespace frontend
489 using support::bformat;
490 using support::contains;
491 using support::FileName;
492 using support::getExtension;
493 using support::getFileContents;
494 using support::getVectorFromString;
495 using support::libFileSearch;
496 using support::onlyFilename;
497 using support::package;
498 using support::quoteName;
499 using support::split;
500 using support::Systemcall;
501 using support::token;
505 void rescanTexStyles()
507 // Run rescan in user lyx directory
508 support::Path p(package().user_support());
509 FileName const command = libFileSearch("scripts", "TeXFiles.py");
511 int const status = one.startscript(Systemcall::Wait,
512 lyx::support::os::python() + ' ' +
513 quoteName(command.toFilesystemEncoding()));
517 Alert::error(_("Could not update TeX information"),
518 bformat(_("The script `%s' failed."), lyx::from_utf8(command.absFilename())));
524 // Run texhash in user lyx directory
525 support::Path p(package().user_support());
527 //path to texhash through system
529 one.startscript(Systemcall::Wait,"texhash");
533 void getTexFileList(string const & filename, std::vector<string> & list)
536 FileName const file = libFileSearch("", filename);
540 list = getVectorFromString(getFileContents(file), "\n");
542 // Normalise paths like /foo//bar ==> /foo/bar
543 boost::RegEx regex("/{2,}");
544 std::vector<string>::iterator it = list.begin();
545 std::vector<string>::iterator end = list.end();
546 for (; it != end; ++it) {
547 *it = regex.Merge((*it), "/");
550 // remove empty items and duplicates
551 list.erase(std::remove(list.begin(), list.end(), ""), list.end());
552 eliminate_duplicates(list);
556 string const getListOfOptions(string const & classname, string const & type)
558 FileName const filename(getTexFileFromList(classname, type));
559 if (filename.empty())
561 string optionList = string();
562 std::ifstream is(filename.toFilesystemEncoding().c_str());
566 if (contains(s,"DeclareOption")) {
567 s = s.substr(s.find("DeclareOption"));
568 s = split(s,'{'); // cut front
569 s = token(s,'}',0); // cut end
570 optionList += (s + '\n');
577 string const getTexFileFromList(string const & file,
581 // do we need to add the suffix?
582 if (!(getExtension(file) == type))
585 lyxerr << "Searching for file " << file_ << endl;
589 lstfile = "clsFiles.lst";
590 else if (type == "sty")
591 lstfile = "styFiles.lst";
592 else if (type == "bst")
593 lstfile = "bstFiles.lst";
594 else if (type == "bib")
595 lstfile = "bibFiles.lst";
596 FileName const abslstfile = libFileSearch(string(), lstfile);
597 if (abslstfile.empty()) {
598 lyxerr << "File `'" << lstfile << "' not found." << endl;
601 string const allClasses = getFileContents(abslstfile);
603 string classfile = token(allClasses, '\n', entries);
605 while ((!contains(classfile, file) ||
606 (onlyFilename(classfile) != file)) &&
608 classfile = token(allClasses, '\n', ++entries);
611 // now we have filename with full path
612 lyxerr << "with full path: " << classfile << endl;
617 } // namespace frontend