]> git.lyx.org Git - lyx.git/blob - src/frontends/frontend_helpers.cpp
adjust
[lyx.git] / src / frontends / frontend_helpers.cpp
1 /**
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.
5  *
6  * \author Angus Leeming
7  * \author Herbert Voß
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "frontend_helpers.h"
15
16 #include "gettext.h"
17 #include "Language.h"
18
19 #include "frontends/FileDialog.h"
20 #include "frontends/alert.h"
21
22 #include "support/filetools.h"
23 #include "support/lstrings.h"
24 #include "support/lyxalgo.h"
25 #include "support/os.h"
26 #include "support/Package.h"
27 #include "support/Path.h"
28 #include "support/Systemcall.h"
29
30 #include <boost/cregex.hpp>
31
32 #include <algorithm>
33 #include <fstream>
34
35 using std::string;
36 using std::vector;
37 using std::pair;
38 using std::endl;
39
40 namespace lyx {
41 namespace frontend {
42
43 using support::addName;
44 using support::bformat;
45 using support::FileFilterList;
46 using support::FileName;
47 using support::getExtension;
48 using support::getFileContents;
49 using support::getVectorFromString;
50 using support::libFileSearch;
51 using support::makeAbsPath;
52 using support::makeRelPath;
53 using support::onlyFilename;
54 using support::onlyPath;
55 using support::package;
56 using support::prefixIs;
57 using support::quoteName;
58 using support::removeExtension;
59 using support::Systemcall;
60 using support::token;
61
62
63 namespace {
64
65 struct Sorter
66 {
67         bool operator()(LanguagePair const & lhs, LanguagePair const & rhs) const {
68                 return lhs.first < rhs.first;
69         }
70 };
71
72
73 } // namespace anon
74
75
76 vector<LanguagePair> const getLanguageData(bool character_dlg)
77 {
78         vector<LanguagePair>::size_type const size = character_dlg ?
79                 languages.size() + 2 : languages.size();
80
81         vector<LanguagePair> langs(size);
82
83         if (character_dlg) {
84                 langs[0].first = _("No change");
85                 langs[0].second = "ignore";
86                 langs[1].first = _("Reset");
87                 langs[1].second = "reset";
88         }
89
90         vector<string>::size_type i = character_dlg ? 2 : 0;
91         for (Languages::const_iterator cit = languages.begin();
92              cit != languages.end(); ++cit) {
93                 langs[i].first  = _(cit->second.display());
94                 langs[i].second = cit->second.lang();
95                 ++i;
96         }
97
98         // Don't sort "ignore" and "reset"
99         vector<LanguagePair>::iterator begin = character_dlg ?
100                 langs.begin() + 2 : langs.begin();
101
102         std::sort(begin, langs.end(), Sorter());
103
104         return langs;
105 }
106
107
108 docstring const browseFile(docstring const & filename,
109                         docstring const & title,
110                         FileFilterList const & filters,
111                         bool save,
112                         pair<docstring,docstring> const & dir1,
113                         pair<docstring,docstring> const & dir2)
114 {
115         docstring lastPath = from_ascii(".");
116         if (!filename.empty())
117                 lastPath = from_utf8(onlyPath(to_utf8(filename)));
118
119         FileDialog fileDlg(title, LFUN_SELECT_FILE_SYNC, dir1, dir2);
120
121         FileDialog::Result result;
122
123         if (save)
124                 result = fileDlg.save(lastPath, filters,
125                                       from_utf8(onlyFilename(to_utf8(filename))));
126         else
127                 result = fileDlg.open(lastPath, filters,
128                                       from_utf8(onlyFilename(to_utf8(filename))));
129
130         return result.second;
131 }
132
133
134 docstring const browseRelFile(docstring const & filename,
135                            docstring const & refpath,
136                            docstring const & title,
137                            FileFilterList const & filters,
138                            bool save,
139                            pair<docstring,docstring> const & dir1,
140                            pair<docstring,docstring> const & dir2)
141 {
142         docstring const fname = from_utf8(makeAbsPath(
143                 to_utf8(filename), to_utf8(refpath)).absFilename());
144
145         docstring const outname = browseFile(fname, title, filters, save,
146                                           dir1, dir2);
147         docstring const reloutname = makeRelPath(outname, refpath);
148         if (prefixIs(reloutname, from_ascii("../")))
149                 return outname;
150         else
151                 return reloutname;
152 }
153
154
155 docstring const browseLibFile(docstring const & dir,
156                            docstring const & name,
157                            docstring const & ext,
158                            docstring const & title,
159                            FileFilterList const & filters)
160 {
161         // FIXME UNICODE
162         pair<docstring, docstring> const dir1(_("System files|#S#s"),
163                 from_utf8(addName(package().system_support().absFilename(), to_utf8(dir))));
164
165         pair<docstring, docstring> const dir2(_("User files|#U#u"),
166                 from_utf8(addName(package().user_support().absFilename(), to_utf8(dir))));
167
168         docstring const result = browseFile(from_utf8(
169                 libFileSearch(to_utf8(dir), to_utf8(name), to_utf8(ext)).absFilename()),
170                 title, filters, false, dir1, dir2);
171
172         // remove the extension if it is the default one
173         docstring noextresult;
174         if (from_utf8(getExtension(to_utf8(result))) == ext)
175                 noextresult = from_utf8(removeExtension(to_utf8(result)));
176         else
177                 noextresult = result;
178
179         // remove the directory, if it is the default one
180         docstring const file = from_utf8(onlyFilename(to_utf8(noextresult)));
181         if (from_utf8(libFileSearch(to_utf8(dir), to_utf8(file), to_utf8(ext)).absFilename()) == result)
182                 return file;
183         else
184                 return noextresult;
185 }
186
187
188 docstring const browseDir(docstring const & pathname,
189                        docstring const & title,
190                        pair<docstring,docstring> const & dir1,
191                        pair<docstring,docstring> const & dir2)
192 {
193         docstring lastPath = from_ascii(".");
194         if (!pathname.empty())
195                 lastPath = from_utf8(onlyPath(to_utf8(pathname)));
196
197         FileDialog fileDlg(title, LFUN_SELECT_FILE_SYNC, dir1, dir2);
198
199         FileDialog::Result const result =
200                 fileDlg.opendir(lastPath, from_utf8(onlyFilename(to_utf8(pathname))));
201
202         return result.second;
203 }
204
205
206 void rescanTexStyles()
207 {
208         // Run rescan in user lyx directory
209         support::Path p(package().user_support());
210         FileName const command = libFileSearch("scripts", "TeXFiles.py");
211         Systemcall one;
212         int const status = one.startscript(Systemcall::Wait,
213                         lyx::support::os::python() + ' ' +
214                         quoteName(command.toFilesystemEncoding()));
215         if (status == 0)
216                 return;
217         // FIXME UNICODE
218         Alert::error(_("Could not update TeX information"),
219                 bformat(_("The script `%s' failed."), from_utf8(command.absFilename())));
220 }
221
222
223 void getTexFileList(string const & filename, std::vector<string> & list)
224 {
225         list.clear();
226         FileName const file = libFileSearch("", filename);
227         if (file.empty())
228                 return;
229
230         list = getVectorFromString(getFileContents(file), "\n");
231
232         // Normalise paths like /foo//bar ==> /foo/bar
233         boost::RegEx regex("/{2,}");
234         std::vector<string>::iterator it  = list.begin();
235         std::vector<string>::iterator end = list.end();
236         for (; it != end; ++it)
237                 *it = regex.Merge((*it), "/");
238
239         // remove empty items and duplicates
240         list.erase(std::remove(list.begin(), list.end(), ""), list.end());
241         eliminate_duplicates(list);
242 }
243
244 } // namespace frontend
245 } // namespace lyx