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