forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'upstream/master' into pathfinding
Conflicts: apps/openmw/mwmechanics/aicombat.cpp apps/openmw/mwmechanics/aifollow.cpp apps/openmw/mwmechanics/aipackage.cpp apps/openmw/mwmechanics/aipackage.hpp apps/openmw/mwmechanics/aiwander.cpp apps/openmw/mwmechanics/pathfinding.hpp Ogre::Vector3->osg::Vec3f; REACTION_INTERVAL->AI_REACTION_TIME; MakeOgreVec3->MakeOsgVec3coverity_scan^2
commit
d7d5cc6689
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
OUTPUT=$(grep -nRP '\t' --include=\*.{cpp,hpp,c,h} --exclude=ui_\* apps components)
|
||||
|
||||
if [[ $OUTPUT ]] ; then
|
||||
echo "Error: Tab characters found!"
|
||||
echo $OUTPUT
|
||||
exit 1
|
||||
fi
|
@ -0,0 +1,16 @@
|
||||
Description
|
||||
===========
|
||||
|
||||
Your pull request description should include (if applicable):
|
||||
|
||||
* A link back to the bug report or forum discussion that prompted the change
|
||||
* Summary of the changes made
|
||||
* Reasoning / motivation behind the change
|
||||
* What testing you have carried out to verify the change
|
||||
|
||||
Other notes
|
||||
===========
|
||||
|
||||
* Separate your work into multiple pull requests whenever possible. As a rule of thumb, each feature and each bugfix should go into a separate PR, unless they are closely related or dependent upon each other. Small pull requests are easier to review, and are less likely to require further changes before we can merge them. A "mega" pull request with lots of unrelated commits in it is likely to get held up in review for a long time.
|
||||
* Feel free to submit incomplete pull requests. Even if the work can not be merged yet, pull requests are a great place to collect early feedback. Just make sure to mark it as *[Incomplete]* or *[Do not merge yet]* in the title.
|
||||
* If you plan on contributing often, please read the [Developer Reference](https://wiki.openmw.org/index.php?title=Developer_Reference) on our wiki, especially the [Policies and Standards](https://wiki.openmw.org/index.php?title=Policies_and_Standards).
|
@ -1,44 +0,0 @@
|
||||
#include "graphicssettings.hpp"
|
||||
|
||||
#include <QTextStream>
|
||||
#include <QString>
|
||||
#include <QRegExp>
|
||||
#include <QMap>
|
||||
|
||||
Launcher::GraphicsSettings::GraphicsSettings()
|
||||
{
|
||||
}
|
||||
|
||||
Launcher::GraphicsSettings::~GraphicsSettings()
|
||||
{
|
||||
}
|
||||
|
||||
bool Launcher::GraphicsSettings::writeFile(QTextStream &stream)
|
||||
{
|
||||
QString sectionPrefix;
|
||||
QRegExp sectionRe("([^/]+)/(.+)$");
|
||||
QMap<QString, QString> settings = SettingsBase::getSettings();
|
||||
|
||||
QMapIterator<QString, QString> i(settings);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
|
||||
QString prefix;
|
||||
QString key;
|
||||
|
||||
if (sectionRe.exactMatch(i.key())) {
|
||||
prefix = sectionRe.cap(1);
|
||||
key = sectionRe.cap(2);
|
||||
}
|
||||
|
||||
if (sectionPrefix != prefix) {
|
||||
sectionPrefix = prefix;
|
||||
stream << "\n[" << prefix << "]\n";
|
||||
}
|
||||
|
||||
stream << key << " = " << i.value() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#ifndef GRAPHICSSETTINGS_HPP
|
||||
#define GRAPHICSSETTINGS_HPP
|
||||
|
||||
#include <components/config/settingsbase.hpp>
|
||||
|
||||
namespace Launcher
|
||||
{
|
||||
class GraphicsSettings : public Config::SettingsBase<QMap<QString, QString> >
|
||||
{
|
||||
public:
|
||||
GraphicsSettings();
|
||||
~GraphicsSettings();
|
||||
|
||||
bool writeFile(QTextStream &stream);
|
||||
|
||||
};
|
||||
}
|
||||
#endif // GRAPHICSSETTINGS_HPP
|
@ -0,0 +1,165 @@
|
||||
///Program to test .nif files both on the FileSystem and in BSA archives.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <components/nif/niffile.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/bsaarchive.hpp>
|
||||
#include <components/vfs/filesystemarchive.hpp>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
// Create local aliases for brevity
|
||||
namespace bpo = boost::program_options;
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
///See if the file has the named extension
|
||||
bool hasExtension(std::string filename, std::string extensionToFind)
|
||||
{
|
||||
std::string extension = filename.substr(filename.find_last_of(".")+1);
|
||||
|
||||
//Convert strings to lower case for comparison
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
std::transform(extensionToFind.begin(), extensionToFind.end(), extensionToFind.begin(), ::tolower);
|
||||
|
||||
if(extension == extensionToFind)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
///See if the file has the "nif" extension.
|
||||
bool isNIF(std::string filename)
|
||||
{
|
||||
return hasExtension(filename,"nif");
|
||||
}
|
||||
///See if the file has the "bsa" extension.
|
||||
bool isBSA(std::string filename)
|
||||
{
|
||||
return hasExtension(filename,"bsa");
|
||||
}
|
||||
|
||||
/// Check all the nif files in a given VFS::Archive
|
||||
/// \note Takes ownership!
|
||||
/// \note Can not read a bsa file inside of a bsa file.
|
||||
void readVFS(VFS::Archive* anArchive,std::string archivePath = "")
|
||||
{
|
||||
VFS::Manager myManager(true);
|
||||
myManager.addArchive(anArchive);
|
||||
myManager.buildIndex();
|
||||
|
||||
std::map<std::string, VFS::File*> files=myManager.getIndex();
|
||||
for(std::map<std::string, VFS::File*>::const_iterator it=files.begin(); it!=files.end(); ++it)
|
||||
{
|
||||
std::string name = it->first;
|
||||
|
||||
try{
|
||||
if(isNIF(name))
|
||||
{
|
||||
// std::cout << "Decoding: " << name << std::endl;
|
||||
Nif::NIFFile temp_nif(myManager.get(name),archivePath+name);
|
||||
}
|
||||
else if(isBSA(name))
|
||||
{
|
||||
if(!archivePath.empty() && !isBSA(archivePath))
|
||||
{
|
||||
// std::cout << "Reading BSA File: " << name << std::endl;
|
||||
readVFS(new VFS::BsaArchive(archivePath+name),archivePath+name+"/");
|
||||
// std::cout << "Done with BSA File: " << name << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR, an exception has occurred: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> parseOptions (int argc, char** argv)
|
||||
{
|
||||
bpo::options_description desc("Ensure that OpenMW can use the provided NIF and BSA files\n\n"
|
||||
"Usages:\n"
|
||||
" niftool <nif files, BSA files, or directories>\n"
|
||||
" Scan the file or directories for nif errors.\n\n"
|
||||
"Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "print help message.")
|
||||
("input-file", bpo::value< std::vector<std::string> >(), "input file")
|
||||
;
|
||||
|
||||
//Default option if none provided
|
||||
bpo::positional_options_description p;
|
||||
p.add("input-file", -1);
|
||||
|
||||
bpo::variables_map variables;
|
||||
try
|
||||
{
|
||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run();
|
||||
bpo::store(valid_opts, variables);
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
std::cout << "ERROR parsing arguments: " << e.what() << "\n\n"
|
||||
<< desc << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bpo::notify(variables);
|
||||
if (variables.count ("help"))
|
||||
{
|
||||
std::cout << desc << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (variables.count("input-file"))
|
||||
{
|
||||
return variables["input-file"].as< std::vector<std::string> >();
|
||||
}
|
||||
|
||||
std::cout << "No input files or directories specified!" << std::endl;
|
||||
std::cout << desc << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::vector<std::string> files = parseOptions (argc, argv);
|
||||
|
||||
// std::cout << "Reading Files" << std::endl;
|
||||
for(std::vector<std::string>::const_iterator it=files.begin(); it!=files.end(); ++it)
|
||||
{
|
||||
std::string name = *it;
|
||||
|
||||
try{
|
||||
if(isNIF(name))
|
||||
{
|
||||
//std::cout << "Decoding: " << name << std::endl;
|
||||
Nif::NIFFile temp_nif(Files::openConstrainedFileStream(name.c_str()),name);
|
||||
}
|
||||
else if(isBSA(name))
|
||||
{
|
||||
// std::cout << "Reading BSA File: " << name << std::endl;
|
||||
readVFS(new VFS::BsaArchive(name));
|
||||
}
|
||||
else if(bfs::is_directory(bfs::path(name)))
|
||||
{
|
||||
// std::cout << "Reading All Files in: " << name << std::endl;
|
||||
readVFS(new VFS::FileSystemArchive(name),name);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: \"" << name << "\" is not a nif file, bsa file, or directory!" << std::endl;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR, an exception has occurred: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
|
||||
#include "boolsetting.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, bool default_)
|
||||
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::BoolSetting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
QCheckBox *widget = new QCheckBox (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
widget->setCheckState (mDefault ? Qt::Checked : Qt::Unchecked);
|
||||
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||
widget->setToolTip (tooltip);
|
||||
}
|
||||
|
||||
connect (widget, SIGNAL (stateChanged (int)), this, SLOT (valueChanged (int)));
|
||||
|
||||
return std::make_pair (static_cast<QWidget *> (0), widget);
|
||||
}
|
||||
|
||||
void CSMPrefs::BoolSetting::valueChanged (int value)
|
||||
{
|
||||
{
|
||||
QMutexLocker lock (getMutex());
|
||||
getValues().setBool (getKey(), getParent()->getKey(), value);
|
||||
}
|
||||
|
||||
getParent()->getState()->update (*this);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#ifndef CSM_PREFS_BOOLSETTING_H
|
||||
#define CSM_PREFS_BOOLSETTING_H
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class BoolSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
std::string mTooltip;
|
||||
bool mDefault;
|
||||
|
||||
public:
|
||||
|
||||
BoolSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, bool default_);
|
||||
|
||||
BoolSetting& setTooltip (const std::string& tooltip);
|
||||
|
||||
/// Return label, input widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void valueChanged (int value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,51 @@
|
||||
|
||||
#include "category.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "setting.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMPrefs::Category::Category (State *parent, const std::string& key)
|
||||
: mParent (parent), mKey (key)
|
||||
{}
|
||||
|
||||
const std::string& CSMPrefs::Category::getKey() const
|
||||
{
|
||||
return mKey;
|
||||
}
|
||||
|
||||
CSMPrefs::State *CSMPrefs::Category::getState() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
void CSMPrefs::Category::addSetting (Setting *setting)
|
||||
{
|
||||
mSettings.push_back (setting);
|
||||
}
|
||||
|
||||
CSMPrefs::Category::Iterator CSMPrefs::Category::begin()
|
||||
{
|
||||
return mSettings.begin();
|
||||
}
|
||||
|
||||
CSMPrefs::Category::Iterator CSMPrefs::Category::end()
|
||||
{
|
||||
return mSettings.end();
|
||||
}
|
||||
|
||||
CSMPrefs::Setting& CSMPrefs::Category::operator[] (const std::string& key)
|
||||
{
|
||||
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
|
||||
if ((*iter)->getKey()==key)
|
||||
return **iter;
|
||||
|
||||
throw std::logic_error ("Invalid user setting: " + key);
|
||||
}
|
||||
|
||||
void CSMPrefs::Category::update()
|
||||
{
|
||||
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
|
||||
mParent->update (**iter);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
#ifndef CSM_PREFS_CATEGORY_H
|
||||
#define CSM_PREFS_CATEGORY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class State;
|
||||
class Setting;
|
||||
|
||||
class Category
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<Setting *> Container;
|
||||
typedef Container::iterator Iterator;
|
||||
|
||||
private:
|
||||
|
||||
State *mParent;
|
||||
std::string mKey;
|
||||
Container mSettings;
|
||||
|
||||
public:
|
||||
|
||||
Category (State *parent, const std::string& key);
|
||||
|
||||
const std::string& getKey() const;
|
||||
|
||||
State *getState() const;
|
||||
|
||||
void addSetting (Setting *setting);
|
||||
|
||||
Iterator begin();
|
||||
|
||||
Iterator end();
|
||||
|
||||
Setting& operator[] (const std::string& key);
|
||||
|
||||
void update();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,52 @@
|
||||
|
||||
#include "coloursetting.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "../../view/widget/coloreditor.hpp"
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, QColor default_)
|
||||
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::ColourSetting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
|
||||
CSVWidget::ColorEditor *widget = new CSVWidget::ColorEditor (mDefault, parent);
|
||||
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||
label->setToolTip (tooltip);
|
||||
widget->setToolTip (tooltip);
|
||||
}
|
||||
|
||||
connect (widget, SIGNAL (pickingFinished()), this, SLOT (valueChanged()));
|
||||
|
||||
return std::make_pair (label, widget);
|
||||
}
|
||||
|
||||
void CSMPrefs::ColourSetting::valueChanged()
|
||||
{
|
||||
CSVWidget::ColorEditor& widget = dynamic_cast<CSVWidget::ColorEditor&> (*sender());
|
||||
{
|
||||
QMutexLocker lock (getMutex());
|
||||
getValues().setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data());
|
||||
}
|
||||
|
||||
getParent()->getState()->update (*this);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#ifndef CSM_PREFS_COLOURSETTING_H
|
||||
#define CSM_PREFS_COLOURSETTING_H
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
#include <QColor>
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class ColourSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
std::string mTooltip;
|
||||
QColor mDefault;
|
||||
|
||||
public:
|
||||
|
||||
ColourSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label,
|
||||
QColor default_);
|
||||
|
||||
ColourSetting& setTooltip (const std::string& tooltip);
|
||||
|
||||
/// Return label, input widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void valueChanged();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,75 @@
|
||||
|
||||
#include "doublesetting.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, double default_)
|
||||
: Setting (parent, values, mutex, key, label),
|
||||
mMin (0), mMax (std::numeric_limits<double>::max()),
|
||||
mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max)
|
||||
{
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMin (double min)
|
||||
{
|
||||
mMin = min;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMax (double max)
|
||||
{
|
||||
mMax = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setTooltip (const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
|
||||
QDoubleSpinBox *widget = new QDoubleSpinBox (parent);
|
||||
widget->setRange (mMin, mMax);
|
||||
widget->setValue (mDefault);
|
||||
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||
label->setToolTip (tooltip);
|
||||
widget->setToolTip (tooltip);
|
||||
}
|
||||
|
||||
connect (widget, SIGNAL (valueChanged (double)), this, SLOT (valueChanged (double)));
|
||||
|
||||
return std::make_pair (label, widget);
|
||||
}
|
||||
|
||||
void CSMPrefs::DoubleSetting::valueChanged (double value)
|
||||
{
|
||||
{
|
||||
QMutexLocker lock (getMutex());
|
||||
getValues().setFloat (getKey(), getParent()->getKey(), value);
|
||||
}
|
||||
|
||||
getParent()->getState()->update (*this);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#ifndef CSM_PREFS_DOUBLESETTING_H
|
||||
#define CSM_PREFS_DOUBLESETTING_H
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class DoubleSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
double mMin;
|
||||
double mMax;
|
||||
std::string mTooltip;
|
||||
double mDefault;
|
||||
|
||||
public:
|
||||
|
||||
DoubleSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label,
|
||||
double default_);
|
||||
|
||||
// defaults to [0, std::numeric_limits<double>::max()]
|
||||
DoubleSetting& setRange (double min, double max);
|
||||
|
||||
DoubleSetting& setMin (double min);
|
||||
|
||||
DoubleSetting& setMax (double max);
|
||||
|
||||
DoubleSetting& setTooltip (const std::string& tooltip);
|
||||
|
||||
/// Return label, input widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void valueChanged (double value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,112 @@
|
||||
|
||||
#include "enumsetting.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
|
||||
CSMPrefs::EnumValue::EnumValue (const std::string& value, const std::string& tooltip)
|
||||
: mValue (value), mTooltip (tooltip)
|
||||
{}
|
||||
|
||||
CSMPrefs::EnumValue::EnumValue (const char *value)
|
||||
: mValue (value)
|
||||
{}
|
||||
|
||||
|
||||
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValues& values)
|
||||
{
|
||||
mValues.insert (mValues.end(), values.mValues.begin(), values.mValues.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value)
|
||||
{
|
||||
mValues.push_back (value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip)
|
||||
{
|
||||
mValues.push_back (EnumValue (value, tooltip));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_)
|
||||
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValues (const EnumValues& values)
|
||||
{
|
||||
mValues.add (values);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const EnumValue& value)
|
||||
{
|
||||
mValues.add (value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const std::string& value, const std::string& tooltip)
|
||||
{
|
||||
mValues.add (value, tooltip);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::EnumSetting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
|
||||
QComboBox *widget = new QComboBox (parent);
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int i=0; i<static_cast<int> (mValues.mValues.size()); ++i)
|
||||
{
|
||||
if (mDefault.mValue==mValues.mValues[i].mValue)
|
||||
index = i;
|
||||
|
||||
widget->addItem (QString::fromUtf8 (mValues.mValues[i].mValue.c_str()));
|
||||
|
||||
if (!mValues.mValues[i].mTooltip.empty())
|
||||
widget->setItemData (i, QString::fromUtf8 (mValues.mValues[i].mTooltip.c_str()),
|
||||
Qt::ToolTipRole);
|
||||
}
|
||||
|
||||
widget->setCurrentIndex (index);
|
||||
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||
label->setToolTip (tooltip);
|
||||
}
|
||||
|
||||
connect (widget, SIGNAL (currentIndexChanged (int)), this, SLOT (valueChanged (int)));
|
||||
|
||||
return std::make_pair (label, widget);
|
||||
}
|
||||
|
||||
void CSMPrefs::EnumSetting::valueChanged (int value)
|
||||
{
|
||||
{
|
||||
QMutexLocker lock (getMutex());
|
||||
getValues().setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue);
|
||||
}
|
||||
|
||||
getParent()->getState()->update (*this);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
#ifndef CSM_PREFS_ENUMSETTING_H
|
||||
#define CSM_PREFS_ENUMSETTING_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
struct EnumValue
|
||||
{
|
||||
std::string mValue;
|
||||
std::string mTooltip;
|
||||
|
||||
EnumValue (const std::string& value, const std::string& tooltip = "");
|
||||
|
||||
EnumValue (const char *value);
|
||||
};
|
||||
|
||||
struct EnumValues
|
||||
{
|
||||
std::vector<EnumValue> mValues;
|
||||
|
||||
EnumValues& add (const EnumValues& values);
|
||||
|
||||
EnumValues& add (const EnumValue& value);
|
||||
|
||||
EnumValues& add (const std::string& value, const std::string& tooltip);
|
||||
};
|
||||
|
||||
class EnumSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
std::string mTooltip;
|
||||
EnumValue mDefault;
|
||||
EnumValues mValues;
|
||||
|
||||
public:
|
||||
|
||||
EnumSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label,
|
||||
const EnumValue& default_);
|
||||
|
||||
EnumSetting& setTooltip (const std::string& tooltip);
|
||||
|
||||
EnumSetting& addValues (const EnumValues& values);
|
||||
|
||||
EnumSetting& addValue (const EnumValue& value);
|
||||
|
||||
EnumSetting& addValue (const std::string& value, const std::string& tooltip);
|
||||
|
||||
/// Return label, input widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void valueChanged (int value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,74 @@
|
||||
|
||||
#include "intsetting.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, int default_)
|
||||
: Setting (parent, values, mutex, key, label), mMin (0), mMax (std::numeric_limits<int>::max()),
|
||||
mDefault (default_)
|
||||
{}
|
||||
|
||||
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max)
|
||||
{
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin (int min)
|
||||
{
|
||||
mMin = min;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax (int max)
|
||||
{
|
||||
mMax = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip (const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::IntSetting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||
|
||||
QSpinBox *widget = new QSpinBox (parent);
|
||||
widget->setRange (mMin, mMax);
|
||||
widget->setValue (mDefault);
|
||||
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||
label->setToolTip (tooltip);
|
||||
widget->setToolTip (tooltip);
|
||||
}
|
||||
|
||||
connect (widget, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int)));
|
||||
|
||||
return std::make_pair (label, widget);
|
||||
}
|
||||
|
||||
void CSMPrefs::IntSetting::valueChanged (int value)
|
||||
{
|
||||
{
|
||||
QMutexLocker lock (getMutex());
|
||||
getValues().setInt (getKey(), getParent()->getKey(), value);
|
||||
}
|
||||
|
||||
getParent()->getState()->update (*this);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
#ifndef CSM_PREFS_INTSETTING_H
|
||||
#define CSM_PREFS_INTSETTING_H
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class IntSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
int mMin;
|
||||
int mMax;
|
||||
std::string mTooltip;
|
||||
int mDefault;
|
||||
|
||||
public:
|
||||
|
||||
IntSetting (Category *parent, Settings::Manager *values,
|
||||
QMutex *mutex, const std::string& key, const std::string& label, int default_);
|
||||
|
||||
// defaults to [0, std::numeric_limits<int>::max()]
|
||||
IntSetting& setRange (int min, int max);
|
||||
|
||||
IntSetting& setMin (int min);
|
||||
|
||||
IntSetting& setMax (int max);
|
||||
|
||||
IntSetting& setTooltip (const std::string& tooltip);
|
||||
|
||||
/// Return label, input widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void valueChanged (int value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,97 @@
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
#include <QColor>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
Settings::Manager& CSMPrefs::Setting::getValues()
|
||||
{
|
||||
return *mValues;
|
||||
}
|
||||
|
||||
QMutex *CSMPrefs::Setting::getMutex()
|
||||
{
|
||||
return mMutex;
|
||||
}
|
||||
|
||||
CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, QMutex *mutex,
|
||||
const std::string& key, const std::string& label)
|
||||
: QObject (parent->getState()), mParent (parent), mValues (values), mMutex (mutex), mKey (key),
|
||||
mLabel (label)
|
||||
{}
|
||||
|
||||
CSMPrefs::Setting:: ~Setting() {}
|
||||
|
||||
std::pair<QWidget *, QWidget *> CSMPrefs::Setting::makeWidgets (QWidget *parent)
|
||||
{
|
||||
return std::pair<QWidget *, QWidget *> (0, 0);
|
||||
}
|
||||
|
||||
const CSMPrefs::Category *CSMPrefs::Setting::getParent() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
const std::string& CSMPrefs::Setting::getKey() const
|
||||
{
|
||||
return mKey;
|
||||
}
|
||||
|
||||
const std::string& CSMPrefs::Setting::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
int CSMPrefs::Setting::toInt() const
|
||||
{
|
||||
QMutexLocker lock (mMutex);
|
||||
return mValues->getInt (mKey, mParent->getKey());
|
||||
}
|
||||
|
||||
double CSMPrefs::Setting::toDouble() const
|
||||
{
|
||||
QMutexLocker lock (mMutex);
|
||||
return mValues->getFloat (mKey, mParent->getKey());
|
||||
}
|
||||
|
||||
std::string CSMPrefs::Setting::toString() const
|
||||
{
|
||||
QMutexLocker lock (mMutex);
|
||||
return mValues->getString (mKey, mParent->getKey());
|
||||
}
|
||||
|
||||
bool CSMPrefs::Setting::isTrue() const
|
||||
{
|
||||
QMutexLocker lock (mMutex);
|
||||
return mValues->getBool (mKey, mParent->getKey());
|
||||
}
|
||||
|
||||
QColor CSMPrefs::Setting::toColor() const
|
||||
{
|
||||
// toString() handles lock
|
||||
return QColor (QString::fromUtf8 (toString().c_str()));
|
||||
}
|
||||
|
||||
bool CSMPrefs::operator== (const Setting& setting, const std::string& key)
|
||||
{
|
||||
std::string fullKey = setting.getParent()->getKey() + "/" + setting.getKey();
|
||||
return fullKey==key;
|
||||
}
|
||||
|
||||
bool CSMPrefs::operator== (const std::string& key, const Setting& setting)
|
||||
{
|
||||
return setting==key;
|
||||
}
|
||||
|
||||
bool CSMPrefs::operator!= (const Setting& setting, const std::string& key)
|
||||
{
|
||||
return !(setting==key);
|
||||
}
|
||||
|
||||
bool CSMPrefs::operator!= (const std::string& key, const Setting& setting)
|
||||
{
|
||||
return !(key==setting);
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
#ifndef CSM_PREFS_SETTING_H
|
||||
#define CSM_PREFS_SETTING_H
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QWidget;
|
||||
class QColor;
|
||||
class QMutex;
|
||||
|
||||
namespace Settings
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Category;
|
||||
|
||||
class Setting : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Category *mParent;
|
||||
Settings::Manager *mValues;
|
||||
QMutex *mMutex;
|
||||
std::string mKey;
|
||||
std::string mLabel;
|
||||
|
||||
protected:
|
||||
|
||||
Settings::Manager& getValues();
|
||||
|
||||
QMutex *getMutex();
|
||||
|
||||
public:
|
||||
|
||||
Setting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label);
|
||||
|
||||
virtual ~Setting();
|
||||
|
||||
/// Return label, input widget.
|
||||
///
|
||||
/// \note first can be a 0-pointer, which means that the label is part of the input
|
||||
/// widget.
|
||||
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||
|
||||
const Category *getParent() const;
|
||||
|
||||
const std::string& getKey() const;
|
||||
|
||||
const std::string& getLabel() const;
|
||||
|
||||
int toInt() const;
|
||||
|
||||
double toDouble() const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
bool isTrue() const;
|
||||
|
||||
QColor toColor() const;
|
||||
};
|
||||
|
||||
// note: fullKeys have the format categoryKey/settingKey
|
||||
bool operator== (const Setting& setting, const std::string& fullKey);
|
||||
bool operator== (const std::string& fullKey, const Setting& setting);
|
||||
bool operator!= (const Setting& setting, const std::string& fullKey);
|
||||
bool operator!= (const std::string& fullKey, const Setting& setting);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,392 @@
|
||||
|
||||
#include "state.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "intsetting.hpp"
|
||||
#include "doublesetting.hpp"
|
||||
#include "boolsetting.hpp"
|
||||
#include "coloursetting.hpp"
|
||||
|
||||
CSMPrefs::State *CSMPrefs::State::sThis = 0;
|
||||
|
||||
void CSMPrefs::State::load()
|
||||
{
|
||||
// default settings file
|
||||
boost::filesystem::path local = mConfigurationManager.getLocalPath() / mConfigFile;
|
||||
boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mConfigFile;
|
||||
|
||||
if (boost::filesystem::exists (local))
|
||||
mSettings.loadDefault (local.string());
|
||||
else if (boost::filesystem::exists (global))
|
||||
mSettings.loadDefault (global.string());
|
||||
else
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"openmw-cs.cfg\" was properly installed.");
|
||||
|
||||
// user settings file
|
||||
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
|
||||
|
||||
if (boost::filesystem::exists (user))
|
||||
mSettings.loadUser (user.string());
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declare()
|
||||
{
|
||||
declareCategory ("Windows");
|
||||
declareInt ("default-width", "Default window width", 800).
|
||||
setTooltip ("Newly opened top-level windows will open with this width.").
|
||||
setMin (80);
|
||||
declareInt ("default-height", "Default window height", 600).
|
||||
setTooltip ("Newly opened top-level windows will open with this height.").
|
||||
setMin (80);
|
||||
declareBool ("show-statusbar", "Show Status Bar", true).
|
||||
setTooltip ("If a newly open top level window is showing status bars or not. "
|
||||
" Note that this does not affect existing windows.");
|
||||
declareSeparator();
|
||||
declareBool ("reuse", "Reuse Subviews", true).
|
||||
setTooltip ("When a new subview is requested and a matching subview already "
|
||||
" exist, do not open a new subview and use the existing one instead.");
|
||||
declareInt ("max-subviews", "Maximum number of subviews per top-level window", 256).
|
||||
setTooltip ("If the maximum number is reached and a new subview is opened "
|
||||
"it will be placed into a new top-level window.").
|
||||
setRange (1, 256);
|
||||
declareBool ("hide-subview", "Hide single subview", false).
|
||||
setTooltip ("When a view contains only a single subview, hide the subview title "
|
||||
"bar and if this subview is closed also close the view (unless it is the last "
|
||||
"view for this document)");
|
||||
declareInt ("minimum-width", "Minimum subview width", 325).
|
||||
setTooltip ("Minimum width of subviews.").
|
||||
setRange (50, 10000);
|
||||
declareSeparator();
|
||||
EnumValue scrollbarOnly ("Scrollbar Only", "Simple addition of scrollbars, the view window "
|
||||
"does not grow automatically.");
|
||||
declareEnum ("mainwindow-scrollbar", "Horizontal scrollbar mode for main window.", scrollbarOnly).
|
||||
addValue (scrollbarOnly).
|
||||
addValue ("Grow Only", "The view window grows as subviews are added. No scrollbars.").
|
||||
addValue ("Grow then Scroll", "The view window grows. The scrollbar appears once it cannot grow any further.");
|
||||
declareBool ("grow-limit", "Grow Limit Screen", false).
|
||||
setTooltip ("When \"Grow then Scroll\" option is selected, the window size grows to"
|
||||
" the width of the virtual desktop. \nIf this option is selected the the window growth"
|
||||
"is limited to the current screen.");
|
||||
|
||||
declareCategory ("Records");
|
||||
EnumValue iconAndText ("Icon and Text");
|
||||
EnumValues recordValues;
|
||||
recordValues.add (iconAndText).add ("Icon Only").add ("Text Only");
|
||||
declareEnum ("status-format", "Modification status display format", iconAndText).
|
||||
addValues (recordValues);
|
||||
declareEnum ("type-format", "ID type display format", iconAndText).
|
||||
addValues (recordValues);
|
||||
|
||||
declareCategory ("ID Tables");
|
||||
EnumValue inPlaceEdit ("Edit in Place", "Edit the clicked cell");
|
||||
EnumValue editRecord ("Edit Record", "Open a dialogue subview for the clicked record");
|
||||
EnumValue view ("View", "Open a scene subview for the clicked record (not available everywhere)");
|
||||
EnumValue editRecordAndClose ("Edit Record and Close");
|
||||
EnumValues doubleClickValues;
|
||||
doubleClickValues.add (inPlaceEdit).add (editRecord).add (view).add ("Revert").
|
||||
add ("Delete").add (editRecordAndClose).
|
||||
add ("View and Close", "Open a scene subview for the clicked record and close the table subview");
|
||||
declareEnum ("double", "Double Click", inPlaceEdit).addValues (doubleClickValues);
|
||||
declareEnum ("double-s", "Shift Double Click", editRecord).addValues (doubleClickValues);
|
||||
declareEnum ("double-c", "Control Double Click", view).addValues (doubleClickValues);
|
||||
declareEnum ("double-sc", "Shift Control Double Click", editRecordAndClose).addValues (doubleClickValues);
|
||||
declareSeparator();
|
||||
EnumValue jumpAndSelect ("Jump and Select", "Scroll new record into view and make it the selection");
|
||||
declareEnum ("jump-to-added", "Action on adding or cloning a record", jumpAndSelect).
|
||||
addValue (jumpAndSelect).
|
||||
addValue ("Jump Only", "Scroll new record into view").
|
||||
addValue ("No Jump", "No special action");
|
||||
declareBool ("extended-config",
|
||||
"Manually specify affected record types for an extended delete/revert", false).
|
||||
setTooltip ("Delete and revert commands have an extended form that also affects "
|
||||
"associated records.\n\n"
|
||||
"If this option is enabled, types of affected records are selected "
|
||||
"manually before a command execution.\nOtherwise, all associated "
|
||||
"records are deleted/reverted immediately.");
|
||||
|
||||
declareCategory ("ID Dialogues");
|
||||
declareBool ("toolbar", "Show toolbar", true);
|
||||
|
||||
declareCategory ("Reports");
|
||||
EnumValue actionNone ("None");
|
||||
EnumValue actionEdit ("Edit", "Open a table or dialogue suitable for addressing the listed report");
|
||||
EnumValue actionRemove ("Remove", "Remove the report from the report table");
|
||||
EnumValue actionEditAndRemove ("Edit And Remove", "Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table");
|
||||
EnumValues reportValues;
|
||||
reportValues.add (actionNone).add (actionEdit).add (actionRemove).add (actionEditAndRemove);
|
||||
declareEnum ("double", "Double Click", actionEdit).addValues (reportValues);
|
||||
declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues);
|
||||
declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues);
|
||||
declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues);
|
||||
|
||||
declareCategory ("Search & Replace");
|
||||
declareInt ("char-before", "Characters before search string", 10).
|
||||
setTooltip ("Maximum number of character to display in search result before the searched text");
|
||||
declareInt ("char-after", "Characters after search string", 10).
|
||||
setTooltip ("Maximum number of character to display in search result after the searched text");
|
||||
declareBool ("auto-delete", "Delete row from result table after a successful replace", true);
|
||||
|
||||
declareCategory ("Scripts");
|
||||
declareBool ("show-linenum", "Show Line Numbers", true).
|
||||
setTooltip ("Show line numbers to the left of the script editor window."
|
||||
"The current row and column numbers of the text cursor are shown at the bottom.");
|
||||
declareBool ("mono-font", "Use monospace font", true);
|
||||
EnumValue warningsNormal ("Normal", "Report warnings as warning");
|
||||
declareEnum ("warnings", "Warning Mode", warningsNormal).
|
||||
addValue ("Ignore", "Do not report warning").
|
||||
addValue (warningsNormal).
|
||||
addValue ("Strcit", "Promote warning to an error");
|
||||
declareBool ("toolbar", "Show toolbar", true);
|
||||
declareInt ("compile-delay", "Delay between updating of source errors", 100).
|
||||
setTooltip ("Delay in milliseconds").
|
||||
setRange (0, 10000);
|
||||
declareInt ("error-height", "Initial height of the error panel", 100).
|
||||
setRange (100, 10000);
|
||||
declareSeparator();
|
||||
declareColour ("colour-int", "Highlight Colour: Integer Literals", QColor ("darkmagenta"));
|
||||
declareColour ("colour-float", "Highlight Colour: Float Literals", QColor ("magenta"));
|
||||
declareColour ("colour-name", "Highlight Colour: Names", QColor ("grey"));
|
||||
declareColour ("colour-keyword", "Highlight Colour: Keywords", QColor ("red"));
|
||||
declareColour ("colour-special", "Highlight Colour: Special Characters", QColor ("darkorange"));
|
||||
declareColour ("colour-comment", "Highlight Colour: Comments", QColor ("green"));
|
||||
declareColour ("colour-id", "Highlight Colour: IDs", QColor ("blue"));
|
||||
|
||||
declareCategory ("General Input");
|
||||
declareBool ("cycle", "Cyclic next/previous", false).
|
||||
setTooltip ("When using next/previous functions at the last/first item of a "
|
||||
"list go to the first/last item");
|
||||
|
||||
declareCategory ("3D Scene Input");
|
||||
EnumValue left ("Left Mouse-Button");
|
||||
EnumValue cLeft ("Ctrl-Left Mouse-Button");
|
||||
EnumValue right ("Right Mouse-Button");
|
||||
EnumValue cRight ("Ctrl-Right Mouse-Button");
|
||||
EnumValue middle ("Middle Mouse-Button");
|
||||
EnumValue cMiddle ("Ctrl-Middle Mouse-Button");
|
||||
EnumValues inputButtons;
|
||||
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
|
||||
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
|
||||
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
|
||||
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
|
||||
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
|
||||
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
|
||||
declareEnum ("s-select", "Secondary Selection Button", cMiddle).addValues (inputButtons);
|
||||
declareSeparator();
|
||||
declareBool ("context-select", "Context Sensitive Selection", false);
|
||||
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
|
||||
setRange (0.001, 100.0);
|
||||
declareDouble ("drag-wheel-factor", "Mouse wheel sensitivity during drag operations", 1.0).
|
||||
setRange (0.001, 100.0);
|
||||
declareDouble ("drag-shift-factor",
|
||||
"Shift-acceleration factor during drag operations", 4.0).
|
||||
setTooltip ("Acceleration factor during drag operations while holding down shift").
|
||||
setRange (0.001, 100.0);
|
||||
|
||||
declareCategory ("Tooltips");
|
||||
declareBool ("scene", "Show Tooltips in 3D scenes", true);
|
||||
declareBool ("scene-hide-basic", "Hide basic 3D scenes tooltips", false);
|
||||
declareInt ("scene-delay", "Tooltip delay in milliseconds", 500).
|
||||
setMin (1);
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declareCategory (const std::string& key)
|
||||
{
|
||||
std::map<std::string, Category>::iterator iter = mCategories.find (key);
|
||||
|
||||
if (iter!=mCategories.end())
|
||||
{
|
||||
mCurrentCategory = iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentCategory =
|
||||
mCategories.insert (std::make_pair (key, Category (this, key))).first;
|
||||
}
|
||||
}
|
||||
|
||||
CSMPrefs::IntSetting& CSMPrefs::State::declareInt (const std::string& key,
|
||||
const std::string& label, int default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << default_;
|
||||
setDefault (key, stream.str());
|
||||
|
||||
default_ = mSettings.getInt (key, mCurrentCategory->second.getKey());
|
||||
|
||||
CSMPrefs::IntSetting *setting =
|
||||
new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||
default_);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble (const std::string& key,
|
||||
const std::string& label, double default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << default_;
|
||||
setDefault (key, stream.str());
|
||||
|
||||
default_ = mSettings.getFloat (key, mCurrentCategory->second.getKey());
|
||||
|
||||
CSMPrefs::DoubleSetting *setting =
|
||||
new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||
key, label, default_);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::BoolSetting& CSMPrefs::State::declareBool (const std::string& key,
|
||||
const std::string& label, bool default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
setDefault (key, default_ ? "true" : "false");
|
||||
|
||||
default_ = mSettings.getBool (key, mCurrentCategory->second.getKey());
|
||||
|
||||
CSMPrefs::BoolSetting *setting =
|
||||
new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||
default_);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum (const std::string& key,
|
||||
const std::string& label, EnumValue default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
setDefault (key, default_.mValue);
|
||||
|
||||
default_.mValue = mSettings.getString (key, mCurrentCategory->second.getKey());
|
||||
|
||||
CSMPrefs::EnumSetting *setting =
|
||||
new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||
default_);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
|
||||
const std::string& label, QColor default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
setDefault (key, default_.name().toUtf8().data());
|
||||
|
||||
default_.setNamedColor (QString::fromUtf8 (mSettings.getString (key, mCurrentCategory->second.getKey()).c_str()));
|
||||
|
||||
CSMPrefs::ColourSetting *setting =
|
||||
new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||
default_);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declareSeparator()
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
CSMPrefs::Setting *setting =
|
||||
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", "");
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
}
|
||||
|
||||
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
|
||||
{
|
||||
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
|
||||
|
||||
Settings::CategorySettingValueMap::iterator iter =
|
||||
mSettings.mDefaultSettings.find (fullKey);
|
||||
|
||||
if (iter==mSettings.mDefaultSettings.end())
|
||||
mSettings.mDefaultSettings.insert (std::make_pair (fullKey, default_));
|
||||
}
|
||||
|
||||
CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
|
||||
: mConfigFile ("openmw-cs.cfg"), mConfigurationManager (configurationManager),
|
||||
mCurrentCategory (mCategories.end())
|
||||
{
|
||||
if (sThis)
|
||||
throw std::logic_error ("An instance of CSMPRefs::State already exists");
|
||||
|
||||
load();
|
||||
declare();
|
||||
|
||||
sThis = this;
|
||||
}
|
||||
|
||||
CSMPrefs::State::~State()
|
||||
{
|
||||
sThis = 0;
|
||||
}
|
||||
|
||||
void CSMPrefs::State::save()
|
||||
{
|
||||
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
|
||||
mSettings.saveUser (user.string());
|
||||
}
|
||||
|
||||
CSMPrefs::State::Iterator CSMPrefs::State::begin()
|
||||
{
|
||||
return mCategories.begin();
|
||||
}
|
||||
|
||||
CSMPrefs::State::Iterator CSMPrefs::State::end()
|
||||
{
|
||||
return mCategories.end();
|
||||
}
|
||||
|
||||
CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
|
||||
{
|
||||
Iterator iter = mCategories.find (key);
|
||||
|
||||
if (iter==mCategories.end())
|
||||
throw std::logic_error ("Invalid user settings category: " + key);
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void CSMPrefs::State::update (const Setting& setting)
|
||||
{
|
||||
emit (settingChanged (&setting));
|
||||
}
|
||||
|
||||
CSMPrefs::State& CSMPrefs::State::get()
|
||||
{
|
||||
if (!sThis)
|
||||
throw std::logic_error ("No instance of CSMPrefs::State");
|
||||
|
||||
return *sThis;
|
||||
}
|
||||
|
||||
|
||||
CSMPrefs::State& CSMPrefs::get()
|
||||
{
|
||||
return State::get();
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
#ifndef CSV_PREFS_STATE_H
|
||||
#define CSM_PREFS_STATE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "category.hpp"
|
||||
#include "setting.hpp"
|
||||
#include "enumsetting.hpp"
|
||||
|
||||
class QColor;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class IntSetting;
|
||||
class DoubleSetting;
|
||||
class BoolSetting;
|
||||
class ColourSetting;
|
||||
|
||||
/// \brief User settings state
|
||||
///
|
||||
/// \note Access to the user settings is thread-safe once all declarations and loading has
|
||||
/// been completed.
|
||||
class State : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
static State *sThis;
|
||||
|
||||
public:
|
||||
|
||||
typedef std::map<std::string, Category> Collection;
|
||||
typedef Collection::iterator Iterator;
|
||||
|
||||
private:
|
||||
|
||||
const std::string mConfigFile;
|
||||
const Files::ConfigurationManager& mConfigurationManager;
|
||||
Settings::Manager mSettings;
|
||||
Collection mCategories;
|
||||
Iterator mCurrentCategory;
|
||||
QMutex mMutex;
|
||||
|
||||
// not implemented
|
||||
State (const State&);
|
||||
State& operator= (const State&);
|
||||
|
||||
private:
|
||||
|
||||
void load();
|
||||
|
||||
void declare();
|
||||
|
||||
void declareCategory (const std::string& key);
|
||||
|
||||
IntSetting& declareInt (const std::string& key, const std::string& label, int default_);
|
||||
DoubleSetting& declareDouble (const std::string& key, const std::string& label, double default_);
|
||||
|
||||
BoolSetting& declareBool (const std::string& key, const std::string& label, bool default_);
|
||||
|
||||
EnumSetting& declareEnum (const std::string& key, const std::string& label, EnumValue default_);
|
||||
|
||||
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
|
||||
|
||||
void declareSeparator();
|
||||
|
||||
void setDefault (const std::string& key, const std::string& default_);
|
||||
|
||||
public:
|
||||
|
||||
State (const Files::ConfigurationManager& configurationManager);
|
||||
|
||||
~State();
|
||||
|
||||
void save();
|
||||
|
||||
Iterator begin();
|
||||
|
||||
Iterator end();
|
||||
|
||||
Category& operator[](const std::string& key);
|
||||
|
||||
void update (const Setting& setting);
|
||||
|
||||
static State& get();
|
||||
|
||||
signals:
|
||||
|
||||
void settingChanged (const CSMPrefs::Setting *setting);
|
||||
};
|
||||
|
||||
// convenience function
|
||||
State& get();
|
||||
}
|
||||
|
||||
#endif
|
@ -1,128 +0,0 @@
|
||||
#include "connector.hpp"
|
||||
#include "../../view/settings/view.hpp"
|
||||
#include "../../view/settings/page.hpp"
|
||||
|
||||
CSMSettings::Connector::Connector(CSVSettings::View *master,
|
||||
QObject *parent)
|
||||
: QObject(parent), mMasterView (master)
|
||||
{}
|
||||
|
||||
void CSMSettings::Connector::addSlaveView (CSVSettings::View *view,
|
||||
QList <QStringList> &masterProxyValues)
|
||||
{
|
||||
mSlaveViews.append (view);
|
||||
|
||||
mProxyListMap[view->viewKey()].append (masterProxyValues);
|
||||
}
|
||||
|
||||
QList <QStringList> CSMSettings::Connector::getSlaveViewValues() const
|
||||
{
|
||||
QList <QStringList> list;
|
||||
|
||||
foreach (const CSVSettings::View *view, mSlaveViews)
|
||||
list.append (view->selectedValues());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool CSMSettings::Connector::proxyListsMatch (
|
||||
const QList <QStringList> &list1,
|
||||
const QList <QStringList> &list2) const
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
for (int i = 0; i < list1.size(); i++)
|
||||
{
|
||||
success = stringListsMatch (list1.at(i), list2.at(i));
|
||||
|
||||
if (!success)
|
||||
break;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void CSMSettings::Connector::slotUpdateMaster() const
|
||||
{
|
||||
//list of the current values for each slave.
|
||||
QList <QStringList> slaveValueList = getSlaveViewValues();
|
||||
|
||||
int masterColumn = -1;
|
||||
|
||||
/*
|
||||
* A row in the master view is one of the values in the
|
||||
* master view's data model. This corresponds directly to the number of
|
||||
* values in a proxy list contained in the ProxyListMap member.
|
||||
* Thus, we iterate each "column" in the master proxy list
|
||||
* (one for each vlaue in the master. Each column represents
|
||||
* one master value's corresponding list of slave values. We examine
|
||||
* each master value's list, comparing it to the current slave value list,
|
||||
* stopping when we find a match using proxyListsMatch().
|
||||
*
|
||||
* If no match is found, clear the master view's value
|
||||
*/
|
||||
|
||||
for (int i = 0; i < mMasterView->rowCount(); i++)
|
||||
{
|
||||
QList <QStringList> proxyValueList;
|
||||
|
||||
foreach (const QString &settingKey, mProxyListMap.keys())
|
||||
{
|
||||
// append the proxy value list stored in the i'th column
|
||||
// for each setting key. A setting key is the id of the setting
|
||||
// in page.name format.
|
||||
proxyValueList.append (mProxyListMap.value(settingKey).at(i));
|
||||
}
|
||||
|
||||
if (proxyListsMatch (slaveValueList, proxyValueList))
|
||||
{
|
||||
masterColumn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString masterValue = mMasterView->value (masterColumn);
|
||||
|
||||
mMasterView->setSelectedValue (masterValue);
|
||||
}
|
||||
|
||||
void CSMSettings::Connector::slotUpdateSlaves() const
|
||||
{
|
||||
int row = mMasterView->currentIndex();
|
||||
|
||||
if (row == -1)
|
||||
return;
|
||||
|
||||
//iterate the proxy lists for the chosen master index
|
||||
//and pass the list to each slave for updating
|
||||
for (int i = 0; i < mSlaveViews.size(); i++)
|
||||
{
|
||||
QList <QStringList> proxyList =
|
||||
mProxyListMap.value(mSlaveViews.at(i)->viewKey());
|
||||
|
||||
mSlaveViews.at(i)->setSelectedValues (proxyList.at(row));
|
||||
}
|
||||
}
|
||||
|
||||
bool CSMSettings::Connector::stringListsMatch (
|
||||
const QStringList &list1,
|
||||
const QStringList &list2) const
|
||||
{
|
||||
//returns a "sloppy" match, verifying that each list contains all the same
|
||||
//items, though not necessarily in the same order.
|
||||
|
||||
if (list1.size() != list2.size())
|
||||
return false;
|
||||
|
||||
QStringList tempList(list2);
|
||||
|
||||
//iterate each value in the list, removing one occurrence of the value in
|
||||
//the other list. If no corresponding value is found, test fails
|
||||
foreach (const QString &value, list1)
|
||||
{
|
||||
if (!tempList.contains(value))
|
||||
return false;
|
||||
|
||||
tempList.removeOne(value);
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
#ifndef CSMSETTINGS_CONNECTOR_HPP
|
||||
#define CSMSETTINGS_CONNECTOR_HPP
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QStringList>
|
||||
|
||||
#include "support.hpp"
|
||||
|
||||
namespace CSVSettings {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace CSMSettings {
|
||||
|
||||
class Connector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSVSettings::View *mMasterView;
|
||||
|
||||
///map using the view pointer as a key to it's index value
|
||||
QList <CSVSettings::View *> mSlaveViews;
|
||||
|
||||
///list of proxy values for each master value.
|
||||
///value list order is indexed to the master value index.
|
||||
QMap < QString, QList <QStringList> > mProxyListMap;
|
||||
|
||||
public:
|
||||
explicit Connector(CSVSettings::View *master,
|
||||
QObject *parent = 0);
|
||||
|
||||
///Set the view which acts as a proxy for other setting views
|
||||
void setMasterView (CSVSettings::View *view);
|
||||
|
||||
///Add a view to be updated / update to the master
|
||||
void addSlaveView (CSVSettings::View *view,
|
||||
QList <QStringList> &masterProxyValues);
|
||||
|
||||
private:
|
||||
|
||||
///loosely matches lists of proxy values across registered slaves
|
||||
///against a proxy value list for a given master value
|
||||
bool proxyListsMatch (const QList <QStringList> &list1,
|
||||
const QList <QStringList> &list2) const;
|
||||
|
||||
///loosely matches two string lists
|
||||
bool stringListsMatch (const QStringList &list1,
|
||||
const QStringList &list2) const;
|
||||
|
||||
///retrieves current values of registered slave views
|
||||
QList <QStringList> getSlaveViewValues() const;
|
||||
|
||||
public slots:
|
||||
|
||||
///updates slave views with proxy values associated with current
|
||||
///master value
|
||||
void slotUpdateSlaves() const;
|
||||
|
||||
///updates master value associated with the currently selected
|
||||
///slave values, if applicable.
|
||||
void slotUpdateMaster() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSMSETTINGS_CONNECTOR_HPP
|
@ -1,414 +0,0 @@
|
||||
#include "setting.hpp"
|
||||
#include "support.hpp"
|
||||
|
||||
CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
|
||||
const QString &pageName, const QString& label)
|
||||
: mIsEditorSetting (true)
|
||||
{
|
||||
buildDefaultSetting();
|
||||
|
||||
int settingType = static_cast <int> (typ);
|
||||
|
||||
//even-numbered setting types are multi-valued
|
||||
if ((settingType % 2) == 0)
|
||||
setProperty (Property_IsMultiValue, QVariant(true).toString());
|
||||
|
||||
//view type is related to setting type by an order of magnitude
|
||||
setProperty (Property_SettingType, QVariant (settingType).toString());
|
||||
setProperty (Property_Page, pageName);
|
||||
setProperty (Property_Name, settingName);
|
||||
setProperty (Property_Label, label.isEmpty() ? settingName : label);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::buildDefaultSetting()
|
||||
{
|
||||
int arrLen = sizeof(sPropertyDefaults) / sizeof (*sPropertyDefaults);
|
||||
|
||||
for (int i = 0; i < arrLen; i++)
|
||||
{
|
||||
QStringList propertyList;
|
||||
|
||||
if (i <Property_DefaultValues)
|
||||
propertyList.append (sPropertyDefaults[i]);
|
||||
|
||||
mProperties.append (propertyList);
|
||||
}
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::addProxy (const Setting *setting,
|
||||
const QStringList &vals)
|
||||
{
|
||||
if (serializable())
|
||||
setSerializable (false);
|
||||
|
||||
QList <QStringList> list;
|
||||
|
||||
foreach (const QString &val, vals)
|
||||
list << (QStringList() << val);
|
||||
|
||||
mProxies [setting->page() + '/' + setting->name()] = list;
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::addProxy (const Setting *setting,
|
||||
const QList <QStringList> &list)
|
||||
{
|
||||
if (serializable())
|
||||
setProperty (Property_Serializable, false);
|
||||
|
||||
mProxies [setting->page() + '/' + setting->name()] = list;
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setColumnSpan (int value)
|
||||
{
|
||||
setProperty (Property_ColumnSpan, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::columnSpan() const
|
||||
{
|
||||
return property (Property_ColumnSpan).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDeclaredValues (QStringList list)
|
||||
{
|
||||
setProperty (Property_DeclaredValues, list);
|
||||
}
|
||||
|
||||
QStringList CSMSettings::Setting::declaredValues() const
|
||||
{
|
||||
return property (Property_DeclaredValues);
|
||||
}
|
||||
|
||||
QStringList CSMSettings::Setting::property (SettingProperty prop) const
|
||||
{
|
||||
if (prop >= mProperties.size())
|
||||
return QStringList();
|
||||
|
||||
return mProperties.at(prop);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDefaultValue (int value)
|
||||
{
|
||||
setDefaultValues (QStringList() << QVariant (value).toString());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDefaultValue (double value)
|
||||
{
|
||||
setDefaultValues (QStringList() << QVariant (value).toString());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDefaultValue (const QString &value)
|
||||
{
|
||||
setDefaultValues (QStringList() << value);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDefaultValues (const QStringList &values)
|
||||
{
|
||||
setProperty (Property_DefaultValues, values);
|
||||
}
|
||||
|
||||
QStringList CSMSettings::Setting::defaultValues() const
|
||||
{
|
||||
return property (Property_DefaultValues);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setDelimiter (const QString &value)
|
||||
{
|
||||
setProperty (Property_Delimiter, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::delimiter() const
|
||||
{
|
||||
return property (Property_Delimiter).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setEditorSetting(bool state)
|
||||
{
|
||||
mIsEditorSetting = true;
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::isEditorSetting() const
|
||||
{
|
||||
return mIsEditorSetting;
|
||||
}
|
||||
void CSMSettings::Setting::setIsMultiLine (bool state)
|
||||
{
|
||||
setProperty (Property_IsMultiLine, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::isMultiLine() const
|
||||
{
|
||||
return (property (Property_IsMultiLine).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setIsMultiValue (bool state)
|
||||
{
|
||||
setProperty (Property_IsMultiValue, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::isMultiValue() const
|
||||
{
|
||||
return (property (Property_IsMultiValue).at(0) == "true");
|
||||
}
|
||||
|
||||
const CSMSettings::ProxyValueMap &CSMSettings::Setting::proxyLists() const
|
||||
{
|
||||
return mProxies;
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setSerializable (bool state)
|
||||
{
|
||||
setProperty (Property_Serializable, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::serializable() const
|
||||
{
|
||||
return (property (Property_Serializable).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setSpecialValueText(const QString &text)
|
||||
{
|
||||
setProperty (Property_SpecialValueText, text);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::specialValueText() const
|
||||
{
|
||||
return property (Property_SpecialValueText).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setName (const QString &value)
|
||||
{
|
||||
setProperty (Property_Name, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::name() const
|
||||
{
|
||||
return property (Property_Name).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setPage (const QString &value)
|
||||
{
|
||||
setProperty (Property_Page, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::page() const
|
||||
{
|
||||
return property (Property_Page).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setStyleSheet (const QString &value)
|
||||
{
|
||||
setProperty (Property_StyleSheet, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::styleSheet() const
|
||||
{
|
||||
return property (Property_StyleSheet).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setPrefix (const QString &value)
|
||||
{
|
||||
setProperty (Property_Prefix, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::prefix() const
|
||||
{
|
||||
return property (Property_Prefix).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setRowSpan (const int value)
|
||||
{
|
||||
setProperty (Property_RowSpan, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::rowSpan () const
|
||||
{
|
||||
return property (Property_RowSpan).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setSingleStep (int value)
|
||||
{
|
||||
setProperty (Property_SingleStep, value);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setSingleStep (double value)
|
||||
{
|
||||
setProperty (Property_SingleStep, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::singleStep() const
|
||||
{
|
||||
return property (Property_SingleStep).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setSuffix (const QString &value)
|
||||
{
|
||||
setProperty (Property_Suffix, value);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::suffix() const
|
||||
{
|
||||
return property (Property_Suffix).at(0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setTickInterval (int value)
|
||||
{
|
||||
setProperty (Property_TickInterval, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::tickInterval () const
|
||||
{
|
||||
return property (Property_TickInterval).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setTicksAbove (bool state)
|
||||
{
|
||||
setProperty (Property_TicksAbove, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::ticksAbove() const
|
||||
{
|
||||
return (property (Property_TicksAbove).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setTicksBelow (bool state)
|
||||
{
|
||||
setProperty (Property_TicksBelow, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::ticksBelow() const
|
||||
{
|
||||
return (property (Property_TicksBelow).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setType (int settingType)
|
||||
{
|
||||
setProperty (Property_SettingType, settingType);
|
||||
}
|
||||
|
||||
CSMSettings::SettingType CSMSettings::Setting::type() const
|
||||
{
|
||||
return static_cast <CSMSettings::SettingType> ( property (
|
||||
Property_SettingType).at(0).toInt());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setRange (int min, int max)
|
||||
{
|
||||
setProperty (Property_Minimum, min);
|
||||
setProperty (Property_Maximum, max);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setRange (double min, double max)
|
||||
{
|
||||
setProperty (Property_Minimum, min);
|
||||
setProperty (Property_Maximum, max);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::maximum() const
|
||||
{
|
||||
return property (Property_Maximum).at(0);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::minimum() const
|
||||
{
|
||||
return property (Property_Minimum).at(0);
|
||||
}
|
||||
|
||||
CSVSettings::ViewType CSMSettings::Setting::viewType() const
|
||||
{
|
||||
return static_cast <CSVSettings::ViewType> ( property (
|
||||
Property_SettingType).at(0).toInt() / 10);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setViewColumn (int value)
|
||||
{
|
||||
setProperty (Property_ViewColumn, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::viewColumn() const
|
||||
{
|
||||
return property (Property_ViewColumn).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setViewLocation (int row, int column)
|
||||
{
|
||||
setViewRow (row);
|
||||
setViewColumn (column);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setViewRow (int value)
|
||||
{
|
||||
setProperty (Property_ViewRow, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::viewRow() const
|
||||
{
|
||||
return property (Property_ViewRow).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setWidgetWidth (int value)
|
||||
{
|
||||
setProperty (Property_WidgetWidth, value);
|
||||
}
|
||||
|
||||
int CSMSettings::Setting::widgetWidth() const
|
||||
{
|
||||
return property (Property_WidgetWidth).at(0).toInt();
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setWrapping (bool state)
|
||||
{
|
||||
setProperty (Property_Wrapping, state);
|
||||
}
|
||||
|
||||
bool CSMSettings::Setting::wrapping() const
|
||||
{
|
||||
return (property (Property_Wrapping).at(0) == "true");
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setLabel (const QString& label)
|
||||
{
|
||||
setProperty (Property_Label, label);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::getLabel() const
|
||||
{
|
||||
return property (Property_Label).at (0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setToolTip (const QString& toolTip)
|
||||
{
|
||||
setProperty (Property_ToolTip, toolTip);
|
||||
}
|
||||
|
||||
QString CSMSettings::Setting::getToolTip() const
|
||||
{
|
||||
return property (Property_ToolTip).at (0);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop, bool value)
|
||||
{
|
||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop, int value)
|
||||
{
|
||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop, double value)
|
||||
{
|
||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop,
|
||||
const QString &value)
|
||||
{
|
||||
setProperty (prop, QStringList() << value);
|
||||
}
|
||||
|
||||
void CSMSettings::Setting::setProperty (SettingProperty prop,
|
||||
const QStringList &value)
|
||||
{
|
||||
if (prop < mProperties.size())
|
||||
mProperties.replace (prop, value);
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
#ifndef CSMSETTINGS_SETTING_HPP
|
||||
#define CSMSETTINGS_SETTING_HPP
|
||||
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include "support.hpp"
|
||||
|
||||
namespace CSMSettings
|
||||
{
|
||||
//QString is the setting id in the form of "page/name"
|
||||
//QList is a list of stringlists of proxy values.
|
||||
//Order is important! Proxy stringlists are matched against
|
||||
//master values by their position in the QList.
|
||||
typedef QMap <QString, QList <QStringList> > ProxyValueMap;
|
||||
|
||||
///Setting class is the interface for the User Settings. It contains
|
||||
///a great deal of boiler plate to provide the core API functions, as
|
||||
///well as the property() functions which use enumeration to be iterable.
|
||||
///This makes the Setting class capable of being manipulated by script.
|
||||
///See CSMSettings::support.hpp for enumerations / string values.
|
||||
class Setting
|
||||
{
|
||||
QList <QStringList> mProperties;
|
||||
QStringList mDefaults;
|
||||
|
||||
bool mIsEditorSetting;
|
||||
|
||||
ProxyValueMap mProxies;
|
||||
|
||||
public:
|
||||
|
||||
Setting(SettingType typ, const QString &settingName,
|
||||
const QString &pageName, const QString& label = "");
|
||||
|
||||
void addProxy (const Setting *setting, const QStringList &vals);
|
||||
void addProxy (const Setting *setting, const QList <QStringList> &list);
|
||||
|
||||
const QList <QStringList> &properties() const { return mProperties; }
|
||||
const ProxyValueMap &proxies() const { return mProxies; }
|
||||
|
||||
void setColumnSpan (int value);
|
||||
int columnSpan() const;
|
||||
|
||||
void setDeclaredValues (QStringList list);
|
||||
QStringList declaredValues() const;
|
||||
|
||||
void setDefaultValue (int value);
|
||||
void setDefaultValue (double value);
|
||||
void setDefaultValue (const QString &value);
|
||||
|
||||
void setDefaultValues (const QStringList &values);
|
||||
QStringList defaultValues() const;
|
||||
|
||||
void setDelimiter (const QString &value);
|
||||
QString delimiter() const;
|
||||
|
||||
void setEditorSetting (bool state);
|
||||
bool isEditorSetting() const;
|
||||
|
||||
void setIsMultiLine (bool state);
|
||||
bool isMultiLine() const;
|
||||
|
||||
void setIsMultiValue (bool state);
|
||||
bool isMultiValue() const;
|
||||
|
||||
void setMask (const QString &value);
|
||||
QString mask() const;
|
||||
|
||||
void setRange (int min, int max);
|
||||
void setRange (double min, double max);
|
||||
|
||||
QString maximum() const;
|
||||
|
||||
QString minimum() const;
|
||||
|
||||
void setName (const QString &value);
|
||||
QString name() const;
|
||||
|
||||
void setPage (const QString &value);
|
||||
QString page() const;
|
||||
|
||||
void setStyleSheet (const QString &value);
|
||||
QString styleSheet() const;
|
||||
|
||||
void setPrefix (const QString &value);
|
||||
QString prefix() const;
|
||||
|
||||
void setRowSpan (const int value);
|
||||
int rowSpan() const;
|
||||
|
||||
const ProxyValueMap &proxyLists() const;
|
||||
|
||||
void setSerializable (bool state);
|
||||
bool serializable() const;
|
||||
|
||||
void setSpecialValueText (const QString &text);
|
||||
QString specialValueText() const;
|
||||
|
||||
void setSingleStep (int value);
|
||||
void setSingleStep (double value);
|
||||
QString singleStep() const;
|
||||
|
||||
void setSuffix (const QString &value);
|
||||
QString suffix() const;
|
||||
|
||||
void setTickInterval (int value);
|
||||
int tickInterval() const;
|
||||
|
||||
void setTicksAbove (bool state);
|
||||
bool ticksAbove() const;
|
||||
|
||||
void setTicksBelow (bool state);
|
||||
bool ticksBelow() const;
|
||||
|
||||
void setViewColumn (int value);
|
||||
int viewColumn() const;
|
||||
|
||||
void setViewLocation (int row = -1, int column = -1);
|
||||
|
||||
void setViewRow (int value);
|
||||
int viewRow() const;
|
||||
|
||||
void setType (int settingType);
|
||||
CSMSettings::SettingType type() const;
|
||||
|
||||
CSVSettings::ViewType viewType() const;
|
||||
|
||||
void setWrapping (bool state);
|
||||
bool wrapping() const;
|
||||
|
||||
void setWidgetWidth (int value);
|
||||
int widgetWidth() const;
|
||||
|
||||
/// This is the text the user gets to see.
|
||||
void setLabel (const QString& label);
|
||||
QString getLabel() const;
|
||||
|
||||
void setToolTip (const QString& toolTip);
|
||||
QString getToolTip() const;
|
||||
|
||||
///returns the specified property value
|
||||
QStringList property (SettingProperty prop) const;
|
||||
|
||||
///boilerplate code to convert setting values of common types
|
||||
void setProperty (SettingProperty prop, bool value);
|
||||
void setProperty (SettingProperty prop, int value);
|
||||
void setProperty (SettingProperty prop, double value);
|
||||
void setProperty (SettingProperty prop, const QString &value);
|
||||
void setProperty (SettingProperty prop, const QStringList &value);
|
||||
|
||||
void addProxy (Setting* setting,
|
||||
QMap <QString, QStringList> &proxyMap);
|
||||
|
||||
protected:
|
||||
void buildDefaultSetting();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSMSETTINGS_SETTING_HPP
|
@ -1,149 +0,0 @@
|
||||
#ifndef SETTING_SUPPORT_HPP
|
||||
#define SETTING_SUPPORT_HPP
|
||||
|
||||
#include <Qt>
|
||||
#include <QPair>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QStringList>
|
||||
|
||||
//Enums
|
||||
namespace CSMSettings
|
||||
{
|
||||
///Enumerated properties for scripting
|
||||
enum SettingProperty
|
||||
{
|
||||
Property_Name = 0,
|
||||
Property_Page = 1,
|
||||
Property_SettingType = 2,
|
||||
Property_IsMultiValue = 3,
|
||||
Property_IsMultiLine = 4,
|
||||
Property_WidgetWidth = 5,
|
||||
Property_ViewRow = 6,
|
||||
Property_ViewColumn = 7,
|
||||
Property_Delimiter = 8,
|
||||
Property_Serializable = 9,
|
||||
Property_ColumnSpan = 10,
|
||||
Property_RowSpan = 11,
|
||||
Property_Minimum = 12,
|
||||
Property_Maximum = 13,
|
||||
Property_SpecialValueText = 14,
|
||||
Property_Prefix = 15,
|
||||
Property_Suffix = 16,
|
||||
Property_SingleStep = 17,
|
||||
Property_Wrapping = 18,
|
||||
Property_TickInterval = 19,
|
||||
Property_TicksAbove = 20,
|
||||
Property_TicksBelow = 21,
|
||||
Property_StyleSheet = 22,
|
||||
Property_Label = 23,
|
||||
Property_ToolTip = 24,
|
||||
|
||||
//Stringlists should always be the last items
|
||||
Property_DefaultValues = 25,
|
||||
Property_DeclaredValues = 26,
|
||||
Property_DefinedValues = 27,
|
||||
Property_Proxies = 28
|
||||
};
|
||||
|
||||
///Basic setting widget types.
|
||||
enum SettingType
|
||||
{
|
||||
/*
|
||||
* 0 - 9 - Boolean widgets
|
||||
* 10-19 - List widgets
|
||||
* 21-29 - Range widgets
|
||||
* 31-39 - Text widgets
|
||||
*
|
||||
* Each range corresponds to a View_Type enum by a factor of 10.
|
||||
*
|
||||
* Even-numbered values are single-value widgets
|
||||
* Odd-numbered values are multi-valued widgets
|
||||
*/
|
||||
|
||||
Type_CheckBox = 0,
|
||||
Type_RadioButton = 1,
|
||||
Type_ListView = 10,
|
||||
Type_ComboBox = 11,
|
||||
Type_SpinBox = 21,
|
||||
Type_DoubleSpinBox = 23,
|
||||
Type_Slider = 25,
|
||||
Type_Dial = 27,
|
||||
Type_TextArea = 30,
|
||||
Type_LineEdit = 31,
|
||||
Type_Undefined = 40
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace CSVSettings
|
||||
{
|
||||
///Categorical view types which encompass the setting widget types
|
||||
enum ViewType
|
||||
{
|
||||
ViewType_Boolean = 0,
|
||||
ViewType_List = 1,
|
||||
ViewType_Range = 2,
|
||||
ViewType_Text = 3,
|
||||
ViewType_Undefined = 4
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
namespace CSMSettings
|
||||
{
|
||||
///used to construct default settings in the Setting class
|
||||
struct PropertyDefaultValues
|
||||
{
|
||||
int id;
|
||||
QString name;
|
||||
QVariant value;
|
||||
};
|
||||
|
||||
///strings which correspond to setting values. These strings represent
|
||||
///the script language keywords which would be used to declare setting
|
||||
///views for 3rd party addons
|
||||
const QString sPropertyNames[] =
|
||||
{
|
||||
"name", "page", "setting_type", "is_multi_value",
|
||||
"is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
|
||||
"is_serializable","column_span", "row_span", "minimum", "maximum",
|
||||
"special_value_text", "prefix", "suffix", "single_step", "wrapping",
|
||||
"tick_interval", "ticks_above", "ticks_below", "stylesheet",
|
||||
"defaults", "declarations", "definitions", "proxies"
|
||||
};
|
||||
|
||||
///Default values for a setting. Used in setting creation.
|
||||
const QString sPropertyDefaults[] =
|
||||
{
|
||||
"", //name
|
||||
"", //page
|
||||
"40", //setting type
|
||||
"false", //multivalue
|
||||
"false", //multiline
|
||||
"7", //widget width
|
||||
"-1", //view row
|
||||
"-1", //view column
|
||||
",", //delimiter
|
||||
"true", //serialized
|
||||
"1", //column span
|
||||
"1", //row span
|
||||
"0", //value range
|
||||
"0", //value minimum
|
||||
"0", //value maximum
|
||||
"", //special text
|
||||
"", //prefix
|
||||
"", //suffix
|
||||
"false", //wrapping
|
||||
"1", //tick interval
|
||||
"false", //ticks above
|
||||
"true", //ticks below
|
||||
"", //StyleSheet
|
||||
"", //default values
|
||||
"", //declared values
|
||||
"", //defined values
|
||||
"" //proxy values
|
||||
};
|
||||
}
|
||||
|
||||
#endif // VIEW_SUPPORT_HPP
|
@ -1,744 +0,0 @@
|
||||
#include "usersettings.hpp"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include "setting.hpp"
|
||||
#include "support.hpp"
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
#if (BOOST_VERSION <= 104600)
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<>
|
||||
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
||||
{
|
||||
return boost::filesystem::path(arg);
|
||||
}
|
||||
|
||||
} /* namespace boost */
|
||||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
CSMSettings::UserSettings *CSMSettings::UserSettings::sUserSettingsInstance = 0;
|
||||
|
||||
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
|
||||
: mCfgMgr (configurationManager)
|
||||
, mSettingDefinitions(NULL)
|
||||
{
|
||||
assert(!sUserSettingsInstance);
|
||||
sUserSettingsInstance = this;
|
||||
|
||||
buildSettingModelDefaults();
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||
{
|
||||
QString section;
|
||||
|
||||
declareSection ("3d-render", "3D Rendering");
|
||||
{
|
||||
Setting *shaders = createSetting (Type_CheckBox, "shaders", "Enable Shaders");
|
||||
shaders->setDefaultValue ("true");
|
||||
|
||||
Setting *farClipDist = createSetting (Type_DoubleSpinBox, "far-clip-distance", "Far clipping distance");
|
||||
farClipDist->setDefaultValue (300000);
|
||||
farClipDist->setRange (0, 1000000);
|
||||
farClipDist->setToolTip ("The maximum distance objects are still rendered at.");
|
||||
|
||||
QString defaultValue = "None";
|
||||
Setting *antialiasing = createSetting (Type_ComboBox, "antialiasing", "Antialiasing");
|
||||
antialiasing->setDeclaredValues (QStringList()
|
||||
<< defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16");
|
||||
antialiasing->setDefaultValue (defaultValue);
|
||||
}
|
||||
|
||||
declareSection ("3d-render-adv", "3D Rendering (Advanced)");
|
||||
{
|
||||
Setting *numLights = createSetting (Type_SpinBox, "num_lights",
|
||||
"Number of lights per pass");
|
||||
numLights->setDefaultValue (8);
|
||||
numLights->setRange (1, 100);
|
||||
}
|
||||
|
||||
declareSection ("scene-input", "Scene Input");
|
||||
{
|
||||
Setting *timer = createSetting (Type_SpinBox, "timer", "Input responsiveness");
|
||||
timer->setDefaultValue (20);
|
||||
timer->setRange (1, 100);
|
||||
timer->setToolTip ("The time between two checks for user input in milliseconds.<p>"
|
||||
"Lower value result in higher responsiveness.");
|
||||
|
||||
Setting *fastFactor = createSetting (Type_SpinBox, "fast-factor",
|
||||
"Fast movement factor");
|
||||
fastFactor->setDefaultValue (4);
|
||||
fastFactor->setRange (1, 100);
|
||||
fastFactor->setToolTip (
|
||||
"Factor by which movement is speed up while the shift key is held down.");
|
||||
}
|
||||
|
||||
declareSection ("window", "Window");
|
||||
{
|
||||
Setting *preDefined = createSetting (Type_ComboBox, "pre-defined",
|
||||
"Default window size");
|
||||
preDefined->setEditorSetting (false);
|
||||
preDefined->setDeclaredValues (
|
||||
QStringList() << "640 x 480" << "800 x 600" << "1024 x 768" << "1440 x 900");
|
||||
preDefined->setViewLocation (1, 1);
|
||||
preDefined->setColumnSpan (2);
|
||||
preDefined->setToolTip ("Newly opened top-level windows will open with this size "
|
||||
"(picked from a list of pre-defined values)");
|
||||
|
||||
Setting *width = createSetting (Type_LineEdit, "default-width",
|
||||
"Default window width");
|
||||
width->setDefaultValues (QStringList() << "1024");
|
||||
width->setViewLocation (2, 1);
|
||||
width->setColumnSpan (1);
|
||||
width->setToolTip ("Newly opened top-level windows will open with this width.");
|
||||
preDefined->addProxy (width, QStringList() << "640" << "800" << "1024" << "1440");
|
||||
|
||||
Setting *height = createSetting (Type_LineEdit, "default-height",
|
||||
"Default window height");
|
||||
height->setDefaultValues (QStringList() << "768");
|
||||
height->setViewLocation (2, 2);
|
||||
height->setColumnSpan (1);
|
||||
height->setToolTip ("Newly opened top-level windows will open with this height.");
|
||||
preDefined->addProxy (height, QStringList() << "480" << "600" << "768" << "900");
|
||||
|
||||
Setting *reuse = createSetting (Type_CheckBox, "reuse", "Reuse Subviews");
|
||||
reuse->setDefaultValue ("true");
|
||||
reuse->setToolTip ("When a new subview is requested and a matching subview already "
|
||||
" exist, do not open a new subview and use the existing one instead.");
|
||||
|
||||
Setting *statusBar = createSetting (Type_CheckBox, "show-statusbar", "Show Status Bar");
|
||||
statusBar->setDefaultValue ("true");
|
||||
statusBar->setToolTip ("If a newly open top level window is showing status bars or not. "
|
||||
" Note that this does not affect existing windows.");
|
||||
|
||||
Setting *maxSubView = createSetting (Type_SpinBox, "max-subviews",
|
||||
"Maximum number of subviews per top-level window");
|
||||
maxSubView->setDefaultValue (256);
|
||||
maxSubView->setRange (1, 256);
|
||||
maxSubView->setToolTip ("If the maximum number is reached and a new subview is opened "
|
||||
"it will be placed into a new top-level window.");
|
||||
|
||||
Setting *hide = createSetting (Type_CheckBox, "hide-subview", "Hide single subview");
|
||||
hide->setDefaultValue ("false");
|
||||
hide->setToolTip ("When a view contains only a single subview, hide the subview title "
|
||||
"bar and if this subview is closed also close the view (unless it is the last "
|
||||
"view for this document)");
|
||||
|
||||
Setting *minWidth = createSetting (Type_SpinBox, "minimum-width",
|
||||
"Minimum subview width");
|
||||
minWidth->setDefaultValue (325);
|
||||
minWidth->setRange (50, 10000);
|
||||
minWidth->setToolTip ("Minimum width of subviews.");
|
||||
|
||||
QString defaultScroll = "Scrollbar Only";
|
||||
QStringList scrollValues = QStringList() << defaultScroll << "Grow Only" << "Grow then Scroll";
|
||||
|
||||
Setting *mainwinScroll = createSetting (Type_RadioButton, "mainwindow-scrollbar",
|
||||
"Add a horizontal scrollbar to the main view window.");
|
||||
mainwinScroll->setDefaultValue (defaultScroll);
|
||||
mainwinScroll->setDeclaredValues (scrollValues);
|
||||
mainwinScroll->setToolTip ("Scrollbar Only: Simple addition of scrollbars, the view window does not grow"
|
||||
" automatically.\n"
|
||||
"Grow Only: Original Editor behaviour. The view window grows as subviews are added. No scrollbars.\n"
|
||||
"Grow then Scroll: The view window grows. The scrollbar appears once it cannot grow any further.");
|
||||
|
||||
Setting *grow = createSetting (Type_CheckBox, "grow-limit", "Grow Limit Screen");
|
||||
grow->setDefaultValue ("false");
|
||||
grow->setToolTip ("When \"Grow then Scroll\" option is selected, the window size grows to"
|
||||
" the width of the virtual desktop. \nIf this option is selected the the window growth"
|
||||
"is limited to the current screen.");
|
||||
}
|
||||
|
||||
declareSection ("records", "Records");
|
||||
{
|
||||
QString defaultValue = "Icon and Text";
|
||||
QStringList values = QStringList() << defaultValue << "Icon Only" << "Text Only";
|
||||
|
||||
Setting *rsd = createSetting (Type_RadioButton, "status-format",
|
||||
"Modification status display format");
|
||||
rsd->setDefaultValue (defaultValue);
|
||||
rsd->setDeclaredValues (values);
|
||||
|
||||
Setting *ritd = createSetting (Type_RadioButton, "type-format",
|
||||
"ID type display format");
|
||||
ritd->setDefaultValue (defaultValue);
|
||||
ritd->setDeclaredValues (values);
|
||||
}
|
||||
|
||||
declareSection ("table-input", "Table Input");
|
||||
{
|
||||
QString inPlaceEdit ("Edit in Place");
|
||||
QString editRecord ("Edit Record");
|
||||
QString view ("View");
|
||||
QString editRecordAndClose ("Edit Record and Close");
|
||||
|
||||
QStringList values;
|
||||
values
|
||||
<< "None" << inPlaceEdit << editRecord << view << "Revert" << "Delete"
|
||||
<< editRecordAndClose << "View and Close";
|
||||
|
||||
QString toolTip = "<ul>"
|
||||
"<li>None</li>"
|
||||
"<li>Edit in Place: Edit the clicked cell</li>"
|
||||
"<li>Edit Record: Open a dialogue subview for the clicked record</li>"
|
||||
"<li>View: Open a scene subview for the clicked record (not available everywhere)</li>"
|
||||
"<li>Revert: Revert record</li>"
|
||||
"<li>Delete: Delete recordy</li>"
|
||||
"<li>Edit Record and Close: Open a dialogue subview for the clicked record and close the table subview</li>"
|
||||
"<li>View And Close: Open a scene subview for the clicked record and close the table subview</li>"
|
||||
"</ul>";
|
||||
|
||||
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
||||
doubleClick->setDeclaredValues (values);
|
||||
doubleClick->setDefaultValue (inPlaceEdit);
|
||||
doubleClick->setToolTip ("Action on double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
||||
"Shift Double Click");
|
||||
shiftDoubleClick->setDeclaredValues (values);
|
||||
shiftDoubleClick->setDefaultValue (editRecord);
|
||||
shiftDoubleClick->setToolTip ("Action on shift double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
||||
"Control Double Click");
|
||||
ctrlDoubleClick->setDeclaredValues (values);
|
||||
ctrlDoubleClick->setDefaultValue (view);
|
||||
ctrlDoubleClick->setToolTip ("Action on control double click in table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
||||
"Shift Control Double Click");
|
||||
shiftCtrlDoubleClick->setDeclaredValues (values);
|
||||
shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose);
|
||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
|
||||
|
||||
QString defaultValue = "Jump and Select";
|
||||
QStringList jumpValues = QStringList() << defaultValue << "Jump Only" << "No Jump";
|
||||
|
||||
Setting *jumpToAdded = createSetting (Type_RadioButton, "jump-to-added",
|
||||
"Jump to the added or cloned record.");
|
||||
jumpToAdded->setDefaultValue (defaultValue);
|
||||
jumpToAdded->setDeclaredValues (jumpValues);
|
||||
}
|
||||
|
||||
declareSection ("report-input", "Report Input");
|
||||
{
|
||||
QString none ("None");
|
||||
QString edit ("Edit");
|
||||
QString remove ("Remove");
|
||||
QString editAndRemove ("Edit And Remove");
|
||||
|
||||
QStringList values;
|
||||
values << none << edit << remove << editAndRemove;
|
||||
|
||||
QString toolTip = "<ul>"
|
||||
"<li>None</li>"
|
||||
"<li>Edit: Open a table or dialogue suitable for addressing the listed report</li>"
|
||||
"<li>Remove: Remove the report from the report table</li>"
|
||||
"<li>Edit and Remove: Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table</li>"
|
||||
"</ul>";
|
||||
|
||||
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
||||
doubleClick->setDeclaredValues (values);
|
||||
doubleClick->setDefaultValue (edit);
|
||||
doubleClick->setToolTip ("Action on double click in report table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
||||
"Shift Double Click");
|
||||
shiftDoubleClick->setDeclaredValues (values);
|
||||
shiftDoubleClick->setDefaultValue (remove);
|
||||
shiftDoubleClick->setToolTip ("Action on shift double click in report table:<p>" + toolTip);
|
||||
|
||||
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
||||
"Control Double Click");
|
||||
ctrlDoubleClick->setDeclaredValues (values);
|
||||
ctrlDoubleClick->setDefaultValue (editAndRemove);
|
||||
ctrlDoubleClick->setToolTip ("Action on control double click in report table:<p>" + toolTip);
|
||||
|
||||
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
||||
"Shift Control Double Click");
|
||||
shiftCtrlDoubleClick->setDeclaredValues (values);
|
||||
shiftCtrlDoubleClick->setDefaultValue (none);
|
||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in report table:<p>" + toolTip);
|
||||
}
|
||||
|
||||
declareSection ("search", "Search & Replace");
|
||||
{
|
||||
Setting *before = createSetting (Type_SpinBox, "char-before",
|
||||
"Characters before search string");
|
||||
before->setDefaultValue (10);
|
||||
before->setRange (0, 1000);
|
||||
before->setToolTip ("Maximum number of character to display in search result before the searched text");
|
||||
|
||||
Setting *after = createSetting (Type_SpinBox, "char-after",
|
||||
"Characters after search string");
|
||||
after->setDefaultValue (10);
|
||||
after->setRange (0, 1000);
|
||||
after->setToolTip ("Maximum number of character to display in search result after the searched text");
|
||||
|
||||
Setting *autoDelete = createSetting (Type_CheckBox, "auto-delete", "Delete row from result table after a successful replace");
|
||||
autoDelete->setDefaultValue ("true");
|
||||
}
|
||||
|
||||
declareSection ("script-editor", "Scripts");
|
||||
{
|
||||
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
||||
lineNum->setDefaultValue ("true");
|
||||
lineNum->setToolTip ("Show line numbers to the left of the script editor window."
|
||||
"The current row and column numbers of the text cursor are shown at the bottom.");
|
||||
|
||||
Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font");
|
||||
monoFont->setDefaultValue ("true");
|
||||
monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview.");
|
||||
|
||||
QString tooltip =
|
||||
"\n#RGB (each of R, G, and B is a single hex digit)"
|
||||
"\n#RRGGBB"
|
||||
"\n#RRRGGGBBB"
|
||||
"\n#RRRRGGGGBBBB"
|
||||
"\nA name from the list of colors defined in the list of SVG color keyword names."
|
||||
"\nX11 color names may also work.";
|
||||
|
||||
QString modeNormal ("Normal");
|
||||
|
||||
QStringList modes;
|
||||
modes << "Ignore" << modeNormal << "Strict";
|
||||
|
||||
Setting *warnings = createSetting (Type_ComboBox, "warnings",
|
||||
"Warning Mode");
|
||||
warnings->setDeclaredValues (modes);
|
||||
warnings->setDefaultValue (modeNormal);
|
||||
warnings->setToolTip ("<ul>How to handle warning messages during compilation:<p>"
|
||||
"<li>Ignore: Do not report warning</li>"
|
||||
"<li>Normal: Report warning as a warning</li>"
|
||||
"<li>Strict: Promote warning to an error</li>"
|
||||
"</ul>");
|
||||
|
||||
Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int");
|
||||
formatInt->setDefaultValues (QStringList() << "Dark magenta");
|
||||
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatFloat = createSetting (Type_LineEdit, "colour-float", "Highlight Colour: Float");
|
||||
formatFloat->setDefaultValues (QStringList() << "Magenta");
|
||||
formatFloat->setToolTip ("(Default: Magenta) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatName = createSetting (Type_LineEdit, "colour-name", "Highlight Colour: Name");
|
||||
formatName->setDefaultValues (QStringList() << "Gray");
|
||||
formatName->setToolTip ("(Default: Gray) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatKeyword = createSetting (Type_LineEdit, "colour-keyword", "Highlight Colour: Keyword");
|
||||
formatKeyword->setDefaultValues (QStringList() << "Red");
|
||||
formatKeyword->setToolTip ("(Default: Red) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatSpecial = createSetting (Type_LineEdit, "colour-special", "Highlight Colour: Special");
|
||||
formatSpecial->setDefaultValues (QStringList() << "Dark yellow");
|
||||
formatSpecial->setToolTip ("(Default: Dark yellow) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatComment = createSetting (Type_LineEdit, "colour-comment", "Highlight Colour: Comment");
|
||||
formatComment->setDefaultValues (QStringList() << "Green");
|
||||
formatComment->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
||||
|
||||
Setting *formatId = createSetting (Type_LineEdit, "colour-id", "Highlight Colour: Id");
|
||||
formatId->setDefaultValues (QStringList() << "Blue");
|
||||
formatId->setToolTip ("(Default: Blue) Use one of the following formats:" + tooltip);
|
||||
}
|
||||
|
||||
{
|
||||
/******************************************************************
|
||||
* There are three types of values:
|
||||
*
|
||||
* Declared values
|
||||
*
|
||||
* Pre-determined values, typically for
|
||||
* combobox drop downs and boolean (radiobutton / checkbox) labels.
|
||||
* These values represent the total possible list of values that
|
||||
* may define a setting. No other values are allowed.
|
||||
*
|
||||
* Defined values
|
||||
*
|
||||
* Values which represent the actual, current value of
|
||||
* a setting. For settings with declared values, this must be one
|
||||
* or several declared values, as appropriate.
|
||||
*
|
||||
* Proxy values
|
||||
* Values the proxy master updates the proxy slave when
|
||||
* it's own definition is set / changed. These are definitions for
|
||||
* proxy slave settings, but must match any declared values the
|
||||
* proxy slave has, if any.
|
||||
*******************************************************************/
|
||||
/*
|
||||
//create setting objects, specifying the basic widget type,
|
||||
//the page name, and the view name
|
||||
|
||||
Setting *masterBoolean = createSetting (Type_RadioButton, section,
|
||||
"Master Proxy");
|
||||
|
||||
Setting *slaveBoolean = createSetting (Type_CheckBox, section,
|
||||
"Proxy Checkboxes");
|
||||
|
||||
Setting *slaveSingleText = createSetting (Type_LineEdit, section,
|
||||
"Proxy TextBox 1");
|
||||
|
||||
Setting *slaveMultiText = createSetting (Type_LineEdit, section,
|
||||
"ProxyTextBox 2");
|
||||
|
||||
Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section,
|
||||
"Alpha Spinbox");
|
||||
|
||||
Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section,
|
||||
"Int Spinbox");
|
||||
|
||||
Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox,
|
||||
section, "Double Spinbox");
|
||||
|
||||
Setting *slaveSlider = createSetting (Type_Slider, section, "Slider");
|
||||
|
||||
Setting *slaveDial = createSetting (Type_Dial, section, "Dial");
|
||||
|
||||
//set declared values for selected views
|
||||
masterBoolean->setDeclaredValues (QStringList()
|
||||
<< "Profile One" << "Profile Two"
|
||||
<< "Profile Three" << "Profile Four");
|
||||
|
||||
slaveBoolean->setDeclaredValues (QStringList()
|
||||
<< "One" << "Two" << "Three" << "Four" << "Five");
|
||||
|
||||
slaveAlphaSpinbox->setDeclaredValues (QStringList()
|
||||
<< "One" << "Two" << "Three" << "Four");
|
||||
|
||||
|
||||
masterBoolean->addProxy (slaveBoolean, QList <QStringList>()
|
||||
<< (QStringList() << "One" << "Three")
|
||||
<< (QStringList() << "One" << "Three")
|
||||
<< (QStringList() << "One" << "Three" << "Five")
|
||||
<< (QStringList() << "Two" << "Four")
|
||||
);
|
||||
|
||||
masterBoolean->addProxy (slaveSingleText, QList <QStringList>()
|
||||
<< (QStringList() << "Text A")
|
||||
<< (QStringList() << "Text B")
|
||||
<< (QStringList() << "Text A")
|
||||
<< (QStringList() << "Text C")
|
||||
);
|
||||
|
||||
masterBoolean->addProxy (slaveMultiText, QList <QStringList>()
|
||||
<< (QStringList() << "One" << "Three")
|
||||
<< (QStringList() << "One" << "Three")
|
||||
<< (QStringList() << "One" << "Three" << "Five")
|
||||
<< (QStringList() << "Two" << "Four")
|
||||
);
|
||||
|
||||
masterBoolean->addProxy (slaveAlphaSpinbox, QList <QStringList>()
|
||||
<< (QStringList() << "Four")
|
||||
<< (QStringList() << "Three")
|
||||
<< (QStringList() << "Two")
|
||||
<< (QStringList() << "One"));
|
||||
|
||||
masterBoolean->addProxy (slaveIntegerSpinbox, QList <QStringList> ()
|
||||
<< (QStringList() << "0")
|
||||
<< (QStringList() << "7")
|
||||
<< (QStringList() << "14")
|
||||
<< (QStringList() << "21"));
|
||||
|
||||
masterBoolean->addProxy (slaveDoubleSpinbox, QList <QStringList> ()
|
||||
<< (QStringList() << "0.17")
|
||||
<< (QStringList() << "0.34")
|
||||
<< (QStringList() << "0.51")
|
||||
<< (QStringList() << "0.68"));
|
||||
|
||||
masterBoolean->addProxy (slaveSlider, QList <QStringList> ()
|
||||
<< (QStringList() << "25")
|
||||
<< (QStringList() << "50")
|
||||
<< (QStringList() << "75")
|
||||
<< (QStringList() << "100")
|
||||
);
|
||||
|
||||
masterBoolean->addProxy (slaveDial, QList <QStringList> ()
|
||||
<< (QStringList() << "25")
|
||||
<< (QStringList() << "50")
|
||||
<< (QStringList() << "75")
|
||||
<< (QStringList() << "100")
|
||||
);
|
||||
|
||||
//settings with proxies are not serialized by default
|
||||
//other settings non-serialized for demo purposes
|
||||
slaveBoolean->setSerializable (false);
|
||||
slaveSingleText->setSerializable (false);
|
||||
slaveMultiText->setSerializable (false);
|
||||
slaveAlphaSpinbox->setSerializable (false);
|
||||
slaveIntegerSpinbox->setSerializable (false);
|
||||
slaveDoubleSpinbox->setSerializable (false);
|
||||
slaveSlider->setSerializable (false);
|
||||
slaveDial->setSerializable (false);
|
||||
|
||||
slaveBoolean->setDefaultValues (QStringList()
|
||||
<< "One" << "Three" << "Five");
|
||||
|
||||
slaveSingleText->setDefaultValue ("Text A");
|
||||
|
||||
slaveMultiText->setDefaultValues (QStringList()
|
||||
<< "One" << "Three" << "Five");
|
||||
|
||||
slaveSingleText->setWidgetWidth (24);
|
||||
slaveMultiText->setWidgetWidth (24);
|
||||
|
||||
slaveAlphaSpinbox->setDefaultValue ("Two");
|
||||
slaveAlphaSpinbox->setWidgetWidth (20);
|
||||
//slaveAlphaSpinbox->setPrefix ("No. ");
|
||||
//slaveAlphaSpinbox->setSuffix ("!");
|
||||
slaveAlphaSpinbox->setWrapping (true);
|
||||
|
||||
slaveIntegerSpinbox->setDefaultValue (14);
|
||||
slaveIntegerSpinbox->setMinimum (0);
|
||||
slaveIntegerSpinbox->setMaximum (58);
|
||||
slaveIntegerSpinbox->setPrefix ("$");
|
||||
slaveIntegerSpinbox->setSuffix (".00");
|
||||
slaveIntegerSpinbox->setWidgetWidth (10);
|
||||
slaveIntegerSpinbox->setSpecialValueText ("Nothing!");
|
||||
|
||||
slaveDoubleSpinbox->setDefaultValue (0.51);
|
||||
slaveDoubleSpinbox->setSingleStep(0.17);
|
||||
slaveDoubleSpinbox->setMaximum(4.0);
|
||||
|
||||
slaveSlider->setMinimum (0);
|
||||
slaveSlider->setMaximum (100);
|
||||
slaveSlider->setDefaultValue (75);
|
||||
slaveSlider->setWidgetWidth (100);
|
||||
slaveSlider->setTicksAbove (true);
|
||||
slaveSlider->setTickInterval (25);
|
||||
|
||||
slaveDial->setMinimum (0);
|
||||
slaveDial->setMaximum (100);
|
||||
slaveDial->setSingleStep (5);
|
||||
slaveDial->setDefaultValue (75);
|
||||
slaveDial->setTickInterval (25);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings::~UserSettings()
|
||||
{
|
||||
sUserSettingsInstance = 0;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
||||
{
|
||||
QString userFilePath = QString::fromUtf8
|
||||
(mCfgMgr.getUserConfigPath().string().c_str());
|
||||
|
||||
QString globalFilePath = QString::fromUtf8
|
||||
(mCfgMgr.getGlobalPath().string().c_str());
|
||||
|
||||
QString otherFilePath = globalFilePath;
|
||||
|
||||
//test for local only if global fails (uninstalled copy)
|
||||
if (!QFile (globalFilePath + fileName).exists())
|
||||
{
|
||||
//if global is invalid, use the local path
|
||||
otherFilePath = QString::fromUtf8
|
||||
(mCfgMgr.getLocalPath().string().c_str());
|
||||
}
|
||||
|
||||
QSettings::setPath
|
||||
(QSettings::IniFormat, QSettings::UserScope, userFilePath);
|
||||
|
||||
QSettings::setPath
|
||||
(QSettings::IniFormat, QSettings::SystemScope, otherFilePath);
|
||||
|
||||
mSettingDefinitions = new QSettings
|
||||
(QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this);
|
||||
}
|
||||
|
||||
// if the key is not found create one with a default value
|
||||
QString CSMSettings::UserSettings::setting(const QString &viewKey, const QString &value)
|
||||
{
|
||||
if(mSettingDefinitions->contains(viewKey))
|
||||
return settingValue(viewKey);
|
||||
else if(value != QString())
|
||||
{
|
||||
mSettingDefinitions->setValue (viewKey, QStringList() << value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool CSMSettings::UserSettings::hasSettingDefinitions (const QString &viewKey) const
|
||||
{
|
||||
return (mSettingDefinitions->contains (viewKey));
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::setDefinitions
|
||||
(const QString &key, const QStringList &list)
|
||||
{
|
||||
mSettingDefinitions->setValue (key, list);
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::saveDefinitions() const
|
||||
{
|
||||
mSettingDefinitions->sync();
|
||||
}
|
||||
|
||||
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
|
||||
{
|
||||
QStringList defs;
|
||||
|
||||
if (!mSettingDefinitions->contains (settingKey))
|
||||
return QString();
|
||||
|
||||
defs = mSettingDefinitions->value (settingKey).toStringList();
|
||||
|
||||
if (defs.isEmpty())
|
||||
return QString();
|
||||
|
||||
return defs.at(0);
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
|
||||
{
|
||||
assert(sUserSettingsInstance);
|
||||
return *sUserSettingsInstance;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
|
||||
const QStringList &list)
|
||||
{
|
||||
mSettingDefinitions->setValue (settingKey ,list);
|
||||
|
||||
if(settingKey == "3d-render-adv/num_lights" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", list.at(0).toStdString());
|
||||
}
|
||||
else if(settingKey == "3d-render/shaders" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setShadersEnabled (list.at(0).toStdString() == "true" ? true : false);
|
||||
}
|
||||
|
||||
emit userSettingUpdated (settingKey, list);
|
||||
}
|
||||
|
||||
CSMSettings::Setting *CSMSettings::UserSettings::findSetting
|
||||
(const QString &pageName, const QString &settingName)
|
||||
{
|
||||
foreach (Setting *setting, mSettings)
|
||||
{
|
||||
if (setting->name() == settingName)
|
||||
{
|
||||
if (setting->page() == pageName)
|
||||
return setting;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::removeSetting
|
||||
(const QString &pageName, const QString &settingName)
|
||||
{
|
||||
if (mSettings.isEmpty())
|
||||
return;
|
||||
|
||||
QList <Setting *>::iterator removeIterator = mSettings.begin();
|
||||
|
||||
while (removeIterator != mSettings.end())
|
||||
{
|
||||
if ((*removeIterator)->name() == settingName)
|
||||
{
|
||||
if ((*removeIterator)->page() == pageName)
|
||||
{
|
||||
mSettings.erase (removeIterator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
removeIterator++;
|
||||
}
|
||||
}
|
||||
|
||||
CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const
|
||||
{
|
||||
SettingPageMap pageMap;
|
||||
|
||||
foreach (Setting *setting, mSettings)
|
||||
{
|
||||
SettingPageMap::iterator iter = pageMap.find (setting->page());
|
||||
|
||||
if (iter==pageMap.end())
|
||||
{
|
||||
QPair<QString, QList <Setting *> > value;
|
||||
|
||||
std::map<QString, QString>::const_iterator iter2 =
|
||||
mSectionLabels.find (setting->page());
|
||||
|
||||
value.first = iter2!=mSectionLabels.end() ? iter2->second : "";
|
||||
|
||||
iter = pageMap.insert (setting->page(), value);
|
||||
}
|
||||
|
||||
iter->second.append (setting);
|
||||
}
|
||||
|
||||
return pageMap;
|
||||
}
|
||||
|
||||
CSMSettings::Setting *CSMSettings::UserSettings::createSetting
|
||||
(CSMSettings::SettingType type, const QString &name, const QString& label)
|
||||
{
|
||||
Setting *setting = new Setting (type, name, mSection, label);
|
||||
|
||||
// set useful defaults
|
||||
int row = 1;
|
||||
|
||||
if (!mSettings.empty())
|
||||
row = mSettings.back()->viewRow()+1;
|
||||
|
||||
setting->setViewLocation (row, 1);
|
||||
|
||||
setting->setColumnSpan (3);
|
||||
|
||||
int width = 10;
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
width = 40;
|
||||
|
||||
setting->setWidgetWidth (width);
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setStyleSheet ("QGroupBox { border: 0px; }");
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setDeclaredValues(QStringList() << "true" << "false");
|
||||
|
||||
if (type==Type_CheckBox)
|
||||
setting->setSpecialValueText (setting->getLabel());
|
||||
|
||||
//add declaration to the model
|
||||
mSettings.append (setting);
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::declareSection (const QString& page, const QString& label)
|
||||
{
|
||||
mSection = page;
|
||||
mSectionLabels[page] = label;
|
||||
}
|
||||
|
||||
QStringList CSMSettings::UserSettings::definitions (const QString &viewKey) const
|
||||
{
|
||||
if (mSettingDefinitions->contains (viewKey))
|
||||
return mSettingDefinitions->value (viewKey).toStringList();
|
||||
|
||||
return QStringList();
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
#ifndef USERSETTINGS_HPP
|
||||
#define USERSETTINGS_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include "support.hpp"
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
||||
struct ConfigurationManager;}
|
||||
|
||||
class QFile;
|
||||
class QSettings;
|
||||
|
||||
namespace CSMSettings {
|
||||
|
||||
class Setting;
|
||||
typedef QMap <QString, QPair<QString, QList <Setting *> > > SettingPageMap;
|
||||
|
||||
class UserSettings: public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
static UserSettings *sUserSettingsInstance;
|
||||
const Files::ConfigurationManager& mCfgMgr;
|
||||
|
||||
QSettings *mSettingDefinitions;
|
||||
QList <Setting *> mSettings;
|
||||
QString mSection;
|
||||
std::map<QString, QString> mSectionLabels;
|
||||
|
||||
public:
|
||||
|
||||
/// Singleton implementation
|
||||
static UserSettings& instance();
|
||||
|
||||
UserSettings (const Files::ConfigurationManager& configurationManager);
|
||||
~UserSettings();
|
||||
|
||||
UserSettings (UserSettings const &); //not implemented
|
||||
UserSettings& operator= (UserSettings const &); //not implemented
|
||||
|
||||
/// Retrieves the settings file at all three levels (global, local and user).
|
||||
void loadSettings (const QString &fileName);
|
||||
|
||||
/// Updates QSettings and syncs with the ini file
|
||||
void setDefinitions (const QString &key, const QStringList &defs);
|
||||
|
||||
QString settingValue (const QString &settingKey);
|
||||
|
||||
///retrieve a setting object from a given page and setting name
|
||||
Setting *findSetting
|
||||
(const QString &pageName, const QString &settingName = QString());
|
||||
|
||||
///remove a setting from the list
|
||||
void removeSetting
|
||||
(const QString &pageName, const QString &settingName);
|
||||
|
||||
///Retrieve a map of the settings, keyed by page name
|
||||
SettingPageMap settingPageMap() const;
|
||||
|
||||
///Returns a string list of defined vlaues for the specified setting
|
||||
///in "page/name" format.
|
||||
QStringList definitions (const QString &viewKey) const;
|
||||
|
||||
///Test to indicate whether or not a setting has any definitions
|
||||
bool hasSettingDefinitions (const QString &viewKey) const;
|
||||
|
||||
///Save any unsaved changes in the QSettings object
|
||||
void saveDefinitions() const;
|
||||
|
||||
QString setting(const QString &viewKey, const QString &value = QString());
|
||||
|
||||
private:
|
||||
|
||||
void buildSettingModelDefaults();
|
||||
|
||||
///add a new setting to the model and return it
|
||||
Setting *createSetting (CSMSettings::SettingType type, const QString &name,
|
||||
const QString& label);
|
||||
|
||||
/// Set the section for createSetting calls.
|
||||
///
|
||||
/// Sections can be declared multiple times.
|
||||
void declareSection (const QString& page, const QString& label);
|
||||
|
||||
signals:
|
||||
|
||||
void userSettingUpdated (const QString &, const QStringList &);
|
||||
|
||||
public slots:
|
||||
|
||||
void updateUserSetting (const QString &, const QStringList &);
|
||||
};
|
||||
}
|
||||
#endif // USERSETTINGS_HPP
|
@ -0,0 +1,133 @@
|
||||
#include "magiceffectcheck.hpp"
|
||||
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
|
||||
#include "../world/resources.hpp"
|
||||
#include "../world/data.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
void addMessageIfNotEmpty(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string text)
|
||||
{
|
||||
if (!text.empty())
|
||||
{
|
||||
messages.push_back(std::make_pair(id, text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CSMTools::MagicEffectCheckStage::isTextureExists(const std::string &texture, bool isIcon) const
|
||||
{
|
||||
const CSMWorld::Resources &textures = isIcon ? mIcons : mTextures;
|
||||
bool exists = false;
|
||||
|
||||
if (textures.searchId(texture) != -1)
|
||||
{
|
||||
exists = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string ddsTexture = texture;
|
||||
if (Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && textures.searchId(ddsTexture) != -1)
|
||||
{
|
||||
exists = true;
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
std::string CSMTools::MagicEffectCheckStage::checkReferenceable(const std::string &id,
|
||||
const CSMWorld::UniversalId &type,
|
||||
const std::string &column) const
|
||||
{
|
||||
std::string error;
|
||||
if (!id.empty())
|
||||
{
|
||||
CSMWorld::RefIdData::LocalIndex index = mReferenceables.getDataSet().searchId(id);
|
||||
if (index.first == -1)
|
||||
{
|
||||
error = "No such " + column + " '" + id + "'";
|
||||
}
|
||||
else if (index.second != type.getType())
|
||||
{
|
||||
error = column + " is not of type " + type.getTypeName();
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
std::string CSMTools::MagicEffectCheckStage::checkSound(const std::string &id, const std::string &column) const
|
||||
{
|
||||
std::string error;
|
||||
if (!id.empty() && mSounds.searchId(id) == -1)
|
||||
{
|
||||
error = "No such " + column + " '" + id + "'";
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection<ESM::MagicEffect> &effects,
|
||||
const CSMWorld::IdCollection<ESM::Sound> &sounds,
|
||||
const CSMWorld::RefIdCollection &referenceables,
|
||||
const CSMWorld::Resources &icons,
|
||||
const CSMWorld::Resources &textures)
|
||||
: mMagicEffects(effects),
|
||||
mSounds(sounds),
|
||||
mReferenceables(referenceables),
|
||||
mIcons(icons),
|
||||
mTextures(textures)
|
||||
{}
|
||||
|
||||
int CSMTools::MagicEffectCheckStage::setup()
|
||||
{
|
||||
return mMagicEffects.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
||||
{
|
||||
ESM::MagicEffect effect = mMagicEffects.getRecord(stage).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, effect.mId);
|
||||
|
||||
if (effect.mData.mBaseCost < 0.0f)
|
||||
{
|
||||
messages.push_back(std::make_pair(id, "Base Cost is negative"));
|
||||
}
|
||||
|
||||
if (effect.mIcon.empty())
|
||||
{
|
||||
messages.push_back(std::make_pair(id, "Icon is not specified"));
|
||||
}
|
||||
else if (!isTextureExists(effect.mIcon, true))
|
||||
{
|
||||
messages.push_back(std::make_pair(id, "No such Icon '" + effect.mIcon + "'"));
|
||||
}
|
||||
|
||||
if (!effect.mParticle.empty() && !isTextureExists(effect.mParticle, false))
|
||||
{
|
||||
messages.push_back(std::make_pair(id, "No such Particle '" + effect.mParticle + "'"));
|
||||
}
|
||||
|
||||
addMessageIfNotEmpty(messages,
|
||||
id,
|
||||
checkReferenceable(effect.mCasting, CSMWorld::UniversalId::Type_Static, "Casting Object"));
|
||||
addMessageIfNotEmpty(messages,
|
||||
id,
|
||||
checkReferenceable(effect.mHit, CSMWorld::UniversalId::Type_Static, "Hit Object"));
|
||||
addMessageIfNotEmpty(messages,
|
||||
id,
|
||||
checkReferenceable(effect.mArea, CSMWorld::UniversalId::Type_Static, "Area Object"));
|
||||
addMessageIfNotEmpty(messages,
|
||||
id,
|
||||
checkReferenceable(effect.mBolt, CSMWorld::UniversalId::Type_Weapon, "Bolt Object"));
|
||||
|
||||
addMessageIfNotEmpty(messages, id, checkSound(effect.mCastSound, "Casting Sound"));
|
||||
addMessageIfNotEmpty(messages, id, checkSound(effect.mHitSound, "Hit Sound"));
|
||||
addMessageIfNotEmpty(messages, id, checkSound(effect.mAreaSound, "Area Sound"));
|
||||
addMessageIfNotEmpty(messages, id, checkSound(effect.mBoltSound, "Bolt Sound"));
|
||||
|
||||
if (effect.mDescription.empty())
|
||||
{
|
||||
messages.push_back(std::make_pair(id, "Description is empty"));
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#ifndef CSM_TOOLS_MAGICEFFECTCHECK_HPP
|
||||
#define CSM_TOOLS_MAGICEFFECTCHECK_HPP
|
||||
|
||||
#include <components/esm/loadmgef.hpp>
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
#include "../world/refidcollection.hpp"
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Resources;
|
||||
}
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that magic effect records are internally consistent
|
||||
class MagicEffectCheckStage : public CSMDoc::Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::MagicEffect> &mMagicEffects;
|
||||
const CSMWorld::IdCollection<ESM::Sound> &mSounds;
|
||||
const CSMWorld::RefIdCollection &mReferenceables;
|
||||
const CSMWorld::Resources &mIcons;
|
||||
const CSMWorld::Resources &mTextures;
|
||||
|
||||
private:
|
||||
bool isTextureExists(const std::string &texture, bool isIcon) const;
|
||||
|
||||
std::string checkReferenceable(const std::string &id,
|
||||
const CSMWorld::UniversalId &type,
|
||||
const std::string &column) const;
|
||||
std::string checkSound(const std::string &id, const std::string &column) const;
|
||||
|
||||
public:
|
||||
MagicEffectCheckStage(const CSMWorld::IdCollection<ESM::MagicEffect> &effects,
|
||||
const CSMWorld::IdCollection<ESM::Sound> &sounds,
|
||||
const CSMWorld::RefIdCollection &referenceables,
|
||||
const CSMWorld::Resources &icons,
|
||||
const CSMWorld::Resources &textures);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
virtual void perform (int stage, CSMDoc::Messages &messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,59 @@
|
||||
|
||||
#include "mergeoperation.hpp"
|
||||
|
||||
#include "../doc/state.hpp"
|
||||
#include "../doc/document.hpp"
|
||||
|
||||
#include "mergestages.hpp"
|
||||
|
||||
CSMTools::MergeOperation::MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding)
|
||||
: CSMDoc::Operation (CSMDoc::State_Merging, true), mState (document)
|
||||
{
|
||||
appendStage (new StartMergeStage (mState));
|
||||
|
||||
appendStage (new MergeIdCollectionStage<ESM::Global> (mState, &CSMWorld::Data::getGlobals));
|
||||
appendStage (new MergeIdCollectionStage<ESM::GameSetting> (mState, &CSMWorld::Data::getGmsts));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Skill> (mState, &CSMWorld::Data::getSkills));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Class> (mState, &CSMWorld::Data::getClasses));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Faction> (mState, &CSMWorld::Data::getFactions));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Race> (mState, &CSMWorld::Data::getRaces));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Sound> (mState, &CSMWorld::Data::getSounds));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Script> (mState, &CSMWorld::Data::getScripts));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Region> (mState, &CSMWorld::Data::getRegions));
|
||||
appendStage (new MergeIdCollectionStage<ESM::BirthSign> (mState, &CSMWorld::Data::getBirthsigns));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Spell> (mState, &CSMWorld::Data::getSpells));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Dialogue> (mState, &CSMWorld::Data::getTopics));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Dialogue> (mState, &CSMWorld::Data::getJournals));
|
||||
appendStage (new MergeIdCollectionStage<CSMWorld::Cell> (mState, &CSMWorld::Data::getCells));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Filter> (mState, &CSMWorld::Data::getFilters));
|
||||
appendStage (new MergeIdCollectionStage<ESM::Enchantment> (mState, &CSMWorld::Data::getEnchantments));
|
||||
appendStage (new MergeIdCollectionStage<ESM::BodyPart> (mState, &CSMWorld::Data::getBodyParts));
|
||||
appendStage (new MergeIdCollectionStage<ESM::DebugProfile> (mState, &CSMWorld::Data::getDebugProfiles));
|
||||
appendStage (new MergeIdCollectionStage<ESM::SoundGenerator> (mState, &CSMWorld::Data::getSoundGens));
|
||||
appendStage (new MergeIdCollectionStage<ESM::MagicEffect> (mState, &CSMWorld::Data::getMagicEffects));
|
||||
appendStage (new MergeIdCollectionStage<ESM::StartScript> (mState, &CSMWorld::Data::getStartScripts));
|
||||
appendStage (new MergeIdCollectionStage<CSMWorld::Pathgrid, CSMWorld::SubCellCollection<CSMWorld::Pathgrid> > (mState, &CSMWorld::Data::getPathgrids));
|
||||
appendStage (new MergeIdCollectionStage<CSMWorld::Info, CSMWorld::InfoCollection> (mState, &CSMWorld::Data::getTopicInfos));
|
||||
appendStage (new MergeIdCollectionStage<CSMWorld::Info, CSMWorld::InfoCollection> (mState, &CSMWorld::Data::getJournalInfos));
|
||||
appendStage (new MergeRefIdsStage (mState));
|
||||
appendStage (new MergeReferencesStage (mState));
|
||||
appendStage (new MergeReferencesStage (mState));
|
||||
appendStage (new ListLandTexturesMergeStage (mState));
|
||||
appendStage (new MergeLandTexturesStage (mState));
|
||||
appendStage (new MergeLandStage (mState));
|
||||
|
||||
appendStage (new FinishMergedDocumentStage (mState, encoding));
|
||||
}
|
||||
|
||||
void CSMTools::MergeOperation::setTarget (std::auto_ptr<CSMDoc::Document> document)
|
||||
{
|
||||
mState.mTarget = document;
|
||||
}
|
||||
|
||||
void CSMTools::MergeOperation::operationDone()
|
||||
{
|
||||
CSMDoc::Operation::operationDone();
|
||||
|
||||
if (mState.mCompleted)
|
||||
emit mergeDone (mState.mTarget.release());
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
#ifndef CSM_TOOLS_MERGEOPERATION_H
|
||||
#define CSM_TOOLS_MERGEOPERATION_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "../doc/operation.hpp"
|
||||
|
||||
#include "mergestate.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
class MergeOperation : public CSMDoc::Operation
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
MergeState mState;
|
||||
|
||||
public:
|
||||
|
||||
MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding);
|
||||
|
||||
/// \attention Do not call this function while a merge is running.
|
||||
void setTarget (std::auto_ptr<CSMDoc::Document> document);
|
||||
|
||||
protected slots:
|
||||
|
||||
virtual void operationDone();
|
||||
|
||||
signals:
|
||||
|
||||
/// \attention When this signal is emitted, *this hands over the ownership of the
|
||||
/// document. This signal must be handled to avoid a leak.
|
||||
void mergeDone (CSMDoc::Document *document);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,258 @@
|
||||
|
||||
#include "mergestages.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "mergestate.hpp"
|
||||
|
||||
#include "../doc/document.hpp"
|
||||
#include "../world/data.hpp"
|
||||
|
||||
|
||||
CSMTools::StartMergeStage::StartMergeStage (MergeState& state)
|
||||
: mState (state)
|
||||
{}
|
||||
|
||||
int CSMTools::StartMergeStage::setup()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSMTools::StartMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
mState.mCompleted = false;
|
||||
mState.mTextureIndices.clear();
|
||||
}
|
||||
|
||||
|
||||
CSMTools::FinishMergedDocumentStage::FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding)
|
||||
: mState (state), mEncoder (encoding)
|
||||
{}
|
||||
|
||||
int CSMTools::FinishMergedDocumentStage::setup()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
// We know that the content file list contains at least two entries and that the first one
|
||||
// does exist on disc (otherwise it would have been impossible to initiate a merge on that
|
||||
// document).
|
||||
boost::filesystem::path path = mState.mSource.getContentFiles()[0];
|
||||
|
||||
ESM::ESMReader reader;
|
||||
reader.setEncoder (&mEncoder);
|
||||
reader.open (path.string());
|
||||
|
||||
CSMWorld::MetaData source;
|
||||
source.mId = "sys::meta";
|
||||
source.load (reader);
|
||||
|
||||
CSMWorld::MetaData target = mState.mTarget->getData().getMetaData();
|
||||
|
||||
target.mAuthor = source.mAuthor;
|
||||
target.mDescription = source.mDescription;
|
||||
|
||||
mState.mTarget->getData().setMetaData (target);
|
||||
|
||||
mState.mCompleted = true;
|
||||
}
|
||||
|
||||
|
||||
CSMTools::MergeRefIdsStage::MergeRefIdsStage (MergeState& state) : mState (state) {}
|
||||
|
||||
int CSMTools::MergeRefIdsStage::setup()
|
||||
{
|
||||
return mState.mSource.getData().getReferenceables().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::MergeRefIdsStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
mState.mSource.getData().getReferenceables().copyTo (
|
||||
stage, mState.mTarget->getData().getReferenceables());
|
||||
}
|
||||
|
||||
|
||||
CSMTools::MergeReferencesStage::MergeReferencesStage (MergeState& state)
|
||||
: mState (state)
|
||||
{}
|
||||
|
||||
int CSMTools::MergeReferencesStage::setup()
|
||||
{
|
||||
mIndex.clear();
|
||||
return mState.mSource.getData().getReferences().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::CellRef>& record =
|
||||
mState.mSource.getData().getReferences().getRecord (stage);
|
||||
|
||||
if (!record.isDeleted())
|
||||
{
|
||||
CSMWorld::CellRef ref = record.get();
|
||||
|
||||
ref.mOriginalCell = ref.mCell;
|
||||
|
||||
ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase (ref.mCell)]++;
|
||||
ref.mRefNum.mContentFile = 0;
|
||||
|
||||
CSMWorld::Record<CSMWorld::CellRef> newRecord (
|
||||
CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref);
|
||||
|
||||
mState.mTarget->getData().getReferences().appendRecord (newRecord);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMTools::ListLandTexturesMergeStage::ListLandTexturesMergeStage (MergeState& state)
|
||||
: mState (state)
|
||||
{}
|
||||
|
||||
int CSMTools::ListLandTexturesMergeStage::setup()
|
||||
{
|
||||
return mState.mSource.getData().getLand().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::ListLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Land>& record =
|
||||
mState.mSource.getData().getLand().getRecord (stage);
|
||||
|
||||
if (!record.isDeleted())
|
||||
{
|
||||
const CSMWorld::Land& land = record.get();
|
||||
|
||||
// make sure record is loaded
|
||||
land.loadData (ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML |
|
||||
ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
||||
|
||||
if (const ESM::Land::LandData *data = land.getLandData (ESM::Land::DATA_VTEX))
|
||||
{
|
||||
// list texture indices
|
||||
std::pair<uint16_t, int> key;
|
||||
key.second = land.mPlugin;
|
||||
|
||||
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
|
||||
{
|
||||
key.first = data->mTextures[i];
|
||||
|
||||
mState.mTextureIndices[key] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSMTools::MergeLandTexturesStage::MergeLandTexturesStage (MergeState& state)
|
||||
: mState (state), mNext (mState.mTextureIndices.end())
|
||||
{}
|
||||
|
||||
int CSMTools::MergeLandTexturesStage::setup()
|
||||
{
|
||||
// Should use the size of mState.mTextureIndices instead, but that is not available at this
|
||||
// point. Unless there are any errors in the land and land texture records this will not
|
||||
// make a difference.
|
||||
return mState.mSource.getData().getLandTextures().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::MergeLandTexturesStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
if (stage==0)
|
||||
mNext = mState.mTextureIndices.begin();
|
||||
|
||||
bool found = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (mNext==mState.mTextureIndices.end())
|
||||
return;
|
||||
|
||||
mNext->second = stage+1;
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << mNext->first.first-1 << "_" << mNext->first.second;
|
||||
|
||||
int index = mState.mSource.getData().getLandTextures().searchId (stream.str());
|
||||
|
||||
if (index!=-1)
|
||||
{
|
||||
CSMWorld::LandTexture texture =
|
||||
mState.mSource.getData().getLandTextures().getRecord (index).get();
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << mNext->second-1 << "_0";
|
||||
|
||||
texture.mIndex = mNext->second-1;
|
||||
texture.mId = stream.str();
|
||||
|
||||
CSMWorld::Record<CSMWorld::LandTexture> newRecord (
|
||||
CSMWorld::RecordBase::State_ModifiedOnly, 0, &texture);
|
||||
|
||||
mState.mTarget->getData().getLandTextures().appendRecord (newRecord);
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
++mNext;
|
||||
}
|
||||
while (!found);
|
||||
}
|
||||
|
||||
|
||||
CSMTools::MergeLandStage::MergeLandStage (MergeState& state) : mState (state) {}
|
||||
|
||||
int CSMTools::MergeLandStage::setup()
|
||||
{
|
||||
return mState.mSource.getData().getLand().getSize();
|
||||
}
|
||||
|
||||
void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Land>& record =
|
||||
mState.mSource.getData().getLand().getRecord (stage);
|
||||
|
||||
if (!record.isDeleted())
|
||||
{
|
||||
const CSMWorld::Land& land = record.get();
|
||||
|
||||
land.loadData (ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML |
|
||||
ESM::Land::DATA_VTEX | ESM::Land::DATA_WNAM);
|
||||
|
||||
CSMWorld::Land newLand (land);
|
||||
|
||||
newLand.mEsm = 0; // avoid potential dangling pointer (ESMReader isn't needed anyway,
|
||||
// because record is already fully loaded)
|
||||
newLand.mPlugin = 0;
|
||||
|
||||
if (land.mDataTypes & ESM::Land::DATA_VTEX)
|
||||
{
|
||||
// adjust land texture references
|
||||
if (ESM::Land::LandData *data = newLand.getLandData())
|
||||
{
|
||||
std::pair<uint16_t, int> key;
|
||||
key.second = land.mPlugin;
|
||||
|
||||
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
|
||||
{
|
||||
key.first = data->mTextures[i];
|
||||
std::map<std::pair<uint16_t, int>, int>::const_iterator iter =
|
||||
mState.mTextureIndices.find (key);
|
||||
|
||||
if (iter!=mState.mTextureIndices.end())
|
||||
data->mTextures[i] = iter->second;
|
||||
else
|
||||
data->mTextures[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::Record<CSMWorld::Land> newRecord (
|
||||
CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand);
|
||||
|
||||
mState.mTarget->getData().getLand().appendRecord (newRecord);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue