diff options
Diffstat (limited to 'src/fbgui.cpp')
| -rw-r--r-- | src/fbgui.cpp | 561 |
1 files changed, 318 insertions, 243 deletions
diff --git a/src/fbgui.cpp b/src/fbgui.cpp index 8d2135a..9e3dba5 100644 --- a/src/fbgui.cpp +++ b/src/fbgui.cpp @@ -10,7 +10,8 @@ #include <QtWebKit> #include <QxtCore> -//QThread dmThread; +QThread dmThread; +QString logFilePath(""); QString ipConfigFilePath(""); QString binPath(""); QUrl baseURL(""); @@ -33,63 +34,59 @@ int debugMode = -1; * @see DownloadManager */ fbgui::fbgui() { - // test for libsys function - //SysInfoLibsysfs* sil = new SysInfoLibsysfs(); - //sil->getInfoAboutNetworkInterface(); - //sil->getInfoMainboardSerial(); - //SysInfo si; - //qxtLog->debug() << si.getInfo("mbserial"); - //si.getInfo("usb"); - setupLayout(); - createActions(); + // test for libsys function + //SysInfo si; + //qxtLog->debug() << si.getInfo("mbserial"); + //si.getInfo("usb"); - // initialize javascript interface - JavascriptInterface* jsi = new JavascriptInterface( - _webView->page()->mainFrame()); - QObject::connect(jsi, SIGNAL(quitFbgui()), this, SLOT(close())); - QObject::connect(jsi, SIGNAL(shutDownClient()), this, SLOT( - performShutDown())); - QObject::connect(_webView->page()->mainFrame(), SIGNAL( - javaScriptWindowObjectCleared()), jsi, SLOT(attachToDOM())); + setupLayout(); + createActions(); - // initialize download manager - DownloadManager* dm = new DownloadManager(); - QObject::connect(dm, SIGNAL(downloadInfo(const QString&, const double&)), - jsi, SLOT(downloadInfo(const QString&, const double&))); - QObject::connect(dm, SIGNAL(notify(const QString&)), jsi, - SLOT(notify(const QString&))); - QObject::connect(jsi, SIGNAL(requestFile(const QString&)), dm, - SLOT(downloadFile(const QString&))); - QObject::connect( - dm, - SIGNAL(updateProgress(const int&, const double&, const QString&)), - jsi, - SLOT(updateProgressBar(const int&, const double&, const QString&))); - QObject::connect(dm, SIGNAL(downloadQueueEmpty()), jsi, SLOT( - callbackOnFinished())); - QObject::connect(dm, SIGNAL(downloadQueueEmpty()), this, SLOT( - prepareKexec())); + // initialize javascript interface + JavascriptInterface* jsi = new JavascriptInterface( + _webView->page()->mainFrame()); + QObject::connect(jsi, SIGNAL(quitFbgui()), this, SLOT(close())); + QObject::connect(jsi, SIGNAL(shutDownClient()), this, + SLOT(performShutDown())); + QObject::connect(_webView->page()->mainFrame(), SIGNAL( + javaScriptWindowObjectCleared()), jsi, SLOT(attachToDOM())); - // move download manager to its own thread - //dm->moveToThread(&dmThread); - //dmThread.start(); + // initialize download manager + DownloadManager* dm = new DownloadManager(); + QObject::connect(dm, SIGNAL(downloadInfo(const QString&, const double&)), jsi, + SLOT(downloadInfo(const QString&, const double&))); + QObject::connect(dm, SIGNAL(notify(const QString&)), jsi, SLOT(notify(const QString&))); + QObject::connect(jsi, SIGNAL(requestFile(const QString&)), dm, + SLOT(downloadFile(const QString&))); + QObject::connect(dm, SIGNAL(updateProgress(const int&, const double&, const QString&)), jsi, + SLOT(updateProgressBar(const int&, const double&, const QString&))); + QObject::connect(dm, SIGNAL(downloadQueueEmpty()), jsi, SLOT( + callbackOnFinished())); + QObject::connect(dm, SIGNAL(downloadQueueEmpty()), this, SLOT(loadSystem())); - //_webView->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar); - // show page - _webView->load(QUrl("qrc:/html/preload.html")); - // start watching for fileToTriggerURL - watchForTrigger(); - //if (checkHost()) loadURL(); + // move download manager to its own thread + dm->moveToThread(&dmThread); + dmThread.start(); - // set properties - setWindowTitle("fbgui"); - setAttribute(Qt::WA_QuitOnClose, true); - setWindowFlags(Qt::FramelessWindowHint); - showFullScreen(); + // show "waiting for internet" page until triggered. + if (debugMode > -1) { + _webView->load(QUrl("qrc:/html/preload-debug.html")); + } else { + _webView->load(QUrl("qrc:/html/preload.html")); + } + + // start watching for fileToTriggerURL + watchForTrigger(); + + // set properties + setWindowTitle("fbgui"); + setAttribute(Qt::WA_QuitOnClose, true); + setWindowFlags(Qt::FramelessWindowHint); + showFullScreen(); } fbgui::~fbgui() { - //dmThread.quit(); + dmThread.quit(); } //------------------------------------------------------------------------------------------- // Layout / actions setup @@ -103,28 +100,28 @@ fbgui::~fbgui() { * out console */ void fbgui::setupLayout() { - // setup layout of the gui: debug split or browser - _webView = new QWebView(this); - 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 - setCentralWidget(_webView); + // setup layout of the gui: debug split or browser + _webView = new QWebView(this); + 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 + setCentralWidget(_webView); } //------------------------------------------------------------------------------------------- /** * This method enables a shortcut for closing the program. + * The shortcut itself is not configurable: CTRL + X */ void fbgui::createActions() { - // CTRL + X to kill the gui - _quit = new QAction(tr("&quit"), this); - _quit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X)); - this->addAction(_quit); - connect(_quit, SIGNAL(triggered()), this, SLOT(close())); + _quit = new QAction(tr("&quit"), this); + _quit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X)); + this->addAction(_quit); + connect(_quit, SIGNAL(triggered()), this, SLOT(close())); } //------------------------------------------------------------------------------------------- // File system watching @@ -139,29 +136,28 @@ void fbgui::createActions() { * */ void fbgui::watchForTrigger() { - // check if fileToTriggerURL already exists - QFile file(fileToTriggerURL); - if (file.exists()) { - qxtLog->debug() << "[watcher] " << fileToTriggerURL - << " exists already!"; - // try to load URL - loadURL(); - } else { - // create it - if (file.open(QIODevice::WriteOnly)) { - qxtLog->debug() << "[gui] Created: " << fileToTriggerURL; - file.close(); - } else { - qxtLog->debug() << "[gui] Creation of " << fileToTriggerURL - << " failed! Exiting..."; - exit( EXIT_FAILURE); - } - } - // watch the path where trigger file is expected - qxtLog->debug() << "[watcher] Watching " << fileToTriggerURL; - _watcher = new QFileSystemWatcher(QStringList(fileToTriggerURL), this); -QObject::connect(_watcher, SIGNAL(fileChanged(const QString&)), this, - SLOT(prepareURLLoad())); + // check if fileToTriggerURL already exists + QFile file(fileToTriggerURL); + if (file.exists()) { + qxtLog->debug() << "[watcher] " << fileToTriggerURL << " found."; + // try to load URL + loadURL(); + } else { + // create it + if (file.open(QIODevice::WriteOnly)) { + qxtLog->debug() << "[gui] Created: " << fileToTriggerURL; + file.close(); + } else { + qxtLog->debug() << "[gui] Creation of " << fileToTriggerURL + << " failed!"; + qxtLog->debug() << "[gui] Exiting in 5 seconds..."; + QTimer::singleShot(5000, this, SLOT(close())); + } + } + // watch the path to trigger file + qxtLog->debug() << "[watcher] Watching " << fileToTriggerURL; + _watcher = new QFileSystemWatcher(QStringList(fileToTriggerURL), this); +QObject::connect(_watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(prepareURLLoad())); } //------------------------------------------------------------------------------------------- @@ -176,37 +172,37 @@ QObject::connect(_watcher, SIGNAL(fileChanged(const QString&)), this, * @see fbgui::loadURL() */ void fbgui::prepareURLLoad() { - qxtLog->debug() << "[watcher] " << fileToTriggerURL << " changed!"; - // disconnect _watcher, his job is done - qxtLog->debug() << "[watcher] disconnected."; - _watcher->disconnect(this); - _watcher->deleteLater(); - // try to load URL - loadURL(); + qxtLog->debug() << "[watcher] " << fileToTriggerURL << " changed!"; + // disconnect _watcher, his job is done + qxtLog->debug() << "[watcher] disconnected."; + _watcher->disconnect(this); + _watcher->deleteLater(); + // try to load URL + loadURL(); } //------------------------------------------------------------------------------------------- // Preparations for URL load //------------------------------------------------------------------------------------------- /** - * This method checks if is connected to the internet. + * This method checks the existance of the host. * - * This method checks if is connected to the internet. + * This method checks if the host exists / can be found. + * The host is from the URL given through the configuration. */ bool fbgui::checkHost() const { - QHostInfo hostInfo = QHostInfo::fromName(baseURL.host()); - if (hostInfo.error() != QHostInfo::NoError) { - qxtLog->debug() << "[gui] Lookup of " << baseURL.host() - << "failed. Exiting..."; - return false; - } else { - qxtLog->debug() << "[gui] Lookup of " << baseURL.host() - << " succeeded."; - return true; - } + QHostInfo hostInfo = QHostInfo::fromName(baseURL.host()); + if (hostInfo.error() != QHostInfo::NoError) { + qxtLog->debug() << "[gui] Lookup of " << baseURL.host() << "failed."; + qxtLog->debug() << "[gui] Host can not be reached."; + return false; + } else { + qxtLog->debug() << "[gui] Lookup of " << baseURL.host() << " succeeded."; + return true; + } } //------------------------------------------------------------------------------------------- /** - * This method loads the main screen. + * This method tries loads the URL. * * This method loads the main screen via an POST request. If also disconnects the watcher * of the file, (Watcher is set in the fbgui::watchForTrigger() method). @@ -216,15 +212,30 @@ bool fbgui::checkHost() const { * @see fbgui::generatePOSTData() */ void fbgui::loadURL() { - if (checkHost()) { - qxtLog->debug() << "[gui] Loading URL..."; - QByteArray postData = generatePOSTData(); - QNetworkRequest req(baseURL); - // show arrow cursor - QWSServer::instance()->setCursorVisible(true); - //qApp->setOverrideCursor(QCursor(Qt::ArrowCursor)); - _webView->load(req, QNetworkAccessManager::PostOperation, postData); - } + if (checkHost()) { + qxtLog->debug() << "[gui] Loading URL: " << baseURL.toString() << " ..."; + + // Generate POST identification data needed by PBS. + QByteArray postData = generatePOSTData(); + QNetworkRequest req(baseURL); + + // show cursor again since user is about to interact. + QWSServer::instance()->setCursorVisible(true); + QObject::connect(_webView, SIGNAL(loadFinished(bool)), this, SLOT(loadURLDone(bool))); + _webView->load(req, QNetworkAccessManager::PostOperation, postData); + } + // TODO: error page if no host. +} +void fbgui::loadURLDone(bool success) { + // done contains the success of the loading: false / true + if (!success) { + qxtLog->debug() << "[gui] Loading failed. URL: " + << _webView->url().toString(); + qxtLog->debug() << "[gui] You can quit with CTRL + X ..."; + // TODO handle failure properly... + } else { + qxtLog->debug() << "[gui] Loaded URL: " << _webView->url().toString(); + } } //------------------------------------------------------------------------------------------- /** @@ -235,92 +246,76 @@ void fbgui::loadURL() { * The hardwarehash is a MD5 hash over the MAC address and the * mainboard serial number. * The specific serial number is set at the creation of the usb boot stick. + * This file has to be present on the directory specified in + * the configuration for this to work. * * @see SysInfo::getMACAddress() * @see SysInfo::getMainboardSerial() */ QByteArray fbgui::generatePOSTData() { - qxtLog->debug() << "[gui] Generating POST data..."; - // use MAC address as base data - SysInfo si; - QByteArray data(si.getInfo("mac").toUtf8()); - // append mainboard serial to the mac address for more unique hardwarehash - data.append(si.getInfo("mbserial").toUtf8()); - qxtLog->debug() << "[post] Hashing: " << data; - // generate MD5 hash of data - QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5); - qxtLog->debug() << "[post] MD5 Hash: " << hash.toHex(); + qxtLog->debug() << "[gui] Generating POST data..."; + // use MAC address as base data + SysInfo si; + QByteArray data(si.getInfo("mac").toUtf8()); + // append mainboard serial to the mac address for more unique hardwarehash + QByteArray mbserial(si.getInfo("mbserial").toUtf8()); + if (!mbserial.isEmpty()) + data.append(mbserial); + else { + qxtLog->debug() << "[gui] Mainboard serial was empty. Not appending to base hash data."; + } + qxtLog->debug() << "[post] Hashing: " << data; + // generate MD5 hash of data + QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5); + qxtLog->debug() << "[post] MD5 Hash: " << hash.toHex(); - // fetch serial number from usb - QByteArray serial; - QFile file(serialLocation); - if (!file.open(QIODevice::ReadOnly)) { - qxtLog->debug() << "[post] No such file: " << file.fileName(); - } - // everything ok, read data - serial = file.readAll(); - file.close(); - serial.chop(1); // chop EOF - qxtLog->debug() << "[post] Serial number is: " << serial; + // fetch serial number from usb + QByteArray serial; + QFile file(serialLocation); + if (!file.open(QIODevice::ReadOnly)) { + qxtLog->debug() << "[post] No such file: " << file.fileName(); + } + // everything ok, read data + serial = file.readAll(); + file.close(); + serial.chop(1); // chop EOF + qxtLog->debug() << "[post] Serial number is: " << serial; - // construct final byte array - QByteArray postData("mac="); - postData.append(si.getInfo("mac")); - postData.append("&hardwarehash=" + hash.toHex()); - postData.append("&serialnumber=" + serial); - qxtLog->debug() << "[post] POST data: " << postData; - return postData; + // construct final byte array + QByteArray postData("mac="); + postData.append(si.getInfo("mac")); + postData.append("&hardwarehash=" + hash.toHex()); + postData.append("&serialnumber=" + serial); + qxtLog->debug() << "[post] POST data: " << postData; + return postData; } + //------------------------------------------------------------------------------------------- -// Debug console setup / control -//------------------------------------------------------------------------------------------- -void fbgui::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())); -} -//------------------------------------------------------------------------------------------- -void fbgui::toggleDebugConsole() { - (_debugConsole->isVisible()) ? _debugConsole->hide() - : _debugConsole->show(); -} +// Shutdown / Reboot of the client //------------------------------------------------------------------------------------------- +// TODO One function for reboot and shutdown, with parameter for the action. +// for example: doSystemCall(_REBOOT_); /** * This method performs the shutdown of the client. * * This method performs the shutdown of the client. It is triggered by the * JavascriptInterface::shutDownClient() signal which will be emited in the * JavascriptInterface::shutDown() method. - * This method uses an QProcess object to execute the standard linux - * shutdown command. + * This method writes the character 'o' in /proc/sysrq-trigger + * which will shutdown the computer immediatly. + * (See linux magic keys) * * @see JavascriptInterface::shutDownClient() * @see JavascriptInterface::shutDown() */ void fbgui::performShutDown() { - QFile file("/proc/sysrq-trigger"); - if (file.open(QIODevice::WriteOnly)) { - file.write("o"); - file.close(); - } - else { - qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger"; - } + QFile file("/proc/sysrq-trigger"); + if (file.open(QIODevice::WriteOnly)) { + file.write("o"); + file.close(); + } else { + qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger"; + } } //------------------------------------------------------------------------------------------- /** @@ -329,81 +324,161 @@ void fbgui::performShutDown() { * This method performs the reboot of the client. It is triggered by the * JavascriptInterface::rebootClient() signal which will be emited in the * JavascriptInterface::reboot() method. - * This method uses an QProcess object to execute the standard linux - * shutdown command. + * This method writes the character 'b' in /proc/sysrq-trigger + * which will shutdown the computer immediatly. + * (See linux magic keys) * * @see JavascriptInterface::rebootClient() * @see JavascriptInterface::reboot() */ void fbgui::performReboot() { - QFile file("/proc/sysrq-trigger"); - if (file.open(QIODevice::WriteOnly)) { - file.write("b"); - file.close(); - } - else { - qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger"; - } + QFile file("/proc/sysrq-trigger"); + if (file.open(QIODevice::WriteOnly)) { + file.write("b"); + file.close(); + } else { + qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger"; + } +} +//------------------------------------------------------------------------------------------- +// Preparing Kernel Switch per kexec (initiating Stage 3) +//------------------------------------------------------------------------------------------- +void fbgui::loadSystem() { + //show loading system page. + //_webView->disconnect(this); + //QObject::connect(_webView, SIGNAL(loadFinished(bool)), this, SLOT(prepareKexec())); + _webView->load(QUrl("qrc:/html/loadsystem.html")); + QTimer::singleShot(1000, this, SLOT(prepareKexec())); } //------------------------------------------------------------------------------------------- /** - * This method performs kexec. + * This method prepares kexec. + * + * The kernel command line file that should have been downloaded from the Preboot-Server + * and the ip config file (created by udhcpc) are merged into the final completed KCL. + * + * A process is then started to load the kernel, initramfs and kcl into kexec. + * The process tries to execute kexec -l with these parameters. + * + * If this succeeds, runKexec() is called + * + * @see fbgui::runKexec() * */ void fbgui::prepareKexec() { - // TODO read kcl file - QFile file(downloadPath + "/kcl"); - if (!file.open(QIODevice::ReadOnly)) { - qxtLog->debug() << "[gui] No such file: " << file.fileName(); - } - // everything ok, read data - QString kcl = file.readAll(); - file.close(); - qxtLog->debug() << "[gui] KCL from PBS: " << kcl; - - // TODO read IP config file - file.setFileName("/tmp/ip_config_fbgui"); - if (!file.open(QIODevice::ReadOnly)) { - qxtLog->debug() << "[gui] No such file: " << file.fileName(); - } - QString ipConfig = file.readAll(); - file.close(); - qxtLog->debug() << "[gui] IP config: " << ipConfig; + qxtLog->debug() << "[gui] Preparing kexec ..."; + // try to read KCL file that was downloaded. + QFile file(downloadPath + "/kcl"); + if (!file.open(QIODevice::ReadOnly)) { + qxtLog->debug() << "[gui] No such file: " << file.fileName(); + } + // everything ok, read data. + QString kcl = file.readAll(); + file.close(); + qxtLog->debug() << "[gui] KCL from PBS: " << kcl; - kcl.append(" ip="); - kcl.append(ipConfig); + // try to read ipconfig file generated by udhcpc. + file.setFileName("/tmp/ip_config_fbgui"); + if (!file.open(QIODevice::ReadOnly)) { + qxtLog->debug() << "[gui] No such file: " << file.fileName(); + } + // everything ok, read data. + QString ipConfig = file.readAll(); + file.close(); + qxtLog->debug() << "[gui] IP config: " << ipConfig; - qxtLog->debug() << "[gui] Complete KCL: " << kcl; + // append ipConfig + kcl.append(" ip="); + kcl.append(ipConfig); + qxtLog->debug() << "[gui] Complete KCL: " << kcl; - QProcess *process = new QProcess(this); - QString cmdline = "kexec -l " + downloadPath.toUtf8() + "/kernel --initrd=" - + downloadPath.toUtf8() + "/initramfs --append=\"" + kcl.toUtf8() - + "\""; - qxtLog->debug() << "[gui] kexec cmdline: " << cmdline; - process->start(cmdline); - bool ret = process->waitForFinished(); - if (!ret) { - qxtLog->debug() << "[sysinfo] Failed to load kexec! Exiting..."; - exit( EXIT_FAILURE); - } else { - qxtLog->debug() << "[gui] Kexec load successfull."; - if (debugMode < 0) { - runKexec(); - } else { - qxtLog->debug() - << "[gui] Skipping execution of kexec - open debug shell."; - qxtLog->debug() - << "[gui] To start the system execute \"kexec -e\" in your shell."; - close(); - } - } + // load the kernel + initramfs + append of kcl into kexec. + QProcess *process = new QProcess(this); + QString cmdline = "kexec -l " + downloadPath.toUtf8() + "/kernel --initrd=" + + downloadPath.toUtf8() + "/initramfs --append=\"" + kcl.toUtf8() + + "\""; + qxtLog->debug() << "[gui] kexec cmdline: " << cmdline; + process->start(cmdline); + bool ret = process->waitForFinished(); + if (!ret) { + qxtLog->debug() << "[gui] Failed to execute: " << cmdline; + qxtLog->debug() << "[gui] Exiting in 5 seconds..."; + QTimer::singleShot(5000, this, SLOT(close())); + } else { + qxtLog->debug() << "[gui] Kexec load was successfull."; + if (debugMode < 0) { + // if process successfully finished, try to run kexec -e + runKexec(); + } else { + qxtLog->debug() + << "[gui] Skipping execution of kexec - open debug shell."; + qxtLog->debug() + << "[gui] To start the system execute \"kexec -e\" in your shell."; + close(); + } + } } +//------------------------------------------------------------------------------------------- +/** + * This method tries to execute: kexec -e + * + * This method tries to execute: kexec -e + * + */ void fbgui::runKexec() { - QProcess *process = new QProcess(this); - process->startDetached("kexec -e"); - if (!process->waitForStarted()) { - qxtLog->debug() << "[gui] Failed to execute: kexec -e"; - exit( EXIT_FAILURE); - } + QProcess *process = new QProcess(this); + process->start("kexec -e"); + if (!process->waitForStarted()) { + qxtLog->debug() << "[gui] Failed to execute: kexec -e"; + qxtLog->debug() << "[gui] Exiting in 5 seconds..."; + QTimer::singleShot(5000, this, SLOT(close())); + //TODO: Handle failure properly... + } +} +//------------------------------------------------------------------------------------------- +// Debug console setup / control +//------------------------------------------------------------------------------------------- +/** + * 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 fbgui::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())); } +//------------------------------------------------------------------------------------------- +/** + * This method toggles the debug console. + * + * Toggle the visibility of the debug console if the action _toggleDebugConsole is triggered. + * + * @see fbgui::createDebugConsole() + */ +void fbgui::toggleDebugConsole() { + (_debugConsole->isVisible()) ? _debugConsole->hide() : _debugConsole->show(); +} +//------------------------------------------------------------------------------------------- +// + +//------------------------------------------------------------------------------------------- |
