From 44bb0e85c26c29c9ba2b8e1480f7aeb7b37889d4 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 10 Jul 2015 19:19:35 +0200 Subject: [PATCH] Qt5 service displayer --HG-- branch : qt5 --- code/CMakeLists.txt | 1 - code/CMakeModules/nel.cmake | 3 +- code/nel/CMakeLists.txt | 4 + code/nel/include/nel/misc/gtk_displayer.h | 2 +- code/nel/include/nel/misc/win_displayer.h | 2 +- code/nel/include/nel/misc/window_displayer.h | 4 +- code/nel/include/nel/net/service.h | 11 +- code/nel/samples/net/chat/CMakeLists.txt | 2 - code/nel/src/misc/gtk_displayer.cpp | 2 +- code/nel/src/misc/win_displayer.cpp | 2 +- code/nel/src/misc/window_displayer.cpp | 12 +- code/nel/src/net/CMakeLists.txt | 4 + code/nel/src/net/service.cpp | 19 +- .../tools/3d/panoply_preview/tool_main.cpp | 19 +- .../tools/misc/crash_report/crash_report.cpp | 6 +- code/nelqt/include/nelqt/common.h | 87 ++++++ .../include/nelqt/displayer/command_log.h | 7 + .../nelqt/displayer/service_displayer.h | 88 ++++++ .../include/nelqt/displayer/service_window.h | 99 +++++++ code/nelqt/src/displayer/command_log.cpp | 2 + .../nelqt/src/displayer/service_displayer.cpp | 274 ++++++++++++++++++ code/nelqt/src/displayer/service_window.cpp | 128 ++++++++ 22 files changed, 736 insertions(+), 42 deletions(-) create mode 100644 code/nelqt/include/nelqt/common.h create mode 100644 code/nelqt/include/nelqt/displayer/service_displayer.h create mode 100644 code/nelqt/include/nelqt/displayer/service_window.h create mode 100644 code/nelqt/src/displayer/service_displayer.cpp create mode 100644 code/nelqt/src/displayer/service_window.cpp diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index ef6775118..301e357c8 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -151,7 +151,6 @@ IF(WITH_QT5) FIND_PACKAGE(Qt5Core) FIND_PACKAGE(Qt5Widgets) FIND_PACKAGE(Qt5LinguistTools) - ADD_DEFINITIONS(-DQT_NO_DEBUG) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/nelqt/include) ENDIF(WITH_QT5) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 312cea864..1259a3652 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -78,7 +78,7 @@ ENDMACRO(NL_GEN_REVISION_H) # ### MACRO(NL_TARGET_LIB name) - CMAKE_POLICY(SET CMP0020 OLD) + CMAKE_POLICY(SET CMP0020 NEW) IF(WITH_STATIC) ADD_LIBRARY(${name} STATIC ${ARGN}) ELSE(WITH_STATIC) @@ -281,6 +281,7 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) OPTION(WITH_GTK "With GTK Support" OFF) OPTION(WITH_QT "With QT4 Support" OFF) OPTION(WITH_QT5 "With QT5 Support" OFF) + OPTION(WITH_NET_QT5 "Use QT5 inside NLNET" OFF) IF(WIN32 AND MFC_FOUND) OPTION(WITH_MFC "With MFC Support" ON ) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index f283eaecb..d1a041dfa 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -37,6 +37,10 @@ IF(WITH_GTK) FIND_PACKAGE(GTK2) ENDIF(WITH_GTK) +IF(WITH_QT5 AND WITH_NET_QT5) + ADD_DEFINITIONS(-DNLNET_USE_QT5) +ENDIF(WITH_QT5 AND WITH_NET_QT5) + IF(WITH_LIBOVR) FIND_PACKAGE(LibOVR) ENDIF(WITH_LIBOVR) diff --git a/code/nel/include/nel/misc/gtk_displayer.h b/code/nel/include/nel/misc/gtk_displayer.h index e2d35c83c..ee5cf4a13 100644 --- a/code/nel/include/nel/misc/gtk_displayer.h +++ b/code/nel/include/nel/misc/gtk_displayer.h @@ -54,7 +54,7 @@ private: void updateLabels (); // called by DT only - void open (std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log); + void open (int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log); // called by DT only void clear (); // called by DT only diff --git a/code/nel/include/nel/misc/win_displayer.h b/code/nel/include/nel/misc/win_displayer.h index f450055a9..f4608a5f0 100644 --- a/code/nel/include/nel/misc/win_displayer.h +++ b/code/nel/include/nel/misc/win_displayer.h @@ -73,7 +73,7 @@ private: void updateLabels (); // called by DT only - void open (std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log); + void open(int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log); // called by DT only void clear (); // called by DT only diff --git a/code/nel/include/nel/misc/window_displayer.h b/code/nel/include/nel/misc/window_displayer.h index a1dfdc8cf..d89378370 100644 --- a/code/nel/include/nel/misc/window_displayer.h +++ b/code/nel/include/nel/misc/window_displayer.h @@ -48,7 +48,7 @@ public: virtual ~CWindowDisplayer (); // open the window and run the display thread (MT) - void create (std::string titleBar = "", bool iconified = false, sint x = -1, sint y = -1, sint w = -1, sint h = -1, sint hs = -1, sint fs = 0, const std::string &fn = "", bool ww = false, CLog *log = InfoLog); + void create(int argc, char **argv, std::string titleBar = "", bool iconified = false, sint x = -1, sint y = -1, sint w = -1, sint h = -1, sint hs = -1, sint fs = 0, const std::string &fn = "", bool ww = false, CLog *log = InfoLog); // create a new label. empty string mean separator. start with @ means that is a command (MT) uint createLabel (const char *value = "?"); @@ -88,7 +88,7 @@ protected: CSynchronized > _CommandsToExecute; // called by DT only - virtual void open (std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) = 0; + virtual void open(int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) = 0; // called by DT only virtual void display_main () = 0; diff --git a/code/nel/include/nel/net/service.h b/code/nel/include/nel/net/service.h index 8c7a52c63..6903b1d60 100644 --- a/code/nel/include/nel/net/service.h +++ b/code/nel/include/nel/net/service.h @@ -14,7 +14,6 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . - #ifndef NL_SERVICE_H #define NL_SERVICE_H @@ -124,7 +123,7 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL scn->setArgs (lpCmdLine); \ createDebug(NULL,!scn->haveLongArg("nolog"));\ scn->setCallbackArray (__ServiceCallbackArray, sizeof(__ServiceCallbackArray)/sizeof(__ServiceCallbackArray[0])); \ - sint retval = scn->main (__ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__" "__TIME__); \ + sint retval = scn->main (__argc, __argv, __ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__" "__TIME__); \ delete scn; \ return retval; \ } @@ -132,14 +131,14 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL #else #define NLNET_SERVICE_MAIN(__ServiceClassName, __ServiceShortName, __ServiceLongName, __ServicePort, __ServiceCallbackArray, __ConfigDir, __LogDir) \ \ -int main(int argc, const char **argv) \ +int main(int argc, char **argv) \ { \ NLMISC::CApplicationContext serviceContext; \ __ServiceClassName *scn = new __ServiceClassName; \ - scn->setArgs (argc, argv); \ + scn->setArgs (argc, (const char **)argv); \ createDebug(NULL,!scn->haveLongArg("nolog"));\ scn->setCallbackArray (__ServiceCallbackArray, sizeof(__ServiceCallbackArray)/sizeof(__ServiceCallbackArray[0])); \ - sint retval = scn->main (__ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__" "__TIME__); \ + sint retval = scn->main (argc, argv, __ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__" "__TIME__); \ delete scn; \ return retval; \ } @@ -335,7 +334,7 @@ public: // @{ /// This main is called by the macro (service5 says if we have to use layer5 or not) - sint main (const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir, const char *compilationDate); + sint main(int argc, char **argv, const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir, const char *compilationDate); /// Sets the command line and init _Args variable. You must call this before calling main() void setArgs (int argc, const char **argv); diff --git a/code/nel/samples/net/chat/CMakeLists.txt b/code/nel/samples/net/chat/CMakeLists.txt index b5c66d67c..c304e6491 100644 --- a/code/nel/samples/net/chat/CMakeLists.txt +++ b/code/nel/samples/net/chat/CMakeLists.txt @@ -2,8 +2,6 @@ ADD_EXECUTABLE(nl_sample_chatclient client.cpp kbhit.cpp kbhit.h) ADD_EXECUTABLE(nl_sample_chatserver WIN32 server.cpp) -ADD_DEFINITIONS(-DCHAT_DIR="\\"${NL_SHARE_ABSOLUTE_PREFIX}/nl_sample_chat/\\"") - TARGET_LINK_LIBRARIES(nl_sample_chatclient nelmisc nelnet) NL_DEFAULT_PROPS(nl_sample_chatclient "NeL, Samples, Net, Chat: Chat Client") NL_ADD_RUNTIME_FLAGS(nl_sample_chatclient) diff --git a/code/nel/src/misc/gtk_displayer.cpp b/code/nel/src/misc/gtk_displayer.cpp index 0c581b2e5..c177457a0 100644 --- a/code/nel/src/misc/gtk_displayer.cpp +++ b/code/nel/src/misc/gtk_displayer.cpp @@ -266,7 +266,7 @@ void CGtkDisplayer::setTitleBar (const string &titleBar) gtk_window_set_title (GTK_WINDOW (RootWindow), wn.c_str()); } -void CGtkDisplayer::open (std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) +void CGtkDisplayer::open (int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) { _HistorySize = hs; diff --git a/code/nel/src/misc/win_displayer.cpp b/code/nel/src/misc/win_displayer.cpp index 5da7db65b..a56e54717 100644 --- a/code/nel/src/misc/win_displayer.cpp +++ b/code/nel/src/misc/win_displayer.cpp @@ -357,7 +357,7 @@ void CWinDisplayer::setTitleBar (const string &titleBar) SetWindowTextW (_HWnd, (LPWSTR)ucstring::makeFromUtf8(wn).c_str()); } -void CWinDisplayer::open (string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) +void CWinDisplayer::open(int argc, char **argv, string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) { if (w == -1) w = 700; diff --git a/code/nel/src/misc/window_displayer.cpp b/code/nel/src/misc/window_displayer.cpp index 35f0d5482..cba3dfa93 100644 --- a/code/nel/src/misc/window_displayer.cpp +++ b/code/nel/src/misc/window_displayer.cpp @@ -33,6 +33,8 @@ namespace NLMISC { class CUpdateThread : public IRunnable { CWindowDisplayer *Disp; + int ArgC; + char **ArgV; string WindowNameEx; sint X, Y, W, H, HS; bool Iconified; @@ -42,14 +44,14 @@ class CUpdateThread : public IRunnable CLog *Log; public: - CUpdateThread (CWindowDisplayer *disp, string windowNameEx, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) : - Disp(disp), WindowNameEx(windowNameEx), X(x), Y(y), W(w), H(h), HS(hs), Iconified(iconified), FS(fs), FN(fn), WW(ww), Log(log) + CUpdateThread(CWindowDisplayer *disp, int argc, char **argv, string windowNameEx, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) : + Disp(disp), ArgC(argc), ArgV(argv), WindowNameEx(windowNameEx), X(x), Y(y), W(w), H(h), HS(hs), Iconified(iconified), FS(fs), FN(fn), WW(ww), Log(log) { } void run() { - Disp->open (WindowNameEx, Iconified, X, Y, W, H, HS, FS, FN, WW, Log); + Disp->open(ArgC, ArgV, WindowNameEx, Iconified, X, Y, W, H, HS, FS, FN, WW, Log); Disp->display_main (); } }; @@ -105,10 +107,10 @@ void CWindowDisplayer::setLabel (uint label, const string &value) } } -void CWindowDisplayer::create (string windowNameEx, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) +void CWindowDisplayer::create(int argc, char **argv, string windowNameEx, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) { nlassert (_Thread == NULL); - _Thread = IThread::create (new CUpdateThread(this, windowNameEx, iconified, x, y, w, h, hs, fs, fn, ww, log)); + _Thread = IThread::create(new CUpdateThread(this, argc, argv, windowNameEx, iconified, x, y, w, h, hs, fs, fn, ww, log)); Log = log; diff --git a/code/nel/src/net/CMakeLists.txt b/code/nel/src/net/CMakeLists.txt index 487516e74..f0c20a983 100644 --- a/code/nel/src/net/CMakeLists.txt +++ b/code/nel/src/net/CMakeLists.txt @@ -12,6 +12,10 @@ IF(WITH_GTK) ENDIF(GTK2_FOUND) ENDIF(WITH_GTK) +IF(WITH_QT5 AND WITH_NET_QT5) + TARGET_LINK_LIBRARIES(nelnet nelqtdisplayer) +ENDIF(WITH_QT5 AND WITH_NET_QT5) + TARGET_LINK_LIBRARIES(nelnet nelmisc) SET_TARGET_PROPERTIES(nelnet PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nelnet "NeL, Library: NeL Net") diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp index 1f3436d1c..ffde47c0e 100644 --- a/code/nel/src/net/service.cpp +++ b/code/nel/src/net/service.cpp @@ -40,6 +40,10 @@ #include "nel/misc/system_info.h" #include "nel/misc/timeout_assertion_thread.h" +#if NLNET_USE_QT5 +# include +#endif + #include "nel/net/naming_client.h" #include "nel/net/service.h" #include "nel/net/unified_network.h" @@ -551,7 +555,7 @@ void cbExecuteCommands (CConfigFile::CVar &var) // The main function of the service // -sint IService::main (const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir, const char *compilationDate) +sint IService::main(int argc, char **argv, const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir, const char *compilationDate) { bool userInitCalled = false; CConfigFile::CVar *var = NULL; @@ -773,17 +777,24 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, #ifdef NL_USE_GTK if (disp == "GTK") { - WindowDisplayer = new CGtkDisplayer ("DEFAULT_WD"); + WindowDisplayer = new CGtkDisplayer("DEFAULT_WD"); } #endif // NL_USE_GTK #ifdef NL_OS_WINDOWS if (disp == "WIN") { - WindowDisplayer = new CWinDisplayer ("DEFAULT_WD"); + WindowDisplayer = new CWinDisplayer("DEFAULT_WD"); } #endif // NL_OS_WINDOWS +#ifdef NLNET_USE_QT5 + if (disp == "QT5") + { + WindowDisplayer = new NLQT::CServiceDisplayer("DEFAULT_WD"); + } +#endif // NLNET_USE_QT5 + if (WindowDisplayer == NULL && disp != "NONE") { nlinfo ("SERVICE: Unknown value for the WindowStyle (should be GTK, WIN or NONE), use no window displayer"); @@ -814,7 +825,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, if (haveArg('I')) iconified = true; - WindowDisplayer->create (string("*INIT* ") + _ShortName + " " + _LongName, iconified, x, y, w, h, history, fs, fn, ww, &CommandLog); + WindowDisplayer->create(argc, argv, string("*INIT* ") + _ShortName + " " + _LongName, iconified, x, y, w, h, history, fs, fn, ww, &CommandLog); DebugLog->addDisplayer (WindowDisplayer); InfoLog->addDisplayer (WindowDisplayer); diff --git a/code/nel/tools/3d/panoply_preview/tool_main.cpp b/code/nel/tools/3d/panoply_preview/tool_main.cpp index d9b85efe7..68b9deb5a 100644 --- a/code/nel/tools/3d/panoply_preview/tool_main.cpp +++ b/code/nel/tools/3d/panoply_preview/tool_main.cpp @@ -38,6 +38,7 @@ #include #include #include +#include // Project includes #include "tool_config.h" @@ -153,23 +154,9 @@ sint main(int argc, char **argv) CSheetId::initWithoutSheet(); + NLQT::preApplication(); QApplication app(argc, const_cast(argv)); - - QApplication::setStyle(QStyleFactory::create("Fusion")); - QPalette palette = app.palette(); - palette.setColor(QPalette::Window, QColor(64, 64, 64)); - palette.setColor(QPalette::WindowText, Qt::white); - palette.setColor(QPalette::Base, QColor(48, 48, 48)); - palette.setColor(QPalette::AlternateBase, QColor(64, 64, 64)); - palette.setColor(QPalette::ToolTipBase, Qt::white); - palette.setColor(QPalette::ToolTipText, Qt::white); - palette.setColor(QPalette::Text, Qt::white); - palette.setColor(QPalette::Button, QColor(64, 64, 64)); - palette.setColor(QPalette::ButtonText, Qt::white); - palette.setColor(QPalette::BrightText, Qt::red); - palette.setColor(QPalette::Highlight, QColor(64, 128, 96)); - palette.setColor(QPalette::HighlightedText, Qt::white); - app.setPalette(palette); + NLQT::postApplication(); QMap customSizeHints = parseCustomSizeHints(argc, argv); diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index c42f1ae6f..f21ad1fa5 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -18,8 +18,10 @@ #include "crash_report_widget.h" +#include #include #include +#include #include #include @@ -91,7 +93,9 @@ int main( int argc, char **argv ) } #endif - QApplication app( argc, argv ); + NLQT::preApplication(); + QApplication app(argc, argv); + NLQT::postApplication(); std::vector< std::pair< std::string, std::string > > params; diff --git a/code/nelqt/include/nelqt/common.h b/code/nelqt/include/nelqt/common.h new file mode 100644 index 000000000..23cb2b86d --- /dev/null +++ b/code/nelqt/include/nelqt/common.h @@ -0,0 +1,87 @@ +/* + +Copyright (C) 2015 by authors +Author: Jan Boon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NLQT_COMMON_H +#define NLQT_COMMON_H +#include + +// STL includes + +// Qt includes +#include +#include +#include +#include + +// NeL includes + +// Project includes + +namespace NLQT { +namespace { + +void preApplication() +{ + QCoreApplication::libraryPaths(); + QString app_location = QCoreApplication::applicationFilePath(); + app_location.truncate(app_location.lastIndexOf(QLatin1Char('/'))); + app_location = QDir(app_location).canonicalPath(); + QCoreApplication::removeLibraryPath(app_location); + QCoreApplication::addLibraryPath("./platforms"); + QCoreApplication::addLibraryPath("./qtwebengine"); + QCoreApplication::addLibraryPath("./imageformats"); + QCoreApplication::addLibraryPath("./iconengines"); + QCoreApplication::addLibraryPath("./designer"); +} + +void postApplication() +{ + QApplication::setStyle(QStyleFactory::create("Fusion")); + QPalette palette = qApp->palette(); + palette.setColor(QPalette::Window, QColor(64, 64, 64)); + palette.setColor(QPalette::WindowText, Qt::white); + palette.setColor(QPalette::Base, QColor(48, 48, 48)); + palette.setColor(QPalette::AlternateBase, QColor(64, 64, 64)); + palette.setColor(QPalette::ToolTipBase, Qt::white); + palette.setColor(QPalette::ToolTipText, Qt::white); + palette.setColor(QPalette::Text, Qt::white); + palette.setColor(QPalette::Button, QColor(64, 64, 64)); + palette.setColor(QPalette::ButtonText, Qt::white); + palette.setColor(QPalette::BrightText, Qt::red); + palette.setColor(QPalette::Highlight, QColor(64, 128, 96)); + palette.setColor(QPalette::HighlightedText, Qt::white); + qApp->setPalette(palette); +} + +} +} /* namespace NLQT */ + +#endif /* #ifndef NLQT_SERVICE_WINDOW_H */ + +/* end of file */ diff --git a/code/nelqt/include/nelqt/displayer/command_log.h b/code/nelqt/include/nelqt/displayer/command_log.h index d51a93463..d92f84b72 100644 --- a/code/nelqt/include/nelqt/displayer/command_log.h +++ b/code/nelqt/include/nelqt/displayer/command_log.h @@ -41,11 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // NeL includes #include #include +#include // Project includes namespace NLQT { +typedef NLMISC::CCallback TCommandExecute; + class CCommandLog : public QWidget { Q_OBJECT @@ -54,8 +57,11 @@ public: CCommandLog(QWidget *parent); virtual ~CCommandLog(); + void setExecCommand(const TCommandExecute &func) { m_Func = func; } void doDisplay(const NLMISC::CLog::TDisplayInfo& args, const char *message); + void clear() { m_DisplayerOutput->clear(); } + signals: void tSigDisplay(const QColor &c, const QString &text); void execCommand(const std::string &cmd); @@ -67,6 +73,7 @@ private slots: private: QTextEdit *m_DisplayerOutput; QLineEdit *m_CommandInput; + TCommandExecute m_Func; private: CCommandLog(const CCommandLog &); diff --git a/code/nelqt/include/nelqt/displayer/service_displayer.h b/code/nelqt/include/nelqt/displayer/service_displayer.h new file mode 100644 index 000000000..247cc8d22 --- /dev/null +++ b/code/nelqt/include/nelqt/displayer/service_displayer.h @@ -0,0 +1,88 @@ +/* + +Copyright (C) 2015 by authors +Author: Jan Boon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NLQT_SERVICE_DISPLAYER_H +#define NLQT_SERVICE_DISPLAYER_H +#include + +// STL includes + +// NeL includes +#include +#include +#include + +// Project includes + +class QWidget; + +namespace NLQT { + class CServiceWindow; + class CCommandLog; + +class CServiceDisplayer : public NLMISC::CWindowDisplayer +{ +public: + CServiceDisplayer(const char *displayerName); + virtual ~CServiceDisplayer(); + + virtual void setTitleBar(const std::string &titleBar); + +protected: + virtual void doDisplay(const NLMISC::CLog::TDisplayInfo& args, const char *message); + + virtual void open(int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, NLMISC::CLog *log); + + virtual void display_main(); + + void commandExecute(const std::string &cmd); + void buttonCallback(QWidget *sender); + void timerCallback(); + void exitCallback(); + +private: + CServiceWindow *m_ServiceWindow; + CCommandLog *m_CommandLog; + NLMISC::CLog *m_Log; + NLMISC::CSynchronized > > m_DelayLog; + + NLMISC::CSynchronized m_SetTitleBar; + bool m_DoSetTitleBar; + +private: + CServiceDisplayer(const CServiceDisplayer &); + CServiceDisplayer &operator=(const CServiceDisplayer &); + +}; /* class CServiceDisplayer */ + +} /* namespace NLQT */ + +#endif /* #ifndef NLQT_SERVICE_DISPLAYER_H */ + +/* end of file */ diff --git a/code/nelqt/include/nelqt/displayer/service_window.h b/code/nelqt/include/nelqt/displayer/service_window.h new file mode 100644 index 000000000..60f32f924 --- /dev/null +++ b/code/nelqt/include/nelqt/displayer/service_window.h @@ -0,0 +1,99 @@ +/* + +Copyright (C) 2015 by authors +Author: Jan Boon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef NLQT_SERVICE_WINDOW_H +#define NLQT_SERVICE_WINDOW_H +#include + +// STL includes + +// Qt includes +#include +#include + +// NeL includes +#include +#include +#include + +// Project includes + +class QHBoxLayout; +class QVBoxLayout; + +namespace NLQT { + class CCommandLog; + +typedef NLMISC::CCallback TDisplayerButtonCallback; +typedef NLMISC::CCallback TDisplayerTimerCallback; +typedef NLMISC::CCallback TDisplayerExitCallback; + +class CServiceWindow : public QMainWindow +{ + Q_OBJECT + +public: + CServiceWindow(QWidget *parent = NULL, Qt::WindowFlags flags = 0); + virtual ~CServiceWindow(); + + inline void setButtonCallback(const TDisplayerButtonCallback &cb) { m_ButtonCallback = cb; } + inline void setTimerCallback(const TDisplayerTimerCallback &cb) { m_TimerCallback = cb; } + inline void setExitCallback(const TDisplayerExitCallback &cb) { m_ExitCallback = cb; } + inline CCommandLog *commandLog() { return m_CommandLog; } + + QWidget *addLabel(); + QWidget *addButton(); + void addLine(); + +private slots: + void buttonCallback(); + void timerCallback(); + +private: + CCommandLog *m_CommandLog; + TDisplayerButtonCallback m_ButtonCallback; + TDisplayerTimerCallback m_TimerCallback; + TDisplayerExitCallback m_ExitCallback; + + QVBoxLayout *m_LabelVBox; + QHBoxLayout *m_LabelHBox; + + QFont m_Font; + +private: + CServiceWindow(const CServiceWindow &); + CServiceWindow &operator=(const CServiceWindow &); + +}; /* class CServiceWindow */ + +} /* namespace NLQT */ + +#endif /* #ifndef NLQT_SERVICE_WINDOW_H */ + +/* end of file */ diff --git a/code/nelqt/src/displayer/command_log.cpp b/code/nelqt/src/displayer/command_log.cpp index d51565306..c0ab0e965 100644 --- a/code/nelqt/src/displayer/command_log.cpp +++ b/code/nelqt/src/displayer/command_log.cpp @@ -117,6 +117,7 @@ void CCommandLog::returnPressed() std::string cmd = text.toLocal8Bit().data(); execCommand(cmd); + if (m_Func) m_Func(cmd); m_CommandInput->clear(); } @@ -149,6 +150,7 @@ void CCommandLogDisplayer::doDisplay(const NLMISC::CLog::TDisplayInfo& args, con void CCommandLogDisplayer::execCommandLog(const std::string &cmd) { + m_Log.displayRawNL("> %s", cmd.c_str()); ICommand::execute(cmd, m_Log); } diff --git a/code/nelqt/src/displayer/service_displayer.cpp b/code/nelqt/src/displayer/service_displayer.cpp new file mode 100644 index 000000000..31af8f664 --- /dev/null +++ b/code/nelqt/src/displayer/service_displayer.cpp @@ -0,0 +1,274 @@ +/* + +Copyright (C) 2015 by authors +Author: Jan Boon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +// STL includes + +// Qt includes +#include +#include +#include +#include + +// NeL includes +#include +#include +#include + +// Project includes +#include +#include +#include + +using namespace std; +using namespace NLMISC; + +namespace NLQT { + +CServiceDisplayer::CServiceDisplayer(const char *displayerName) : CWindowDisplayer(displayerName), m_DelayLog("CServiceDisplayer::m_DelayLog"), m_SetTitleBar("CServiceDisplayer::m_SetTitleBar"), m_CommandLog(NULL), m_DoSetTitleBar(false) +{ + createLabel("@Clear|CLEAR"); + + INelContext::getInstance().setWindowedApplication(true); +} + +CServiceDisplayer::~CServiceDisplayer() +{ + +} + +void CServiceDisplayer::doDisplay(const CLog::TDisplayInfo& args, const char *message) +{ + if (!m_Log) + return; + + if (m_CommandLog) + { + m_CommandLog->doDisplay(args, message); + } + else + { + NLMISC::CSynchronized > >::CAccessor access(&m_DelayLog); + access.value().push_back(std::pair(args, message)); + } +} + +void CServiceDisplayer::open(int argc, char **argv, std::string titleBar, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, NLMISC::CLog *log) +{ + if (w == -1) + w = 700; + if (h == -1) + h = 300; + if (hs == -1) + hs = 1000; + + m_Log = log; + + NLQT::preApplication(); + QApplication app(argc, argv); + NLQT::postApplication(); + + CServiceWindow serviceWindow; + // serviceWindow.move(x, y); + serviceWindow.resize(w, h); + serviceWindow.setWindowTitle(QString::fromUtf8(titleBar.c_str())); + m_ServiceWindow = &serviceWindow; + ; { + NLMISC::CSynchronized > >::CAccessor access(&m_DelayLog); + for (std::vector >::iterator it(access.value().begin()), end(access.value().end()); it != end; ++it) + serviceWindow.commandLog()->doDisplay(it->first, it->second.c_str()); + access.value().clear(); + } + m_CommandLog = serviceWindow.commandLog(); + ; { + NLMISC::CSynchronized > >::CAccessor access(&m_DelayLog); + for (std::vector >::iterator it(access.value().begin()), end(access.value().end()); it != end; ++it) + serviceWindow.commandLog()->doDisplay(it->first, it->second.c_str()); + access.value().clear(); + } + serviceWindow.setButtonCallback(TDisplayerButtonCallback(this, &CServiceDisplayer::buttonCallback)); + serviceWindow.setTimerCallback(TDisplayerTimerCallback(this, &CServiceDisplayer::timerCallback)); + serviceWindow.setExitCallback(TDisplayerExitCallback(this, &CServiceDisplayer::exitCallback)); + m_CommandLog->setExecCommand(TCommandExecute(this, &CServiceDisplayer::commandExecute)); + serviceWindow.show(); + app.exec(); +} + +void CServiceDisplayer::display_main() +{ + +} + +void CServiceDisplayer::commandExecute(const std::string &cmd) // DT +{ + m_Log->displayRawNL("> %s", cmd.c_str()); + + { + CSynchronized >::CAccessor access(&_CommandsToExecute); + access.value().push_back(cmd); + } +} + +void CServiceDisplayer::setTitleBar(const std::string &titleBar) +{ + NLMISC::CSynchronized::CAccessor access(&m_SetTitleBar); + access.value() = titleBar; + m_DoSetTitleBar = true; +} + +namespace { +QString rstrip(const QString& str) +{ + int n = str.size() - 1; + for (; n >= 0; --n) + { + if (!str.at(n).isSpace()) + { + return str.left(n + 1); + } + } + return ""; +} +} + +void CServiceDisplayer::buttonCallback(QWidget *sender) // DT +{ + CSynchronized >::CAccessor access(&_Labels); + for (uint i = 0; i < access.value().size(); i++) + { + if (access.value()[i].Hwnd == sender) + { + if (access.value()[i].Value == "@Clear|CLEAR") + { + // special commands because the clear must be called by the display thread and not main thread + m_CommandLog->clear(); + } + else + { + // the button was found, add the command in the command stack + CSynchronized >::CAccessor accessCommands(&_CommandsToExecute); + string str; + nlassert(!access.value()[i].Value.empty()); + nlassert(access.value()[i].Value[0] == '@'); + + string::size_type pos = access.value()[i].Value.find("|"); + if (pos != string::npos) + { + str = access.value()[i].Value.substr(pos + 1); + } + else + { + str = access.value()[i].Value.substr(1); + } + if (!str.empty()) + accessCommands.value().push_back(str); + } + break; + } + } +} + +void CServiceDisplayer::timerCallback() // DT +{ + if (m_DoSetTitleBar) + { + NLMISC::CSynchronized::CAccessor access(&m_SetTitleBar); + m_ServiceWindow->setWindowTitle(QString::fromUtf8(access.value().c_str())); + m_DoSetTitleBar = false; + access.value().clear(); + } + ; { + CSynchronized >::CAccessor access(&_Labels); + for (uint i = 0; i < access.value().size(); i++) + { + if (access.value()[i].NeedUpdate && !access.value()[i].Value.empty()) + { + if (access.value()[i].Hwnd == NULL) + { + // empty char (on previous) is separator + if (i > 0 && access.value()[i - 1].Value.empty()) + { + m_ServiceWindow->addLine(); + } + + // create a button for command and label for variables + if (access.value()[i].Value[0] == '@') + { + access.value()[i].Hwnd = m_ServiceWindow->addButton(); + } + else + { + access.value()[i].Hwnd = m_ServiceWindow->addLabel(); + } + } + + string n; + + // do this tricks to be sure that windows will clear what is after the number + if (access.value()[i].Value[0] != '@') + n = access.value()[i].Value + " "; + else + { + string::size_type pos = access.value()[i].Value.find('|'); + if (pos != string::npos) + { + n = access.value()[i].Value.substr(1, pos - 1); + } + else + { + n = access.value()[i].Value.substr(1); + } + } + + if (access.value()[i].Value[0] == '@') + { + ((QPushButton *)access.value()[i].Hwnd)->setText(rstrip(QString::fromUtf8(n.c_str()))); + } + else + { + ((QLabel *)access.value()[i].Hwnd)->setText(rstrip(QString::fromUtf8(n.c_str()))); + } + } + } + } +} + +void CServiceDisplayer::exitCallback() // DT +{ + _Continue = false; + m_Log = NULL; + m_CommandLog = NULL; + m_ServiceWindow = NULL; +} + +} /* namespace NLQT */ + +/* end of file */ diff --git a/code/nelqt/src/displayer/service_window.cpp b/code/nelqt/src/displayer/service_window.cpp new file mode 100644 index 000000000..e013cfb21 --- /dev/null +++ b/code/nelqt/src/displayer/service_window.cpp @@ -0,0 +1,128 @@ +/* + +Copyright (C) 2015 by authors +Author: Jan Boon +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +// STL includes + +// Qt includes +#include +#include +#include +#include +#include +#include + +// NeL includes +#include +#include +#include + +// Project includes +#include + +using namespace std; +using namespace NLMISC; + +namespace NLQT { + + CServiceWindow::CServiceWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), m_Font(QFontDatabase::systemFont(QFontDatabase::FixedFont)) +{ + m_LabelVBox = new QVBoxLayout(this); + m_LabelHBox = new QHBoxLayout(this); + m_LabelVBox->addLayout(m_LabelHBox); + + QWidget *widget = new QWidget(this); + QVBoxLayout *vbox = new QVBoxLayout(widget); + vbox->addLayout(m_LabelVBox); + + m_CommandLog = new CCommandLog(this); + m_CommandLog->layout()->setMargin(0); + vbox->addWidget(m_CommandLog); + + widget->setLayout(vbox); + setCentralWidget(widget); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timerCallback())); + timer->start(25); +} + +QWidget *CServiceWindow::addLabel() +{ + QLabel *label = new QLabel(this); + label->setFont(m_Font); + m_LabelHBox->addWidget(label); + return label; +} + +QWidget *CServiceWindow::addButton() +{ + QPushButton *button = new QPushButton(this); + button->setFont(m_Font); + connect(button, SIGNAL(clicked()), this, SLOT(buttonCallback())); + m_LabelHBox->addWidget(button); + return button; +} + +void CServiceWindow::addLine() +{ + m_LabelHBox = new QHBoxLayout(this); + m_LabelVBox->addLayout(m_LabelHBox); +} + +CServiceWindow::~CServiceWindow() +{ + if (m_ExitCallback) + { + m_ExitCallback(); + } +} + +void CServiceWindow::timerCallback() +{ + if (m_TimerCallback) + { + m_TimerCallback(); + } +} + +void CServiceWindow::buttonCallback() +{ + if (m_ButtonCallback) + { + QWidget *s = (QWidget *)sender(); + m_ButtonCallback(s); + } +} + +} /* namespace NLQT */ + +/* end of file */