]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/GuiAbout.cpp
MasterChild.ui: Group radio buttons (part of #12470)
[lyx.git] / src / frontends / qt / GuiAbout.cpp
1 /**
2  * \file GuiAbout.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Kalle Dalheimer
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "GuiAbout.h"
14 #include "GuiApplication.h"
15
16 #include "ui_AboutUi.h"
17
18 #include "qt_helpers.h"
19 #include "version.h"
20
21 #include "support/filetools.h"
22 #include "support/gettext.h"
23 #include "support/lstrings.h"
24 #include "support/Package.h"
25
26 #include <QClipboard>
27 #include <QDate>
28 #include <QFile>
29 #include <QTextStream>
30
31 using namespace lyx::support;
32 using lyx::support::package;
33 using lyx::support::makeDisplayPath;
34
35
36 namespace lyx {
37 namespace frontend {
38
39
40 static QDate release_date()
41 {
42         return QDate::fromString(QString(lyx_release_date), Qt::ISODate);
43 }
44
45
46 static QString credits()
47 {
48         QString res;
49         QFile file(toqstr(package().system_support().absFileName()) + "/CREDITS");
50         QTextStream out(&res);
51
52         if (!file.exists()) {
53                 out << qt_("ERROR: LyX wasn't able to find the CREDITS file\n");
54                 out << qt_("Please install correctly to estimate the great\namount of work other people have done for the LyX project.");
55         } else {
56                 file.open(QIODevice::ReadOnly);
57                 if (!file.isReadable()) {
58                         out << qt_("ERROR: LyX wasn't able to read the CREDITS file\n");
59                         out << qt_("Please install correctly to estimate the great\namount of work other people have done for the LyX project.");
60                 } else {
61                         QTextStream ts(&file);
62 #if QT_VERSION < 0x060000
63                         ts.setCodec("UTF-8");
64 #endif
65                         QString line;
66                         do {
67                                 line = ts.readLine();
68                                 if (line.startsWith("#"))
69                                         continue;
70                                 if (line.startsWith("@b"))
71                                         out << "<b>" << line.mid(2) << "</b>";
72                                 else if (line.startsWith("@i")) {
73                                         if (line.startsWith("@iE-mail")) {
74                                                 // unmask email
75                                                 line.replace(QString(" () "), QString("@"));
76                                                 line.replace(QString(" ! "), QString("."));
77                                         }
78                                         out << "<i>" << line.mid(2) << "</i>";
79                                 } else
80                                         out << line;
81                                 out << "<br>";
82                         } while (!line.isNull());
83                 }
84         }
85         out.flush();
86         return res;
87 }
88
89
90 static QString release_notes()
91 {
92         QString res;
93         QFile file(toqstr(package().system_support().absFileName()) + "/RELEASE-NOTES");
94         QTextStream out(&res);
95
96         if (!file.exists()) {
97                 out << qt_("ERROR: LyX wasn't able to find the RELEASE-NOTES file\n");
98                 out << qt_("Please install correctly to see what has changed\nfor this version of LyX.");
99         } else {
100                 file.open(QIODevice::ReadOnly);
101                 if (!file.isReadable()) {
102                         out << qt_("ERROR: LyX wasn't able to read the RELEASE-NOTES file\n");
103                         out << qt_("Please install correctly to see what has changed\nfor this version of LyX.");
104                 } else {
105                         QTextStream ts(&file);
106 #if QT_VERSION < 0x060000
107                         ts.setCodec("UTF-8");
108 #endif
109                         QString line;
110                         bool incomment = false;
111                         bool inlist = false;
112                         do {
113                                 // a simple markdown parser
114                                 line = ts.readLine();
115                                 // skipe empty lines
116                                 if (line.isEmpty())
117                                         continue;
118                                 // parse (:comments:)
119                                 if (line.startsWith("(:")) {
120                                         if (!line.endsWith(":)"))
121                                                 incomment = true;
122                                         continue;
123                                 } if (line.endsWith(":)") && incomment) {
124                                         incomment = false;
125                                         continue;
126                                 } if (incomment)
127                                         continue;
128
129                                 // detect links to the tracker
130 #if QT_VERSION < 0x060000
131                                 line.replace(QRegExp("(bug )(\\#)(\\d+)*"),
132                                              "<a href=\"http://www.lyx.org/trac/ticket/\\3\">\\1\\3</a>");
133 #else
134                                 line.replace(QRegularExpression("(bug )(\\#)(\\d+)*"),
135                                              "<a href=\"http://www.lyx.org/trac/ticket/\\3\">\\1\\3</a>");
136 #endif
137
138                                 // headings
139                                 if (line.startsWith("!!!")) {
140                                         if (inlist) {
141                                             out << "</li>";
142                                             out << "</ul><br>";
143                                             inlist = false;
144                                         }
145                                         out << "<h4>" << line.mid(3) << "</h4>";
146                                 }
147                                 else if (line.startsWith("!!")) {
148                                         if (inlist) {
149                                             out << "</li>";
150                                             out << "</ul><br>";
151                                             inlist = false;
152                                         }
153                                         out << "<h3>" << line.mid(2) << "</h3>";
154                                 } else if (line.startsWith("!")) {
155                                         if (inlist) {
156                                             out << "</li>";
157                                             out << "</ul><br>";
158                                             inlist = false;
159                                         }
160                                         out << "<h2>" << line.mid(1) << "</h2>";
161                                 // lists
162                                 } else if (line.startsWith("* ")) {
163                                         if (inlist)
164                                                 out << "</li>";
165                                         else
166                                                 out << "<ul>";
167                                         inlist = true;
168                                         out << "<li>" << line.mid(2);
169                                 } else if (inlist && line.startsWith("  ")) {
170                                         out << line.mid(2);
171                                 } else if (inlist) {
172                                         inlist = false;
173                                         out << "</li>";
174                                         out << "</ul><br>";
175                                         out << line;
176                                 } else
177                                         out << line;
178
179                                 out << " ";
180                         } while (!line.isNull());
181                 }
182         }
183         out.flush();
184         return res;
185 }
186
187
188 static QString copyright()
189 {
190         QString release_year = release_date().toString("yyyy");
191         docstring copy_message =
192                 bformat(_("LyX is Copyright (C) 1995 by Matthias Ettrich,\n1995--%1$s LyX Team"),
193                         qstring_to_ucs4(release_year));
194         return toqstr(copy_message);
195 }
196
197
198 static QString license()
199 {
200         return qt_("This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.");
201 }
202
203
204 static QString disclaimer()
205 {
206         return qt_("LyX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\nSee the GNU General Public License for more details.\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.");
207 }
208
209
210 static QString buildinfo()
211 {
212         QString res;
213         QTextStream out(&res);
214         out << "LyX " << lyx_version
215                 << " (" << lyx_release_date << ")"
216 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
217                 << Qt::endl;
218 #else
219                 << endl;
220 #endif
221         if (std::string(lyx_git_commit_hash) != "none")
222                 out << qt_("  Git commit hash ")
223                     << QString(lyx_git_commit_hash).left(8)
224 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
225                     << Qt::endl;
226 #else
227                     << endl;
228 #endif
229
230         out << lyx_version_info 
231 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
232             << Qt::endl;
233 #else
234             << endl;
235 #endif
236         return res;
237 }
238
239
240 static QString dirLibrary()
241 {
242         return toqstr(makeDisplayPath(package().system_support().absFileName()));
243 }
244
245
246 static QString dirUser()
247 {
248         return toqstr(makeDisplayPath(package().user_support().absFileName()));
249 }
250
251
252 static QString version(bool const plain = false)
253 {
254         QString loc_release_date;
255         QDate date = release_date();
256         if (date.isValid()) {
257                 QLocale loc;
258                 loc_release_date = loc.toString(date, QLocale::LongFormat);
259         } else {
260                 if (QString(lyx_release_date) == "not released yet")
261                         loc_release_date = qt_("not released yet");
262                 else
263                         loc_release_date = toqstr(lyx_release_date);
264         }
265         docstring version_date =
266                 bformat(_("Version %1$s\n(%2$s)"),
267                         from_ascii(lyx_version),
268                         qstring_to_ucs4(loc_release_date))+"\n";
269         if (std::string(lyx_git_commit_hash) != "none") {
270                 if (plain)
271                         version_date += '\n';
272                 else
273                         version_date += from_ascii("</p><p>");
274                 version_date += _("Built from git commit hash ")
275                         + from_utf8(lyx_git_commit_hash).substr(0,8);
276         }
277
278         QString res;
279         QTextStream out(&res);
280         if (!plain)
281                 out << toqstr("<html><head/><body><p><span style=\" font-weight:600;\">");
282         out << toqstr(version_date);
283         if (plain)
284                 out << '\n';
285         else
286                 out << "</span></p><p>";
287         out << toqstr(bformat(_("Qt Version (run-time): %1$s on platform %2$s"), from_ascii(qVersion()), qstring_to_ucs4(guiApp->platformName())));
288         if (plain)
289                 out << '\n';
290         else
291                 out << "</p><p>";
292         out << toqstr(bformat(_("Qt Version (compile-time): %1$s"), from_ascii(QT_VERSION_STR)));
293         if (plain)
294                 out << '\n';
295         else
296                 out << "</p><p>";
297 #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
298         out << toqstr(bformat(_("OS Version (run-time): %1$s"),
299                 qstring_to_ucs4(QSysInfo::prettyProductName())));
300         if (plain)
301                 out << '\n';
302         else
303                 out << "</p><p>";
304 #endif
305         out << toqstr(bformat(_("Python detected: %1$s"), from_utf8(os::python())));
306         if (!plain)
307                 out << toqstr("</p></body></html>");
308         return res;
309 }
310
311
312 struct GuiAbout::Private
313 {
314         Ui::AboutUi ui;
315 };
316
317 void GuiAbout::on_showDirLibraryPB_clicked()
318 {
319         showDirectory(package().system_support());
320 }
321
322
323 void GuiAbout::on_showDirUserPB_clicked()
324 {
325         showDirectory(package().user_support());
326 }
327
328
329 void GuiAbout::on_versionCopyPB_clicked()
330 {
331         qApp->clipboard()->setText(version(true));
332 }
333
334
335 GuiAbout::GuiAbout(GuiView & lv)
336         : DialogView(lv, "aboutlyx", qt_("About LyX")),
337         d(new GuiAbout::Private)
338 {
339         d->ui.setupUi(this);
340
341         d->ui.copyrightTB->setPlainText(copyright());
342         d->ui.copyrightTB->append(QString());
343         d->ui.copyrightTB->append(license());
344         d->ui.copyrightTB->append(QString());
345         d->ui.copyrightTB->append(disclaimer());
346
347         d->ui.versionLA->setText(version());
348         QPixmap icon = getPixmap("images/", "lyx", "svg,png");
349         int const iconsize = d->ui.versionLA->height() * 1.5;
350         d->ui.iconLA->setPixmap(icon.scaled(iconsize, iconsize,
351                                             Qt::IgnoreAspectRatio,
352                                             Qt::SmoothTransformation));
353         d->ui.iconLA->setFixedWidth(iconsize);
354         d->ui.dirLibraryLA->setText(dirLibrary());
355         d->ui.dirLibraryLA->adjustSize();
356         d->ui.dirUserLA->setText(dirUser());
357         d->ui.dirUserLA->adjustSize();
358         d->ui.buildinfoTB->setText(buildinfo());
359         d->ui.releasenotesTB->setHtml(release_notes());
360         d->ui.releasenotesTB->setOpenExternalLinks(true);
361         d->ui.creditsTB->setHtml(credits());
362
363         d->ui.tab->setUsesScrollButtons(false);
364
365         // fix height to minimum
366         // setFixedHeight(sizeHint().height());
367 }
368
369
370 GuiAbout::~GuiAbout()
371 {
372         delete d;
373 }
374
375
376 void GuiAbout::on_buttonBox_rejected()
377 {
378         close();
379 }
380
381
382 } // namespace frontend
383 } // namespace lyx
384
385 #include "moc_GuiAbout.cpp"