BALL  1.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
main.C
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 // order of includes is important: first qapplication, than BALL includes
6 #include <QtGui/QApplication>
7 #include <BALL/CONFIG/config.h>
8 
9 #ifdef BALL_HAS_GLEW
10 # include <GL/glew.h>
11 #endif
12 
13 #include <QtCore/QLocale>
14 #include <QtCore/QTranslator>
15 
16 #include <QtGui/QMessageBox>
17 #include <QtGui/QSplashScreen>
18 #include <QtOpenGL/qgl.h>
19 
20 #include "mainframe.h"
21 #include <BALL/SYSTEM/path.h>
22 #include <BALL/SYSTEM/directory.h>
23 #include <BALL/FORMAT/INIFile.h>
24 #include <BALL/SYSTEM/fileSystem.h>
25 #include <BALL/COMMON/logStream.h>
26 
27 #include <iostream>
28 
29 #ifdef Q_WS_X11
30 #include <X11/Xlib.h>
31 #endif
32 
33 void logMessages(QtMsgType type, const char *msg)
34 {
35  BALL::String s(msg);
36  if (s.hasPrefix("QTextBrowser")) return;
37 
38  switch ( type ) {
39  case QtDebugMsg:
40  BALL::Log.info() << msg << std::endl;
41  break;
42  case QtWarningMsg:
43  BALL::Log.warn() << msg << std::endl;
44  break;
45  case QtFatalMsg:
46  fprintf( stderr, "Fatal: %s\n", msg );
47  abort(); // deliberately core dump
48  case QtCriticalMsg:
49  fprintf( stderr, "Critical: %s\n", msg );
50  abort(); // deliberately core dump
51  }
52 }
53 
54 
55 // uncomment this to use debugging to std::cout!
56 //#undef BALL_OS_WINDOWS
57 
58 #ifndef BALL_OS_WINDOWS
59 int main(int argc, char **argv)
60 {
61 #else
62 int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR cmd_line, int)
63 {
64  int argc = __argc;
65  char** argv = __argv;
66 #endif
67 
68 #ifdef Q_WS_X11
69  XInitThreads();
70 #endif
71 
72  qInstallMsgHandler(logMessages);
73 
74  putenv("BALL_RETURN_VALUE=");
75  QApplication application(argc, argv);
76 
77  QPixmap splash_pm(":BALLView-1.4-Splashscreen.png");
78  QSplashScreen* splash = new QSplashScreen(splash_pm);
79  splash->show();
80 
81  // =============== testing for opengl support ======================================
82  if (!QGLFormat::hasOpenGL())
83  {
84  QMessageBox::critical(0, "Error while starting BALLView",
85  "Your computer has no OpenGL support, please install the correct drivers. Aborting for now...",
86  QMessageBox::Ok, Qt::NoButton, Qt::NoButton);
87  return -1;
88  }
89 
91 
92  // =============== load translations =====================
93  BALL::INIFile f(home_dir + BALL::FileSystem::PATH_SEPARATOR + ".BALLView");
94  f.read();
95 
96  if (f.hasEntry("GENERAL", "language"))
97  {
98  QString str = f.getValue("GENERAL", "language").c_str();
99 
100  if (!(str == "Default"))
101  {
102  QString loc = "BALLView." + str;
103 
104  BALL::Path p;
105  QStringList dpaths = QString(p.getDataPath().c_str()).split("\n");
106 
107  QTranslator* translator = new QTranslator(&application);
108  foreach(QString str, dpaths)
109  {
110  translator->load(loc, str + "BALLView/translations");
111  if (!translator->isEmpty())
112  {
113  QCoreApplication::installTranslator(translator);
114  break;
115  }
116  }
117  }
118  }
119 
120  // =============== testing if we can write in current directory =====================
121  if (home_dir == "")
122  {
123  try
124  {
125  BALL::String temp_file_name;
126  BALL::File::createTemporaryFilename(temp_file_name);
127  BALL::File out(temp_file_name, std::ios::out);
128  out << "test" << std::endl;
129  out.remove();
130  }
131  catch(...)
132  {
133  QMessageBox::warning(0, "Error while starting BALLView",
134  QString("You dont have write access to the current working directory\n") +
135  "and BALLView can not find your home directory. This can cause\n" +
136  "unexpected behaviour. Please start BALLView from your homedir with\n" +
137  "absolute path (e.g. C:\\Programs\\BALLView\\BALLView).\n");
138  }
139  }
140 
141  // =============== initialize Mainframe ============================================
142  // Create the mainframe.
143  BALL::Mainframe mainframe(0, "Mainframe");
144 
145  // can we use the users homedir as working dir?
146  if (home_dir != "")
147  {
148  mainframe.setWorkingDir(home_dir);
149  }
150 
151  // Register the mainfram (required for Python support).
152  mainframe.setIdentifier("Mainframe");
153  mainframe.registerThis();
154 
155  // Show the main window.
156  mainframe.show();
157 
158  // =============== parsing command line arguments ==================================
159  // If there are additional command line arguments, interpret them as files to open or logging flag.
160  for (BALL::Index i = 1; i < argc; ++i)
161  {
162  BALL::String argument(argv[i]);
163  if (argument == "-l")
164  {
165  mainframe.enableLoggingToFile();
166  continue;
167  }
168 
169  mainframe.openFile(argument);
170  }
171 
172  // enable ending of program from python script
173  if (mainframe.isAboutToQuit())
174  {
175  mainframe.aboutToExit();
176  return 0;
177  }
178 
179  // Remove the splashscreen
180  splash->finish(&mainframe);
181  delete splash;
182 
183  // Hand over control to the application.
184  int value = application.exec();
185  char* return_value = getenv("BALL_RETURN_VALUE");
186  if (return_value != 0)
187  {
188  try
189  {
190  value = BALL::String(return_value).toInt();
191  }
192  catch(...)
193  {
194  }
195  }
196 
197  return value;
198 }