From 3d06de12fffd29261f5726419b691675a32cf1db Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 21 Feb 2011 16:26:24 +0200 Subject: [PATCH] Changed: #1206 Update core and example plugin. --- .../3d/object_viewer_qt/src/CMakeLists.txt | 2 +- .../tools/3d/object_viewer_qt/src/main.cpp | 84 +++++- .../src/plugins/core/CMakeLists.txt | 3 + .../src/plugins/core/core.cpp | 66 +++++ .../object_viewer_qt/src/plugins/core/core.h | 52 ++++ .../src/plugins/core/core_plugin.cpp | 22 +- .../src/plugins/core/core_plugin.h | 2 +- .../plugins/core/{iapp_page.h => icontext.h} | 26 +- .../object_viewer_qt/src/plugins/core/icore.h | 60 ++++ .../src/plugins/core/main_window.cpp | 257 ++++++++++-------- .../src/plugins/core/main_window.h | 66 +++-- .../src/plugins/core/settings_dialog.cpp | 5 +- .../src/plugins/core/settings_dialog.h | 5 +- .../src/plugins/example/CMakeLists.txt | 3 +- .../src/plugins/example/plugin1.cpp | 13 +- .../src/plugins/example/plugin1.h | 11 +- .../src/plugins/example/qnel_widget.cpp | 78 +++--- .../src/plugins/example/qnel_widget.h | 18 +- .../src/plugins/log/CMakeLists.txt | 3 +- .../src/translations/object_viewer_qt_de.qm | Bin 23 -> 0 bytes .../src/translations/object_viewer_qt_en.qm | Bin 23 -> 0 bytes .../src/translations/object_viewer_qt_fr.qm | Bin 23 -> 0 bytes .../src/translations/object_viewer_qt_ru.qm | Bin 40561 -> 0 bytes 23 files changed, 552 insertions(+), 224 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h rename code/nel/tools/3d/object_viewer_qt/src/plugins/core/{iapp_page.h => icontext.h} (77%) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_de.qm delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_en.qm delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_fr.qm delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_ru.qm diff --git a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt index 01e9251bc..ba438d72a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/CMakeLists.txt @@ -57,7 +57,7 @@ FOREACH(LANGUAGE ${LANGUAGES}) ADD_CUSTOM_COMMAND (OUTPUT ${QM} COMMAND ${QT_LRELEASE_EXECUTABLE} ${TS} MAIN_DEPENDENCY ${TS}) ENDFOREACH() -ADD_CUSTOM_TARGET (translations COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} -recursive -ts ${TRANSLATIONS}) +ADD_CUSTOM_TARGET (translations COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} -recursive -no-obsolete -ts ${TRANSLATIONS}) ADD_CUSTOM_COMMAND (TARGET translations COMMAND ${QT_LRELEASE_EXECUTABLE} ${TRANSLATIONS}) SOURCE_GROUP(QtResources FILES ${OBJECT_VIEWER_UIS} ${OBJECT_VIEWER_RCS}) diff --git a/code/nel/tools/3d/object_viewer_qt/src/main.cpp b/code/nel/tools/3d/object_viewer_qt/src/main.cpp index b394711b1..90381cfea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/main.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/main.cpp @@ -40,6 +40,9 @@ // Project includes #include "modules.h" #include "extension_system/iplugin_spec.h" +#include "extension_system/plugin_manager.h" + +static const char *appNameC = "ObjectViewerQt"; // nel_qt log file name #define NLQT_LOG_FILE "nel_qt.log" @@ -82,6 +85,29 @@ CFileDisplayer *s_FileDisplayer = NULL; # endif #endif +#ifdef Q_OS_WIN + +static void displayError(const QString &t) // No console on Windows. +{ + QMessageBox::critical(0, QLatin1String(appNameC), t); +} + +#else + +static void displayError(const QString &t) +{ + qCritical("%s", qPrintable(t)); +} + +#endif + +static inline QString msgCoreLoadFailure(const QString &why) +{ + return QCoreApplication::translate("Application", "Failed to load Core plugin: %1").arg(why); +} + +#define OVQT_OLD true + sint main(int argc, char **argv) { // go nel! @@ -111,8 +137,9 @@ sint main(int argc, char **argv) splash->setPixmap(QPixmap(":/images/nel_ide_load.png")); splash->show(); + QSettings::setDefaultFormat(QSettings::IniFormat); QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, - QLatin1String("Ryzom Core"), QLatin1String("ObjectViewerQt")); + QLatin1String("RyzomCore"), QLatin1String(appNameC)); QTranslator translator; QTranslator qtTranslator; @@ -128,6 +155,7 @@ sint main(int argc, char **argv) CLibrary::addLibPath((qApp->applicationDirPath() + QString("/../PlugIns/nel")).toStdString()); #endif +#if defined(OVQT_OLD) Modules::init(); Modules::plugMan().setSettings(settings); @@ -161,5 +189,57 @@ sint main(int argc, char **argv) splash->finish(&Modules::mainWin()); int result = app.exec(); Modules::release(); +#else + ExtensionSystem::CPluginManager pluginManager; + pluginManager.setSettings(settings); + QStringList pluginPaths; +#if !defined(NL_OS_MAC) + pluginPaths << QString("./plugins"); +#else + pluginPaths << qApp->applicationDirPath() + QString("/../PlugIns/ovqt"); +#endif + + pluginManager.setPluginPaths(pluginPaths); + pluginManager.loadPlugins(); + + splash->hide(); + + const QList plugins = pluginManager.plugins(); + ExtensionSystem::IPluginSpec *corePlugin = 0; + Q_FOREACH(ExtensionSystem::IPluginSpec *spec, plugins) + { + if (spec->name() == QLatin1String("Core")) + { + corePlugin = spec; + break; + } + } + + if (!corePlugin) + { + QDir absolutePluginPaths(pluginPaths.join(QLatin1String(","))); + QString absolutePaths = absolutePluginPaths.absolutePath(); + const QString reason = QCoreApplication::translate("Application", "Could not find ovqt_plugin_core in %1").arg(absolutePaths); + displayError(msgCoreLoadFailure(reason)); + return 1; + } + if (corePlugin->hasError()) + { + displayError(msgCoreLoadFailure(corePlugin->errorString())); + return 1; + } + + QStringList errors; + Q_FOREACH (ExtensionSystem::IPluginSpec *spec, pluginManager.plugins()) + if (spec->hasError()) + errors.append(spec->fileName() + " : " + spec->errorString()); + + if (!errors.isEmpty()) + QMessageBox::warning(0, QCoreApplication::translate("Application", "Object Viewer Qt - Plugin loader messages"), + errors.join(QString::fromLatin1("\n\n"))); + + int result = app.exec(); +#endif + return result; -} +} \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt index 4bbf7ea63..726cb4a2d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt @@ -9,10 +9,13 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) SET(OVQT_CORE_PLUGIN_HDR + icore.h + icontext.h imenu_manager.h icore_listener.h ioptions_page.h core_plugin.h + core.h main_window.h menu_manager.h settings_dialog.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp new file mode 100644 index 000000000..380413077 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.cpp @@ -0,0 +1,66 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "core.h" +#include "imenu_manager.h" +#include "main_window.h" + +static Core::CoreImpl *m_coreInstance = 0; + +namespace Core +{ + +ICore *ICore::instance() +{ + return m_coreInstance; +} + +CoreImpl::CoreImpl(MainWindow *mainWindow) +{ + m_mainWindow = mainWindow; + m_coreInstance = this; +} + +CoreImpl::~CoreImpl() +{ + m_coreInstance = 0; +} + +bool CoreImpl::showOptionsDialog(const QString &group, + const QString &page, + QWidget *parent) +{ + return m_mainWindow->showOptionsDialog(group, page, parent); +} + +IMenuManager *CoreImpl::menuManager() const +{ + return m_mainWindow->menuManager(); +} + +QSettings *CoreImpl::settings() const +{ + return m_mainWindow->settings(); +} + +QMainWindow *CoreImpl::mainWindow() const +{ + return m_mainWindow; +} + +} // namespace Core diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h new file mode 100644 index 000000000..e138b73ca --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core.h @@ -0,0 +1,52 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CORE_H +#define CORE_H + +#include "icore.h" + +namespace Core +{ +class MainWindow; + +class CoreImpl : public ICore +{ + Q_OBJECT + +public: + CoreImpl(MainWindow *mainWindow); + virtual ~CoreImpl(); + + virtual bool showOptionsDialog(const QString &group = QString(), + const QString &page = QString(), + QWidget *parent = 0); + + virtual IMenuManager *menuManager() const; + + virtual QSettings *settings() const; + virtual QMainWindow *mainWindow() const; + +private: + MainWindow *m_mainWindow; + friend class MainWindow; +}; + +} // namespace Core + +#endif // CORE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp index 664fae7c6..adf00409b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.cpp @@ -48,13 +48,15 @@ CorePlugin::~CorePlugin() } qDeleteAll(_autoReleaseObjects); _autoReleaseObjects.clear(); + + if (_oldOVQT) + delete _mainWindow; } bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { Q_UNUSED(errorString); _plugMan = pluginManager; - _oldOVQT = false; // for old ovqt QMainWindow *wnd = qobject_cast(_plugMan->objectByName("CMainWindow")); @@ -72,11 +74,11 @@ bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStr connect(newAction, SIGNAL(triggered()), this, SLOT(execSettings())); connect(newAction2, SIGNAL(triggered()), _pluginView, SLOT(show())); - _oldOVQT = true; + _oldOVQT = false; } else { - _mainWindow = new CMainWindow(this); + _mainWindow = new MainWindow(pluginManager); #ifdef Q_WS_X11 _mainWindow->setAttribute(Qt::WA_TranslucentBackground); _mainWindow->setAttribute(Qt::WA_NoSystemBackground, false); @@ -93,7 +95,9 @@ bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStr QtWin::extendFrameIntoClientArea(_mainWindow); _mainWindow->setContentsMargins(0, 0, 0, 0); } - _mainWindow->show(); + _oldOVQT = true; + bool success = _mainWindow->initialize(errorString); + return success; } addAutoReleasedObject(new CSearchPathsSettingsPage(this)); @@ -103,20 +107,18 @@ bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStr void CorePlugin::extensionsInitialized() { _pluginView = new ExtensionSystem::CPluginView(_plugMan); + if (_oldOVQT) + _mainWindow->extensionsInitialized(); } void CorePlugin::shutdown() { - if (!_oldOVQT) - { - delete _mainWindow; - delete _pluginView; - } + delete _pluginView; } void CorePlugin::execSettings() { - CSettingsDialog settingsDialog(this); + CSettingsDialog settingsDialog(_plugMan); settingsDialog.show(); settingsDialog.execDialog(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h index 53940016e..0df1bb238 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_plugin.h @@ -75,7 +75,7 @@ private Q_SLOTS: private: ExtensionSystem::IPluginManager *_plugMan; ExtensionSystem::CPluginView *_pluginView; - CMainWindow *_mainWindow; + MainWindow *_mainWindow; QList _autoReleaseObjects; bool _oldOVQT; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/iapp_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icontext.h similarity index 77% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/core/iapp_page.h rename to code/nel/tools/3d/object_viewer_qt/src/plugins/core/icontext.h index 49e9ea265..776246d8d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/iapp_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icontext.h @@ -15,25 +15,35 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef IAPP_PAGE_H -#define IAPP_PAGE_H +#ifndef ICONTEXT_H +#define ICONTEXT_H +// Project includes +#include "core_global.h" + +// Qt includes #include +#include +#include +QT_BEGIN_NAMESPACE class QWidget; +QT_END_NAMESPACE namespace Core { /** -@interface IAppPage -@brief The IAppPage is an interface for providing app pages in main window. +@interface IContext +@brief The IContext is an interface for providing tab pages in main window. @details You need to subclass this interface and put an instance of your subclass into the plugin manager object pool. */ -class IAppPage +class CORE_EXPORT IContext: public QObject { + Q_OBJECT public: - virtual ~IAppPage() {} + IContext(QObject *parent = 0): QObject(parent) {} + virtual ~IContext() {} /// id() is a unique identifier for referencing this page virtual QString id() const = 0; @@ -50,6 +60,4 @@ public: } // namespace Core -Q_DECLARE_INTERFACE(Core::IAppPage, "dev.ryzom.com.IAppPage/0.1") - -#endif // IAPP_PAGE_H +#endif // ICONTEXT_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h new file mode 100644 index 000000000..942daedc2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/icore.h @@ -0,0 +1,60 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef ICORE_H +#define ICORE_H + +#include "core_global.h" + +#include + +QT_BEGIN_NAMESPACE +class QMainWindow; +class QSettings; +QT_END_NAMESPACE + +namespace Core +{ +class IMenuManager; + +class CORE_EXPORT ICore : public QObject +{ + Q_OBJECT + +public: + ICore() {} + virtual ~ICore() {} + + static ICore *instance(); + + virtual bool showOptionsDialog(const QString &group = QString(), + const QString &page = QString(), + QWidget *parent = 0) = 0; + + virtual IMenuManager *menuManager() const = 0; + + virtual QSettings *settings() const = 0; + virtual QMainWindow *mainWindow() const = 0; + +Q_SIGNALS: + void closeMainWindow(); +}; + +} // namespace Core + +#endif // ICORE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp index 9aa7611c3..aff6bcd3f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.cpp @@ -17,10 +17,10 @@ // Project includes #include "main_window.h" -#include "menu_manager.h" -#include "core_plugin.h" -#include "iapp_page.h" +#include "icontext.h" #include "icore_listener.h" +#include "menu_manager.h" +#include "core.h" #include "core_constants.h" #include "settings_dialog.h" @@ -28,94 +28,117 @@ #include // Qt includes +#include #include namespace Core { -CMainWindow::CMainWindow(CorePlugin *corePlugin, QWidget *parent) +MainWindow::MainWindow(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent) : QMainWindow(parent), - _pluginManager(0), - _corePlugin(0), - _menuManager(0), - _lastDir("."), - _settings(0) + m_pluginManager(0), + m_menuManager(0), + m_coreImpl(0), + m_lastDir("."), + m_settings(0) { - _corePlugin = corePlugin; - _pluginManager = _corePlugin->pluginManager(); - _settings = _pluginManager->settings(); + QCoreApplication::setApplicationName(QLatin1String("ObjectViewerQt")); + QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::OVQT_VERSION_LONG)); + QCoreApplication::setOrganizationName(QLatin1String("RyzomCore")); setObjectName(Constants::MAIN_WINDOW); + setWindowIcon(QIcon(Constants::ICON_NEL)); + setWindowTitle(tr("Object Viewer Qt")); - _menuManager = new MenuManager(this); - _menuManager->setMenuBar(menuBar()); - _pluginManager->addObject(_menuManager); + m_pluginManager = pluginManager; + m_settings = m_pluginManager->settings(); + m_coreImpl = new CoreImpl(this); - _tabWidget = new QTabWidget(this); - _tabWidget->setTabPosition(QTabWidget::South); - setCentralWidget(_tabWidget); + m_menuManager = new MenuManager(this); + m_menuManager->setMenuBar(menuBar()); - QList listAppPages = _pluginManager->getObjects(); - - Q_FOREACH(IAppPage *appPage, listAppPages) - { - addAppPage(appPage); - } + m_tabWidget = new QTabWidget(this); + m_tabWidget->setTabPosition(QTabWidget::South); + setCentralWidget(m_tabWidget); setDockNestingEnabled(true); - - _originalPalette = QApplication::palette(); + m_originalPalette = QApplication::palette(); createDialogs(); createActions(); createMenus(); createStatusBar(); +} +MainWindow::~MainWindow() +{ + m_pluginManager->removeObject(m_coreImpl); + m_pluginManager->removeObject(m_menuManager); + + delete m_coreImpl; + m_coreImpl = 0; +} + +bool MainWindow::initialize(QString *errorString) +{ + Q_UNUSED(errorString); + m_pluginManager->addObject(m_coreImpl); + m_pluginManager->addObject(m_menuManager); + return true; +} + +void MainWindow::extensionsInitialized() +{ + QList listContexts = m_pluginManager->getObjects(); + + Q_FOREACH(IContext *context, listContexts) + { + addContextObject(context); + } + + connect(m_pluginManager, SIGNAL(objectAdded(QObject *)), this, SLOT(checkObject(QObject *))); readSettings(); - - setWindowIcon(QIcon(Constants::ICON_NEL)); - setWindowTitle(tr("Object Viewer Qt")); - - connect(_pluginManager, SIGNAL(objectAdded(QObject *)), this, SLOT(checkObject(QObject *))); + show(); } -CMainWindow::~CMainWindow() +IMenuManager *MainWindow::menuManager() const { + return m_menuManager; } -IMenuManager *CMainWindow::menuManager() const +QSettings *MainWindow::settings() const { - return _menuManager; + return m_settings; } -void CMainWindow::checkObject(QObject *obj) +void MainWindow::checkObject(QObject *obj) { - IAppPage *appPage = qobject_cast(obj); - if (appPage) - addAppPage(appPage); + IContext *context = qobject_cast(obj); + if (context) + addContextObject(context); } -bool CMainWindow::showOptionsDialog(const QString &group, - const QString &page, - QWidget *parent) +bool MainWindow::showOptionsDialog(const QString &group, + const QString &page, + QWidget *parent) { if (!parent) parent = this; - CSettingsDialog _settingsDialog(_corePlugin, group, page, parent); - _settingsDialog.show(); - return _settingsDialog.execDialog(); + CSettingsDialog settingsDialog(m_pluginManager, group, page, parent); + settingsDialog.show(); + return settingsDialog.execDialog(); } -void CMainWindow::about() +void MainWindow::about() { QMessageBox::about(this, tr("About Object Viewer Qt"), tr("

Object Viewer Qt NG

" "

Author: dnk-88

Compiled on %1 %2").arg(__DATE__).arg(__TIME__)); } -void CMainWindow::closeEvent(QCloseEvent *event) +void MainWindow::closeEvent(QCloseEvent *event) { - QList listeners = _pluginManager->getObjects(); + QList listeners = m_pluginManager->getObjects(); Q_FOREACH(ICoreListener *listener, listeners) { if (!listener->closeMainWindow()) @@ -124,112 +147,122 @@ void CMainWindow::closeEvent(QCloseEvent *event) return; } } + Q_EMIT m_coreImpl->closeMainWindow(); writeSettings(); event->accept(); } -void CMainWindow::addAppPage(IAppPage *appPage) +void MainWindow::addContextObject(IContext *context) { - QWidget *tabWidget = new QWidget(_tabWidget); - _tabWidget->addTab(tabWidget, appPage->icon(), appPage->trName()); + QWidget *tabWidget = new QWidget(m_tabWidget); + m_tabWidget->addTab(tabWidget, context->icon(), context->trName()); QGridLayout *gridLayout = new QGridLayout(tabWidget); - gridLayout->setObjectName(QString::fromUtf8("gridLayout_") + appPage->id()); + gridLayout->setObjectName(QString::fromUtf8("gridLayout_") + context->id()); gridLayout->setContentsMargins(0, 0, 0, 0); - gridLayout->addWidget(appPage->widget(), 0, 0, 1, 1); + gridLayout->addWidget(context->widget(), 0, 0, 1, 1); } -void CMainWindow::createActions() +void MainWindow::createActions() { - _openAction = new QAction(tr("&Open..."), this); - _openAction->setIcon(QIcon(":/images/open-file.png")); - _openAction->setShortcut(QKeySequence::Open); - _openAction->setStatusTip(tr("Open an existing file")); - menuManager()->registerAction(_openAction, Constants::OPEN); -// connect(_openAction, SIGNAL(triggered()), this, SLOT(open())); + m_openAction = new QAction(tr("&Open..."), this); + m_openAction->setIcon(QIcon(":/images/open-file.png")); + m_openAction->setShortcut(QKeySequence::Open); + m_openAction->setStatusTip(tr("Open an existing file")); + menuManager()->registerAction(m_openAction, Constants::OPEN); +// connect(m_openAction, SIGNAL(triggered()), this, SLOT(open())); - _exitAction = new QAction(tr("E&xit"), this); - _exitAction->setShortcut(tr("Ctrl+Q")); - _exitAction->setStatusTip(tr("Exit the application")); - menuManager()->registerAction(_exitAction, Constants::EXIT); - connect(_exitAction, SIGNAL(triggered()), this, SLOT(close())); + m_exitAction = new QAction(tr("E&xit"), this); + m_exitAction->setShortcut(QKeySequence(tr("Ctrl+Q"))); + m_exitAction->setStatusTip(tr("Exit the application")); + menuManager()->registerAction(m_exitAction, Constants::EXIT); + connect(m_exitAction, SIGNAL(triggered()), this, SLOT(close())); - _settingsAction = new QAction(tr("&Settings"), this); - _settingsAction->setIcon(QIcon(":/images/preferences.png")); - _settingsAction->setStatusTip(tr("Open the settings dialog")); - menuManager()->registerAction(_settingsAction, Constants::SETTINGS); - connect(_settingsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog())); + m_settingsAction = new QAction(tr("&Settings"), this); + m_settingsAction->setIcon(QIcon(":/images/preferences.png")); + m_settingsAction->setShortcut(QKeySequence::Preferences); + m_settingsAction->setStatusTip(tr("Open the settings dialog")); + menuManager()->registerAction(m_settingsAction, Constants::SETTINGS); + connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog())); - _aboutAction = new QAction(tr("&About"), this); - _aboutAction->setStatusTip(tr("Show the application's About box")); - menuManager()->registerAction(_aboutAction, Constants::ABOUT); - connect(_aboutAction, SIGNAL(triggered()), this, SLOT(about())); + m_aboutAction = new QAction(tr("&About"), this); + m_aboutAction->setStatusTip(tr("Show the application's About box")); + menuManager()->registerAction(m_aboutAction, Constants::ABOUT); + connect(m_aboutAction, SIGNAL(triggered()), this, SLOT(about())); - _aboutQtAction = new QAction(tr("About &Qt"), this); - _aboutQtAction->setStatusTip(tr("Show the Qt library's About box")); - menuManager()->registerAction(_aboutQtAction, Constants::ABOUT_QT); - connect(_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + m_aboutQtAction = new QAction(tr("About &Qt"), this); + m_aboutQtAction->setStatusTip(tr("Show the Qt library's About box")); + menuManager()->registerAction(m_aboutQtAction, Constants::ABOUT_QT); + connect(m_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - _pluginViewAction = new QAction(tr("About &Plugins"), this); - _pluginViewAction->setStatusTip(tr("Show the plugin view dialog")); - menuManager()->registerAction(_pluginViewAction, Constants::ABOUT_PLUGINS); - connect(_pluginViewAction, SIGNAL(triggered()), _pluginView, SLOT(show())); + m_pluginViewAction = new QAction(tr("About &Plugins"), this); + m_pluginViewAction->setStatusTip(tr("Show the plugin view dialog")); + menuManager()->registerAction(m_pluginViewAction, Constants::ABOUT_PLUGINS); + connect(m_pluginViewAction, SIGNAL(triggered()), m_pluginView, SLOT(show())); + +#ifdef Q_WS_MAC + m_exitAction->setMenuRole(QAction::QuitRole); + m_settingsAction->setMenuRole(QAction::PreferencesRole); + m_aboutAction->setMenuRole(QAction::AboutRole); + m_aboutQtAction->setMenuRole(QAction::AboutQtRole); + m_pluginViewAction->setMenuRole(QAction::ApplicationSpecificRole); +#endif } -void CMainWindow::createMenus() +void MainWindow::createMenus() { - _fileMenu = menuBar()->addMenu(tr("&File")); - menuManager()->registerMenu(_fileMenu, Constants::M_FILE); - _fileMenu->addSeparator(); - _fileMenu->addAction(_exitAction); + m_fileMenu = menuBar()->addMenu(tr("&File")); + menuManager()->registerMenu(m_fileMenu, Constants::M_FILE); + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_exitAction); - _editMenu = menuBar()->addMenu(tr("&Edit")); - menuManager()->registerMenu(_editMenu, Constants::M_EDIT); + m_editMenu = menuBar()->addMenu(tr("&Edit")); + menuManager()->registerMenu(m_editMenu, Constants::M_EDIT); - _viewMenu = menuBar()->addMenu(tr("&View")); - menuManager()->registerMenu(_viewMenu, Constants::M_VIEW); + m_viewMenu = menuBar()->addMenu(tr("&View")); + menuManager()->registerMenu(m_viewMenu, Constants::M_VIEW); - _toolsMenu = menuBar()->addMenu(tr("&Tools")); - menuManager()->registerMenu(_toolsMenu, Constants::M_TOOLS); + m_toolsMenu = menuBar()->addMenu(tr("&Tools")); + menuManager()->registerMenu(m_toolsMenu, Constants::M_TOOLS); - _toolsMenu->addSeparator(); + m_toolsMenu->addSeparator(); - _toolsMenu->addAction(_settingsAction); + m_toolsMenu->addAction(m_settingsAction); menuBar()->addSeparator(); - _helpMenu = menuBar()->addMenu(tr("&Help")); - menuManager()->registerMenu(_helpMenu, Constants::M_HELP); - _helpMenu->addAction(_aboutAction); - _helpMenu->addAction(_aboutQtAction); - _helpMenu->addAction(_pluginViewAction); + m_helpMenu = menuBar()->addMenu(tr("&Help")); + menuManager()->registerMenu(m_helpMenu, Constants::M_HELP); + m_helpMenu->addAction(m_aboutAction); + m_helpMenu->addAction(m_aboutQtAction); + m_helpMenu->addAction(m_pluginViewAction); } -void CMainWindow::createStatusBar() +void MainWindow::createStatusBar() { statusBar()->showMessage(tr("StatusReady")); } -void CMainWindow::createDialogs() +void MainWindow::createDialogs() { - _pluginView = new ExtensionSystem::CPluginView(_pluginManager, this); + m_pluginView = new ExtensionSystem::CPluginView(m_pluginManager, this); } -void CMainWindow::readSettings() +void MainWindow::readSettings() { - _settings->beginGroup("MainWindowSettings"); - restoreState(_settings->value("QtWindowState").toByteArray()); - restoreGeometry(_settings->value("QtWindowGeometry").toByteArray()); - _settings->endGroup(); + m_settings->beginGroup("MainWindow"); + restoreState(m_settings->value("WindowState").toByteArray()); + restoreGeometry(m_settings->value("WindowGeometry").toByteArray()); + m_settings->endGroup(); } -void CMainWindow::writeSettings() +void MainWindow::writeSettings() { - _settings->beginGroup("MainWindowSettings"); - _settings->setValue("QtWindowState", saveState()); - _settings->setValue("QtWindowGeometry", saveGeometry()); - _settings->endGroup(); + m_settings->beginGroup("MainWindow"); + m_settings->setValue("WindowState", saveState()); + m_settings->setValue("WindowGeometry", saveGeometry()); + m_settings->endGroup(); } } /* namespace Core */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h index e0b030b87..11a77cc56 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/main_window.h @@ -32,31 +32,39 @@ namespace Core { class CSettingsDialog; class CorePlugin; -class IAppPage; +class IContext; class IMenuManager; class MenuManager; +class CoreImpl; -class CMainWindow : public QMainWindow +class MainWindow : public QMainWindow { Q_OBJECT public: - CMainWindow(CorePlugin *corePlugin, QWidget *parent = 0); - ~CMainWindow(); + MainWindow(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent = 0); + ~MainWindow(); + + bool initialize(QString *errorString); + void extensionsInitialized(); IMenuManager *menuManager() const; + QSettings *settings() const; -private Q_SLOTS: - void checkObject(QObject *obj); +public Q_SLOTS: bool showOptionsDialog(const QString &group = QString(), const QString &page = QString(), QWidget *parent = 0); + +private Q_SLOTS: + void checkObject(QObject *obj); void about(); + protected: virtual void closeEvent(QCloseEvent *event); private: - void addAppPage(IAppPage *appPage); + void addContextObject(IContext *appPage); void createActions(); void createMenus(); @@ -66,35 +74,35 @@ private: void readSettings(); void writeSettings(); - ExtensionSystem::IPluginManager *_pluginManager; - ExtensionSystem::CPluginView *_pluginView; - CorePlugin *_corePlugin; - MenuManager *_menuManager; + ExtensionSystem::IPluginManager *m_pluginManager; + ExtensionSystem::CPluginView *m_pluginView; + MenuManager *m_menuManager; + CoreImpl *m_coreImpl; - QPalette _originalPalette; - QString _lastDir; + QPalette m_originalPalette; + QString m_lastDir; - QSettings *_settings; + QSettings *m_settings; - QTimer *_mainTimer; - QTimer *_statusBarTimer; + QTimer *m_mainTimer; + QTimer *m_statusBarTimer; - QTabWidget *_tabWidget; + QTabWidget *m_tabWidget; - QMenu *_fileMenu; - QMenu *_editMenu; - QMenu *_viewMenu; - QMenu *_toolsMenu; - QMenu *_helpMenu; + QMenu *m_fileMenu; + QMenu *m_editMenu; + QMenu *m_viewMenu; + QMenu *m_toolsMenu; + QMenu *m_helpMenu; - QAction *_openAction; - QAction *_exitAction; - QAction *_settingsAction; - QAction *_pluginViewAction; - QAction *_aboutAction; - QAction *_aboutQtAction; + QAction *m_openAction; + QAction *m_exitAction; + QAction *m_settingsAction; + QAction *m_pluginViewAction; + QAction *m_aboutAction; + QAction *m_aboutQtAction; -};/* class CMainWindow */ +};/* class MainWindow */ } /* namespace Core */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp index 3cee8edc7..30fd7835e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.cpp @@ -18,7 +18,6 @@ // Project includes #include "settings_dialog.h" -#include "core_plugin.h" #include "ioptions_page.h" // Qt includes @@ -36,7 +35,7 @@ Q_DECLARE_METATYPE(PageData); namespace Core { -CSettingsDialog::CSettingsDialog(CorePlugin *corePlugin, +CSettingsDialog::CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, const QString &categoryId, const QString &pageId, QWidget *parent) @@ -45,7 +44,7 @@ CSettingsDialog::CSettingsDialog(CorePlugin *corePlugin, { _ui.setupUi(this); - _plugMan = corePlugin->pluginManager(); + _plugMan = pluginManager; QString initialCategory = categoryId; QString initialPage = pageId; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h index ce461b234..07adc7fee 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/settings_dialog.h @@ -25,11 +25,10 @@ #include // Project includes -#include "../../extension_system/iplugin.h" +#include "../../extension_system/iplugin_manager.h" namespace Core { -class CorePlugin; class IOptionsPage; /** @@ -41,7 +40,7 @@ class CSettingsDialog: public QDialog Q_OBJECT public: - CSettingsDialog(CorePlugin *corePlugin, + CSettingsDialog(ExtensionSystem::IPluginManager *pluginManager, const QString &initialCategory = QString(), const QString &initialPage = QString(), QWidget *parent = 0); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt index 6a49f1e41..ee46fcd3d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/CMakeLists.txt @@ -12,8 +12,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUG_EXAMPLE_HDR plugin1.h qnel_widget.h simple_viewer.h - example_settings_page.h - ${CMAKE_CURRENT_SOURCE_DIR}/../core/iapp_page.h) + example_settings_page.h) SET(OVQT_PLUG_EXAMPLE_UIS example_settings_page.ui) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp index 50c7e6eef..75ff06692 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.cpp @@ -2,7 +2,7 @@ #include "plugin1.h" #include "example_settings_page.h" #include "simple_viewer.h" -#include "../core/iapp_page.h" +#include "../core/icore.h" #include "../core/core_constants.h" #include "../core/imenu_manager.h" #include "../../extension_system/iplugin_spec.h" @@ -36,19 +36,20 @@ bool MyPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QStrin _plugMan = pluginManager; addAutoReleasedObject(new CExampleSettingsPage(this)); - addAutoReleasedObject(new CExampleAppPage(this)); + addAutoReleasedObject(new CExampleContext(this)); addAutoReleasedObject(new CCoreListener(this)); return true; } void MyPlugin::extensionsInitialized() { - Core::IMenuManager *menuManager = 0; - menuManager = _plugMan->getObject(); - if (menuManager == 0) - nlinfo("error menu manager"); + Core::ICore *core = Core::ICore::instance(); + if (core == 0) + nlinfo("This not ovqt ng"); else { + Core::IMenuManager *menuManager = core->menuManager(); + //menuManager = _plugMan->getObject(); QAction *exampleAction1 = new QAction("Example1", this); QAction *exampleAction2 = new QAction("Example2", this); QAction *aboutQtAction = menuManager->action(Core::Constants::ABOUT_QT); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h index a6374db60..081dfda89 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/plugin1.h @@ -3,8 +3,8 @@ // Project includes #include "../../extension_system/iplugin.h" +#include "../core/icontext.h" #include "simple_viewer.h" -#include "../core/iapp_page.h" // NeL includes #include "nel/misc/app_context.h" @@ -58,17 +58,16 @@ private: QList _autoReleaseObjects; }; -class CExampleAppPage: public QObject, public Core::IAppPage +class CExampleContext: public Core::IContext { Q_OBJECT - Q_INTERFACES(Core::IAppPage) public: - CExampleAppPage(QObject *parent = 0): QObject(parent) {} - virtual ~CExampleAppPage() {} + CExampleContext(QObject *parent = 0): IContext(parent) {} + virtual ~CExampleContext() {} virtual QString id() const { - return QLatin1String("ExampleAppPage"); + return QLatin1String("ExampleContext"); } virtual QString trName() const { diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp index d2db23883..7c2338de1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.cpp @@ -34,16 +34,16 @@ namespace NLQT QNLWidget::QNLWidget(QWidget *parent) : QWidget(parent), - _driver(NULL), - _initialized(false), - _interval(25) + m_driver(NULL), + m_initialized(false), + m_interval(25) { setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); init(); - _mainTimer = new QTimer(this); - connect(_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender())); + m_mainTimer = new QTimer(this); + connect(m_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender())); } QNLWidget::~QNLWidget() @@ -54,49 +54,59 @@ QNLWidget::~QNLWidget() void QNLWidget::init() { // create the driver - _driver = NL3D::UDriver::createDriver(NULL, false, NULL); - nlassert(_driver); + m_driver = NL3D::UDriver::createDriver(NULL, false, NULL); + nlassert(m_driver); // initialize the nel 3d viewport - _driver->setDisplay((nlWindow)winId(), NL3D::UDriver::CMode(width(), height(), 32)); + m_driver->setDisplay((nlWindow)winId(), NL3D::UDriver::CMode(width(), height(), 32)); // set the cache size for the font manager(in bytes) - _driver->setFontManagerMaxMemory(2097152); + m_driver->setFontManagerMaxMemory(2097152); - _initialized = true; + m_initialized = true; } void QNLWidget::release() { - _mainTimer->stop(); - delete _mainTimer; - if (_initialized) + m_mainTimer->stop(); + delete m_mainTimer; + if (m_initialized) { - _driver->release(); - delete _driver; - _driver = NULL; + m_driver->release(); + delete m_driver; + m_driver = NULL; } } void QNLWidget::setInterval(int msec) { - _interval = msec; - _mainTimer->setInterval(msec); + m_interval = msec; + m_mainTimer->setInterval(msec); } void QNLWidget::updateRender() { if (isVisible()) { - if (_initialized) - _driver->EventServer.pump(); - if (_initialized && !_driver->isLost()) - { - _driver->activate(); - _driver->clearBuffers(NLMISC::CRGBA(125,12,58)); + if (m_initialized) + m_driver->EventServer.pump(); + Q_EMIT updateData(); + // Calc FPS + static sint64 lastTime = NLMISC::CTime::getPerformanceTime (); + sint64 newTime = NLMISC::CTime::getPerformanceTime (); + m_fps = float(1.0 / NLMISC::CTime::ticksToSecond (newTime-lastTime)); + lastTime = newTime; + + if (m_initialized && !m_driver->isLost()) + { + //_driver->activate(); + m_driver->clearBuffers(NLMISC::CRGBA(125,12,58)); + Q_EMIT updatePreRender(); + + Q_EMIT updatePostRender(); // swap 3d buffers - _driver->swapBuffers(); + m_driver->swapBuffers(); } } } @@ -106,11 +116,11 @@ void QNLWidget::showEvent(QShowEvent *showEvent) QWidget::showEvent(showEvent); if (isVisible()) { - _driver->activate(); - _mainTimer->start(_interval); + m_driver->activate(); + m_mainTimer->start(m_interval); } else - _mainTimer->stop(); + m_mainTimer->stop(); } #if defined(NL_OS_WINDOWS) @@ -119,9 +129,9 @@ typedef bool (*winProc)(NL3D::IDriver *driver, HWND hWnd, UINT message, WPARAM w bool QNLWidget::winEvent(MSG *message, long *result) { - if (_driver && _driver->isActive()) + if (m_driver && m_driver->isActive()) { - NL3D::IDriver *driver = dynamic_cast(_driver)->getDriver(); + NL3D::IDriver *driver = dynamic_cast(m_driver)->getDriver(); if (driver) { winProc proc = (winProc)driver->getWindowProc(); @@ -141,9 +151,9 @@ bool QNLWidget::macEvent(EventHandlerCallRef caller, EventRef event) if(caller) nlerror("You are using QtCarbon! Only QtCocoa supported, please upgrade Qt"); - if (_driver && _driver->isActive()) + if (m_driver && m_driver->isActive()) { - NL3D::IDriver *driver = dynamic_cast(_driver)->getDriver(); + NL3D::IDriver *driver = dynamic_cast(m_driver)->getDriver(); if (driver) { cocoaProc proc = (cocoaProc)driver->getWindowProc(); @@ -160,9 +170,9 @@ typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e); bool QNLWidget::x11Event(XEvent *event) { - if (_driver && _driver->isActive()) + if (m_driver && m_driver->isActive()) { - NL3D::IDriver *driver = dynamic_cast(_driver)->getDriver(); + NL3D::IDriver *driver = dynamic_cast(m_driver)->getDriver(); if (driver) { x11Proc proc = (x11Proc)driver->getWindowProc(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h index 0473f819d..b0969c3a2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/example/qnel_widget.h @@ -54,10 +54,19 @@ public: /// Set the update interval renderer void setInterval(int msec); + float getFPS() const + { + return m_fps; + } + virtual QPaintEngine* paintEngine() const { return NULL; } +Q_SIGNALS: + void updateData(); + void updatePreRender(); + void updatePostRender(); private Q_SLOTS: void updateRender(); @@ -80,10 +89,11 @@ private: QNLWidget(const QNLWidget &); QNLWidget &operator=(const QNLWidget &); - NL3D::UDriver *_driver; - QTimer *_mainTimer; - bool _initialized; - int _interval; + NL3D::UDriver *m_driver; + QTimer *m_mainTimer; + bool m_initialized; + int m_interval; + float m_fps; }; /* class QNLWidget */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt index d1caa1ead..555eac232 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/CMakeLists.txt @@ -9,8 +9,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) SET(OVQT_PLUG_LOG_HDR log_plugin.h - log_settings_page.h - ${CMAKE_CURRENT_SOURCE_DIR}/../core/iapp_page.h) + log_settings_page.h) SET(OVQT_PLUG_LOG_UIS log_form.ui log_settings_page.ui) diff --git a/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_de.qm b/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_de.qm deleted file mode 100644 index 9dad8dffceb9623e88f8b96d9cd0caf25574c6fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmcE7ks@*G{hX<16=n7(EZlpygMop8iIEWihQJ9+ diff --git a/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_en.qm b/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_en.qm deleted file mode 100644 index 9dad8dffceb9623e88f8b96d9cd0caf25574c6fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmcE7ks@*G{hX<16=n7(EZlpygMop8iIEWihQJ9+ diff --git a/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_fr.qm b/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_fr.qm deleted file mode 100644 index c02994cafb69a42d7f77c4004edd5eae08bb0f3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23 fcmcE7ks@*G{hX<16=n7(EZlpygMop8iJ1`qhQtX? diff --git a/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_ru.qm b/code/nel/tools/3d/object_viewer_qt/src/translations/object_viewer_qt_ru.qm deleted file mode 100644 index ae1f9a911bdea237f15d292db12348dfa68b9a7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40561 zcmeHwdwg6~wf|0XW-^&f9&OV$w4t1q(xx>{)AW^wG$oxheI)5Cp`}s4Npg}5oy>%p zNt0B$Ac7)RK=dN`z!xA-#RtgK2LcK|@p`#l_{s05{8admr+^@+uG-+bq1AN+|FCBw{LP=`&Vuk zUd63i%ZR25XSHH+@>mqKq-O26tCT@3j>n-pnymrO7?ZJHMeb2ev_P)aH zzAL#sv`_e&x`kNzobatr3(@Q6cK6xBx8a>a6t!`?;%&mWW4#cYb_ib&=+`w%_zrBt z{I3+gVXRTjCxkDFb?NF7z7K-VXUr46Yq2)H9o+8u2Dk73zVLn4C&bCk+@5z-_-+Od zl?@BuZ8Y9J!uK%xcU&xdk3A&B+@EuM@^83ZvP7(;_1eEmto-3=Xh*n>-zQeS)P(n+ z;5Pn>c-y~$5BfgM?Zmsp_Gi(r|Et`lip7qpO<31jv1qCYwYK6^#nwD~VagpeM^EL40i{ilL|1Ct@xHx#< zdoli#;;hFW7NX&Kap+p$TT#L7u61Idn)-i&+unC`d+~3@z~Qff9;?JatW${1=ZFE~ z*G>5TTj;;}d2R=Gh=G?r3x52TIQvgG3$f^QZV#U?&WQrwMU&#ZlRk&_cv+nH;P

g`8g&6+e062_dcsiZ?F50_*tc zqN)|`Sg*rHRUNkq@vg5F?OIqP#OkV|$kqKqoVtYDqt_N`10NM)%~?gU##YGFg+=KD zpo9OOqAMOL65{ed6n$#ZHq7_OMR)uT<4pam=)TK=*MT&*Gv^k)@%#%y>{(N+oKgZj zMRDcnb3n&RZVyctul^#&Yki}*`8(jVdAAi0Klii{=av>viZe0KJBu&6=IcV7`KjXT z8vh_f^5WvpU59yA{-F5tpI#uu-qVY}a1GXB-;3PFr;G1cFobmva(h;=_})(fzr;6+ z?;lx!Y3SoOP- z2k*tYZMn1L+5dV@2<0&)BnF`$zpX5I@_ZrQU7@_Q59@#CE^a69R)&9$al0m!RL6th zmrruLYFL^1#2=L(h3BUhDKozU{Xck2x$yGqh0vZ=u4qaN@xBq|nuoy;dw;52 z7e^a>f!ifla=Yz4-0r-T+p|8dTz|=bV!fYJZg02|`s4|2-yh`m%0DQ#9|gTv-^uMo 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 Wfm14G6}`El{I4~|%9{