Updated Russian translation
[lxde/liblxqt.git] / lxqtapplication.cpp
1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
4 * LXQt - a lightweight, Qt based, desktop toolset
5 * http://razor-qt.org
6 *
7 * Copyright: 2012-2013 Razor team
8 * Authors:
9 * Petr Vanek <petr@scribus.info>
10 *
11 * This program or library is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20
21 * You should have received a copy of the GNU Lesser General
22 * Public License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
25 *
26 * END_COMMON_COPYRIGHT_HEADER */
27
28 #include <QDir>
29
30 #include "lxqtapplication.h"
31 #include "lxqtsettings.h"
32
33 #include <XdgIcon>
34 #include <XdgDirs>
35
36 using namespace LXQt;
37
38 #define COLOR_DEBUG "\033[32;2m"
39 #define COLOR_WARN "\033[33;2m"
40 #define COLOR_CRITICAL "\033[31;1m"
41 #define COLOR_FATAL "\033[33;1m"
42 #define COLOR_RESET "\033[0m"
43
44 #define QAPP_NAME qApp ? qApp->objectName().toUtf8().constData() : ""
45
46 #include <cstdio>
47 #include <unistd.h>
48 #include <cstring>
49 #include <csignal>
50 #include <sys/socket.h>
51 #include <QDateTime>
52 #include <QDebug>
53 #include <QSocketNotifier>
54 /*! \brief Log qDebug input to file
55 Used only in pure Debug builds or when is the system environment
56 variable LXQT_DEBUG set
57 */
58 void dbgMessageOutput(QtMsgType type, const QMessageLogContext &ctx, const QString & msgStr)
59 {
60 QByteArray msgBuf = msgStr.toUtf8();
61 const char* msg = msgBuf.constData();
62 QDir dir(XdgDirs::configHome().toUtf8() + "/lxqt");
63 dir.mkpath(".");
64
65 const char* typestr;
66 const char* color;
67 switch (type) {
68 case QtDebugMsg:
69 typestr = "Debug";
70 color = COLOR_DEBUG;
71 break;
72 case QtWarningMsg:
73 typestr = "Warning";
74 color = COLOR_WARN;
75 break;
76 case QtFatalMsg:
77 typestr = "Fatal";
78 color = COLOR_FATAL;
79 break;
80 default: // QtCriticalMsg
81 typestr = "Critical";
82 color = COLOR_CRITICAL;
83 }
84
85 QByteArray dt = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8();
86 if (isatty(STDERR_FILENO))
87 fprintf(stderr, "%s %s(%p) %s: %s%s\n", color, QAPP_NAME, qApp, typestr, msg, COLOR_RESET);
88 else
89 fprintf(stderr, "%s(%p) %s: %s\n", QAPP_NAME, qApp, typestr, msg);
90
91 FILE *f = fopen(dir.absoluteFilePath("debug.log").toUtf8().constData(), "a+");
92 fprintf(f, "%s %s(%p) %s: %s\n", dt.constData(), QAPP_NAME, qApp, typestr, msg);
93 fclose(f);
94
95 if (type == QtFatalMsg)
96 abort();
97 }
98
99 Application::Application(int &argc, char** argv)
100 : QApplication(argc, argv)
101 {
102 #ifdef DEBUG
103 qInstallMessageHandler(dbgMessageOutput);
104 #else
105 if (!qgetenv("LXQT_DEBUG").isNull())
106 qInstallMessageHandler(dbgMessageOutput);
107 #endif
108
109 XdgIcon::setThemeName(Settings::globalSettings()->value("icon_theme").toString());
110 setWindowIcon(QIcon(QString(LXQT_GRAPHICS_DIR) + "/lxqt_logo.png"));
111 connect(Settings::globalSettings(), SIGNAL(lxqtThemeChanged()), this, SLOT(updateTheme()));
112 updateTheme();
113 }
114
115 Application::Application(int &argc, char** argv, bool handleQuitSignals)
116 : Application(argc, argv)
117 {
118 if (handleQuitSignals)
119 {
120 QList<int> signo_list = {SIGINT, SIGTERM, SIGHUP};
121 connect(this, &Application::unixSignal, [this, signo_list] (int signo)
122 {
123 if (signo_list.contains(signo))
124 quit();
125 });
126 listenToUnixSignals(signo_list);
127 }
128 }
129
130 void Application::updateTheme()
131 {
132 QString styleSheetKey = QFileInfo(applicationFilePath()).fileName();
133 setStyleSheet(lxqtTheme.qss(styleSheetKey));
134 emit themeChanged();
135 }
136
137 namespace
138 {
139 int signal_sock[2];
140
141
142 void signalHandler(int signo)
143 {
144 int ret = write(signal_sock[0], &signo, sizeof (int));
145 if (sizeof (int) != ret)
146 qCritical() << QStringLiteral("unable to write into socketpair, %1").arg(strerror(errno));
147 }
148 }
149
150 void Application::listenToUnixSignals(QList<int> const & signoList)
151 {
152 static QSocketNotifier * signal_notifier = nullptr;
153
154 if (nullptr == signal_notifier)
155 {
156 if (0 != socketpair(AF_UNIX, SOCK_STREAM, 0, signal_sock))
157 {
158 qCritical() << QStringLiteral("unable to create socketpair for correct signal handling: %1)").arg(strerror(errno));
159 return;
160 }
161
162 signal_notifier = new QSocketNotifier(signal_sock[1], QSocketNotifier::Read, this);
163 connect(signal_notifier, &QSocketNotifier::activated, [this] {
164 int signo = 0;
165 int ret = read(signal_sock[1], &signo, sizeof (int));
166 if (sizeof (int) != ret)
167 qCritical() << QStringLiteral("unable to read signal from socketpair, %1").arg(strerror(errno));
168 emit unixSignal(signo);
169 });
170 }
171
172 struct sigaction sa;
173 sa.sa_handler = signalHandler;
174 sigemptyset(&sa.sa_mask);
175 sa.sa_flags = 0;
176 for (auto const & signo : signoList)
177 sigaction(signo, &sa, nullptr);
178 }