ArmarXGuiApp.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ArmarX::Component::ArmarXGui
17 * @author David Ruscheweyh (david.ruscheweyh at student.kit dot edu)
18 * @author Kai Welke (welke at kit dot edu)
19 * @copyright 2011 Humanoids Group, HIS, KITh
20 * @license http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23 
24 #include "ArmarXGuiApp.h"
25 
26 #include <iostream>
27 #include <optional>
28 
29 #include <QHostInfo>
30 #include <QListWidget>
31 #include <QMessageBox>
32 #include <QTextCodec>
33 #include <QTime>
34 
35 #include <SimoxUtility/algorithm/string.h>
36 #include <SimoxUtility/algorithm/string/string_tools.h>
37 
41 
42 namespace armarx
43 {
45 
48  {
49  defineOptionalProperty<std::string>(
50  "LoadPlugins", "", "List of paths to GuiPlugin-Libs (semi-colon seperated)");
51  defineOptionalProperty<std::string>(
52  "GuiConfigFile", "", "Path to config file, that should be loaded on startup");
53  defineOptionalProperty<bool>("DisablePreloading",
54  false,
55  "Disables the preloading of widgets. Can be helpful if some "
56  "preloaded widget crashes the gui.");
57  }
58 
59  ArmarXGuiApp::ArmarXGuiApp(int& argc, char** argv) :
60  qApplication(nullptr), argc(argc), argv(argv)
61  {
62  qApplication = new ArmarXQApplication(argc, argv);
63 
64  // Set text encoding to UTF-8 (otherwise, umlauts display wrongly in, e.g., the log viewer)
65  QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
66  }
67 
69  {
70  // std::cout << "FINISH" << std::endl;
71  }
72 
73  void
75  Ice::PropertiesPtr properties)
76  {
77  this->registry = registry;
78  }
79 
80  int
81  ArmarXGuiApp::run(int argc, char* argv[])
82  {
83  if (!ArmarXManager::CheckIceConnection(communicator(), false))
84  {
85  if (QMessageBox::question(nullptr,
86  "ArmarX is not running",
87  "ArmarX is not running - do you want me to start it now?",
90  {
91  int result = startArmarX();
92  if (result != 0)
93  {
94  return result;
95  }
96  }
97  else
98  {
99  return 1;
100  }
101  }
102  setName(makeName());
103  return armarx::Application::run(argc, argv);
104  }
105 
106  int
107  ArmarXGuiApp::exec(const ArmarXManagerPtr& armarXManager)
108  {
109  // init SoDB and Qt, SoQt::init also creates an application object
110  SoDB::init();
111  SoQt::init(argc, argv, "ArmarXGuiApp*1123");
112 
113  // enable Coin3D extension: transparent settings without color
114  (void)coin_setenv("COIN_SEPARATE_DIFFUSE_TRANSPARENCY_OVERRIDE", "1", TRUE);
115 
116  {
117  const std::vector<std::string> packageNames = getArmarXPackageNames();
118  QString configToLoad;
119  if (getProperty<std::string>("GuiConfigFile").isSet())
120  {
121  configToLoad =
122  QString::fromStdString(getProperty<std::string>("GuiConfigFile").getValue());
123  }
124 
125  // create top-level widget
126  mainWindow = new ArmarXMainWindow(registry,
127  packageNames,
128  configToLoad,
129  getProperty<bool>("DisablePreloading").getValue());
130  connect(mainWindow, SIGNAL(closeRequest()), this, SLOT(closeRequest_sent()));
131  }
132  {
133  // parse properties
134  std::string plugins = getProperty<std::string>("LoadPlugins").getValue();
135  std::vector<std::string> pluginList = Split(plugins, ",");
136  for (auto iter = pluginList.begin(); iter != pluginList.end(); ++iter)
137  {
138  if (!iter->empty())
139  {
140  ARMARX_VERBOSE << "Loading plugin: " << iter->c_str() << std::endl;
141  mainWindow->loadPlugin(iter->c_str());
142  }
143  }
144  }
145  std::cout << "Started ArmarXGui App" << std::endl;
146 
147  armarxManagerTask = new RunningTask<ArmarXGuiApp>(
148  this, &ArmarXGuiApp::runArmarXManager, "ArmarXManagerWaitThread");
149  armarxManagerTask->start();
150 
151  mainWindow->show();
152  mainWindow->appendFileToWindowTitle();
153 
154  ARMARX_INFO << "Now showing main window";
155  int result = qApplication->exec();
156 
157  // exit SoQt and Qt
158  interruptCallback(0); // signal to the application it should terminate the ice connection
159 
160  armarXManager->waitForShutdown();
161 
162  // Shutdown.
163  qApplication->quit();
164  delete mainWindow;
165 
166  SoQt::done();
167  delete qApplication;
168  qApplication = 0;
169 
170  return result;
171  }
172 
173  void
174  ArmarXGuiApp::closeRequest_sent()
175  {
176  }
177 
178  void
179  ArmarXGuiApp::runArmarXManager()
180  {
181  getArmarXManager()->waitForShutdown();
182 
183  if (qApplication)
184  {
185  qApplication->quit();
186  }
187  }
188 
189  int
190  ArmarXGuiApp::startArmarX()
191  {
192  CMakePackageFinder armarx_core("ArmarXCore");
193  CMakePackageFinder armarx_memoryx("MemoryX");
194 
195  int res;
196  if (armarx_core.packageFound())
197  {
198  res = system(
199  std::string(armarx_core.getBinaryDir() + std::string("/armarx start")).c_str());
200  }
201  else
202  {
203  res = system("armarx start");
204  }
205  res = WEXITSTATUS(res);
206  if (res == EXIT_SUCCESS)
207  {
208  ARMARX_INFO_S << "Started ArmarX successfully!";
209  if (armarx_memoryx.packageFound())
210  {
211  if (armarx_core.packageFound())
212  {
213  res = system(std::string(armarx_core.getBinaryDir() +
214  std::string("/armarx memory start"))
215  .c_str());
216  }
217  else
218  {
219  res = system("armarx memory assureRunning");
220  }
221  res = WEXITSTATUS(res);
222  if (res == EXIT_FAILURE)
223  {
224  QMessageBox::warning(nullptr,
225  "ArmarX Error",
226  "Could not start MongoDB! See terminal output for more "
227  "information. The GUI will now started anyway.");
228  return 0;
229  }
230  }
231  }
232  else
233  {
234  QMessageBox::critical(
235  nullptr,
236  "ArmarX Error",
237  "Could not start ArmarX! See terminal output for more information.");
238  return 1;
239  }
240  return 0;
241  }
242 
243  static QString
244  getUserName()
245  {
246  QString username = qgetenv("USER");
247  if (username.isEmpty())
248  {
249  username = qgetenv("USERNAME");
250  }
251  return username;
252  }
253 
254  static QString
255  getUserNameAtHostName(const QString& delimiter, const QString& at)
256  {
257  const QString hostname = QHostInfo::localHostName();
258  QString user = getUserName();
259  if (user.isEmpty())
260  {
261  return hostname;
262  }
263  else
264  {
265  return user + delimiter + at + delimiter + hostname;
266  }
267  }
268 
269  std::string
270  ArmarXGuiApp::makeName()
271  {
272  std::vector<std::string> items{"ArmarXGui"};
273  items.push_back(getUserNameAtHostName("-", "at").toStdString());
274  items.push_back(DateTime::Now().toDateTimeString());
275 
276  std::string name = simox::alg::join(items, "_");
277 
278  return name;
279  }
280 
281  bool
282  ArmarXQApplication::notify(QObject* obj, QEvent* ev)
283  {
284  try
285  {
286  return QApplication::notify(obj, ev);
287  }
288  catch (std::exception& e)
289  {
290  ARMARX_ERROR_S << "Exception caught:\n" << armarx::GetHandledExceptionString();
291  emit exceptionCaught(QString::fromStdString(armarx::GetHandledExceptionString()));
293  }
294 
295  return false;
296  }
297 
298  void
299  ArmarXQApplication::showException(QString exceptionReason)
300  {
301  QStringList infos = exceptionReason.split("Backtrace:");
302  QListWidget* list = exceptionDialogHandler.listWidgetExceptions;
303  auto item = new QListWidgetItem("[" + QTime::currentTime().toString() + "] " +
304  infos.first().trimmed());
305  item->setToolTip(exceptionReason);
306  list->addItem(item);
307  list->scrollToBottom();
308 
309  if (!exceptionDialogHandler.checkBoxDoNotShowAgain->isChecked())
310  {
311  exceptionDialog.show();
312  }
313  /*
314  QStringList infos = exceptionReason.split("Backtrace:");
315  QMessageBox box;
316  box.setIcon(QMessageBox::Warning);
317  box.setWindowTitle("An exception occured!");
318  box.setText("An exception was caught!\n" + infos.first());
319  if(infos.size() > 1)
320  box.setDetailedText(infos.last());
321  box.exec();
322  */
323  }
324 
325  ArmarXQApplication::ArmarXQApplication(int& argc, char** argv) : QApplication(argc, argv)
326  {
327  const auto guiWindowBaseName = QString{"ArmarX"} + " @ " + QHostInfo::localHostName();
328  setApplicationName(guiWindowBaseName);
329 
330  {
331  const char* envArmarxWorkspace = std::getenv("ARMARX_WORKSPACE_NAME");
332  if (envArmarxWorkspace == nullptr)
333  {
334  envArmarxWorkspace = std::getenv("ARMARX_WORKSPACE");
335  }
336 
337  QString applicationDisplayName;
338  if (envArmarxWorkspace != nullptr)
339  {
340  applicationDisplayName += "[▽" + QString(envArmarxWorkspace) + "] ";
341  }
342  applicationDisplayName += getUserNameAtHostName(" ", "@");
343  setApplicationDisplayName(applicationDisplayName);
344  }
345 
346  connect(this,
347  SIGNAL(exceptionCaught(QString)),
348  this,
349  SLOT(showException(QString)),
350  Qt::QueuedConnection);
352  QListWidget* list = exceptionDialogHandler.listWidgetExceptions;
353  connect(exceptionDialogHandler.pushButtonClearHistory,
354  SIGNAL(clicked()),
355  list,
356  SLOT(clear()),
357  Qt::QueuedConnection);
358  }
359 
361  {
362  }
363 
364 } // namespace armarx
armarx::ArmarXGuiApp::exec
int exec(const ArmarXManagerPtr &armarXManager) override
Runs the Qt Event Loop.
Definition: ArmarXGuiApp.cpp:107
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::Application::run
int run(int argc, char *argv[]) override
Ice::Application replacement for the main function.
Definition: Application.cpp:363
armarx::ArmarXQApplication::ArmarXQApplication
ArmarXQApplication(int &argc, char **argv)
Definition: ArmarXGuiApp.cpp:325
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
DateTime.h
armarx::ArmarXManager::CheckIceConnection
static bool CheckIceConnection(const Ice::CommunicatorPtr &communicator, bool printHint)
Definition: ArmarXManager.cpp:132
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
armarx::ArmarXGuiApp::setup
void setup(const ManagedIceObjectRegistryInterfacePtr &registry, Ice::PropertiesPtr properties) override
Configures the app, sets Qt up.
Definition: ArmarXGuiApp.cpp:74
armarx::ArmarXMainWindow
The ArmarXMainWindow class.
Definition: ArmarXMainWindow.h:80
trace.h
armarx::ArmarXMainWindow::appendFileToWindowTitle
void appendFileToWindowTitle(const QString &filepath="")
Definition: ArmarXMainWindow.cpp:877
armarx::Application::getArmarXManager
ArmarXManagerPtr getArmarXManager()
Definition: Application.cpp:749
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:35
plugins
StringHelpers.h
armarx::ArmarXMainWindow::loadPlugin
void loadPlugin(QString filePath)
loads a plugin with the given file path
Definition: ArmarXMainWindow.cpp:525
ArmarXGuiApp.h
IceInternal::Handle< ::Ice::Properties >
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
armarx::ArmarXQApplication::exceptionCaught
void exceptionCaught(QString exceptionReason)
armarx::ArmarXGuiApp::ArmarXGuiApp
ArmarXGuiApp(int &argc=ArmarXGuiApp::globalargc, char **argv=NULL)
Constructs and initialized an ArmarXGuiApp.
Definition: ArmarXGuiApp.cpp:59
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
armarx::ArmarXGuiAppPropertyDefinitions::ArmarXGuiAppPropertyDefinitions
ArmarXGuiAppPropertyDefinitions(std::string prefix)
Definition: ArmarXGuiApp.cpp:46
armarx::ArmarXQApplication::~ArmarXQApplication
~ArmarXQApplication() override
Definition: ArmarXGuiApp.cpp:360
armarx::ArmarXQApplication::notify
bool notify(QObject *obj, QEvent *ev) override
Definition: ArmarXGuiApp.cpp:282
armarx::ApplicationPropertyDefinitions
Application property definition container.
Definition: Application.h:101
armarx::ArmarXGuiApp::~ArmarXGuiApp
~ArmarXGuiApp() override
Definition: ArmarXGuiApp.cpp:68
armarx::ArmarXQApplication
Definition: ArmarXGuiApp.h:59
No
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics No
Definition: ReadMe.txt:21
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
IceUtil::Handle< ManagedIceObjectRegistryInterface >
armarx::Application::getArmarXPackageNames
std::vector< std::string > getArmarXPackageNames()
getDefaultPackageNames returns the value of the ArmarX.DefaultPackages property It splits the string ...
Definition: Application.cpp:668
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::ArmarXGuiApp::globalargc
static int globalargc
Definition: ArmarXGuiApp.h:96
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::ArmarXQApplication::showException
void showException(QString exceptionReason)
Definition: ArmarXGuiApp.cpp:299
armarx::detail::Trace::ClearExceptionBacktrace
static void ClearExceptionBacktrace()
Definition: trace.cpp:90
armarx::Application::interruptCallback
void interruptCallback(int signal) override
Cleans up connections with IceStorm before terminating the app.
Definition: Application.cpp:620
armarx::ArmarXQApplication::exceptionDialog
QDialog exceptionDialog
Definition: ArmarXGuiApp.h:74
armarx::ArmarXQApplication::exceptionDialogHandler
Ui_ExceptionDialog exceptionDialogHandler
Definition: ArmarXGuiApp.h:75
armarx::Application::setName
void setName(const std::string &name)
Set name of the application.
Definition: Application.cpp:608
armarx::ArmarXGuiApp::run
int run(int argc, char *argv[]) override
Definition: ArmarXGuiApp.cpp:81
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
GfxTL::Yes
OnOff< true > Yes
Definition: OnOff.h:12