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