]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/qt_helpers.cpp
getting rid of superfluous lyx::support:: statements.
[lyx.git] / src / frontends / qt4 / qt_helpers.cpp
1 /**
2  * \file qt_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 Dekel Tsur
7  * \author Jürgen Spitzmüller
8  * \author Richard Heck
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "qt_helpers.h"
16
17 #include "LengthCombo.h"
18
19 #include "support/debug.h"
20 #include "support/gettext.h"
21 #include "Language.h"
22 #include "Length.h"
23
24 #include "frontends/FileDialog.h"
25 #include "frontends/alert.h"
26
27 #include "support/filetools.h"
28 #include "support/lstrings.h"
29 #include "support/lyxalgo.h"
30 #include "support/os.h"
31 #include "support/Package.h"
32 #include "support/Path.h"
33 #include "support/Systemcall.h"
34
35 #include <QComboBox>
36 #include <QCheckBox>
37 #include <QPalette>
38 #include <QLineEdit>
39
40 #include <boost/cregex.hpp>
41
42 #include <algorithm>
43 #include <fstream>
44 #include <locale>
45
46 using namespace std;
47 using namespace lyx::support;
48
49 namespace lyx {
50 namespace frontend {
51
52 string widgetsToLength(QLineEdit const * input, LengthCombo const * combo)
53 {
54         QString const length = input->text();
55         if (length.isEmpty())
56                 return string();
57
58         // Don't return unit-from-choice if the input(field) contains a unit
59         if (isValidGlueLength(fromqstr(length)))
60                 return fromqstr(length);
61
62         Length::UNIT const unit = combo->currentLengthItem();
63
64         return Length(length.toDouble(), unit).asString();
65 }
66
67
68 Length widgetsToLength(QLineEdit const * input, QComboBox const * combo)
69 {
70         QString const length = input->text();
71         if (length.isEmpty())
72                 return Length();
73
74         // don't return unit-from-choice if the input(field) contains a unit
75         if (isValidGlueLength(fromqstr(length)))
76                 return Length(fromqstr(length));
77
78         Length::UNIT const unit = unitFromString(fromqstr(combo->currentText()));
79
80         return Length(length.toDouble(), unit);
81 }
82
83
84 void lengthToWidgets(QLineEdit * input, LengthCombo * combo,
85                      Length const & len, Length::UNIT /*defaultUnit*/)
86 {
87         combo->setCurrentItem(len.unit());
88         input->setText(QString::number(Length(len).value()));
89 }
90
91
92 void lengthToWidgets(QLineEdit * input, LengthCombo * combo,
93         string const & len, Length::UNIT defaultUnit)
94 {
95         if (len.empty()) {
96                 // no length (UNIT_NONE)
97                 combo->setCurrentItem(defaultUnit);
98                 input->setText("");
99         } else if (!isValidLength(len) && !isStrDbl(len)) {
100                 // use input field only for gluelengths
101                 combo->setCurrentItem(defaultUnit);
102                 input->setText(toqstr(len));
103         } else {
104                 lengthToWidgets(input, combo, Length(len), defaultUnit);
105         }
106 }
107
108
109 void lengthAutoToWidgets(QLineEdit * input, LengthCombo * combo,
110         Length const & len, Length::UNIT defaultUnit)
111 {
112         if (len.value() == 0)
113                 lengthToWidgets(input, combo, "auto", defaultUnit);
114         else
115                 lengthToWidgets(input, combo, len, defaultUnit);
116 }
117
118
119 void setValid(QWidget * widget, bool valid)
120 {
121         if (valid) {
122                 widget->setPalette(QPalette());
123         } else {
124                 QPalette pal = widget->palette();
125                 pal.setColor(QPalette::Active, QPalette::Foreground, QColor(255, 0, 0));
126                 widget->setPalette(pal);
127         }
128 }
129
130 } // namespace frontend
131
132 QString const qt_(char const * str, const char *)
133 {
134         return toqstr(_(str));
135 }
136
137
138 QString const qt_(string const & str)
139 {
140         return toqstr(_(str));
141 }
142
143 namespace {
144
145 class Sorter
146 {
147 public:
148 #if !defined(USE_WCHAR_T) && defined(__GNUC__)
149         bool operator()(LanguagePair const & lhs, LanguagePair const & rhs) const {
150                 return lhs.first < rhs.first;
151         }
152 #else
153         Sorter() : loc_ok(true)
154         {
155                 try {
156                         loc_ = locale("");
157                 } catch (...) {
158                         loc_ok = false;
159                 }
160         };
161
162         bool operator()(LanguagePair const & lhs,
163                         LanguagePair const & rhs) const {
164                 if (loc_ok)
165                         return loc_(lhs.first, rhs.first);
166                 else
167                         return lhs.first < rhs.first;
168         }
169 private:
170         locale loc_;
171         bool loc_ok;
172 #endif
173 };
174
175
176 } // namespace anon
177
178
179 vector<LanguagePair> const getLanguageData(bool character_dlg)
180 {
181         size_t const size = languages.size() + (character_dlg ? 2 : 0);
182
183         vector<LanguagePair> langs(size);
184
185         if (character_dlg) {
186                 langs[0].first = _("No change");
187                 langs[0].second = "ignore";
188                 langs[1].first = _("Reset");
189                 langs[1].second = "reset";
190         }
191
192         size_t i = character_dlg ? 2 : 0;
193         for (Languages::const_iterator cit = languages.begin();
194              cit != languages.end(); ++cit) {
195                 langs[i].first  = _(cit->second.display());
196                 langs[i].second = cit->second.lang();
197                 ++i;
198         }
199
200         // Don't sort "ignore" and "reset"
201         vector<LanguagePair>::iterator begin = character_dlg ?
202                 langs.begin() + 2 : langs.begin();
203
204         sort(begin, langs.end(), Sorter());
205
206         return langs;
207 }
208
209
210 docstring browseFile(docstring const & filename, docstring const & title,
211         FileFilterList const & filters, bool save,
212         docstring const & label1, docstring const & dir1,
213         docstring const & label2, docstring const & dir2)
214 {
215         docstring lastPath = from_ascii(".");
216         if (!filename.empty())
217                 lastPath = from_utf8(onlyPath(to_utf8(filename)));
218
219         FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
220         dlg.setButton1(label1, dir1);
221         dlg.setButton2(label2, dir2);
222
223         FileDialog::Result result;
224
225         if (save)
226                 result = dlg.save(lastPath, filters,
227                                       from_utf8(onlyFilename(to_utf8(filename))));
228         else
229                 result = dlg.open(lastPath, filters,
230                                       from_utf8(onlyFilename(to_utf8(filename))));
231
232         return result.second;
233 }
234
235
236 docstring browseRelFile(docstring const & filename, docstring const & refpath,
237         docstring const & title, FileFilterList const & filters, bool save,
238         docstring const & label1, docstring const & dir1,
239         docstring const & label2, docstring const & dir2)
240 {
241         docstring const fname = from_utf8(makeAbsPath(
242                 to_utf8(filename), to_utf8(refpath)).absFilename());
243
244         docstring const outname = browseFile(fname, title, filters, save,
245                                           label1, dir1, label2, dir2);
246         docstring const reloutname = makeRelPath(outname, refpath);
247         if (prefixIs(reloutname, from_ascii("../")))
248                 return outname;
249         else
250                 return reloutname;
251 }
252
253
254 docstring browseLibFile(docstring const & dir, docstring const & name,
255         docstring const & ext, docstring const & title,
256         FileFilterList const & filters)
257 {
258         // FIXME UNICODE
259         docstring const label1 = _("System files|#S#s");
260         docstring const dir1 =
261                 from_utf8(addName(package().system_support().absFilename(), to_utf8(dir)));
262
263         docstring const label2 = _("User files|#U#u");
264         docstring const dir2 =
265                 from_utf8(addName(package().user_support().absFilename(), to_utf8(dir)));
266
267         docstring const result = browseFile(from_utf8(
268                 libFileSearch(to_utf8(dir), to_utf8(name), to_utf8(ext)).absFilename()),
269                 title, filters, false, dir1, dir2);
270
271         // remove the extension if it is the default one
272         docstring noextresult;
273         if (from_utf8(getExtension(to_utf8(result))) == ext)
274                 noextresult = from_utf8(removeExtension(to_utf8(result)));
275         else
276                 noextresult = result;
277
278         // remove the directory, if it is the default one
279         docstring const file = from_utf8(onlyFilename(to_utf8(noextresult)));
280         if (from_utf8(libFileSearch(to_utf8(dir), to_utf8(file), to_utf8(ext)).absFilename()) == result)
281                 return file;
282         else
283                 return noextresult;
284 }
285
286
287 docstring browseDir(docstring const & pathname, docstring const & title,
288         docstring const & label1, docstring const & dir1,
289         docstring const & label2, docstring const & dir2)
290 {
291         docstring lastPath = from_ascii(".");
292         if (!pathname.empty())
293                 lastPath = from_utf8(onlyPath(to_utf8(pathname)));
294
295         FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
296         dlg.setButton1(label1, dir1);
297         dlg.setButton2(label2, dir2);
298
299         FileDialog::Result const result =
300                 dlg.opendir(lastPath, from_utf8(onlyFilename(to_utf8(pathname))));
301
302         return result.second;
303 }
304
305
306 void rescanTexStyles()
307 {
308         // Run rescan in user lyx directory
309         PathChanger p(package().user_support());
310         FileName const command = libFileSearch("scripts", "TeXFiles.py");
311         Systemcall one;
312         int const status = one.startscript(Systemcall::Wait,
313                         os::python() + ' ' +
314                         quoteName(command.toFilesystemEncoding()));
315         if (status == 0)
316                 return;
317         // FIXME UNICODE
318         frontend::Alert::error(_("Could not update TeX information"),
319                 bformat(_("The script `%s' failed."), from_utf8(command.absFilename())));
320 }
321
322
323 void getTexFileList(string const & filename, vector<string> & list)
324 {
325         list.clear();
326         FileName const file = libFileSearch("", filename);
327         if (file.empty())
328                 return;
329
330         // FIXME Unicode.
331         vector<docstring> doclist = 
332                 getVectorFromString(file.fileContents("UTF-8"), from_ascii("\n"));
333
334         // Normalise paths like /foo//bar ==> /foo/bar
335         boost::RegEx regex("/{2,}");
336         vector<docstring>::iterator it  = doclist.begin();
337         vector<docstring>::iterator end = doclist.end();
338         for (; it != end; ++it)
339                 list.push_back(regex.Merge(to_utf8(*it), "/"));
340
341         // remove empty items and duplicates
342         list.erase(remove(list.begin(), list.end(), ""), list.end());
343         eliminate_duplicates(list);
344 }
345
346 } // namespace lyx