summaryrefslogblamecommitdiffstats
path: root/src/fbgui/ndgui.cpp
blob: 4e0b3f647c02c0828f29426aa5af70d7fd3b4193 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                                                             

                  








                                                  






                              


              

                                   
 
 
 
 


             
                 
 


                                   
                         

                                 
 
 
 
 
 


                                                                              
                    
 

                            







































                                                                                       
 
         
 
                         




   
                                           








                                                                    

                                                                                                        






                                                     

                                                                                                  
                                 
    




   
                                                          















                                                                  
                                                                              
                                           
                                                                 










                                                                        
                                                











                                                                                             


                                                                     

                            
                                                                


                                                                                        



                                                                        




   

                             









                                                                   

                                    





                                                                     
                               
 
                                                     
                                                                      




   

                                     



                                                                    







                                                                                
                                                                            





         

                                                  











                                                                           

                                                                                                           







                                                                                      
                                                          
                                            









                                                                               



                                                                              
                                 
                         
                 
                

                                                                                                              

                                                                    





         

                            








                                               
                                                                              





         

                              








                                               
                                                                              





         

                                    



                                                            


                                                            
                                                                                
                                 
                              
                

                                                                                                             
         
 
 


 


                                                                                                  
                                                      
                                                                        


                         



   
                                                                           

                              
                                            
                                                



 


                                             
                        
                                               
                                             




                                           
                                
                         



                                 




 


                         
                                                                       


                                               
                                                                
                             
                         


                                           
                                     
         
                                                                 



                       





                                                        

                                                     
                                                       


 

   
                                                                      
                                               


                                                                             

                                                            
                                                                      










                                                  
                                                                             







                                                                                           


                                                                                              










                                                   

                                                     







                                                                                     
                                                                       






               
 





                                               







                                                                  



                                                                                    








                                                                      



                                     










                                                             
                                                      
















                                                                                     
                                              
















                                                                                 
                                                                                            














                                                             
                             

                                    
                                                         
 
/**
 * @class ndgui
 *
 * @brief the GUI.
 *
 * This class is responsible for creating and displaying the user interface.
 * It also connects the webView via QWebBridge to javascript functions inside the html files.
 */



#include "ndgui.h"


#include <log4cxx/logger.h>
#include "qlog4cxx.h"

using namespace log4cxx;
using namespace log4cxx::helpers;
LoggerPtr ndLogger(Logger::getLogger("fbgui.nd"));


QString gServerIp("");
bool gAutoUp = true;
QString gSocketServerPath("");
QString gPathToDhcpExe("");



/**
 * constructor
 */
ndgui::ndgui(QMainWindow *parent) :
	QMainWindow(parent) {
}



/**
 * destructor
 */
ndgui::~ndgui() {

	delete _debugConsole;
	delete _toggleDebugConsole;
	delete _allowUserChoice;
	delete _tryAgain;
	delete _webView;
	delete _networkDiscovery;

}



/**
 * @brief initialize all variables and prepare everything for a successful run
 */
void ndgui::init() {

	_started = false;
	_userChoice = false;
	_ifNameList.clear();
	_manConfList.clear();

	setupLayout();
	createAction();

	_networkDiscovery = new NetworkDiscovery();
	connect(_networkDiscovery, SIGNAL(addInterface(const QString &)), this,
			SLOT(addInterface( const QString &)));
	connect(_networkDiscovery,
			SIGNAL(changeProgressBarValue(const QString & , const int& )),
			this, SLOT(updateIfProgressBar(const QString & , const int&)));
	connect(_networkDiscovery, SIGNAL(connectionEstablished(QString)), this,
			SLOT(handleConnectionEstablished(QString)));
	connect(_networkDiscovery, SIGNAL(abortBoot(QString)), this,
			SLOT(abortBoot(const QString)));
	connect(_networkDiscovery, SIGNAL(updateIfStatus(QString,QString)), this,
			SLOT(updateIfStatus(const QString &, const QString &)));
	connect(_networkDiscovery, SIGNAL(updateStatus(QString)), this,
			SLOT(updateStatus(const QString&)));
	connect(_networkDiscovery, SIGNAL(allProcessesFinished()), this,
			SLOT(handleAllProcessesFinished()));
	connect(_networkDiscovery, SIGNAL(continueBoot(QString)), this,
			SLOT(continueBoot(QString)));
	connect(_networkDiscovery, SIGNAL(continueBootWithoutCheck(QString )),
			this, SLOT(continueBootWithoutCheck(QString)));

	connect(_webView->page()->mainFrame(), SIGNAL(
			javaScriptWindowObjectCleared()), this, SLOT(attachToDOM()));
	connect(_webView, SIGNAL(loadFinished(bool)), this, SLOT(startSingleShot()));

	setWindowTitle(tr("NetD"));
	setAttribute(Qt::WA_QuitOnClose, true);
	setWindowFlags(Qt::FramelessWindowHint);
	showFullScreen();

	if (debugMode > -1) {
		_webView->load(QUrl("qrc:html/networkdiscovery_debug.html"));
	} else {
		_webView->load(QUrl("qrc:html/networkdiscovery.html"));

	}

	_webView->show();
}



/**
 * @brief This method sets the used Layout.
 *
 * This method sets the used Layout. Possible layout are:
 *  - browser mode: only the browser is visible
 *  - debug mode: the screen is divided into the browser and a debug
 *      out console
 */
void ndgui::setupLayout() {
   // setup layout of the gui: debug split or browser
   _webView = new QWebView(this);
   _webView->setContextMenuPolicy(Qt::NoContextMenu); // if this does not work try Qt::CustomContextMenu

   if (debugMode == 1) {
      // split main window in browser & debug console
      createDebugConsole();
      _splitter = new QSplitter(Qt::Vertical, this);
      _splitter->addWidget(_webView);
      _splitter->addWidget(_debugConsole);
      setCentralWidget(_splitter);
   } else {
	  _webView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
      setCentralWidget(_webView);
   }
}



/**
 * @brief This method creates a debug console as a widget.
 *
 * It is basicly a QTextEdit widget as provided by QT's Framework.
 * An action to toggle this widget is implemented (CTRL + D).
 *
 * @see fbgui::toggleDebugConsole()
 */
void ndgui::createDebugConsole() {
   // create the debug console widget
   _debugConsole = new QTextEdit(this);
   _debugConsole->setWindowFlags(Qt::FramelessWindowHint);
   // fanciness
   QPalette pal;
   pal.setColor(QPalette::Base, Qt::black);
   _debugConsole->setPalette(pal);
   _debugConsole->setTextColor(Qt::white);
   // enable custom logger engine
//   qxtLog->addLoggerEngine("fb_logger", new LoggerEngine_fb(_debugConsole));
   //qxtLog->initLoggerEngine("fb_logger");
//   qxtLog->setMinimumLevel("fb_logger", QxtLogger::DebugLevel);
   // CTRL + D  toggles debug window
   _toggleDebugConsole = new QAction(tr("&toggleDebug"), this);
   _toggleDebugConsole->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
   addAction(_toggleDebugConsole);
   connect(_toggleDebugConsole, SIGNAL(triggered()), this, SLOT(
         toggleDebugConsole()));
}



/**
 * @brief This method toggles the debug console.
 *
 * Toggle the visibility of the debug console if the action _toggleDebugConsole is triggered.
 *
 * @see fbgui::createDebugConsole()
 */
void ndgui::toggleDebugConsole() {
   (_debugConsole->isVisible()) ? _debugConsole->hide() : _debugConsole->show();
}



/**
 * @brief Create actions
 *
 * creates an action which you can trigger with the F5 and F9 Button.
 */
void ndgui::createAction() {
	_allowUserChoice = new QAction(tr("&userChoice"), this);
	_allowUserChoice->setShortcut(QKeySequence(Qt::Key_F5));
	connect(_allowUserChoice, SIGNAL(triggered()), this, SLOT(setUserChoiceTrue()));
	this->addAction(_allowUserChoice);
	_tryAgain = new QAction(tr("&tryAgain"), this);
	_tryAgain->setShortcut(QKeySequence(Qt::Key_F9));
	connect(_tryAgain, SIGNAL(triggered()), this, SLOT(tryAgain()));
	this->addAction(_tryAgain);
}



/**
 * @brief set userChoice true
 *
 * is the connected to the triggered action pressing the F5 button.
 * set the _userChoice member true
 */
void ndgui::setUserChoiceTrue() {
	_userChoice = true;
}



/**
 * @brief starts a singleshot event.
 *
 * is connected to the singleShot event. Triggering this method means
 * that we go on with the main NetworkDiscovery screen.
 * connects the loadFinished signal of the _webView with the
 * startNetworkDiscovery slot and removes the
 * action.
 */
void ndgui::startSingleShot() {

	LOG4CXX_DEBUG(ndLogger, "start single shot");
	QTimer::singleShot(3000, this, SLOT(startNetworkDiscovery()));
}



/**
 * @brief start the network discovery
 *
 * main starting point of the whole procedure.
 * disconnect the loadFinished signal with the startNetworkDiscovery
 * and starts the networkDiscovery.
 */
void ndgui::startNetworkDiscovery() {
	disconnect(_webView, SIGNAL(loadFinished(bool)), this,
			SLOT(startSingleShot()));
	if (!_started) {
		_started = true;
		_networkDiscovery->initAndRun(gServerIp, _userChoice, gAutoUp,
				logFilePath, gSocketServerPath, gPathToDhcpExe);
	} else {
		LOG4CXX_DEBUG(ndLogger, "NetworkDiscovery already started");
	}
}



/**
 * @brief handle if a interface is able to connect
 *
 * if we have a user choice (_userChoice = true) than networkDiscovery will
 * emit connectionEstablished signals.
 * Add the interface name to a _ifNameList. This list holds all interfaces
 * the user can choose out of.
 */
void ndgui::handleConnectionEstablished(QString ifName) {
	_ifNameList.append(ifName);
}



/**
 * @brief determines if we continue the boot sequence or if we show the chooseInterface or abortBoot dialog
 *
 * if we have a user choice (_userChoice = true) than networkDiscovery will
 * emit a allProcessesFinished signal if all processes are done.
 * This method determines if user will see an abort boot dialog (no interface names in
 * the ifNameList list) or an
 * choose interface dialog (one or more interface names in the list (add with
 * handleConnectionEstablished)).
 */
void ndgui::handleAllProcessesFinished() {
	LOG4CXX_DEBUG(ndLogger, "all Processes finished");
	_allowUserChoice->setEnabled(false);
	if (_ifNameList.size() > 0) {
		if (_userChoice) {
			QString jsonArr = "[";
			for (int i = 0; i < _ifNameList.size() - 1; i++) {
				jsonArr += "\"" + _ifNameList.value(i) + "\",";
			}
			jsonArr += "\"" + _ifNameList.last() + "\"]";
			chooseInterfaceDialog(jsonArr);
		} else {
			foreach(QString i, _ifNameList)
			{
				if (_networkDiscovery->checkConnectivity(i)) {
					continueBootWithoutCheck(i);
					break;
				}
			}
		}
	} else {
		LOG4CXX_DEBUG(ndLogger, " No usable interfaces found!: " << _networkDiscovery->GetErrorStr());
		LOG4CXX_DEBUG(ndLogger, " list is empty");
		abortBoot("No usable interfaces found!"
				+ _networkDiscovery->GetErrorStr());
	}
}



/**
 * @brief restart the system
 *
 * this method will restart the system.
 * triggered through a button click in the gui.
 */
void ndgui::restartSystem() {
	QFile file("/proc/sysrq-trigger");
	if (file.open(QIODevice::WriteOnly)) {
		file.write("b");
		file.close();
	} else {
		LOG4CXX_DEBUG(ndLogger, "Could not open /proc/sysrq-trigger");
	}
}



/**
 * @brief shut down the system
 *
 * this method will restart the system.
 * triggered through a button click in the gui.
 */
void ndgui::shutDownSystem() {
	QFile file("/proc/sysrq-trigger");
	if (file.open(QIODevice::WriteOnly)) {
		file.write("o");
		file.close();
	} else {
		LOG4CXX_DEBUG(ndLogger, "Could not open /proc/sysrq-trigger");
	}
}



/**
 * @brief continue the boot sequence
 *
 * represents the end of the NetworkDiscovery life time.
 * will start the fbgui screen. All networkDiscovery signals
 * will be ignored after this point.
 */
//void ndgui::continueBoot(QString ifName, int userChoice) {
void ndgui::continueBoot(QString ifName) {
	if (_networkDiscovery->checkConnectivity(ifName)) {
		LOG4CXX_DEBUG(ndLogger, " continue with interface: " << ifName);
		emit initFbgui();
		this->close();
	} else {
		abortBoot(
				"Interface was suddenly made unusable. Please check the log and try again.");
	}

}



/**
 * @brief continue the boot sequence without further checking if the connection is still possible.
 */
void ndgui::continueBootWithoutCheck(QString ifName) {
	LOG4CXX_DEBUG(ndLogger, " continue with interface: " << ifName);
	emit initFbgui();
	this->close();
}



/**
 * @brief read the log file. Log File will be presented inside of a dialog.
 */
QString ndgui::readLogFile() {
	LOG4CXX_DEBUG(ndLogger, "show log");
	return _networkDiscovery->readLogFile();
}



/**
 * @brief starts the whole application again.
 */
void ndgui::tryAgain() {
	LOG4CXX_DEBUG(ndLogger, " try again ");
	_networkDiscovery->prepareTryAgain();
	if(debugMode > -1) {
		delete _splitter;
		delete _debugConsole;
		delete _toggleDebugConsole;
	}
	delete _allowUserChoice;
	delete _tryAgain;
	delete _webView;
	delete _networkDiscovery;

	init();

}



/*test html gui version*/

/**
 * @brief fills the drop down box of the manual interface configuration
 * dialog.
 */
QVariantList ndgui::getManualConfInterfaces() {
	LOG4CXX_DEBUG(ndLogger, "call getManualConfInterfaces");
	QVariantList jsonArr;
	QString debugOut;
	foreach (QString s, _manConfList) {
		QVariant e(s);
		jsonArr << e;
		debugOut += s + "; ";
	}
	LOG4CXX_DEBUG(ndLogger, "value of jsonArr:" << debugOut);
	return jsonArr;
}


/**
 * @brief return a json formated interface configuration
 *
 * @param ifName
 *        the name of the interface
 */
QVariantMap ndgui::getInterfaceConf(QString ifName) {

  return _networkDiscovery->getInterfaceConfig(ifName);
}



/**
 * @brief takes the entered manual configuration dates and delivers it
 * to the networkDiscovery for further actions.
 *
 * @param jsonArr
 *        a jsonArr which contains the manual entered interface configuration
 */
int ndgui::ip4_setManualConfiguration(QVariantMap jsonArr) {
	return _networkDiscovery->ip4_setManualConfiguration(jsonArr);

}



/* slots */
/************************************************/
//////////////////////////////////////////////////
/************************************************/

/**
 * @brief stellt ein ndgui/fbgui Objekt zur verwendung durch die html bereit.
 */
void ndgui::attachToDOM(){
	_webView->page()->mainFrame()->addToJavaScriptWindowObject(QString("fbgui"), this);
	loadJQuery();
}



/**
 * @brief load jQuery and js scripts into the page so that all javascript functions will work.
 */
void ndgui::loadJQuery() {
   QString js;
   QString pathToJsDir(":/html");
   pathToJsDir.append("/js");

   QDir qrcJSDir(pathToJsDir);
   QFileInfoList fiList = qrcJSDir.entryInfoList();
   QFileInfo fi;
   foreach(fi, fiList)
      {
         if (fi.suffix() == "js") {
            //LOG4CXX_DEBUG(ndLogger, fi.fileName());
            //LOG4CXX_DEBUG(ndLogger, fi.fileName());
            //if (fi.fileName() != "test.js" && fi.fileName() != "nd-functions.js") {
               QFile file;
               file.setFileName(pathToJsDir + "/" + fi.fileName());
               file.open(QIODevice::ReadOnly);
               js = file.readAll();
               file.close();

               _webView->page()->mainFrame()->evaluateJavaScript(js);
               //LOG4CXX_DEBUG(ndLogger, "evaluated " + fi.fileName());
            //}
         }
      }
}




/**
 * @brief show abortBoot dialog
 *
 * @param msg
 *        the message, displayed in the dialog.
 */
void ndgui::abortBoot(const QString msg) {
	QString code = QString("abortBootDialog('\%1')").arg(msg);
	_webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief opens ths chooseInterfaceDialog
 *
 * @param msg
 *        the interfaces as json formated string. will be displayed in a select box.
 */
void ndgui::chooseInterfaceDialog(const QString msg) {
	QString code = QString("chooseInterfaceDialog(\%1)").arg(msg);
	_webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief updates the over all status
 *
 * @param status
 *        the new status message
 */
void ndgui::updateStatus(const QString &status) {
   if (status == "")
      return;
   QString code = QString("updateStatus('\%1')").arg(status);
   _webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief updates the progress bar for each interface.
 *
 * @param	ifname
 * 			the name ot the interface to update
 *
 * @param	percent
 * 			the progress in percent
 */
void ndgui::updateIfProgressBar(const QString &ifName, const int& percent) {
   if (percent == 0)
      return;
   QString code = QString("updateIfProgressBar('\%1',\%2)").arg(ifName).arg(percent);
   _webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief update the status for each interface
 *
 * @param	ifName
 * 			the name ot the interface to update
 *
 * @param 	status
 * 			the new status of the interface.
 */
void ndgui::updateIfStatus(const QString &ifName, const QString &status) {
   if (ifName == "")
      return;
   QString code = QString("updateIfStatus('\%1','\%2')").arg(ifName).arg(status);
   _webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief adds an interface to the DOM tree. Creates its progress bar and it's status label.
 *
 * @param 	ifName
 * 			name of the new interface.
 */
void ndgui::addInterface(const QString &ifName) {
   if (ifName == "")
      return;
   _manConfList.append(ifName);
   QString code = QString("addInterface('\%1')").arg(ifName);
   _webView->page()->mainFrame()->evaluateJavaScript(code);
}



/**
 * @brief just for debugging.
 */
void ndgui::notifyCall(QString msg){
	LOG4CXX_DEBUG(ndLogger, "------ called:" << msg);
}