SoDaRadio-5.0.3-master:8901fb5
main_sodaradio.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017 Matthew H. Reilly (kb1vc)
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #include "mainwindow.hpp"
30 #include <QApplication>
31 #include <iostream>
32 #include <QMessageBox>
33 #include <QStyleFactory>
34 #include <QTextStream>
35 #include <QDir>
36 
37 #include "../common/GuiParams.hxx"
38 #include <stdlib.h>
45 static QString ss2QS(const std::string & st)
46 {
47  return QString::fromStdString(st);
48 }
49 
55 static void alertAndExit(const QString & err_msg)
56 {
57  QMessageBox mbox(QMessageBox::Critical,
58  "Fatal Error",
59  err_msg,
60  QMessageBox::Ok, NULL);
61  mbox.exec();
62  exit(-1);
63 }
64 
71 static void startupServer(const QString & lock_file_name, SoDa::GuiParams & p)
72 {
73  // start the radio server
74  QString server_name;
75 
76  if(p.getServerName() != "") {
77  server_name = ss2QS(p.getServerName());
78  }
79  else {
80  QString app_dir = QCoreApplication::applicationDirPath();
81  server_name = app_dir + "/SoDaServer";
82  }
83 
84  if(!QFile::exists(server_name)) {
85  alertAndExit(QString("%1 did not find the SoDa Radio server program.\n"
86  "It looked in\n[%2]\n"
87  "Please press OK button to quit.\n\n"
88  "(Though this is -not- OK. "
89  "Send a note when you get a chance to kb1vc@kb1vc.org)").arg(qApp->applicationDisplayName()).arg(server_name));
90  }
91 
92  // now build the command
93  QString server_command;
94  // fix a problem with the UBUNTU menu proxy, whatever that is.
95  char ub_fix[] = "UBUNTU_MENUPROXY=";
96  putenv(ub_fix);
97 
98  server_command = QString("%1 --uds_name %2 ").arg(server_name).arg(ss2QS(p.getServerSocketBasename()));
99 
100  // now add the uhd args
101  QString uhd_args = ss2QS(p.getUHDArgs());
102  if(uhd_args != "") server_command += QString("--uhdargs %1 ").arg(uhd_args);
103  if(p.getDebugLevel() > 0) server_command += QString("--debug %1 ").arg(p.getDebugLevel());
104  QString server_args = ss2QS(p.getServerArgs());
105  if(server_args != "") server_command += QString("%1 ").arg(server_args);
106 
107 
108  server_command += QString(" --lockfile %1 ").arg(lock_file_name);
109 
110  QProcess::startDetached(server_command);
111 
112 }
113 
123 {
124  qApp->setStyle(QStyleFactory::create("fusion"));
125 
126  QPalette palette;
127  palette.setColor(QPalette::Window, QColor(53,53,53));
128  palette.setColor(QPalette::WindowText, Qt::white);
129  palette.setColor(QPalette::Base, QColor(15,15,15));
130  palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
131  palette.setColor(QPalette::ToolTipBase, Qt::lightGray);
132  palette.setColor(QPalette::ToolTipText, Qt::blue);
133  palette.setColor(QPalette::Text, Qt::white);
134  palette.setColor(QPalette::Button, QColor(53,53,53));
135  palette.setColor(QPalette::ButtonText, Qt::white);
136  palette.setColor(QPalette::BrightText, Qt::red);
137 
138  palette.setColor(QPalette::Highlight, QColor(61,79,201).lighter());
139  palette.setColor(QPalette::HighlightedText, Qt::black);
140 
141  palette.setColor(QPalette::Disabled, QPalette::Text, Qt::darkGray);
142  palette.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::darkGray);
143 
144  qApp->setPalette(palette);
145 }
146 
147 bool checkForZombies(const QString & server_lock_filename, const QString & server_socket_base)
148 {
149  // does the server lock filename exist?
150  if(QFileInfo::exists(server_lock_filename)) {
151  QString error_message = QString("%1 exists. \
152 This is an indication that a zombiefied \
153 SoDaServer instance is still running.\
154 <ol>\
155 <li>Kill the zombie SoDaServer process.</li>\
156 <li>Delete files that look like this: <p>%2_cmd</p> and <p>%2_wfall</p></li> \
157 <li>Delete this file: <p>%1</p></li> \
158 <li>Try again.</li>\
159 </ol>").arg(server_lock_filename).arg(server_socket_base);
160  QMessageBox mbox(QMessageBox::Critical,
161  "Fatal Error",
162  error_message,
163  QMessageBox::Ok, NULL);
164  // mbox.setDetailedText(err_string);
165  mbox.exec();
166 
167  QTextStream qw(stdout);
168 
169  qw << QString("%1 exists.\nThis is an indication that a zombiefied\n\
170 SoDaServer instance is still running.\n\n\
171 1. Kill the zombie SoDaServer process.\n\
172 2. Delete files that look like this: %2_cmd and %2_wfall\n\
173 3. Delete this file: %1\n\
174 4. Try again.\n").arg(server_lock_filename).arg(server_socket_base);
175 
176  // we should not continue.
177  return true;
178  }
179 
180  return false;
181 }
182 
183 
190 int main(int argc, char *argv[])
191 {
192  QApplication a(argc, argv);
193  SoDa::GuiParams p(argc, argv);
194 
195  if(p.hadNoCommand()) {
196  a.quit();
197  return 0;
198  }
199 
200  QString apdir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
201 
202  if(!QDir(apdir).exists()) {
203  QDir().mkdir(apdir);
204  }
205 
206  QString uhdargs = QString::fromStdString(p.getUHDArgs());
207  QString server_lock_filename = QString("%1/sodaserver_args%2.lock")
208  .arg(apdir)
209  .arg(uhdargs);
210 
211  QString ssbn;
212  if(p.getServerSocketBasename() == std::string("")) {
213  ssbn = QString("%1/SoDa_%2_").arg(apdir).arg(uhdargs);
214  std::string nbn = ssbn.toStdString();
215  p.setServerSocketBasename(nbn);
216  }
217  else {
218  ssbn = QString::fromStdString(p.getServerSocketBasename());
219  }
220 
221  if(!checkForZombies(server_lock_filename, ssbn)) {
222  startupServer(server_lock_filename, p);
223 
224  setupLookNFeel();
225 
226  MainWindow w(0, p);
227  w.show();
228  return a.exec();
229  }
230 }
static void alertAndExit(const QString &err_msg)
pop up a notification box and then bail out.
void setupLookNFeel()
initialize colors and shades for GUI elements to present a look and feel based on the fusion style...
bool checkForZombies(const QString &server_lock_filename, const QString &server_socket_base)
int main(int argc, char *argv[])
Start the SoDaRadio GUI app and launch the server process.
static QString ss2QS(const std::string &st)
simple conversion from std::string to QString...
static void startupServer(const QString &lock_file_name, SoDa::GuiParams &p)
start the radio server process