diff --git a/.hgignore b/.hgignore index 530c92512..5587652fd 100644 --- a/.hgignore +++ b/.hgignore @@ -43,7 +43,7 @@ default_c *.so *.so.* *_debug -core +core.* *.pc *.gch diff --git a/code/studio/src/plugins/core/CMakeLists.txt b/code/studio/src/plugins/core/CMakeLists.txt new file mode 100644 index 000000000..5a20ba46c --- /dev/null +++ b/code/studio/src/plugins/core/CMakeLists.txt @@ -0,0 +1,73 @@ +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${QT_INCLUDES}) + +FILE(GLOB SRC *.cpp *.h) +SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h) + +SET(OVQT_CORE_PLUGIN_HDR + icore.h + icontext.h + icore_listener.h + ioptions_page.h + core_plugin.h + core.h + main_window.h + menu_manager.h + context_manager.h + settings_dialog.h + search_paths_settings_page.h + general_settings_page.h + plugin_view_dialog.h +) + +SET(OVQT_CORE_PLUGIN_UIS settings_dialog.ui + plugin_view_dialog.ui + general_settings_page.ui + search_paths_settings_page.ui +) + +SET(OVQT_CORE_PLUGIN_RCS core.qrc) + +SET(QT_USE_QTGUI TRUE) +SET(QT_USE_QTOPENGL TRUE) + +QT4_ADD_RESOURCES(OVQT_CORE_PLUGIN_RC_SRCS ${OVQT_CORE_PLUGIN_RCS}) +QT4_WRAP_CPP(OVQT_CORE_PLUGIN_MOC_SRC ${OVQT_CORE_PLUGIN_HDR}) +QT4_WRAP_UI(OVQT_CORE_PLUGIN_UI_HDRS ${OVQT_CORE_PLUGIN_UIS}) + +SOURCE_GROUP(QtResources FILES ${OVQT_CORE_PLUGIN_UIS} ${OVQT_CORE_PLUGIN_RCS}) +SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_CORE_PLUGIN_UI_HDRS}) +SOURCE_GROUP(QtGeneratedMocSrc FILES ${OVQT_CORE_PLUGIN_MOC_SRC}) +SOURCE_GROUP("Core Plugin" FILES ${SRC}) +SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) + +ADD_LIBRARY(ovqt_plugin_core SHARED ${SRC} ${OVQT_CORE_PLUGIN_MOC_SRC} ${OVQT_EXT_SYS_SRC} ${OVQT_CORE_PLUGIN_RC_SRCS} ${OVQT_CORE_PLUGIN_UI_HDRS}) + +TARGET_LINK_LIBRARIES(ovqt_plugin_core nelmisc ${QT_LIBRARIES}) + +NL_DEFAULT_PROPS(ovqt_plugin_core "NeL, Tools, 3D: Object Viewer Qt Plugin: Core") +NL_ADD_RUNTIME_FLAGS(ovqt_plugin_core) +NL_ADD_LIB_SUFFIX(ovqt_plugin_core) + +ADD_DEFINITIONS(-DCORE_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) + +IF(WIN32) + IF(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) + ELSE(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) + ENDIF(WITH_INSTALL_LIBRARIES) +ELSE(WIN32) + IF(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) + ELSE(WITH_INSTALL_LIBRARIES) + INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) + ENDIF(WITH_INSTALL_LIBRARIES) +ENDIF(WIN32) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_core.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) + diff --git a/code/studio/src/plugins/core/context_manager.cpp b/code/studio/src/plugins/core/context_manager.cpp new file mode 100644 index 000000000..8355b5cb8 --- /dev/null +++ b/code/studio/src/plugins/core/context_manager.cpp @@ -0,0 +1,167 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "context_manager.h" +#include "icontext.h" +#include "main_window.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace Core +{ + +struct ContextManagerPrivate +{ + explicit ContextManagerPrivate(Core::MainWindow *mainWindow, QTabWidget *tabWidget); + Core::MainWindow *m_mainWindow; + QTabWidget *m_tabWidget; + QVector m_contexts; + int m_oldCurrent; +}; + +ContextManagerPrivate::ContextManagerPrivate(Core::MainWindow *mainWindow, QTabWidget *tabWidget) + : m_mainWindow(mainWindow), + m_tabWidget(tabWidget), + m_oldCurrent(-1) +{ +} + +ContextManager::ContextManager(Core::MainWindow *mainWindow, QTabWidget *tabWidget) + : d(new ContextManagerPrivate(mainWindow, tabWidget)) +{ + QObject::connect(d->m_mainWindow->pluginManager(), SIGNAL(objectAdded(QObject *)), + this, SLOT(objectAdded(QObject *))); + QObject::connect(d->m_mainWindow->pluginManager(), SIGNAL(aboutToRemoveObject(QObject *)), + this, SLOT(aboutToRemoveObject(QObject *))); + + QObject::connect(d->m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); +} + +ContextManager::~ContextManager() +{ + delete d; +} + +Core::IContext *ContextManager::currentContext() const +{ + int currentIndex = d->m_tabWidget->currentIndex(); + if (currentIndex < 0) + return 0; + return d->m_contexts.at(currentIndex); +} + +Core::IContext *ContextManager::context(const QString &id) const +{ + const int index = indexOf(id); + if (index >= 0) + return d->m_contexts.at(index); + return 0; +} + +void ContextManager::registerUndoStack(QUndoStack *stack) +{ + nlassert(stack); + d->m_mainWindow->undoGroup()->addStack(stack); +} + +void ContextManager::unregisterUndoStack(QUndoStack *stack) +{ + nlassert(stack); + d->m_mainWindow->undoGroup()->removeStack(stack); +} + +void ContextManager::activateContext(const QString &id) +{ + const int index = indexOf(id); + if (index >= 0) + d->m_tabWidget->setCurrentIndex(index); +} + +void ContextManager::updateCurrentContext() +{ + d->m_mainWindow->updateContext(currentContext()); +} + +void ContextManager::objectAdded(QObject *obj) +{ + IContext *context = qobject_cast(obj); + if (context) + addContextObject(context); +} + +void ContextManager::aboutToRemoveObject(QObject *obj) +{ + IContext *context = qobject_cast(obj); + if (context) + removeContextObject(context); +} + +void ContextManager::addContextObject(IContext *context) +{ + d->m_contexts.push_back(context); + d->m_mainWindow->addContextObject(context); + + QWidget *tabWidget = new QWidget(d->m_tabWidget); + d->m_tabWidget->addTab(tabWidget, context->icon(), context->trName()); + QGridLayout *gridLayout = new QGridLayout(tabWidget); + gridLayout->setObjectName(QString::fromUtf8("gridLayout_") + context->id()); + gridLayout->setContentsMargins(0, 0, 0, 0); + gridLayout->addWidget(context->widget(), 0, 0, 1, 1); +} + +void ContextManager::removeContextObject(IContext *context) +{ + d->m_mainWindow->removeContextObject(context); + + const int index = indexOf(context->id()); + QWidget *widget = d->m_tabWidget->widget(index); + d->m_tabWidget->removeTab(index); + d->m_contexts.remove(index); + delete widget; +} + +void ContextManager::currentTabChanged(int index) +{ + if (index >= 0) + { + IContext *context = d->m_contexts.at(index); + IContext *oldContext = 0; + if (d->m_oldCurrent >= 0) + oldContext = d->m_contexts.at(d->m_oldCurrent); + d->m_oldCurrent = index; + Q_EMIT currentContextChanged(context, oldContext); + } +} + +int ContextManager::indexOf(const QString &id) const +{ + for (int i = 0; i < d->m_contexts.count(); ++i) + { + if (d->m_contexts.at(i)->id() == id) + return i; + } + nlwarning(QString("Warning, no such context: %1").arg(id).toUtf8().constData()); + return -1; +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/context_manager.h b/code/studio/src/plugins/core/context_manager.h new file mode 100644 index 000000000..8151648e7 --- /dev/null +++ b/code/studio/src/plugins/core/context_manager.h @@ -0,0 +1,76 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 CONTEXT_MANAGER_H +#define CONTEXT_MANAGER_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include + +QT_BEGIN_NAMESPACE +class QTabWidget; +class QUndoStack; +QT_END_NAMESPACE + +namespace Core +{ +class IContext; +class MainWindow; +struct ContextManagerPrivate; + +class CORE_EXPORT ContextManager : public QObject +{ + Q_OBJECT + +public: + explicit ContextManager(Core::MainWindow *mainWindow, QTabWidget *tabWidget); + virtual ~ContextManager(); + + Core::IContext *currentContext() const; + Core::IContext *context(const QString &id) const; + + // temporary solution for multiple undo stacks per context + void registerUndoStack(QUndoStack *stack); + void unregisterUndoStack(QUndoStack *stack); + +Q_SIGNALS: + // the default argument '=0' is important for connects without the oldContext argument. + void currentContextChanged(Core::IContext *context, Core::IContext *oldContext = 0); + +public Q_SLOTS: + void activateContext(const QString &id); + void updateCurrentContext(); + +private Q_SLOTS: + void objectAdded(QObject *obj); + void aboutToRemoveObject(QObject *obj); + void addContextObject(IContext *context); + void removeContextObject(IContext *context); + void currentTabChanged(int index); + +private: + int indexOf(const QString &id) const; + + ContextManagerPrivate *d; +}; + +} // namespace Core + +#endif // CONTEXT_MANAGER_H diff --git a/code/studio/src/plugins/core/core_constants.h b/code/studio/src/plugins/core/core_constants.h new file mode 100644 index 000000000..8bf6d5fcd --- /dev/null +++ b/code/studio/src/plugins/core/core_constants.h @@ -0,0 +1,121 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2010 Dzmitry Kamiahin +// +// 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_CONSTANTS_H +#define CORE_CONSTANTS_H + +namespace Core +{ +namespace Constants +{ + +const char *const OVQT_VERSION_LONG = "0.8"; +const char *const OVQT_VENDOR = "Ryzom Core"; +const char *const OVQT_YEAR = "2010, 2011"; +const char *const OVQT_CORE_PLUGIN = "Core"; + +//mainwindow +const char *const MAIN_WINDOW = "ObjectViewerQt.MainWindow"; + +//menubar +const char *const MENU_BAR = "ObjectViewerQt.MenuBar"; + +//menus +const char *const M_FILE = "ObjectViewerQt.Menu.File"; +const char *const M_EDIT = "ObjectViewerQt.Menu.Edit"; +const char *const M_VIEW = "ObjectViewerQt.Menu.View"; +const char *const M_SCENE = "ObjectViewerQt.Menu.Scene"; +const char *const M_TOOLS = "ObjectViewerQt.Menu.Tools"; +const char *const M_WINDOW = "ObjectViewerQt.Menu.Window"; +const char *const M_HELP = "ObjectViewerQt.Menu.Help"; + +const char *const M_FILE_RECENTFILES = "ObjectViewerQt.Menu.File.RecentFiles"; +const char *const M_SHEET = "ObjectViewerQt.Menu.Sheet"; + +//actions +const char *const NEW = "ObjectViewerQt.New"; +const char *const OPEN = "ObjectViewerQt.Open"; +const char *const SAVE = "ObjectViewerQt.Save"; +const char *const SAVE_AS = "ObjectViewerQt.SaveAs"; +const char *const SAVE_ALL = "ObjectViewerQt.SaveAll"; +const char *const EXIT = "ObjectViewerQt.Exit"; + +const char *const UNDO = "ObjectViewerQt.Undo"; +const char *const REDO = "ObjectViewerQt.Redo"; +const char *const CUT = "ObjectViewerQt.Cut"; +const char *const COPY = "ObjectViewerQt.Copy"; +const char *const PASTE = "ObjectViewerQt.Paste"; +const char *const DEL = "ObjectViewerQt.Del"; +const char *const FIND = "ObjectViewerQt.Find"; +const char *const SELECT_ALL = "ObjectViewerQt.SelectAll"; +const char *const GOTO_POS = "ObjectViewerQt.Goto"; + +const char *const SETTINGS = "ObjectViewerQt.Settings"; +const char *const TOGGLE_FULLSCREEN = "ObjectViewerQt.ToggleFullScreen"; + +const char *const CLOSE = "ObjectViewerQt.Close"; +const char *const CLOSEALL = "ObjectViewerQt.CloseAll"; +const char *const CLOSEOTHERS = "ObjectViewerQt.CloseOthers"; +const char *const ABOUT = "ObjectViewerQt.About"; +const char *const ABOUT_PLUGINS = "ObjectViewerQt.AboutPlugins"; +const char *const ABOUT_QT = "ObjectViewerQt.AboutQt"; + +//settings +const char *const SETTINGS_CATEGORY_GENERAL = "general"; +const char *const SETTINGS_CATEGORY_GENERAL_ICON = ":/icons/ic_nel_generic_settings.png"; +const char *const SETTINGS_TR_CATEGORY_GENERAL = QT_TR_NOOP("General"); + +const char *const MAIN_WINDOW_SECTION = "MainWindow"; +const char *const MAIN_WINDOW_STATE = "WindowState"; +const char *const MAIN_WINDOW_GEOMETRY = "WindowGeometry"; +const char *const QT_STYLE = "QtStyle"; +const char *const QT_PALETTE = "QtPalette"; + +const char *const LANGUAGE = "Language"; +const char *const PLUGINS_PATH = "PluginPath"; +const char *const DATA_PATH_SECTION = "DataPath"; +const char *const SEARCH_PATHS = "SearchPaths"; +const char *const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes"; +const char *const LEVELDESIGN_PATH = "LevelDesignPath"; +const char *const PRIMITIVES_PATH = "PrimitivesPath"; +const char *const ASSETS_PATH = "AssetsPath"; +const char *const LIGOCONFIG_FILE = "LigoConfigFile"; +const char *const REMAP_EXTENSIONS = "RemapExtensions"; + +const char *const LOG_SECTION = "LogSettings"; +const char *const LOG_ERROR = "LogError"; +const char *const LOG_WARNING = "LogWarning"; +const char *const LOG_DEBUG = "LogDebug"; +const char *const LOG_ASSERT = "LogAssert"; +const char *const LOG_INFO = "LogInfo"; + +//resources +const char *const ICON_NEL = ":/core/images/nel.png"; +const char *const ICON_SETTINGS = ":/core/images/preferences.png"; +const char *const ICON_PILL = ":/core/icons/ic_nel_pill.png"; +const char *const ICON_OPEN = ":/core/icons/ic_nel_open.png"; +const char *const ICON_NEW = ":/core/icons/ic_nel_new.png"; +const char *const ICON_SAVE = ":/core/icons/ic_nel_save.png"; +const char *const ICON_SAVE_AS = ":/core/icons/ic_nel_save_as.png"; +const char *const ICON_CRASH = ":/core/icons/ic_nel_crash.png"; +const char *const ICON_UNDO = ":/core/icons/ic_nel_undo.png"; +const char *const ICON_REDO = ":/core/icons/ic_nel_redo.png"; + +} // namespace Constants +} // namespace Core + +#endif // CORE_CONSTANTS_H diff --git a/code/studio/src/plugins/core/core_global.h b/code/studio/src/plugins/core/core_global.h new file mode 100644 index 000000000..48fe0ece9 --- /dev/null +++ b/code/studio/src/plugins/core/core_global.h @@ -0,0 +1,30 @@ +// 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_GLOBAL_H +#define CORE_GLOBAL_H + +#include + +#if defined(CORE_LIBRARY) +# define CORE_EXPORT Q_DECL_EXPORT +#else +# define CORE_EXPORT Q_DECL_IMPORT +#endif + +#endif // CORE_GLOBAL_H diff --git a/code/studio/src/plugins/core/core_plugin.cpp b/code/studio/src/plugins/core/core_plugin.cpp new file mode 100644 index 000000000..a72a68ccc --- /dev/null +++ b/code/studio/src/plugins/core/core_plugin.cpp @@ -0,0 +1,104 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2010 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "core_plugin.h" +#include "settings_dialog.h" +#include "core_constants.h" +#include "search_paths_settings_page.h" +#include "general_settings_page.h" +#include "../../extension_system/iplugin_spec.h" + +// NeL includes +#include "nel/misc/debug.h" + +// Qt includes +#include +#include +#include +#include +#include +#include + +using namespace Core; + +CorePlugin::CorePlugin() + : m_plugMan(0), + m_mainWindow(0) +{ +} + +CorePlugin::~CorePlugin() +{ + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); + + if (m_mainWindow) + delete m_mainWindow; +} + +bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + m_mainWindow = new MainWindow(pluginManager); + bool success = m_mainWindow->initialize(errorString); + + GeneralSettingsPage *generalSettings = new GeneralSettingsPage(this); + SearchPathsSettingsPage *searchPathPage = new SearchPathsSettingsPage(false, this); + SearchPathsSettingsPage *recureseSearchPathPage = new SearchPathsSettingsPage(true, this); + + generalSettings->applyGeneralSettings(); + searchPathPage->applySearchPaths(); + recureseSearchPathPage->applySearchPaths(); + addAutoReleasedObject(generalSettings); + addAutoReleasedObject(searchPathPage); + addAutoReleasedObject(recureseSearchPathPage); + return success; +} + +void CorePlugin::extensionsInitialized() +{ + m_mainWindow->extensionsInitialized(); +} + +void CorePlugin::shutdown() +{ +} + +void CorePlugin::setNelContext(NLMISC::INelContext *nelContext) +{ +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // NL_OS_WINDOWS + m_libContext = new NLMISC::CLibraryContext(*nelContext); +} + +void CorePlugin::addAutoReleasedObject(QObject *obj) +{ + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); +} + +Q_EXPORT_PLUGIN(CorePlugin) diff --git a/code/studio/src/plugins/core/core_plugin.h b/code/studio/src/plugins/core/core_plugin.h new file mode 100644 index 000000000..5062227e3 --- /dev/null +++ b/code/studio/src/plugins/core/core_plugin.h @@ -0,0 +1,74 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2010 Dzmitry Kamiahin +// +// 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_PLUGIN_H +#define CORE_PLUGIN_H + +#include "../../extension_system/iplugin.h" +#include "main_window.h" + +#include "nel/misc/app_context.h" + +#include + +namespace NLMISC +{ +class CLibraryContext; +} + +namespace ExtensionSystem +{ +class IPluginSpec; +} + +namespace Core +{ + +class CorePlugin : public QObject, public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_INTERFACES(ExtensionSystem::IPlugin) +public: + + CorePlugin(); + virtual ~CorePlugin(); + + bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); + void extensionsInitialized(); + void shutdown(); + + void setNelContext(NLMISC::INelContext *nelContext); + + void addAutoReleasedObject(QObject *obj); + + ExtensionSystem::IPluginManager *pluginManager() const + { + return m_plugMan; + } + +protected: + NLMISC::CLibraryContext *m_libContext; + +private: + ExtensionSystem::IPluginManager *m_plugMan; + MainWindow *m_mainWindow; + QList m_autoReleaseObjects; +}; + +} // namespace Core + +#endif // CORE_PLUGIN_H diff --git a/code/studio/src/plugins/core/general_settings_page.cpp b/code/studio/src/plugins/core/general_settings_page.cpp new file mode 100644 index 000000000..bfbb06d66 --- /dev/null +++ b/code/studio/src/plugins/core/general_settings_page.cpp @@ -0,0 +1,241 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "general_settings_page.h" +#include "core_constants.h" +#include "icore.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +namespace Core +{ + +GeneralSettingsPage::GeneralSettingsPage(QObject *parent) + : IOptionsPage(parent), + m_page(0) +{ + m_originalPalette = QApplication::palette(); +} + +GeneralSettingsPage::~GeneralSettingsPage() +{ +} + +QString GeneralSettingsPage::id() const +{ + return QLatin1String("general_settings"); +} + +QString GeneralSettingsPage::trName() const +{ + return tr("General"); +} + +QString GeneralSettingsPage::category() const +{ + return QLatin1String(Constants::SETTINGS_CATEGORY_GENERAL); +} + +QString GeneralSettingsPage::trCategory() const +{ + return tr(Constants::SETTINGS_TR_CATEGORY_GENERAL); +} + +QIcon GeneralSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +void GeneralSettingsPage::applyGeneralSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + QApplication::setStyle(QStyleFactory::create(settings->value(Constants::QT_STYLE, "").toString())); + + if (settings->value(Constants::QT_PALETTE, true).toBool()) + QApplication::setPalette(QApplication::style()->standardPalette()); + else + QApplication::setPalette(m_originalPalette); + settings->endGroup(); + + QString levelDesignPrefix; +#if defined(_DEBUG) && defined(NL_OS_WINDOWS) + levelDesignPrefix = "l:"; +#else + levelDesignPrefix = QString("%1/data_leveldesign").arg(RYZOM_SHARE_PREFIX); +#endif + + // Add primitives path and ligo config file to CPath + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + QString primitivePath = settings->value(Core::Constants::PRIMITIVES_PATH, QString("%1/primitives").arg(levelDesignPrefix)).toString(); + QString ligoConfigFile = settings->value(Core::Constants::LIGOCONFIG_FILE, QString("%1/leveldesign/world_editor_files/world_editor_classes.xml").arg(levelDesignPrefix)).toString(); + QString leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, QString("%1/leveldesign").arg(levelDesignPrefix)).toString(); + NLMISC::CPath::addSearchPath(primitivePath.toUtf8().constData(), true, false); + NLMISC::CPath::display(); + NLMISC::CPath::addSearchFile(ligoConfigFile.toUtf8().constData()); + NLMISC::CPath::addSearchPath(leveldesignPath.toUtf8().constData(), true, false); + settings->endGroup(); +} + +QWidget *GeneralSettingsPage::createPage(QWidget *parent) +{ + m_page = new QWidget(parent); + m_ui.setupUi(m_page); + + readSettings(); + connect(m_ui.languageComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeLanguage(QString))); + connect(m_ui.pluginsPathButton, SIGNAL(clicked()), this, SLOT(setPluginsPath())); + connect(m_ui.leveldesignPathButton, SIGNAL(clicked()), this, SLOT(setLevelDesignPath())); + connect(m_ui.assetsPathButton, SIGNAL(clicked()), this, SLOT(setAssetsPath())); + connect(m_ui.primitivesPathButton, SIGNAL(clicked()), this, SLOT(setPrimitivesPath())); + connect(m_ui.ligoConfigFileButton, SIGNAL(clicked()), this, SLOT(setLigoConfigFile())); + return m_page; +} + +void GeneralSettingsPage::apply() +{ + writeSettings(); + applyGeneralSettings(); +} + +void GeneralSettingsPage::finish() +{ + delete m_page; + m_page = 0; +} + +void GeneralSettingsPage::changeLanguage(const QString &lang) +{ + QMessageBox::information(0, tr("Restart required"), + tr("The language change will take effect after a restart of Object Viewer Qt.")); +} + +void GeneralSettingsPage::setPluginsPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the plugins path"), + m_ui.pluginsPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.pluginsPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setLevelDesignPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the level design path"), + m_ui.leveldesignPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.leveldesignPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setPrimitivesPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the primitives path"), + m_ui.primitivesPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.primitivesPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::setLigoConfigFile() +{ + QString newFile = QFileDialog::getOpenFileName(0, tr("Set the ligo config file"), + m_ui.ligoConfigFileLineEdit->text()); + if (!newFile.isEmpty()) + { + m_ui.ligoConfigFileLineEdit->setText(newFile); + } +} + + +void GeneralSettingsPage::setAssetsPath() +{ + QString newPath = QFileDialog::getExistingDirectory(0, tr("Set the assets path"), + m_ui.assetsPathLineEdit->text()); + if (!newPath.isEmpty()) + { + m_ui.assetsPathLineEdit->setText(newPath); + } +} + +void GeneralSettingsPage::readSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + m_ui.pluginsPathLineEdit->setText(settings->value(Core::Constants::PLUGINS_PATH, "./plugins").toString()); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + m_ui.styleComboBox->addItems(QStyleFactory::keys()); + QString style = settings->value(Constants::QT_STYLE, "").toString(); + if (style == "") + m_ui.styleComboBox->setCurrentIndex(0); + else + m_ui.styleComboBox->setCurrentIndex(m_ui.styleComboBox->findText(style)); + m_ui.paletteCheckBox->setChecked(settings->value(Constants::QT_PALETTE, true).toBool()); + settings->endGroup(); + + QStringList paths; + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + m_ui.leveldesignPathLineEdit->setText(settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString()); + m_ui.assetsPathLineEdit->setText(settings->value(Core::Constants::ASSETS_PATH, "w:/database").toString()); + m_ui.primitivesPathLineEdit->setText(settings->value(Core::Constants::PRIMITIVES_PATH, "l:/primitives").toString()); + m_ui.ligoConfigFileLineEdit->setText(settings->value(Core::Constants::LIGOCONFIG_FILE, "l:/leveldesign/world_editor_files/world_editor_classes.xml").toString()); + settings->endGroup(); +} + +void GeneralSettingsPage::writeSettings() +{ + QSettings *settings = Core::ICore::instance()->settings(); + + settings->setValue(Core::Constants::PLUGINS_PATH, m_ui.pluginsPathLineEdit->text()); + + settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + if (m_ui.styleComboBox->currentIndex() == 0) + settings->setValue(Constants::QT_STYLE, ""); + else + settings->setValue(Constants::QT_STYLE, m_ui.styleComboBox->currentText()); + settings->setValue(Constants::QT_PALETTE, m_ui.paletteCheckBox->isChecked()); + settings->endGroup(); + + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + settings->setValue(Core::Constants::LEVELDESIGN_PATH, m_ui.leveldesignPathLineEdit->text()); + settings->setValue(Core::Constants::ASSETS_PATH, m_ui.assetsPathLineEdit->text()); + settings->setValue(Core::Constants::PRIMITIVES_PATH, m_ui.primitivesPathLineEdit->text()); + settings->setValue(Core::Constants::LIGOCONFIG_FILE, m_ui.ligoConfigFileLineEdit->text()); + settings->endGroup(); + settings->sync(); +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/general_settings_page.h b/code/studio/src/plugins/core/general_settings_page.h new file mode 100644 index 000000000..66eacd189 --- /dev/null +++ b/code/studio/src/plugins/core/general_settings_page.h @@ -0,0 +1,74 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 GENERAL_SETTINGS_PAGE_H +#define GENERAL_SETTINGS_PAGE_H + +#include + +#include "ioptions_page.h" + +#include "ui_general_settings_page.h" + +class QWidget; + +namespace Core +{ +/** +@class GeneralSettingsPage +*/ +class GeneralSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + explicit GeneralSettingsPage(QObject *parent = 0); + ~GeneralSettingsPage(); + + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + QIcon categoryIcon() const; + QWidget *createPage(QWidget *parent); + + void apply(); + void finish(); + + void applyGeneralSettings(); + +private Q_SLOTS: + void changeLanguage(const QString &lang); + void setPluginsPath(); + void setLevelDesignPath(); + void setAssetsPath(); + void setPrimitivesPath(); + void setLigoConfigFile(); + +private: + void readSettings(); + void writeSettings(); + + QPalette m_originalPalette; + QWidget *m_page; + Ui::GeneralSettingsPage m_ui; +}; + +} // namespace Core + +#endif // GENERAL_SETTINGS_H diff --git a/code/studio/src/plugins/core/general_settings_page.ui b/code/studio/src/plugins/core/general_settings_page.ui new file mode 100644 index 000000000..7d40b65df --- /dev/null +++ b/code/studio/src/plugins/core/general_settings_page.ui @@ -0,0 +1,233 @@ + + + GeneralSettingsPage + + + + 0 + 0 + 267 + 282 + + + + Form + + + + 6 + + + 3 + + + + + Qt Style + + + + 6 + + + 6 + + + + + + default + + + + + + + + Use style's standard palette + + + + + + + + + + Language + + + + 6 + + + + + false + + + + English + + + + + German + + + + + French + + + + + Russian + + + + + + + + + + + Paths + + + + 6 + + + 6 + + + + + Plugins + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + Sheets + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + Assets Database: + + + + + + + + 0 + 0 + + + + + + + + ... + + + + + + + Primitives + + + + + + + + + + ... + + + + + + + + + + Ligo Config File + + + + + + + ... + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/code/studio/src/plugins/core/icons/ic_nel_add_item.png b/code/studio/src/plugins/core/icons/ic_nel_add_item.png new file mode 100644 index 000000000..bde338f78 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_add_item.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_crash.png b/code/studio/src/plugins/core/icons/ic_nel_crash.png new file mode 100644 index 000000000..5e1f6380b Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_crash.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_delete_item.png b/code/studio/src/plugins/core/icons/ic_nel_delete_item.png new file mode 100644 index 000000000..a5a1787d5 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_delete_item.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_down_item.png b/code/studio/src/plugins/core/icons/ic_nel_down_item.png new file mode 100644 index 000000000..fc86c4f6d Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_down_item.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_generic_settings.png b/code/studio/src/plugins/core/icons/ic_nel_generic_settings.png new file mode 100644 index 000000000..799bacb28 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_generic_settings.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_new.png b/code/studio/src/plugins/core/icons/ic_nel_new.png new file mode 100644 index 000000000..159e3e18e Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_new.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_open.png b/code/studio/src/plugins/core/icons/ic_nel_open.png new file mode 100644 index 000000000..c4992affd Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_open.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_path_settings.png b/code/studio/src/plugins/core/icons/ic_nel_path_settings.png new file mode 100644 index 000000000..8f3441112 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_path_settings.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_pill.png b/code/studio/src/plugins/core/icons/ic_nel_pill.png new file mode 100644 index 000000000..e748b8190 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_pill.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_redo.png b/code/studio/src/plugins/core/icons/ic_nel_redo.png new file mode 100644 index 000000000..19ccf20f1 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_redo.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_reset_all.png b/code/studio/src/plugins/core/icons/ic_nel_reset_all.png new file mode 100644 index 000000000..aea193c70 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_reset_all.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_save.png b/code/studio/src/plugins/core/icons/ic_nel_save.png new file mode 100644 index 000000000..5aeb3bbe9 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_save.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_save_as.png b/code/studio/src/plugins/core/icons/ic_nel_save_as.png new file mode 100644 index 000000000..6cb71a334 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_save_as.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_undo.png b/code/studio/src/plugins/core/icons/ic_nel_undo.png new file mode 100644 index 000000000..d605e4602 Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_undo.png differ diff --git a/code/studio/src/plugins/core/icons/ic_nel_up_item.png b/code/studio/src/plugins/core/icons/ic_nel_up_item.png new file mode 100644 index 000000000..ee471023e Binary files /dev/null and b/code/studio/src/plugins/core/icons/ic_nel_up_item.png differ diff --git a/code/studio/src/plugins/core/icontext.h b/code/studio/src/plugins/core/icontext.h new file mode 100644 index 000000000..d2cbb412c --- /dev/null +++ b/code/studio/src/plugins/core/icontext.h @@ -0,0 +1,76 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 ICONTEXT_H +#define ICONTEXT_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QWidget; +class QUndoStack; +QT_END_NAMESPACE + +namespace Core +{ +/** +@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 CORE_EXPORT IContext: public QObject +{ + Q_OBJECT +public: + IContext(QObject *parent = 0): QObject(parent) {} + virtual ~IContext() {} + + /// id() is a unique identifier for referencing this page + virtual QString id() const = 0; + + /// trName() is the (translated) name for display. + virtual QString trName() const = 0; + + /// icon() is the icon for display + virtual QIcon icon() const = 0; + + /// The widget will be destroyed by the widget hierarchy when the main window closes + virtual QWidget *widget() = 0; + + virtual QUndoStack *undoStack() = 0; + + virtual void open() = 0; + + virtual void save(){} + + virtual void saveAs(){} + + virtual void newDocument(){} + + virtual void close(){} +}; + +} // namespace Core + +#endif // ICONTEXT_H diff --git a/code/studio/src/plugins/core/icore.h b/code/studio/src/plugins/core/icore.h new file mode 100644 index 000000000..4f1ee474f --- /dev/null +++ b/code/studio/src/plugins/core/icore.h @@ -0,0 +1,70 @@ +// 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 ExtensionSystem +{ +class IPluginManager; +} + +namespace Core +{ +class MenuManager; +class ContextManager; + +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 MenuManager *menuManager() const = 0; + virtual ContextManager *contextManager() const = 0; + + virtual QSettings *settings() const = 0; + virtual QMainWindow *mainWindow() const = 0; + + virtual ExtensionSystem::IPluginManager *pluginManager() const = 0; + +Q_SIGNALS: + void changeSettings(); + void closeMainWindow(); +}; + +} // namespace Core + +#endif // ICORE_H diff --git a/code/studio/src/plugins/core/icore_listener.h b/code/studio/src/plugins/core/icore_listener.h new file mode 100644 index 000000000..c27e40242 --- /dev/null +++ b/code/studio/src/plugins/core/icore_listener.h @@ -0,0 +1,63 @@ +// 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_LISTENER_H +#define ICORE_LISTENER_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +namespace Core +{ +/** +@interface ICoreListener +@brief The ICoreListener is an interface for providing a hook for plugins to veto on close event emitted from +the core plugin. +@details You implement this interface if you want to prevent the closing of the whole application. +If the application window requests a close, then first ICoreListener::closeMainWindow() is called +(in arbitrary order) on all registered objects implementing this interface. +If one if these calls returns false, the process is aborted and the event is ignored. If all calls return +true, the corresponding signal is emitted and the event is accepted/performed. + +You need to add your implementing object to the plugin managers objects: +PluginManager->addObject(yourImplementingObject); +Don't forget to remove the object again at deconstruction (e.g. in the destructor of +your plugin) +*/ +class CORE_EXPORT ICoreListener: public QObject +{ + Q_OBJECT +public: + ICoreListener(QObject *parent = 0): QObject(parent) {} + virtual ~ICoreListener() {} + + /// Return false from the implemented method if you want to prevent the event. + virtual bool closeMainWindow() const = 0; +}; + +} // namespace Core + + +#endif // ICORE_LISTENER_H diff --git a/code/studio/src/plugins/core/images/nel.png b/code/studio/src/plugins/core/images/nel.png new file mode 100644 index 000000000..d2139bb25 Binary files /dev/null and b/code/studio/src/plugins/core/images/nel.png differ diff --git a/code/studio/src/plugins/core/images/preferences.png b/code/studio/src/plugins/core/images/preferences.png new file mode 100644 index 000000000..729bc0393 Binary files /dev/null and b/code/studio/src/plugins/core/images/preferences.png differ diff --git a/code/studio/src/plugins/core/ioptions_page.h b/code/studio/src/plugins/core/ioptions_page.h new file mode 100644 index 000000000..4d9ed6fda --- /dev/null +++ b/code/studio/src/plugins/core/ioptions_page.h @@ -0,0 +1,75 @@ +// 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 IOPTIONS_PAGE_H +#define IOPTIONS_PAGE_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include + +QT_BEGIN_NAMESPACE +class QWidget; +class QIcon; +QT_END_NAMESPACE + +namespace Core +{ +/** +@interface IOptionsPage +@brief The IOptionsPage is an interface for providing options pages. +@details You need to subclass this interface and put an instance of your subclass + into the plugin manager object pool. +*/ +class CORE_EXPORT IOptionsPage: public QObject +{ + Q_OBJECT +public: + IOptionsPage(QObject *parent = 0): QObject(parent) {} + virtual ~IOptionsPage() {} + + /// id() is a unique identifier for referencing this page + virtual QString id() const = 0; + + /// trName() is the (translated) name for display. + virtual QString trName() const = 0; + + /// category() is the unique id for the category that the page should be displayed in + virtual QString category() const = 0; + + /// trCategory() is the translated category + virtual QString trCategory() const = 0; + + virtual QIcon categoryIcon() const = 0; + + /// createPage() is called to retrieve the widget to show in the preferences dialog + /// The widget will be destroyed by the widget hierarchy when the dialog closes + virtual QWidget *createPage(QWidget *parent) = 0; + + /// apply() is called to store the settings. It should detect if any changes have been made and store those. + virtual void apply() = 0; + + /// finish() is called directly before the preferences dialog closes + virtual void finish() = 0; +}; + +} // namespace Core + +#endif // IOPTIONS_PAGE_H diff --git a/code/studio/src/plugins/core/main_window.cpp b/code/studio/src/plugins/core/main_window.cpp new file mode 100644 index 000000000..a90e67bc0 --- /dev/null +++ b/code/studio/src/plugins/core/main_window.cpp @@ -0,0 +1,492 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "main_window.h" +#include "icontext.h" +#include "icore_listener.h" +#include "menu_manager.h" +#include "context_manager.h" +#include "core.h" +#include "core_constants.h" +#include "settings_dialog.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace Core +{ + +MainWindow::MainWindow(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent) + : QMainWindow(parent), + m_pluginManager(0), + m_menuManager(0), + m_contextManager(0), + m_coreImpl(0), + m_lastDir("."), + m_undoGroup(0), + m_settings(0) +{ + QCoreApplication::setApplicationName(QLatin1String("ObjectViewerQt")); + QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::OVQT_VERSION_LONG)); + QCoreApplication::setOrganizationName(QLatin1String("RyzomCore")); + + setObjectName(Constants::MAIN_WINDOW); + setWindowIcon(QIcon(Constants::ICON_PILL)); + setWindowTitle(tr("Object Viewer Qt")); + + m_pluginManager = pluginManager; + m_settings = m_pluginManager->settings(); + m_coreImpl = new CoreImpl(this); + +#ifdef Q_WS_MAC + m_menuBar = new QMenuBar(0); +#else + m_menuBar = new QMenuBar(this); + setMenuBar(m_menuBar); +#endif + + m_menuManager = new MenuManager(m_menuBar, this); + + m_tabWidget = new QTabWidget(this); + m_tabWidget->setTabPosition(QTabWidget::South); + m_tabWidget->setMovable(false); + m_tabWidget->setDocumentMode(true); + setCentralWidget(m_tabWidget); + + m_contextManager = new ContextManager(this, m_tabWidget); + + setDockNestingEnabled(true); + m_originalPalette = QApplication::palette(); + m_undoGroup = new QUndoGroup(this); + + createDialogs(); + createActions(); + createMenus(); + createStatusBar(); + resize(1024, 768); +} + +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() +{ + readSettings(); + connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext *)), + this, SLOT(updateContext(Core::IContext *))); + if (m_contextManager->currentContext() != NULL) + updateContext(m_contextManager->currentContext()); + show(); +} + +MenuManager *MainWindow::menuManager() const +{ + return m_menuManager; +} + +ContextManager *MainWindow::contextManager() const +{ + return m_contextManager; +} + +QSettings *MainWindow::settings() const +{ + return m_settings; +} + +QUndoGroup *MainWindow::undoGroup() const +{ + return m_undoGroup; +} + +ExtensionSystem::IPluginManager *MainWindow::pluginManager() const +{ + return m_pluginManager; +} + +void MainWindow::addContextObject(IContext *context) +{ + QUndoStack *stack = context->undoStack(); + if (stack) + m_undoGroup->addStack(stack); +} + +void MainWindow::removeContextObject(IContext *context) +{ + QUndoStack *stack = context->undoStack(); + if (stack) + m_undoGroup->removeStack(stack); +} + +void MainWindow::open() +{ + m_contextManager->currentContext()->open(); +} + +void MainWindow::newFile() +{ + m_contextManager->currentContext()->newDocument(); +} + +void MainWindow::save() +{ + m_contextManager->currentContext()->save(); +} + +void MainWindow::saveAs() +{ + m_contextManager->currentContext()->saveAs(); +} + +void MainWindow::saveAll() +{ +} + +void MainWindow::closeDocument() +{ + m_contextManager->currentContext()->close(); +} + + +void MainWindow::cut() +{ +} + +void MainWindow::copy() +{ +} + +void MainWindow::paste() +{ +} + +void MainWindow::del() +{ +} + +void MainWindow::find() +{ +} + +void MainWindow::gotoPos() +{ +} + +void MainWindow::setFullScreen(bool enabled) +{ + if (bool(windowState() & Qt::WindowFullScreen) == enabled) + return; + if (enabled) + setWindowState(windowState() | Qt::WindowFullScreen); + else + setWindowState(windowState() & ~Qt::WindowFullScreen); +} + +bool MainWindow::showOptionsDialog(const QString &group, + const QString &page, + QWidget *parent) +{ + if (!parent) + parent = this; + SettingsDialog settingsDialog(m_pluginManager, group, page, parent); + settingsDialog.show(); + bool ok = settingsDialog.execDialog(); + if (ok) + Q_EMIT m_coreImpl->changeSettings(); + return ok; +} + +void MainWindow::about() +{ + QMessageBox::about(this, tr("About Object Viewer Qt"), + tr("

Object Viewer Qt

" + "

Ryzom Core team

Compiled on %1 %2").arg(__DATE__).arg(__TIME__)); +} + +void MainWindow::updateContext(Core::IContext *context) +{ + m_undoGroup->setActiveStack(context->undoStack()); +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + QList listeners = m_pluginManager->getObjects(); + Q_FOREACH(ICoreListener *listener, listeners) + { + if (!listener->closeMainWindow()) + { + event->ignore(); + return; + } + } + Q_EMIT m_coreImpl->closeMainWindow(); + + writeSettings(); + event->accept(); +} + +void MainWindow::createActions() +{ + m_newAction = new QAction(tr("&New"), this); + m_newAction->setIcon(QIcon(Constants::ICON_NEW)); + m_newAction->setShortcut(QKeySequence::New); + menuManager()->registerAction(m_newAction, Constants::NEW); + connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile())); + m_newAction->setEnabled(false); + + m_openAction = new QAction(tr("&Open..."), this); + m_openAction->setIcon(QIcon(Constants::ICON_OPEN)); + 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())); + + m_saveAction = new QAction(tr("&Save"), this); + m_saveAction->setIcon(QIcon(Constants::ICON_SAVE)); + m_saveAction->setShortcut(QKeySequence::Save); + menuManager()->registerAction(m_saveAction, Constants::SAVE); + connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save())); + m_saveAction->setEnabled(false); + + m_saveAsAction = new QAction(tr("Save &As..."), this); + m_saveAsAction->setIcon(QIcon(Constants::ICON_SAVE_AS)); + m_saveAsAction->setShortcut(QKeySequence::SaveAs); + menuManager()->registerAction(m_saveAsAction, Constants::SAVE_AS); + connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs())); + m_saveAsAction->setEnabled(false); + + m_saveAllAction = new QAction(tr("&Save A&ll"), this); + m_saveAllAction->setShortcut(QKeySequence::SelectAll); + menuManager()->registerAction(m_saveAllAction, Constants::SAVE_ALL); + connect(m_saveAllAction, SIGNAL(triggered()), this, SLOT(saveAll())); + m_saveAllAction->setEnabled(false); + + m_closeAction = new QAction(tr("Close"), this); + m_closeAction->setShortcut(QKeySequence::Close); + menuManager()->registerAction(m_closeAction, Constants::CLOSE); + connect(m_closeAction, SIGNAL(triggered()), this, SLOT(closeDocument())); + m_closeAction->setEnabled(false); + + 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())); + + m_cutAction = new QAction(tr("Cu&t"), this); + m_cutAction->setShortcut(QKeySequence::Cut); + menuManager()->registerAction(m_cutAction, Constants::CUT); + connect(m_cutAction, SIGNAL(triggered()), this, SLOT(cut())); + m_cutAction->setEnabled(false); + + m_copyAction = new QAction(tr("&Copy"), this); + m_copyAction->setShortcut(QKeySequence::Copy); + menuManager()->registerAction(m_copyAction, Constants::COPY); + connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copy())); + m_copyAction->setEnabled(false); + + m_pasteAction = new QAction(tr("&Paste"), this); + m_pasteAction->setShortcut(QKeySequence::Paste); + menuManager()->registerAction(m_pasteAction, Constants::PASTE); + connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste())); + m_pasteAction->setEnabled(false); + + m_delAction = new QAction(tr("&Delete"), this); + m_delAction->setShortcut(QKeySequence::Delete); + menuManager()->registerAction(m_delAction, Constants::DEL); + connect(m_delAction, SIGNAL(triggered()), this, SLOT(del())); + m_delAction->setEnabled(false); + + m_selectAllAction = new QAction(tr("Select &All"), this); + m_selectAllAction->setShortcut(QKeySequence::SelectAll); + menuManager()->registerAction(m_selectAllAction, Constants::SELECT_ALL); + connect(m_selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll())); + m_selectAllAction->setEnabled(false); + + m_findAction = new QAction(tr("&Find"), this); + m_findAction->setShortcut(QKeySequence::Find); + menuManager()->registerAction(m_findAction, Constants::FIND); + connect(m_findAction, SIGNAL(triggered()), this, SLOT(find())); + m_findAction->setEnabled(false); + + m_gotoAction = new QAction(tr("&Go To.."), this); + m_gotoAction->setShortcut(QKeySequence(tr("Ctrl+G"))); + menuManager()->registerAction(m_gotoAction, Constants::GOTO_POS); + connect(m_gotoAction, SIGNAL(triggered()), this, SLOT(gotoPos())); + m_gotoAction->setEnabled(false); + + m_fullscreenAction = new QAction(tr("Fullscreen"), this); + m_fullscreenAction->setCheckable(true); + m_fullscreenAction->setShortcut(QKeySequence(tr("Ctrl+Shift+F11"))); + menuManager()->registerAction(m_fullscreenAction, Constants::TOGGLE_FULLSCREEN); + connect(m_fullscreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool))); + + 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())); + + 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())); + + 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())); + + 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 MainWindow::createMenus() +{ + m_fileMenu = m_menuBar->addMenu(tr("&File")); + menuManager()->registerMenu(m_fileMenu, Constants::M_FILE); + m_fileMenu->addAction(m_newAction); + m_fileMenu->addAction(m_openAction); + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_saveAction); + m_fileMenu->addAction(m_saveAsAction); + m_fileMenu->addAction(m_saveAllAction); + m_fileMenu->addAction(m_closeAction); + m_fileMenu->addSeparator(); + + m_recentFilesMenu = m_fileMenu->addMenu(tr("Recent &Files")); + m_recentFilesMenu->setEnabled(false); + menuManager()->registerMenu(m_recentFilesMenu, Constants::M_FILE_RECENTFILES); + + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_exitAction); + + m_editMenu = m_menuBar->addMenu(tr("&Edit")); + QAction *undoAction = m_undoGroup->createUndoAction(this); + menuManager()->registerAction(undoAction, Constants::UNDO); + undoAction->setIcon(QIcon(Constants::ICON_UNDO)); + undoAction->setShortcut(QKeySequence::Undo); + QAction *redoAction = m_undoGroup->createRedoAction(this); + menuManager()->registerAction(redoAction, Constants::REDO); + redoAction->setIcon(QIcon(Constants::ICON_REDO)); + redoAction->setShortcut(QKeySequence::Redo); + m_editMenu->addAction(undoAction); + m_editMenu->addAction(redoAction); + + m_editMenu->addSeparator(); + m_editMenu->addAction(m_cutAction); + m_editMenu->addAction(m_copyAction); + m_editMenu->addAction(m_pasteAction); + m_editMenu->addAction(m_delAction); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_selectAllAction); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_findAction); + m_editMenu->addAction(m_gotoAction); + menuManager()->registerMenu(m_editMenu, Constants::M_EDIT); + + m_viewMenu = m_menuBar->addMenu(tr("&View")); + m_viewMenu->addAction(m_fullscreenAction); + m_viewMenu->addAction(m_dockWidget->toggleViewAction()); + menuManager()->registerMenu(m_viewMenu, Constants::M_VIEW); + + m_toolsMenu = m_menuBar->addMenu(tr("&Tools")); + menuManager()->registerMenu(m_toolsMenu, Constants::M_TOOLS); + + m_sheetMenu = m_toolsMenu->addMenu(tr("&Sheet")); + menuManager()->registerMenu(m_sheetMenu, Constants::M_SHEET); + +// m_toolsMenu->addSeparator(); + + m_toolsMenu->addAction(m_settingsAction); + + m_menuBar->addSeparator(); + + m_helpMenu = m_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 MainWindow::createStatusBar() +{ + statusBar()->showMessage(tr("StatusReady")); +} + +void MainWindow::createDialogs() +{ + m_pluginView = new PluginView(m_pluginManager, this); + + // Create undo/redo command list + m_dockWidget = new QDockWidget("Command List", this); + m_dockWidget->setObjectName(QString::fromUtf8("UndoRedoCommandDockWidget")); + QUndoView *undoView = new QUndoView(m_undoGroup, m_dockWidget); + m_dockWidget->setWidget(undoView); + addDockWidget(Qt::RightDockWidgetArea, m_dockWidget); +} + +void MainWindow::readSettings() +{ + m_settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + restoreState(m_settings->value(Constants::MAIN_WINDOW_STATE).toByteArray()); + restoreGeometry(m_settings->value(Constants::MAIN_WINDOW_GEOMETRY).toByteArray()); + m_settings->endGroup(); +} + +void MainWindow::writeSettings() +{ + m_settings->beginGroup(Constants::MAIN_WINDOW_SECTION); + m_settings->setValue(Constants::MAIN_WINDOW_STATE, saveState()); + m_settings->setValue(Constants::MAIN_WINDOW_GEOMETRY, saveGeometry()); + m_settings->endGroup(); +} + +} /* namespace Core */ + +/* end of file */ diff --git a/code/studio/src/plugins/core/main_window.h b/code/studio/src/plugins/core/main_window.h new file mode 100644 index 000000000..d258a5eba --- /dev/null +++ b/code/studio/src/plugins/core/main_window.h @@ -0,0 +1,147 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 MAIN_WINDOW_H +#define MAIN_WINDOW_H + +// Project includes +#include "../../extension_system/iplugin_manager.h" +#include "plugin_view_dialog.h" + +// STL includes + +// Qt includes +#include +#include +#include + +namespace Core +{ +class CSettingsDialog; +class CorePlugin; +class IContext; +class MenuManager; +class ContextManager; +class CoreImpl; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent = 0); + ~MainWindow(); + + bool initialize(QString *errorString); + void extensionsInitialized(); + + MenuManager *menuManager() const; + ContextManager *contextManager() const; + QSettings *settings() const; + QUndoGroup *undoGroup() const; + + ExtensionSystem::IPluginManager *pluginManager() const; + + void addContextObject(IContext *context); + void removeContextObject(IContext *context); + +public Q_SLOTS: + bool showOptionsDialog(const QString &group = QString(), + const QString &page = QString(), + QWidget *parent = 0); + void updateContext(Core::IContext *context); + +private Q_SLOTS: + void open(); + void newFile(); + void save(); + void saveAs(); + void saveAll(); + void closeDocument(); + void cut(); + void copy(); + void paste(); + void del(); + void find(); + void gotoPos(); + void setFullScreen(bool enabled); + void about(); + +protected: + virtual void closeEvent(QCloseEvent *event); + +private: + void createActions(); + void createMenus(); + void createStatusBar(); + void createDialogs(); + + void readSettings(); + void writeSettings(); + + ExtensionSystem::IPluginManager *m_pluginManager; + PluginView *m_pluginView; + MenuManager *m_menuManager; + ContextManager *m_contextManager; + CoreImpl *m_coreImpl; + + QPalette m_originalPalette; + QString m_lastDir; + + QDockWidget *m_dockWidget; + QUndoGroup *m_undoGroup; + QSettings *m_settings; + + QTimer *m_mainTimer; + QTimer *m_statusBarTimer; + + QTabWidget *m_tabWidget; + + QMenu *m_fileMenu; + QMenu *m_recentFilesMenu; + QMenu *m_editMenu; + QMenu *m_viewMenu; + QMenu *m_toolsMenu; + QMenu *m_helpMenu; + QMenuBar *m_menuBar; + QMenu *m_sheetMenu; + + QAction *m_newAction; + QAction *m_openAction; + QAction *m_saveAction; + QAction *m_saveAsAction; + QAction *m_saveAllAction; + QAction *m_closeAction; + QAction *m_exitAction; + QAction *m_cutAction; + QAction *m_copyAction; + QAction *m_pasteAction; + QAction *m_delAction; + QAction *m_selectAllAction; + QAction *m_findAction; + QAction *m_gotoAction; + QAction *m_fullscreenAction; + QAction *m_settingsAction; + QAction *m_pluginViewAction; + QAction *m_aboutAction; + QAction *m_aboutQtAction; + +};/* class MainWindow */ + +} /* namespace Core */ + +#endif // MAIN_WINDOW_H diff --git a/code/studio/src/plugins/core/menu_manager.cpp b/code/studio/src/plugins/core/menu_manager.cpp new file mode 100644 index 000000000..3e6272f0a --- /dev/null +++ b/code/studio/src/plugins/core/menu_manager.cpp @@ -0,0 +1,96 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "menu_manager.h" + +// NeL includes +#include + +namespace Core +{ +struct MenuManagerPrivate +{ + MenuManagerPrivate(): m_menuBar(0) {} + QMenuBar *m_menuBar; + typedef QHash IdMenuMap; + IdMenuMap m_menuMap; + typedef QHash IdActionMap; + IdActionMap m_actionMap; +}; + +MenuManager::MenuManager(QMenuBar *menuBar, QObject *parent) + : QObject(parent), + d(new MenuManagerPrivate()) +{ + d->m_menuBar = menuBar; +} + +MenuManager::~MenuManager() +{ + d->m_menuMap.clear(); + delete d; +} + +void MenuManager::registerMenu(QMenu *menu, const QString &id) +{ + menu->setObjectName(id); + d->m_menuMap.insert(id, menu); +} + +void MenuManager::registerAction(QAction *action, const QString &id) +{ + action->setObjectName(id); + d->m_actionMap.insert(id, action); +} + +QMenu *MenuManager::menu(const QString &id) const +{ + QMenu *result = 0; + if (!d->m_menuMap.contains(id)) + nlwarning("QMenu %s not found", id.toUtf8().constData()); + else + result = d->m_menuMap.value(id); + return result; +} + +QAction *MenuManager::action(const QString &id) const +{ + QAction *result = 0; + if (!d->m_actionMap.contains(id)) + nlwarning("QAction %s not found", id.toUtf8().constData()); + else + result = d->m_actionMap.value(id); + return result; +} + +void MenuManager::unregisterMenu(const QString &id) +{ + d->m_menuMap.remove(id); +} + +void MenuManager::unregisterAction(const QString &id) +{ + d->m_actionMap.remove(id); +} + +QMenuBar *MenuManager::menuBar() const +{ + return d->m_menuBar; +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/menu_manager.h b/code/studio/src/plugins/core/menu_manager.h new file mode 100644 index 000000000..fd6af8f3a --- /dev/null +++ b/code/studio/src/plugins/core/menu_manager.h @@ -0,0 +1,67 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 MENU_MANAGER_H +#define MENU_MANAGER_H + +// Project includes +#include "core_global.h" + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace Core +{ +struct MenuManagerPrivate; + +/* +@interface MenuManager +@brief The MenuManager provide the interface for registration of menus and menu item. +@details The MenuManager provides centralized access to menus and menu items. +All menus and menu items should be registered in the MenuManager. +*/ +class CORE_EXPORT MenuManager: public QObject +{ + Q_OBJECT + +public: + MenuManager(QMenuBar *menuBar, QObject *parent = 0); + virtual ~MenuManager(); + + void registerMenu(QMenu *menu, const QString &id); + void registerAction(QAction *action, const QString &id); + + QMenu *menu(const QString &id) const; + QAction *action(const QString &id) const; + + void unregisterMenu(const QString &id); + void unregisterAction(const QString &id); + + QMenuBar *menuBar() const; +private: + + MenuManagerPrivate *d; +}; + +} // namespace Core + +#endif // MENU_MANAGER_H diff --git a/code/studio/src/plugins/core/ovqt_plugin_core.xml b/code/studio/src/plugins/core/ovqt_plugin_core.xml new file mode 100644 index 000000000..2f5d6e9a8 --- /dev/null +++ b/code/studio/src/plugins/core/ovqt_plugin_core.xml @@ -0,0 +1,7 @@ + + ovqt_plugin_core + Core + 0.8 + Ryzom Core + Core plugin. + \ No newline at end of file diff --git a/code/studio/src/plugins/core/plugin_view_dialog.cpp b/code/studio/src/plugins/core/plugin_view_dialog.cpp new file mode 100644 index 000000000..175902d39 --- /dev/null +++ b/code/studio/src/plugins/core/plugin_view_dialog.cpp @@ -0,0 +1,108 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 "plugin_view_dialog.h" +#include "core_constants.h" + +#include "nel/misc/debug.h" + +// Qt includes +#include +#include +#include +#include + +// Project includes +#include "../../extension_system/iplugin_spec.h" +#include "../../extension_system/iplugin_manager.h" + +namespace Core +{ + +PluginView::PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent) + : QDialog(parent), + m_checkStateColumn(0) +{ + m_ui.setupUi(this); + m_pluginManager = pluginManager; + + connect(m_pluginManager, SIGNAL(pluginsChanged()), this, SLOT(updateList())); + connect(this, SIGNAL(accepted()), this, SLOT(updateSettings())); + + // WhiteList is list of plugins which can not disable. + m_whiteList << Constants::OVQT_CORE_PLUGIN; + updateList(); +} + +PluginView::~PluginView() +{ +} + +void PluginView::updateList() +{ + static QIcon okIcon = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton); + static QIcon errorIcon = QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton); + static QIcon notLoadedIcon = QApplication::style()->standardIcon(QStyle::SP_DialogResetButton); + + m_specToItem.clear(); + + QList items; + Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins()) + { + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() + << spec->name() + << QString("%1").arg(spec->version()) + << spec->vendor() + << QDir::toNativeSeparators(spec->filePath())); + + bool ok = !spec->hasError(); + QIcon icon = ok ? okIcon : errorIcon; + if (ok && (spec->state() != ExtensionSystem::State::Running)) + icon = notLoadedIcon; + + item->setIcon(m_checkStateColumn, icon); + + if (!m_whiteList.contains(spec->name())) + item->setCheckState(m_checkStateColumn, spec->isEnabled() ? Qt::Checked : Qt::Unchecked); + + items.append(item); + m_specToItem.insert(spec, item); + } + + m_ui.pluginTreeWidget->clear(); + if (!items.isEmpty()) + m_ui.pluginTreeWidget->addTopLevelItems(items); + + m_ui.pluginTreeWidget->resizeColumnToContents(m_checkStateColumn); +} + +void PluginView::updateSettings() +{ + Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins()) + { + if (m_specToItem.contains(spec) && (!m_whiteList.contains(spec->name()))) + { + QTreeWidgetItem *item = m_specToItem.value(spec); + if (item->checkState(m_checkStateColumn) == Qt::Checked) + spec->setEnabled(true); + else + spec->setEnabled(false); + } + } +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/plugin_view_dialog.h b/code/studio/src/plugins/core/plugin_view_dialog.h new file mode 100644 index 000000000..aae16749d --- /dev/null +++ b/code/studio/src/plugins/core/plugin_view_dialog.h @@ -0,0 +1,58 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 PLUGIN_VIEW_H +#define PLUGIN_VIEW_H + +#include "ui_plugin_view_dialog.h" + +#include +#include + +namespace ExtensionSystem +{ +class IPluginManager; +class IPluginSpec; +} + +namespace Core +{ + +class PluginView: public QDialog +{ + Q_OBJECT + +public: + PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent = 0); + ~PluginView(); + +private Q_SLOTS: + void updateList(); + void updateSettings(); + +private: + + const int m_checkStateColumn; + QMap m_specToItem; + QStringList m_whiteList; + ExtensionSystem::IPluginManager *m_pluginManager; + Ui::PluginView m_ui; +}; /* class PluginView */ + +} /* namespace Core */ + +#endif // PLUGIN_VIEW_H diff --git a/code/studio/src/plugins/core/plugin_view_dialog.ui b/code/studio/src/plugins/core/plugin_view_dialog.ui new file mode 100644 index 000000000..9d7d395be --- /dev/null +++ b/code/studio/src/plugins/core/plugin_view_dialog.ui @@ -0,0 +1,135 @@ + + + PluginView + + + + 0 + 0 + 756 + 296 + + + + About plugins + + + true + + + + + + true + + + 0 + + + false + + + true + + + false + + + true + + + + Name + + + + + Version + + + + + Vendor + + + + + Location + + + + + + + + false + + + Details + + + + + + + false + + + Error details + + + + + + + Qt::Horizontal + + + + 427 + 20 + + + + + + + + Close + + + + + + + false + + + All objects list + + + + + + + + + + + closePushButton + clicked() + PluginView + accept() + + + 620 + 232 + + + 507 + 226 + + + + + diff --git a/code/studio/src/plugins/core/qtwin.cpp b/code/studio/src/plugins/core/qtwin.cpp new file mode 100644 index 000000000..115203ded --- /dev/null +++ b/code/studio/src/plugins/core/qtwin.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#include "qtwin.h" +#include +#include +#include +#include +#include + +#ifdef Q_WS_WIN + +#include + +// Blur behind data structures +#define DWM_BB_ENABLE 0x00000001 // fEnable has been specified +#define DWM_BB_BLURREGION 0x00000002 // hRgnBlur has been specified +#define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004 // fTransitionOnMaximized has been specified +#define WM_DWMCOMPOSITIONCHANGED 0x031E // Composition changed window message + +typedef struct _DWM_BLURBEHIND +{ + DWORD dwFlags; + BOOL fEnable; + HRGN hRgnBlur; + BOOL fTransitionOnMaximized; +} DWM_BLURBEHIND, *PDWM_BLURBEHIND; + +typedef struct _MARGINS +{ + int cxLeftWidth; + int cxRightWidth; + int cyTopHeight; + int cyBottomHeight; +} MARGINS, *PMARGINS; + +typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *pfEnabled); +typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset); +typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND *pBlurBehind); +typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend); + +static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0; +static PtrDwmEnableBlurBehindWindow pDwmEnableBlurBehindWindow = 0; +static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0; +static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0; + + +/* + * Internal helper class that notifies windows if the + * DWM compositing state changes and updates the widget + * flags correspondingly. + */ +class WindowNotifier : public QWidget +{ +public: + WindowNotifier() + { + winId(); + } + void addWidget(QWidget *widget) + { + widgets.append(widget); + } + void removeWidget(QWidget *widget) + { + widgets.removeAll(widget); + } + bool winEvent(MSG *message, long *result); + +private: + QWidgetList widgets; +}; + +static bool resolveLibs() +{ + if (!pDwmIsCompositionEnabled) + { + QLibrary dwmLib(QString::fromAscii("dwmapi")); + pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled"); + pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea"); + pDwmEnableBlurBehindWindow = (PtrDwmEnableBlurBehindWindow)dwmLib.resolve("DwmEnableBlurBehindWindow"); + pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor"); + } + return pDwmIsCompositionEnabled != 0; +} + +#endif + +/*! + * Chekcs and returns true if Windows DWM composition + * is currently enabled on the system. + * + * To get live notification on the availability of + * this feature, you will currently have to + * reimplement winEvent() on your widget and listen + * for the WM_DWMCOMPOSITIONCHANGED event to occur. + * + */ +bool QtWin::isCompositionEnabled() +{ +#ifdef Q_WS_WIN + if (resolveLibs()) + { + HRESULT hr = S_OK; + BOOL isEnabled = false; + hr = pDwmIsCompositionEnabled(&isEnabled); + if (SUCCEEDED(hr)) + return isEnabled; + } +#endif + return false; +} + +/*! + * Enables Blur behind on a Widget. + * + * \a enable tells if the blur should be enabled or not + */ +bool QtWin::enableBlurBehindWindow(QWidget *widget, bool enable) +{ + Q_ASSERT(widget); + bool result = false; +#ifdef Q_WS_WIN + if (resolveLibs()) + { + DWM_BLURBEHIND bb = {0}; + HRESULT hr = S_OK; + bb.fEnable = enable; + bb.dwFlags = DWM_BB_ENABLE; + bb.hRgnBlur = NULL; + widget->setAttribute(Qt::WA_TranslucentBackground, enable); + widget->setAttribute(Qt::WA_NoSystemBackground, enable); + hr = pDwmEnableBlurBehindWindow(widget->winId(), &bb); + if (SUCCEEDED(hr)) + { + result = true; + windowNotifier()->addWidget(widget); + } + } +#endif + return result; +} + +/*! + * ExtendFrameIntoClientArea. + * + * This controls the rendering of the frame inside the window. + * Note that passing margins of -1 (the default value) will completely + * remove the frame from the window. + * + * \note you should not call enableBlurBehindWindow before calling + * this functions + * + * \a enable tells if the blur should be enabled or not + */ +bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom) +{ + + Q_ASSERT(widget); + Q_UNUSED(left); + Q_UNUSED(top); + Q_UNUSED(right); + Q_UNUSED(bottom); + + bool result = false; +#ifdef Q_WS_WIN + if (resolveLibs()) + { + QLibrary dwmLib(QString::fromAscii("dwmapi")); + HRESULT hr = S_OK; + MARGINS m = {left, top, right, bottom}; + hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m); + if (SUCCEEDED(hr)) + { + result = true; + windowNotifier()->addWidget(widget); + } + widget->setAttribute(Qt::WA_TranslucentBackground, result); + } +#endif + return result; +} + +/*! + * Returns the current colorizationColor for the window. + * + * \a enable tells if the blur should be enabled or not + */ +QColor QtWin::colorizatinColor() +{ + QColor resultColor = QApplication::palette().window().color(); + +#ifdef Q_WS_WIN + if (resolveLibs()) + { + DWORD color = 0; + BOOL opaque = FALSE; + QLibrary dwmLib(QString::fromAscii("dwmapi")); + HRESULT hr = S_OK; + hr = pDwmGetColorizationColor(&color, &opaque); + if (SUCCEEDED(hr)) + resultColor = QColor(color); + } +#endif + return resultColor; +} + +#ifdef Q_WS_WIN +WindowNotifier *QtWin::windowNotifier() +{ + static WindowNotifier *windowNotifierInstance = 0; + if (!windowNotifierInstance) + windowNotifierInstance = new WindowNotifier; + return windowNotifierInstance; +} + + +/* Notify all enabled windows that the DWM state changed */ +bool WindowNotifier::winEvent(MSG *message, long *result) +{ + if (message && message->message == WM_DWMCOMPOSITIONCHANGED) + { + bool compositionEnabled = QtWin::isCompositionEnabled(); + Q_FOREACH(QWidget * widget, widgets) + { + if (widget) + { + widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled); + } + widget->update(); + } + } + return QWidget::winEvent(message, result); +} +#endif diff --git a/code/studio/src/plugins/core/qtwin.h b/code/studio/src/plugins/core/qtwin.h new file mode 100644 index 000000000..5692a34fb --- /dev/null +++ b/code/studio/src/plugins/core/qtwin.h @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#ifndef QTWIN_H +#define QTWIN_H + +#include +#include +/** + * This is a helper class for using the Desktop Window Manager + * functionality on Windows 7 and Windows Vista. On other platforms + * these functions will simply not do anything. + */ + +class WindowNotifier; + +class QtWin +{ +public: + static bool enableBlurBehindWindow(QWidget *widget, bool enable = true); + static bool extendFrameIntoClientArea(QWidget *widget, + int left = -1, int top = -1, + int right = -1, int bottom = -1); + static bool isCompositionEnabled(); + static QColor colorizatinColor(); + +private: + static WindowNotifier *windowNotifier(); +}; + +#endif // QTWIN_H diff --git a/code/studio/src/plugins/core/search_paths_settings_page.cpp b/code/studio/src/plugins/core/search_paths_settings_page.cpp new file mode 100644 index 000000000..e76d6c796 --- /dev/null +++ b/code/studio/src/plugins/core/search_paths_settings_page.cpp @@ -0,0 +1,219 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "search_paths_settings_page.h" +#include "core_constants.h" +#include "icore.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace Core +{ + +QString lastDir = "."; + +SearchPathsSettingsPage::SearchPathsSettingsPage(bool recurse, QObject *parent) + : IOptionsPage(parent), + m_recurse(recurse), + m_page(0) +{ +} + +SearchPathsSettingsPage::~SearchPathsSettingsPage() +{ +} + +QString SearchPathsSettingsPage::id() const +{ + if (m_recurse) + return QLatin1String("search_recurse_paths"); + else + return QLatin1String("search_paths"); +} + +QString SearchPathsSettingsPage::trName() const +{ + if (m_recurse) + return tr("Search Recurse Paths"); + else + return tr("Search Paths"); +} + +QString SearchPathsSettingsPage::category() const +{ + return QLatin1String(Constants::SETTINGS_CATEGORY_GENERAL); +} + +QString SearchPathsSettingsPage::trCategory() const +{ + return tr(Constants::SETTINGS_TR_CATEGORY_GENERAL); +} + +QIcon SearchPathsSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +QWidget *SearchPathsSettingsPage::createPage(QWidget *parent) +{ + m_page = new QWidget(parent); + m_ui.setupUi(m_page); + + readSettings(); + checkEnabledButton(); + connect(m_ui.addToolButton, SIGNAL(clicked()), this, SLOT(addPath())); + connect(m_ui.removeToolButton, SIGNAL(clicked()), this, SLOT(delPath())); + connect(m_ui.upToolButton, SIGNAL(clicked()), this, SLOT(upPath())); + connect(m_ui.downToolButton, SIGNAL(clicked()), this, SLOT(downPath())); + connect(m_ui.resetToolButton, SIGNAL(clicked()), m_ui.pathsListWidget, SLOT(clear())); + return m_page; +} + +void SearchPathsSettingsPage::apply() +{ + writeSettings(); + applySearchPaths(); +} + +void SearchPathsSettingsPage::finish() +{ + delete m_page; + m_page = 0; +} + +void SearchPathsSettingsPage::applySearchPaths() +{ + QStringList paths, remapExt; + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + if (m_recurse) + paths = settings->value(Core::Constants::RECURSIVE_SEARCH_PATHS).toStringList(); + else + paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); + + remapExt = settings->value(Core::Constants::REMAP_EXTENSIONS).toStringList(); + settings->endGroup(); + + for (int i = 1; i < remapExt.size(); i += 2) + NLMISC::CPath::remapExtension(remapExt.at(i - 1).toUtf8().constData(), remapExt.at(i).toUtf8().constData(), true); + + Q_FOREACH(QString path, paths) + { + NLMISC::CPath::addSearchPath(path.toUtf8().constData(), m_recurse, false); + } +} + +void SearchPathsSettingsPage::addPath() +{ + QString newPath = QFileDialog::getExistingDirectory(m_page, "", lastDir); + if (!newPath.isEmpty()) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(newPath); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + m_ui.pathsListWidget->addItem(newItem); + lastDir = newPath; + } + + checkEnabledButton(); +} + +void SearchPathsSettingsPage::delPath() +{ + QListWidgetItem *removeItem = m_ui.pathsListWidget->takeItem(m_ui.pathsListWidget->currentRow()); + if (!removeItem) + delete removeItem; + + checkEnabledButton(); +} + +void SearchPathsSettingsPage::upPath() +{ + int currentRow = m_ui.pathsListWidget->currentRow(); + if (!(currentRow == 0)) + { + QListWidgetItem *item = m_ui.pathsListWidget->takeItem(currentRow); + m_ui.pathsListWidget->insertItem(--currentRow, item); + m_ui.pathsListWidget->setCurrentRow(currentRow); + } +} + +void SearchPathsSettingsPage::downPath() +{ + int currentRow = m_ui.pathsListWidget->currentRow(); + if (!(currentRow == m_ui.pathsListWidget->count()-1)) + { + QListWidgetItem *item = m_ui.pathsListWidget->takeItem(currentRow); + m_ui.pathsListWidget->insertItem(++currentRow, item); + m_ui.pathsListWidget->setCurrentRow(currentRow); + } +} + +void SearchPathsSettingsPage::readSettings() +{ + QStringList paths; + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + if (m_recurse) + paths = settings->value(Core::Constants::RECURSIVE_SEARCH_PATHS).toStringList(); + else + paths = settings->value(Core::Constants::SEARCH_PATHS).toStringList(); + settings->endGroup(); + Q_FOREACH(QString path, paths) + { + QListWidgetItem *newItem = new QListWidgetItem; + newItem->setText(path); + newItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); + m_ui.pathsListWidget->addItem(newItem); + } +} + +void SearchPathsSettingsPage::writeSettings() +{ + QStringList paths; + for (int i = 0; i < m_ui.pathsListWidget->count(); ++i) + paths << m_ui.pathsListWidget->item(i)->text(); + + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(Core::Constants::DATA_PATH_SECTION); + if (m_recurse) + settings->setValue(Core::Constants::RECURSIVE_SEARCH_PATHS, paths); + else + settings->setValue(Core::Constants::SEARCH_PATHS, paths); + settings->endGroup(); + settings->sync(); +} + +void SearchPathsSettingsPage::checkEnabledButton() +{ + bool bEnabled = true; + if (m_ui.pathsListWidget->count() == 0) + bEnabled = false; + + m_ui.removeToolButton->setEnabled(bEnabled); + m_ui.upToolButton->setEnabled(bEnabled); + m_ui.downToolButton->setEnabled(bEnabled); +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/search_paths_settings_page.h b/code/studio/src/plugins/core/search_paths_settings_page.h new file mode 100644 index 000000000..c45b29571 --- /dev/null +++ b/code/studio/src/plugins/core/search_paths_settings_page.h @@ -0,0 +1,74 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 SEARCH_PATHS_SETTINGS_PAGE_H +#define SEARCH_PATHS_SETTINGS_PAGE_H + +#include + +#include "ioptions_page.h" + +#include "ui_search_paths_settings_page.h" + +class QWidget; + +namespace Core +{ +/** +@class SearchPathsSettingsPage +*/ +class SearchPathsSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + explicit SearchPathsSettingsPage(bool recurse, QObject *parent = 0); + ~SearchPathsSettingsPage(); + + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + QIcon categoryIcon() const; + QWidget *createPage(QWidget *parent); + + void apply(); + void finish(); + + // Set of the search paths(not recursive) and the remap extensions (loading from settings file) + void applySearchPaths(); + +private Q_SLOTS: + void addPath(); + void delPath(); + void upPath(); + void downPath(); + +private: + void readSettings(); + void writeSettings(); + void checkEnabledButton(); + + bool m_recurse; + QWidget *m_page; + Ui::SearchPathsSettingsPage m_ui; +}; + +} // namespace Core + +#endif // SEARCH_PATHS_SETTINGS_H diff --git a/code/studio/src/plugins/core/search_paths_settings_page.ui b/code/studio/src/plugins/core/search_paths_settings_page.ui new file mode 100644 index 000000000..cf47314b8 --- /dev/null +++ b/code/studio/src/plugins/core/search_paths_settings_page.ui @@ -0,0 +1,198 @@ + + + SearchPathsSettingsPage + + + + 0 + 0 + 431 + 285 + + + + Form + + + + 6 + + + 3 + + + + + Search paths + + + + + + + Qt::Horizontal + + + + 228 + 20 + + + + + + + + 3 + + + + + + 0 + 0 + + + + Add + + + + + + + :/core/icons/ic_nel_add_item.png:/core/icons/ic_nel_add_item.png + + + + 20 + 20 + + + + true + + + + + + + + 0 + 0 + + + + Delete + + + + + + + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_delete_item.png + + + + 20 + 20 + + + + true + + + + + + + + 0 + 0 + + + + Up + + + + + + + :/core/icons/ic_nel_up_item.png:/core/icons/ic_nel_up_item.png + + + + 20 + 20 + + + + true + + + + + + + + 0 + 0 + + + + Down + + + + + + + :/core/icons/ic_nel_down_item.png:/core/icons/ic_nel_down_item.png + + + + 20 + 20 + + + + true + + + + + + + Reset + + + + + + + :/core/icons/ic_nel_reset_all.png:/core/icons/ic_nel_reset_all.png + + + + 20 + 20 + + + + true + + + + + + + + + + + + + + + diff --git a/code/studio/src/plugins/core/settings_dialog.cpp b/code/studio/src/plugins/core/settings_dialog.cpp new file mode 100644 index 000000000..4b7bbac3a --- /dev/null +++ b/code/studio/src/plugins/core/settings_dialog.cpp @@ -0,0 +1,182 @@ +// 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 . + +// Project includes +#include "settings_dialog.h" +#include "ioptions_page.h" + +// Qt includes +#include +#include + +struct PageData +{ + int index; + QString category; + QString id; +}; + +Q_DECLARE_METATYPE(PageData); + +namespace Core +{ +SettingsDialog::SettingsDialog(ExtensionSystem::IPluginManager *pluginManager, + const QString &categoryId, + const QString &pageId, + QWidget *parent) + : QDialog(parent), + m_applied(false) +{ + m_ui.setupUi(this); + + m_plugMan = pluginManager; + + QString initialCategory = categoryId; + QString initialPage = pageId; + + m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); + + connect(m_ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); + + m_ui.splitter->setCollapsible(1, false); + m_ui.pageTree->header()->setVisible(false); + + connect(m_ui.pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + this, SLOT(pageSelected())); + + QMap categories; + + QList pages = m_plugMan->getObjects(); + + int index = 0; + Q_FOREACH(IOptionsPage *page, pages) + { + PageData pageData; + pageData.index = index; + pageData.category = page->category(); + pageData.id = page->id(); + + QTreeWidgetItem *item = new QTreeWidgetItem; + item->setText(0, page->trName()); + item->setData(0, Qt::UserRole, qVariantFromValue(pageData)); + + QStringList categoriesId = page->category().split(QLatin1Char('|')); + QStringList trCategories = page->trCategory().split(QLatin1Char('|')); + QString currentCategory = categoriesId.at(0); + + QTreeWidgetItem *treeitem; + if (!categories.contains(currentCategory)) + { + treeitem = new QTreeWidgetItem(m_ui.pageTree); + treeitem->setText(0, trCategories.at(0)); + treeitem->setData(0, Qt::UserRole, qVariantFromValue(pageData)); + categories.insert(currentCategory, treeitem); + } + + int catCount = 1; + while (catCount < categoriesId.count()) + { + if (!categories.contains(currentCategory + QLatin1Char('|') + categoriesId.at(catCount))) + { + treeitem = new QTreeWidgetItem(categories.value(currentCategory)); + currentCategory += QLatin1Char('|') + categoriesId.at(catCount); + treeitem->setText(0, trCategories.at(catCount)); + treeitem->setData(0, Qt::UserRole, qVariantFromValue(pageData)); + categories.insert(currentCategory, treeitem); + } + else + { + currentCategory += QLatin1Char('|') + categoriesId.at(catCount); + } + ++catCount; + } + + categories.value(currentCategory)->addChild(item); + + m_pages.append(page); + m_ui.stackedPages->addWidget(page->createPage(m_ui.stackedPages)); + + if (page->id() == initialPage && currentCategory == initialCategory) + { + m_ui.stackedPages->setCurrentIndex(m_ui.stackedPages->count()); + m_ui.pageTree->setCurrentItem(item); + } + + index++; + } + + QList sizes; + sizes << 150 << 300; + m_ui.splitter->setSizes(sizes); + + m_ui.splitter->setStretchFactor(m_ui.splitter->indexOf(m_ui.pageTree), 0); + m_ui.splitter->setStretchFactor(m_ui.splitter->indexOf(m_ui.layoutWidget), 1); +} + +SettingsDialog::~SettingsDialog() +{ +} + +void SettingsDialog::pageSelected() +{ + QTreeWidgetItem *item = m_ui.pageTree->currentItem(); + PageData data = item->data(0, Qt::UserRole).value(); + int index = data.index; + m_currentCategory = data.category; + m_currentPage = data.id; + m_ui.stackedPages->setCurrentIndex(index); +} + +void SettingsDialog::accept() +{ + m_applied = true; + Q_FOREACH(IOptionsPage *page, m_pages) + { + page->apply(); + page->finish(); + } + done(QDialog::Accepted); +} + +void SettingsDialog::reject() +{ + Q_FOREACH(IOptionsPage *page, m_pages) + page->finish(); + done(QDialog::Rejected); +} + +void SettingsDialog::apply() +{ + Q_FOREACH(IOptionsPage *page, m_pages) + page->apply(); + m_applied = true; +} + +bool SettingsDialog::execDialog() +{ + m_applied = false; + exec(); + return m_applied; +} + +void SettingsDialog::done(int val) +{ + QDialog::done(val); +} + +} /* namespace Core */ \ No newline at end of file diff --git a/code/studio/src/plugins/core/settings_dialog.h b/code/studio/src/plugins/core/settings_dialog.h new file mode 100644 index 000000000..9e1c86444 --- /dev/null +++ b/code/studio/src/plugins/core/settings_dialog.h @@ -0,0 +1,75 @@ +// 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 SETTINGS_DIALOG_H +#define SETTINGS_DIALOG_H + +#include "ui_settings_dialog.h" + +// Qt includes +#include + +// Project includes +#include "../../extension_system/iplugin_manager.h" + +namespace Core +{ +class IOptionsPage; + +/** +@class CSettingsDialog +@brief Settings dialog +*/ +class SettingsDialog: public QDialog +{ + Q_OBJECT + +public: + SettingsDialog(ExtensionSystem::IPluginManager *pluginManager, + const QString &initialCategory = QString(), + const QString &initialPage = QString(), + QWidget *parent = 0); + + ~SettingsDialog(); + + /// Run the dialog and return true if 'Ok' was choosen or 'Apply' was invoked at least once + bool execDialog(); + +public Q_SLOTS: + void done(int); + +private Q_SLOTS: + void pageSelected(); + void accept(); + void reject(); + void apply(); + +private: + QList m_pages; + bool m_applied; + QString m_currentCategory; + QString m_currentPage; + + ExtensionSystem::IPluginManager *m_plugMan; + + Ui::SettingsDialog m_ui; +}; /* class CSettingsDialog */ + +} /* namespace Core */ + +#endif // SETTINGS_DIALOG_H diff --git a/code/studio/src/plugins/core/settings_dialog.ui b/code/studio/src/plugins/core/settings_dialog.ui new file mode 100644 index 000000000..8e9780c9a --- /dev/null +++ b/code/studio/src/plugins/core/settings_dialog.ui @@ -0,0 +1,126 @@ + + + SettingsDialog + + + + 0 + 0 + 697 + 476 + + + + Settings + + + + :/core/images/preferences.png:/core/images/preferences.png + + + + 6 + + + 9 + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + 1 + + + + 0 + + + + + + + 6 + + + 0 + + + + + + 350 + 250 + + + + + + + + Qt::Horizontal + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + SettingsDialog + accept() + + + 297 + 361 + + + 297 + 193 + + + + + buttonBox + rejected() + SettingsDialog + reject() + + + 297 + 361 + + + 297 + 193 + + + + +