+
+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
+
+
+
+
+