+
+/*!
+ \brief Return information about version of the each module.
+*/
+CAM_Application::ModuleShortInfoList CAM_Application::getVersionInfo()
+{
+ ModuleShortInfoList info;
+
+ ModuleShortInfo kernel;
+ kernel.name = "KERNEL";
+ kernel.version = KERNEL_VERSION_STR;
+ info.append(kernel);
+
+ ModuleShortInfo gui;
+ gui.name = "GUI";
+ gui.version = GUI_VERSION_STR;
+ info.append(gui);
+
+ for(int i = 0; i < myInfoList.size(); i++) {
+ ModuleShortInfo infoItem;
+ infoItem.name = myInfoList.at(i).title.isEmpty() ? myInfoList.at(i).name : myInfoList.at(i).title;
+ infoItem.version = myInfoList.at(i).version;
+ info.append(infoItem);
+ }
+ return info;
+}
+
+/*!
+ \brief Abort active operations if there are any
+
+ Iterates through all modules and asks each of them if there are pending operations that cannot be aborted.
+
+ \return \c false if some operation cannot be aborted
+*/
+bool CAM_Application::abortAllOperations()
+{
+ bool aborted = true;
+ for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); it != myModules.end() && aborted; ++it )
+ {
+ aborted = (*it)->abortAllOperations();
+ }
+ return aborted;
+}
+
+/*!
+ \brief Log GUI event.
+ \param eventDescription GUI event description.
+*/
+void CAM_Application::logUserEvent( const QString& eventDescription )
+{
+ static QString guiLogFile; // null string means log file was not initialized yet
+ static QMutex aGUILogMutex;
+
+ if ( guiLogFile.isNull() )
+ {
+ // log file was not initialized yet, try to do that by parsing command line arguments
+ guiLogFile = ""; // empty string means initialization was done but log file was not set
+ QStringList args = QApplication::arguments();
+ for ( int i = 1; i < args.count(); i++ )
+ {
+ QRegExp rxs ( "--gui-log-file=(.+)" );
+ if ( rxs.indexIn( args[i] ) >= 0 && rxs.capturedTexts().count() > 1 )
+ {
+ QString file = rxs.capturedTexts()[1];
+ QFileInfo fi ( file );
+ if ( !fi.isDir() && fi.dir().exists() )
+ {
+ guiLogFile = fi.absoluteFilePath();
+ if ( fi.exists() ) {
+ QFile file ( guiLogFile );
+ file.remove(); // remove probably existing log file, to start with empty one
+ }
+ }
+ break;
+ }
+ }
+ }
+ if ( !guiLogFile.isEmpty() ) // non-empty string means log file was already initialized
+ {
+ QMutexLocker aLocker( &aGUILogMutex );
+ QFile file ( guiLogFile );
+ if ( file.open( QFile::Append ) ) // append to log file
+ {
+ QDateTime current = QDateTime::currentDateTime();
+ QTextStream stream( &file );
+ stream << current.toString("yyyyMMdd-hhmmss")
+ << "," << eventDescription
+ << endl;
+ file.close();
+ }
+ }
+}
+
+void CAM_Application::logStructuredUserEvent( const QString& module,
+ const QString& section,
+ const QString& action,
+ const QString& event,
+ const QString& message )
+{
+ const QStringList mes = (QStringList() << module
+ << section
+ << action
+ << event
+ << message);
+
+ logUserEvent( mes.join( "," ) );
+}
+
+/*!
+ \brief Log given action.
+ \param action GUI action being logged.
+ \param moduleName optional name of module, owning an action
+*/
+void CAM_Application::logAction( QAction* action, const QString& moduleName )
+{
+ QString text = action->toolTip();
+ if ( text.isEmpty() )
+ text = action->text();
+ if ( text.isEmpty() )
+ text = action->iconText();
+
+ if ( !text.isEmpty() )
+ {
+ if ( action->isCheckable() )
+ {
+ logStructuredUserEvent ( moduleName,
+ "",
+ "toggled",
+ action->isChecked() ? "on" : "off",
+ text );
+ }
+ else
+ {
+ logStructuredUserEvent ( moduleName,
+ "",
+ "triggered",
+ "",
+ text );
+ }
+ }
+}