]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/qt_helpers.cpp
d62bf9015b8b64db7f8baca20d2f65c373ea0f61
[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 "FileDialog.h"
18 #include "LengthCombo.h"
19
20 #include "frontends/alert.h"
21
22 #include "Language.h"
23 #include "Length.h"
24
25 #include "support/debug.h"
26 #include "support/filetools.h"
27 #include "support/gettext.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 void rescanTexStyles()
210 {
211         // Run rescan in user lyx directory
212         PathChanger p(package().user_support());
213         FileName const command = libFileSearch("scripts", "TeXFiles.py");
214         Systemcall one;
215         int const status = one.startscript(Systemcall::Wait,
216                         os::python() + ' ' +
217                         quoteName(command.toFilesystemEncoding()));
218         if (status == 0)
219                 return;
220         // FIXME UNICODE
221         frontend::Alert::error(_("Could not update TeX information"),
222                 bformat(_("The script `%s' failed."), from_utf8(command.absFilename())));
223 }
224
225
226 void getTexFileList(string const & filename, vector<string> & list)
227 {
228         list.clear();
229         FileName const file = libFileSearch("", filename);
230         if (file.empty())
231                 return;
232
233         // FIXME Unicode.
234         vector<docstring> doclist = 
235                 getVectorFromString(file.fileContents("UTF-8"), from_ascii("\n"));
236
237         // Normalise paths like /foo//bar ==> /foo/bar
238         boost::RegEx regex("/{2,}");
239         vector<docstring>::iterator it  = doclist.begin();
240         vector<docstring>::iterator end = doclist.end();
241         for (; it != end; ++it)
242                 list.push_back(regex.Merge(to_utf8(*it), "/"));
243
244         // remove empty items and duplicates
245         list.erase(remove(list.begin(), list.end(), ""), list.end());
246         eliminate_duplicates(list);
247 }
248
249
250 QString internalPath(const QString & str)
251 {
252         return toqstr(os::internal_path(fromqstr(str)));
253 }
254
255
256 QString onlyFilename(const QString & str)
257 {
258         return toqstr(support::onlyFilename(fromqstr(str)));
259 }
260
261
262 QString onlyPath(const QString & str)
263 {
264         return toqstr(support::onlyPath(fromqstr(str)));
265 }
266
267 } // namespace lyx