2012-05-29 13:31:11 +00:00
|
|
|
// Object Viewer Qt - Georges Editor Plugin - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
|
|
// Copyright (C) 2011 Adrian Jaekel <aj at elane2k dot com>
|
|
|
|
//
|
|
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
// Project includes
|
2012-12-08 10:22:05 +00:00
|
|
|
#include "stdpch.h"
|
2012-05-29 13:31:11 +00:00
|
|
|
#include "georges_editor_form.h"
|
|
|
|
#include "georges_editor_constants.h"
|
|
|
|
#include "georges_dirtree_dialog.h"
|
|
|
|
#include "georges_treeview_dialog.h"
|
|
|
|
|
|
|
|
#include "../core/icore.h"
|
|
|
|
#include "../core/menu_manager.h"
|
|
|
|
#include "../core/core_constants.h"
|
|
|
|
|
|
|
|
// NeL includes
|
|
|
|
#include <nel/misc/debug.h>
|
|
|
|
|
|
|
|
// Qt includes
|
|
|
|
#include <QSettings>
|
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QToolBar>
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
namespace GeorgesQt
|
|
|
|
{
|
2012-09-27 13:22:50 +00:00
|
|
|
QUndoStack *GeorgesEditorForm::UndoStack = NULL;
|
2012-05-29 13:31:11 +00:00
|
|
|
|
|
|
|
GeorgesEditorForm::GeorgesEditorForm(QWidget *parent)
|
|
|
|
: QMainWindow(parent),
|
|
|
|
m_georgesDirTreeDialog(0),
|
|
|
|
m_mainDock(0),
|
|
|
|
m_lastActiveDock(0)
|
|
|
|
{
|
|
|
|
m_ui.setupUi(this);
|
|
|
|
|
|
|
|
// background for the mainwindow
|
|
|
|
QString css = "QWidget#centralwidget {";
|
|
|
|
css += "image: url(:/images/ic_nel_georges_editor.png);";
|
|
|
|
css += "}";
|
|
|
|
|
|
|
|
// add new mainwindow for sheet dockwidgets
|
|
|
|
QWidget *widget = new QWidget(this);
|
|
|
|
widget->setObjectName("centralwidget");
|
|
|
|
widget->setStyleSheet(css);
|
|
|
|
setCentralWidget(widget);
|
|
|
|
QGridLayout *layout = new QGridLayout(widget);
|
|
|
|
layout->setContentsMargins(0,0,0,0);
|
|
|
|
widget->setLayout(layout);
|
|
|
|
m_mainDock = new QMainWindow(this);
|
|
|
|
m_mainDock->setDockNestingEnabled(true);
|
|
|
|
layout->addWidget(m_mainDock);
|
|
|
|
|
2012-09-27 13:22:50 +00:00
|
|
|
UndoStack = new QUndoStack(this);
|
2012-05-29 13:31:11 +00:00
|
|
|
|
|
|
|
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
|
|
|
|
m_openAction = menuManager->action(Core::Constants::OPEN);
|
|
|
|
|
|
|
|
m_newAction = new QAction(tr("&New..."), this);
|
|
|
|
m_newAction->setIcon(QIcon(Core::Constants::ICON_NEW));
|
|
|
|
m_newAction->setShortcut(QKeySequence::New);
|
|
|
|
m_newAction->setStatusTip(tr("Create a new file"));
|
|
|
|
connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));
|
|
|
|
|
|
|
|
m_saveAction = new QAction(tr("&Save..."), this);
|
|
|
|
m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
|
|
|
|
m_saveAction->setShortcut(QKeySequence::Save);
|
|
|
|
m_saveAction->setStatusTip(tr("Save the current file"));
|
|
|
|
connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save()));
|
|
|
|
|
|
|
|
m_fileToolBar = addToolBar(tr("&File"));
|
|
|
|
m_fileToolBar->addAction(m_openAction);
|
|
|
|
m_fileToolBar->addAction(m_newAction);
|
|
|
|
m_fileToolBar->addAction(m_saveAction);
|
|
|
|
|
|
|
|
m_saveAction->setEnabled(false);
|
|
|
|
|
|
|
|
readSettings();
|
|
|
|
|
|
|
|
// create leveldesign directory tree dockwidget
|
|
|
|
m_georgesDirTreeDialog = new CGeorgesDirTreeDialog(m_leveldesignPath, this);
|
|
|
|
addDockWidget(Qt::LeftDockWidgetArea, m_georgesDirTreeDialog);
|
|
|
|
restoreDockWidget(m_georgesDirTreeDialog);
|
|
|
|
|
|
|
|
// Set the default sheet dir dir to the level design path.
|
|
|
|
m_lastSheetDir = ".";
|
|
|
|
QSettings *settings = Core::ICore::instance()->settings();
|
|
|
|
settings->beginGroup(Core::Constants::DATA_PATH_SECTION);
|
|
|
|
m_lastSheetDir = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString();
|
|
|
|
settings->endGroup();
|
|
|
|
|
|
|
|
connect(Core::ICore::instance(), SIGNAL(changeSettings()),
|
|
|
|
this, SLOT(settingsChanged()));
|
|
|
|
connect(m_georgesDirTreeDialog, SIGNAL(selectedForm(const QString)),
|
|
|
|
this, SLOT(loadFile(const QString)));
|
|
|
|
connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)),
|
|
|
|
this, SLOT(focusChanged(QWidget*, QWidget*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GeorgesEditorForm::~GeorgesEditorForm()
|
|
|
|
{
|
|
|
|
writeSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
QUndoStack *GeorgesEditorForm::undoStack() const
|
|
|
|
{
|
2012-09-27 13:22:50 +00:00
|
|
|
return UndoStack;
|
2012-05-29 13:31:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::open()
|
|
|
|
{
|
|
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Form"));
|
|
|
|
if(!fileName.isNull())
|
|
|
|
loadFile(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::newFile()
|
|
|
|
{
|
|
|
|
// Assume it is a form, for now. We'll have to retrieve the DFN we'll be using as a base.
|
|
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Base Form Definition"), m_lastSheetDir, "Form Definition (*.dfn)");
|
|
|
|
if(!fileName.isNull())
|
|
|
|
{
|
|
|
|
// Use the file loader to create the new form.
|
|
|
|
loadFile(fileName, true);
|
|
|
|
|
|
|
|
// Save the folder we just opened for future dialogs.
|
|
|
|
QFileInfo pathInfo( fileName );
|
|
|
|
m_lastSheetDir = pathInfo.absolutePath();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::save()
|
|
|
|
{
|
|
|
|
m_lastActiveDock->write();
|
|
|
|
|
2014-08-18 23:57:20 +00:00
|
|
|
|
|
|
|
m_saveAction->setEnabled(false);
|
|
|
|
QAction *saveAction = Core::ICore::instance()->menuManager()->action( Core::Constants::SAVE );
|
|
|
|
if( saveAction != NULL )
|
|
|
|
saveAction->setEnabled(false);
|
2012-05-29 13:31:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::readSettings()
|
|
|
|
{
|
|
|
|
QSettings *settings = Core::ICore::instance()->settings();
|
|
|
|
settings->beginGroup(Constants::GEORGES_EDITOR_SECTION);
|
|
|
|
|
|
|
|
restoreGeometry(settings->value("geometry").toByteArray());
|
|
|
|
restoreState(settings->value("windowState").toByteArray());
|
|
|
|
|
|
|
|
settings->endGroup();
|
|
|
|
|
|
|
|
settings->beginGroup(Core::Constants::DATA_PATH_SECTION);
|
|
|
|
m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString();
|
|
|
|
settings->endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::writeSettings()
|
|
|
|
{
|
|
|
|
QSettings *settings = Core::ICore::instance()->settings();
|
|
|
|
settings->beginGroup(Constants::GEORGES_EDITOR_SECTION);
|
|
|
|
|
|
|
|
settings->setValue("geometry", saveGeometry());
|
|
|
|
settings->setValue("windowState", saveState());
|
|
|
|
|
|
|
|
settings->endGroup();
|
|
|
|
settings->sync();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::settingsChanged()
|
|
|
|
{
|
|
|
|
QSettings *settings = Core::ICore::instance()->settings();
|
|
|
|
|
|
|
|
settings->beginGroup(Core::Constants::DATA_PATH_SECTION);
|
|
|
|
QString oldLDPath = m_leveldesignPath;
|
|
|
|
m_leveldesignPath = settings->value(Core::Constants::LEVELDESIGN_PATH, "l:/leveldesign").toString();
|
|
|
|
settings->endGroup();
|
|
|
|
|
|
|
|
if (oldLDPath != m_leveldesignPath)
|
|
|
|
{
|
|
|
|
m_georgesDirTreeDialog->ldPathChanged(m_leveldesignPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::loadFile(const QString fileName)
|
|
|
|
{
|
|
|
|
loadFile(fileName, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::loadFile(const QString fileName, bool loadFromDfn)
|
|
|
|
{
|
|
|
|
QFileInfo info(fileName);
|
|
|
|
|
|
|
|
// Check to see if the form is already loaded, if it is just raise it.
|
|
|
|
if (m_dockedWidgets.size())
|
|
|
|
{
|
|
|
|
Q_FOREACH(CGeorgesTreeViewDialog *wgt, m_dockedWidgets)
|
|
|
|
{
|
|
|
|
if (info.fileName() == wgt->loadedForm)
|
|
|
|
{
|
|
|
|
wgt->raise();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CGeorgesTreeViewDialog *dock = new CGeorgesTreeViewDialog(m_mainDock);
|
2012-09-27 13:22:50 +00:00
|
|
|
dock->setUndoStack(UndoStack);
|
2012-05-29 13:31:11 +00:00
|
|
|
m_lastActiveDock = dock;
|
|
|
|
m_dockedWidgets.append(dock);
|
|
|
|
|
|
|
|
connect(m_dockedWidgets.last(), SIGNAL(closing()), this, SLOT(closingTreeView()));
|
|
|
|
connect(m_dockedWidgets.last(), SIGNAL(visibilityChanged(bool)), m_dockedWidgets.last(), SLOT(checkVisibility(bool)));
|
|
|
|
|
|
|
|
// If there is more than one form open - tabify the new form. If this is the first form open add it to the dock.
|
|
|
|
if(m_dockedWidgets.size() > 1)
|
|
|
|
{
|
|
|
|
m_mainDock->tabifyDockWidget(m_dockedWidgets.at(m_dockedWidgets.size() - 2), m_dockedWidgets.last());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_mainDock->addDockWidget(Qt::RightDockWidgetArea, m_dockedWidgets.last());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Retrieve the form and load the form.
|
|
|
|
NLGEORGES::CForm *form;
|
|
|
|
if(loadFromDfn)
|
|
|
|
{
|
|
|
|
// Get the form by DFN name.
|
|
|
|
form = m_dockedWidgets.last()->getFormByDfnName(info.fileName());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
form = m_dockedWidgets.last()->getFormByName(info.fileName());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (form)
|
|
|
|
{
|
|
|
|
m_dockedWidgets.last()->setForm(form);
|
|
|
|
m_dockedWidgets.last()->loadFormIntoDialog(form);
|
|
|
|
QApplication::processEvents();
|
|
|
|
connect(m_dockedWidgets.last(), SIGNAL(modified()),
|
|
|
|
this, SLOT(setModified()));
|
|
|
|
m_dockedWidgets.last()->raise();
|
|
|
|
connect(m_dockedWidgets.last(), SIGNAL(changeFile(QString)),
|
|
|
|
m_georgesDirTreeDialog, SLOT(changeFile(QString)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-28 12:34:58 +00:00
|
|
|
nlwarning("Failed to load form: %s", info.fileName().toUtf8().constData());
|
2012-05-29 13:31:11 +00:00
|
|
|
m_dockedWidgets.last()->close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::closingTreeView()
|
|
|
|
{
|
|
|
|
//qDebug() << "closingTreeView";
|
|
|
|
m_dockedWidgets.removeAll(qobject_cast<CGeorgesTreeViewDialog*>(sender()));
|
|
|
|
if (qobject_cast<CGeorgesTreeViewDialog*>(sender()) == m_lastActiveDock)
|
|
|
|
m_lastActiveDock = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::setModified ()
|
|
|
|
{
|
|
|
|
qDebug() << "setModified";
|
2014-08-18 17:49:32 +00:00
|
|
|
bool saveEnabled = false;
|
2012-05-29 13:31:11 +00:00
|
|
|
if (m_lastActiveDock)
|
2014-08-18 17:49:32 +00:00
|
|
|
saveEnabled = m_lastActiveDock->isModified();
|
2012-05-29 13:31:11 +00:00
|
|
|
else
|
2014-08-18 17:49:32 +00:00
|
|
|
saveEnabled = false;
|
|
|
|
|
|
|
|
m_saveAction->setEnabled( saveEnabled );
|
|
|
|
|
|
|
|
QAction *saveAction = Core::ICore::instance()->menuManager()->action( Core::Constants::SAVE );
|
|
|
|
saveAction->setEnabled( saveEnabled );
|
2012-05-29 13:31:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GeorgesEditorForm::focusChanged ( QWidget * old, QWidget * now )
|
|
|
|
{
|
|
|
|
if (now)
|
|
|
|
{
|
|
|
|
// ugly, UGLY hack for compensating QDockWidgets failure in focus API
|
|
|
|
if (now->objectName() == "treeView" ||
|
|
|
|
now->objectName() == "checkBoxDefaults" ||
|
|
|
|
now->objectName() == "checkBoxParent" ||
|
|
|
|
now->objectName() == "commentEdit")
|
|
|
|
{
|
|
|
|
QWidget *dlg = 0;
|
|
|
|
QApplication::focusWidget()?
|
|
|
|
QApplication::focusWidget()->parentWidget()?
|
|
|
|
QApplication::focusWidget()->parentWidget()->parentWidget()?
|
|
|
|
QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()?
|
|
|
|
QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()?
|
|
|
|
QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()?
|
|
|
|
dlg=QApplication::focusWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget()->parentWidget():dlg=0:dlg=0:dlg=0:dlg=0:dlg=0:dlg=0;
|
|
|
|
CGeorgesTreeViewDialog *active = qobject_cast<CGeorgesTreeViewDialog*>(dlg);
|
|
|
|
if(active)
|
|
|
|
{
|
|
|
|
//qDebug() << "focusChanged" << active->loadedForm;
|
|
|
|
m_lastActiveDock = active;
|
|
|
|
m_saveAction->setEnabled(active->isModified());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* namespace GeorgesQt */
|