Themes: Attempt at working around wrong widget backgrounds on Windows
[pulseview.git] / pv / application.cpp
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2014 Martin Ling <martin-sigrok@earth.li>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "application.hpp"
21 #include "config.h"
22
23 #include <iostream>
24 #include <typeinfo>
25
26 #include <QDebug>
27
28 #include <boost/version.hpp>
29
30 #ifdef ENABLE_STACKTRACE
31 #include <boost/stacktrace.hpp>
32 #endif
33
34 #ifdef ENABLE_DECODE
35 #include <libsigrokdecode/libsigrokdecode.h>
36 #endif
37
38 using std::cout;
39 using std::endl;
40 using std::exception;
41 using std::shared_ptr;
42
43 #ifdef ENABLE_DECODE
44 static gint sort_pds(gconstpointer a, gconstpointer b)
45 {
46         const struct srd_decoder *sda, *sdb;
47
48         sda = (const struct srd_decoder *)a;
49         sdb = (const struct srd_decoder *)b;
50         return strcmp(sda->id, sdb->id);
51 }
52 #endif
53
54 Application::Application(int &argc, char* argv[]) :
55         QApplication(argc, argv)
56 {
57         setApplicationVersion(PV_VERSION_STRING);
58         setApplicationName("PulseView");
59         setOrganizationName("sigrok");
60         setOrganizationDomain("sigrok.org");
61 }
62
63 void Application::collect_version_info(shared_ptr<sigrok::Context> context)
64 {
65         // Library versions and features
66         version_info_.emplace_back(applicationName(), applicationVersion());
67         version_info_.emplace_back("Qt", qVersion());
68         version_info_.emplace_back("glibmm", PV_GLIBMM_VERSION);
69         version_info_.emplace_back("Boost", BOOST_LIB_VERSION);
70
71         version_info_.emplace_back("libsigrok", QString("%1/%2 (rt: %3/%4)")
72                 .arg(SR_PACKAGE_VERSION_STRING, SR_LIB_VERSION_STRING,
73                 sr_package_version_string_get(), sr_lib_version_string_get()));
74
75         GSList *l_orig = sr_buildinfo_libs_get();
76         for (GSList *l = l_orig; l; l = l->next) {
77                 GSList *m = (GSList *)l->data;
78                 const char *lib = (const char *)m->data;
79                 const char *version = (const char *)m->next->data;
80                 version_info_.emplace_back(QString(" - %1").arg(QString(lib)), QString(version));
81                 g_slist_free_full(m, g_free);
82         }
83         g_slist_free(l_orig);
84
85         char *host = sr_buildinfo_host_get();
86         version_info_.emplace_back(" - Host", QString(host));
87         g_free(host);
88
89         char *scpi_backends = sr_buildinfo_scpi_backends_get();
90         version_info_.emplace_back(" - SCPI backends", QString(scpi_backends));
91         g_free(scpi_backends);
92
93 #ifdef ENABLE_DECODE
94         struct srd_decoder *dec;
95
96         version_info_.emplace_back("libsigrokdecode", QString("%1/%2 (rt: %3/%4)")
97                 .arg(SRD_PACKAGE_VERSION_STRING, SRD_LIB_VERSION_STRING,
98                 srd_package_version_string_get(), srd_lib_version_string_get()));
99
100         l_orig = srd_buildinfo_libs_get();
101         for (GSList *l = l_orig; l; l = l->next) {
102                 GSList *m = (GSList *)l->data;
103                 const char *lib = (const char *)m->data;
104                 const char *version = (const char *)m->next->data;
105                 version_info_.emplace_back(QString(" - %1").arg(QString(lib)), QString(version));
106                 g_slist_free_full(m, g_free);
107         }
108         g_slist_free(l_orig);
109
110         host = srd_buildinfo_host_get();
111         version_info_.emplace_back(" - Host", QString(host));
112         g_free(host);
113 #endif
114
115         // Firmware paths
116         l_orig = sr_resourcepaths_get(SR_RESOURCE_FIRMWARE);
117         for (GSList *l = l_orig; l; l = l->next)
118                 fw_path_list_.emplace_back((char*)l->data);
119         g_slist_free_full(l_orig, g_free);
120
121         // PD paths
122 #ifdef ENABLE_DECODE
123         l_orig = srd_searchpaths_get();
124         for (GSList *l = l_orig; l; l = l->next)
125                 pd_path_list_.emplace_back((char*)l->data);
126         g_slist_free_full(l_orig, g_free);
127 #endif
128
129         // Device drivers
130         for (auto& entry : context->drivers())
131                 driver_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
132                         QString::fromUtf8(entry.second->long_name().c_str()));
133
134         // Input formats
135         for (auto& entry : context->input_formats())
136                 input_format_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
137                         QString::fromUtf8(entry.second->description().c_str()));
138
139         // Output formats
140         for (auto& entry : context->output_formats())
141                 output_format_list_.emplace_back(QString::fromUtf8(entry.first.c_str()),
142                         QString::fromUtf8(entry.second->description().c_str()));
143
144         // Protocol decoders
145 #ifdef ENABLE_DECODE
146         GSList *sl = g_slist_copy((GSList *)srd_decoder_list());
147         sl = g_slist_sort(sl, sort_pds);
148         for (const GSList *l = sl; l; l = l->next) {
149                 dec = (struct srd_decoder *)l->data;
150                 pd_list_.emplace_back(QString::fromUtf8(dec->id),
151                         QString::fromUtf8(dec->longname));
152         }
153         g_slist_free(sl);
154 #endif
155 }
156
157 void Application::print_version_info()
158 {
159         cout << PV_TITLE << " " << PV_VERSION_STRING << endl;
160
161         cout << endl << "Libraries and features:" << endl;
162         for (pair<QString, QString>& entry : version_info_)
163                 cout << "  " << entry.first.toStdString() << " " << entry.second.toStdString() << endl;
164
165         cout << endl << "Firmware search paths:" << endl;
166         for (QString& entry : fw_path_list_)
167                 cout << "  " << entry.toStdString() << endl;
168
169         cout << endl << "Protocol decoder search paths:" << endl;
170         for (QString& entry : pd_path_list_)
171                 cout << "  " << entry.toStdString() << endl;
172
173         cout << endl << "Supported hardware drivers:" << endl;
174         for (pair<QString, QString>& entry : driver_list_)
175                 cout << "  " << entry.first.leftJustified(21, ' ').toStdString() <<
176                 entry.second.toStdString() << endl;
177
178         cout << endl << "Supported input formats:" << endl;
179         for (pair<QString, QString>& entry : input_format_list_)
180                 cout << "  " << entry.first.leftJustified(21, ' ').toStdString() <<
181                 entry.second.toStdString() << endl;
182
183         cout << endl << "Supported output formats:" << endl;
184         for (pair<QString, QString>& entry : output_format_list_)
185                 cout << "  " << entry.first.leftJustified(21, ' ').toStdString() <<
186                 entry.second.toStdString() << endl;
187
188 #ifdef ENABLE_DECODE
189         cout << endl << "Supported protocol decoders:" << endl;
190         for (pair<QString, QString>& entry : pd_list_)
191                 cout << "  " << entry.first.leftJustified(21, ' ').toStdString() <<
192                 entry.second.toStdString() << endl;
193 #endif
194 }
195
196 vector< pair<QString, QString> > Application::get_version_info() const
197 {
198         return version_info_;
199 }
200
201 vector<QString> Application::get_fw_path_list() const
202 {
203         return fw_path_list_;
204 }
205
206 vector<QString> Application::get_pd_path_list() const
207 {
208         return pd_path_list_;
209 }
210
211 vector< pair<QString, QString> > Application::get_driver_list() const
212 {
213         return driver_list_;
214 }
215
216 vector< pair<QString, QString> > Application::get_input_format_list() const
217 {
218         return input_format_list_;
219 }
220
221 vector< pair<QString, QString> > Application::get_output_format_list() const
222 {
223         return output_format_list_;
224 }
225
226 vector< pair<QString, QString> > Application::get_pd_list() const
227 {
228         return pd_list_;
229 }
230
231 bool Application::notify(QObject *receiver, QEvent *event)
232 {
233         try {
234                 return QApplication::notify(receiver, event);
235         } catch (exception& e) {
236                 qDebug().nospace() << "Caught exception of type " << \
237                         typeid(e).name() << " (" << e.what() << ")";
238 #ifdef ENABLE_STACKTRACE
239                 throw e;
240 #else
241                 exit(1);
242 #endif
243                 return false;
244         }
245 }