]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/qt_helpers.cpp
Complete the removal of the embedding stuff. Maybe. It's hard to be sure we got every...
[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/foreach.h"
28 #include "support/gettext.h"
29 #include "support/lstrings.h"
30 #include "support/lyxalgo.h"
31 #include "support/os.h"
32 #include "support/Package.h"
33 #include "support/Path.h"
34 #include "support/Systemcall.h"
35
36 #include <QCheckBox>
37 #include <QComboBox>
38 #include <QLineEdit>
39 #include <QPalette>
40 #include <QSet>
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
51 FileName libFileSearch(QString const & dir, QString const & name,
52                                 QString const & ext)
53 {
54         return support::libFileSearch(fromqstr(dir), fromqstr(name), fromqstr(ext));
55 }
56
57 namespace frontend {
58
59 string widgetsToLength(QLineEdit const * input, LengthCombo const * combo)
60 {
61         QString const length = input->text();
62         if (length.isEmpty())
63                 return string();
64
65         // Don't return unit-from-choice if the input(field) contains a unit
66         if (isValidGlueLength(fromqstr(length)))
67                 return fromqstr(length);
68
69         Length::UNIT const unit = combo->currentLengthItem();
70
71         return Length(length.toDouble(), unit).asString();
72 }
73
74
75 Length widgetsToLength(QLineEdit const * input, QComboBox const * combo)
76 {
77         QString const length = input->text();
78         if (length.isEmpty())
79                 return Length();
80
81         // don't return unit-from-choice if the input(field) contains a unit
82         if (isValidGlueLength(fromqstr(length)))
83                 return Length(fromqstr(length));
84
85         Length::UNIT const unit = unitFromString(fromqstr(combo->currentText()));
86
87         return Length(length.toDouble(), unit);
88 }
89
90
91 void lengthToWidgets(QLineEdit * input, LengthCombo * combo,
92                      Length const & len, Length::UNIT /*defaultUnit*/)
93 {
94         combo->setCurrentItem(len.unit());
95         input->setText(QString::number(Length(len).value()));
96 }
97
98
99 void lengthToWidgets(QLineEdit * input, LengthCombo * combo,
100         string const & len, Length::UNIT defaultUnit)
101 {
102         if (len.empty()) {
103                 // no length (UNIT_NONE)
104                 combo->setCurrentItem(defaultUnit);
105                 input->setText("");
106         } else if (!isValidLength(len) && !isStrDbl(len)) {
107                 // use input field only for gluelengths
108                 combo->setCurrentItem(defaultUnit);
109                 input->setText(toqstr(len));
110         } else {
111                 lengthToWidgets(input, combo, Length(len), defaultUnit);
112         }
113 }
114
115
116 void lengthAutoToWidgets(QLineEdit * input, LengthCombo * combo,
117         Length const & len, Length::UNIT defaultUnit)
118 {
119         if (len.value() == 0)
120                 lengthToWidgets(input, combo, "auto", defaultUnit);
121         else
122                 lengthToWidgets(input, combo, len, defaultUnit);
123 }
124
125
126 void setValid(QWidget * widget, bool valid)
127 {
128         if (valid) {
129                 widget->setPalette(QPalette());
130         } else {
131                 QPalette pal = widget->palette();
132                 pal.setColor(QPalette::Active, QPalette::Foreground, QColor(255, 0, 0));
133                 widget->setPalette(pal);
134         }
135 }
136
137 } // namespace frontend
138
139 QString const qt_(char const * str, const char *)
140 {
141         return toqstr(_(str));
142 }
143
144
145 QString const qt_(string const & str)
146 {
147         return toqstr(_(str));
148 }
149
150 namespace {
151
152 class Sorter
153 {
154 public:
155 #if !defined(USE_WCHAR_T) && defined(__GNUC__)
156         bool operator()(LanguagePair const & lhs, LanguagePair const & rhs) const
157         {
158                 return lhs.first < rhs.first;
159         }
160 #else
161         Sorter() : loc_ok(true)
162         {
163                 try {
164                         loc_ = locale("");
165                 } catch (...) {
166                         loc_ok = false;
167                 }
168         }
169
170         bool operator()(LanguagePair const & lhs, LanguagePair const & rhs) const
171         {
172                 //  FIXME: would that be "QString::localeAwareCompare()"?
173                 if (loc_ok)
174                         return loc_(fromqstr(lhs.first), fromqstr(rhs.first));
175                 else
176                         return lhs.first < rhs.first;
177         }
178 private:
179         locale loc_;
180         bool loc_ok;
181 #endif
182 };
183
184
185 } // namespace anon
186
187
188 QList<LanguagePair> languageData(bool character_dlg)
189 {
190         size_t const offset = character_dlg ? 2 : 0;
191         vector<LanguagePair> langs(languages.size() + offset);
192
193         if (character_dlg) {
194                 langs[0].first = qt_("No change");
195                 langs[0].second = "ignore";
196                 langs[1].first = qt_("Reset");
197                 langs[1].second = "reset";
198         }
199
200         Languages::const_iterator it = languages.begin();
201         for (size_t i = 0; i != languages.size(); ++i, ++it) {
202                 langs[i + offset].first  = qt_(it->second.display());
203                 langs[i + offset].second = toqstr(it->second.lang());
204         }
205
206         // Don't sort "ignore" and "reset"
207         vector<LanguagePair>::iterator begin = langs.begin() + offset;
208         sort(begin, langs.end(), Sorter());
209
210         QList<LanguagePair> list;
211         foreach (LanguagePair const & l, langs)
212                 list.append(l);
213         return list;
214 }
215
216
217 void rescanTexStyles()
218 {
219         // Run rescan in user lyx directory
220         PathChanger p(package().user_support());
221         FileName const command = libFileSearch("scripts", "TeXFiles.py");
222         Systemcall one;
223         int const status = one.startscript(Systemcall::Wait,
224                         os::python() + ' ' +
225                         quoteName(command.toFilesystemEncoding()));
226         if (status == 0)
227                 return;
228         // FIXME UNICODE
229         frontend::Alert::error(_("Could not update TeX information"),
230                 bformat(_("The script `%s' failed."), from_utf8(command.absFilename())));
231 }
232
233
234 QStringList texFileList(QString const & filename)
235 {
236         QStringList list;
237         FileName const file = libFileSearch(QString(), filename);
238         if (file.empty())
239                 return list;
240
241         // FIXME Unicode.
242         vector<docstring> doclist = 
243                 getVectorFromString(file.fileContents("UTF-8"), from_ascii("\n"));
244
245         // Normalise paths like /foo//bar ==> /foo/bar
246         QSet<QString> set;
247         for (size_t i = 0; i != doclist.size(); ++i) {
248                 QString file = toqstr(doclist[i]);
249                 file.replace("\r", "");
250                 while (file.contains("//"))
251                         file.replace("//", "/");
252                 if (!file.isEmpty())
253                         set.insert(file);
254         }
255
256         // remove duplicates
257         return QList<QString>::fromSet(set);
258 }
259
260
261 QString internalPath(const QString & str)
262 {
263         return toqstr(os::internal_path(fromqstr(str)));
264 }
265
266
267 QString onlyFilename(const QString & str)
268 {
269         return toqstr(support::onlyFilename(fromqstr(str)));
270 }
271
272
273 QString onlyPath(const QString & str)
274 {
275         return toqstr(support::onlyPath(fromqstr(str)));
276 }
277
278
279 QString changeExtension(QString const & oldname, QString const & ext)
280 {
281         return toqstr(support::changeExtension(fromqstr(oldname), fromqstr(ext)));
282 }
283
284 /// Remove the extension from \p name
285 QString removeExtension(QString const & name)
286 {
287         return toqstr(support::removeExtension(fromqstr(name)));
288 }
289
290 /** Add the extension \p ext to \p name.
291  Use this instead of changeExtension if you know that \p name is without
292  extension, because changeExtension would wrongly interpret \p name if it
293  contains a dot.
294  */
295 QString addExtension(QString const & name, QString const & ext)
296 {
297         return toqstr(support::addExtension(fromqstr(name), fromqstr(ext)));
298 }
299
300 /// Return the extension of the file (not including the .)
301 QString getExtension(QString const & name)
302 {
303         return toqstr(support::getExtension(fromqstr(name)));
304 }
305
306 } // namespace lyx