Merge branch 'master' of git://github.com/OpenMW/openmw into appveyor

coverity_scan
Alexander "Ace" Olofsson 9 years ago
commit b3e985fca2

@ -2,6 +2,8 @@ os:
- linux - linux
# - osx # - osx
language: cpp language: cpp
sudo: required
dist: trusty
branches: branches:
only: only:
- master - master
@ -18,8 +20,8 @@ addons:
name: "OpenMW/openmw" name: "OpenMW/openmw"
description: "<Your project description here>" description: "<Your project description here>"
notification_email: scrawl@baseoftrash.de notification_email: scrawl@baseoftrash.de
build_command_prepend: "cmake . -DBUILD_UNITTESTS=FALSE -DBUILD_OPENCS=FALSE" build_command_prepend: "cmake . -DBUILD_UNITTESTS=FALSE"
build_command: "make" build_command: "make -j2"
branch_pattern: coverity_scan branch_pattern: coverity_scan
matrix: matrix:
include: include:
@ -38,7 +40,7 @@ before_script:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
script: script:
- cd ./build - cd ./build
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j3; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi

@ -113,6 +113,7 @@ Programmers
Stefan Galowicz (bogglez) Stefan Galowicz (bogglez)
Stanislav Bobrov (Jiub) Stanislav Bobrov (Jiub)
Sylvain Thesnieres (Garvek) Sylvain Thesnieres (Garvek)
t6
terrorfisch terrorfisch
Thomas Luppi (Digmaster) Thomas Luppi (Digmaster)
Tom Mason (wheybags) Tom Mason (wheybags)

@ -1,22 +1,17 @@
#!/bin/sh #!/bin/sh
if [ "${ANALYZE}" ]; then if [ "${ANALYZE}" ]; then
if [ $(lsb_release -sc) = "precise" ]; then
echo "yes" | sudo apt-add-repository ppa:ubuntu-toolchain-r/test
fi
echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main" echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main"
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
fi fi
echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse" echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
echo "yes" | sudo apt-add-repository ppa:openmw/openmw echo "yes" | sudo apt-add-repository ppa:openmw/openmw
echo "yes" | sudo apt-add-repository ppa:boost-latest/ppa
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -qq libgtest-dev google-mock sudo apt-get install -qq libgtest-dev google-mock
sudo apt-get install -qq libboost-filesystem1.55-dev libboost-program-options1.55-dev libboost-system1.55-dev libboost-thread1.55-dev sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev
sudo apt-get install -qq ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
sudo apt-get install -qq cmake-data #workaround for broken osgqt cmake script in ubuntu 12.04
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
sudo mkdir /usr/src/gtest/build sudo mkdir /usr/src/gtest/build
cd /usr/src/gtest/build cd /usr/src/gtest/build

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
free -m
mkdir build mkdir build
cd build cd build
export CODE_COVERAGE=1 export CODE_COVERAGE=1

@ -7,7 +7,7 @@ OpenMW is a recreation of the engine for the popular role-playing game Morrowind
OpenMW also comes with OpenMW-CS, a replacement for Morrowind's TES Construction Set. OpenMW also comes with OpenMW-CS, a replacement for Morrowind's TES Construction Set.
* Version: 0.37.0 * Version: 0.38.0
* License: GPL (see docs/license/GPL3.txt for more information) * License: GPL (see docs/license/GPL3.txt for more information)
* Website: http://www.openmw.org * Website: http://www.openmw.org
* IRC: #openmw on irc.freenode.net * IRC: #openmw on irc.freenode.net

@ -121,7 +121,7 @@ public:
{ {
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel; mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
mContext->mPlayerBase = npc; mContext->mPlayerBase = npc;
std::map<const int, float> empty; std::map<int, float> empty;
// FIXME: player start spells and birthsign spells aren't listed here, // FIXME: player start spells and birthsign spells aren't listed here,
// need to fix openmw to account for this // need to fix openmw to account for this
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it) for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)

@ -1,6 +1,7 @@
#include "convertinventory.hpp" #include "convertinventory.hpp"
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <cstdlib>
namespace ESSImport namespace ESSImport
{ {

@ -85,7 +85,7 @@ opencs_units (view/widget
opencs_units (view/render opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode instancemode previewwidget editmode instancemode instanceselectionmode
) )
opencs_units_noqt (view/render opencs_units_noqt (view/render

@ -1,6 +1,6 @@
#include "messages.hpp" #include "messages.hpp"
CSMDoc::Message::Message() {} CSMDoc::Message::Message() : mSeverity(Severity_Default){}
CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& message, CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint, Severity severity) const std::string& hint, Severity severity)

@ -39,9 +39,6 @@ namespace CSMDoc
{ {
public: public:
// \deprecated Use CSMDoc::Message directly instead.
typedef CSMDoc::Message Message;
typedef std::vector<Message> Collection; typedef std::vector<Message> Collection;
typedef Collection::const_iterator Iterator; typedef Collection::const_iterator Iterator;

@ -2,7 +2,9 @@
#include "operation.hpp" #include "operation.hpp"
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false) CSMDoc::OperationHolder::OperationHolder (Operation *operation)
: mOperation(NULL)
, mRunning (false)
{ {
if (operation) if (operation)
setOperation (operation); setOperation (operation);

@ -133,6 +133,8 @@ void CSMPrefs::State::declare()
declareBool ("show-linenum", "Show Line Numbers", true). declareBool ("show-linenum", "Show Line Numbers", true).
setTooltip ("Show line numbers to the left of the script editor window." 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."); "The current row and column numbers of the text cursor are shown at the bottom.");
declareBool ("wrap-lines", "Wrap Lines", false).
setTooltip ("Wrap lines longer than width of script editor.");
declareBool ("mono-font", "Use monospace font", true); declareBool ("mono-font", "Use monospace font", true);
EnumValue warningsNormal ("Normal", "Report warnings as warning"); EnumValue warningsNormal ("Normal", "Report warnings as warning");
declareEnum ("warnings", "Warning Mode", warningsNormal). declareEnum ("warnings", "Warning Mode", warningsNormal).

@ -182,7 +182,7 @@ int CSMTools::ReportModel::countErrors() const
{ {
int count = 0; int count = 0;
for (std::vector<CSMDoc::Messages::Message>::const_iterator iter (mRows.begin()); for (std::vector<CSMDoc::Message>::const_iterator iter (mRows.begin());
iter!=mRows.end(); ++iter) iter!=mRows.end(); ++iter)
if (iter->mSeverity==CSMDoc::Message::Severity_Error || if (iter->mSeverity==CSMDoc::Message::Severity_Error ||
iter->mSeverity==CSMDoc::Message::Severity_SeriousError) iter->mSeverity==CSMDoc::Message::Severity_SeriousError)

@ -16,7 +16,7 @@ namespace CSMTools
{ {
Q_OBJECT Q_OBJECT
std::vector<CSMDoc::Messages::Message> mRows; std::vector<CSMDoc::Message> mRows;
// Fixed columns // Fixed columns
enum Columns enum Columns

@ -14,7 +14,7 @@
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand* parent) const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false) : QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)
{ {
if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model)) if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model))
{ {

@ -22,11 +22,18 @@ bool CSVRender::Cell::removeObject (const std::string& id)
if (iter==mObjects.end()) if (iter==mObjects.end())
return false; return false;
delete iter->second; removeObject (iter);
mObjects.erase (iter);
return true; return true;
} }
std::map<std::string, CSVRender::Object *>::iterator CSVRender::Cell::removeObject (
std::map<std::string, Object *>::iterator iter)
{
delete iter->second;
mObjects.erase (iter++);
return iter;
}
bool CSVRender::Cell::addObjects (int start, int end) bool CSVRender::Cell::addObjects (int start, int end)
{ {
bool modified = false; bool modified = false;
@ -161,8 +168,8 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
// perform update and remove where needed // perform update and remove where needed
bool modified = false; bool modified = false;
for (std::map<std::string, Object *>::iterator iter (mObjects.begin()); std::map<std::string, Object *>::iterator iter = mObjects.begin();
iter!=mObjects.end(); ++iter) while (iter!=mObjects.end())
{ {
if (iter->second->referenceDataChanged (topLeft, bottomRight)) if (iter->second->referenceDataChanged (topLeft, bottomRight))
modified = true; modified = true;
@ -171,23 +178,30 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
if (iter2!=ids.end()) if (iter2!=ids.end())
{ {
if (iter2->second) bool deleted = iter2->second;
ids.erase (iter2);
if (deleted)
{ {
removeObject (iter->first); iter = removeObject (iter);
modified = true; modified = true;
continue;
} }
ids.erase (iter2);
} }
++iter;
} }
// add new objects // add new objects
for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter) for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter)
{ {
mObjects.insert (std::make_pair ( if (!iter->second)
iter->first, new Object (mData, mCellNode, iter->first, false))); {
mObjects.insert (std::make_pair (
iter->first, new Object (mData, mCellNode, iter->first, false)));
modified = true; modified = true;
}
} }
return modified; return modified;
@ -249,6 +263,28 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
} }
} }
void CSVRender::Cell::selectAllWithSameParentId (int elementMask)
{
std::set<std::string> ids;
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
{
if (iter->second->getSelected())
ids.insert (iter->second->getReferenceableId());
}
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
{
if (!iter->second->getSelected() &&
ids.find (iter->second->getReferenceableId())!=ids.end())
{
iter->second->setSelected (true);
}
}
}
void CSVRender::Cell::setCellArrows (int mask) void CSVRender::Cell::setCellArrows (int mask)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
@ -276,3 +312,16 @@ bool CSVRender::Cell::isDeleted() const
{ {
return mDeleted; return mDeleted;
} }
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (unsigned int elementMask) const
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->getSelected())
result.push_back (iter->second->getTag());
return result;
}

@ -31,6 +31,8 @@ namespace CSMWorld
namespace CSVRender namespace CSVRender
{ {
class TagBase;
class Cell class Cell
{ {
CSMWorld::Data& mData; CSMWorld::Data& mData;
@ -47,6 +49,10 @@ namespace CSVRender
/// \return Was the object deleted? /// \return Was the object deleted?
bool removeObject (const std::string& id); bool removeObject (const std::string& id);
// Remove object and return iterator to next object.
std::map<std::string, Object *>::iterator removeObject (
std::map<std::string, Object *>::iterator iter);
/// Add objects from reference table that are within this cell. /// Add objects from reference table that are within this cell.
/// ///
/// \return Have any objects been added? /// \return Have any objects been added?
@ -93,12 +99,18 @@ namespace CSVRender
void setSelection (int elementMask, Selection mode); void setSelection (int elementMask, Selection mode);
// Select everything that references the same ID as at least one of the elements
// already selected
void selectAllWithSameParentId (int elementMask);
void setCellArrows (int mask); void setCellArrows (int mask);
/// Returns 0, 0 in case of an unpaged cell. /// Returns 0, 0 in case of an unpaged cell.
CSMWorld::CellCoordinates getCoordinates() const; CSMWorld::CellCoordinates getCoordinates() const;
bool isDeleted() const; bool isDeleted() const;
std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask) const;
}; };
} }

@ -9,16 +9,73 @@
#include "../../model/world/idtree.hpp" #include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
#include "mask.hpp" #include "mask.hpp"
#include "object.hpp" #include "object.hpp"
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include "instanceselectionmode.hpp"
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing", : EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
parent) parent), mSubMode (0), mSelectionMode (0)
{
}
void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
{
if (!mSubMode)
{
mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
mSubMode->addButton (":placeholder", "move",
"Move selected instances"
"<ul><li>Use primary edit to move instances around freely</li>"
"<li>Use secondary edit to move instances around within the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSubMode->addButton (":placeholder", "rotate",
"Rotate selected instances"
"<ul><li>Use primary edit to rotate instances freely</li>"
"<li>Use secondary edit to rotate instances within the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSubMode->addButton (":placeholder", "scale",
"Scale selected instances"
"<ul><li>Use primary edit to scale instances freely</li>"
"<li>Use secondary edit to scale instances along the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
}
if (!mSelectionMode)
mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget());
EditMode::activate (toolbar);
toolbar->addTool (mSubMode);
toolbar->addTool (mSelectionMode);
}
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
{ {
if (mSelectionMode)
{
toolbar->removeTool (mSelectionMode);
delete mSelectionMode;
mSelectionMode = 0;
}
if (mSubMode)
{
toolbar->removeTool (mSubMode);
delete mSubMode;
mSubMode = 0;
}
EditMode::deactivate (toolbar);
} }
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)

@ -3,16 +3,29 @@
#include "editmode.hpp" #include "editmode.hpp"
namespace CSVWidget
{
class SceneToolMode;
}
namespace CSVRender namespace CSVRender
{ {
class InstanceSelectionMode;
class InstanceMode : public EditMode class InstanceMode : public EditMode
{ {
Q_OBJECT Q_OBJECT
CSVWidget::SceneToolMode *mSubMode;
InstanceSelectionMode *mSelectionMode;
public: public:
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
virtual void activate (CSVWidget::SceneToolbar *toolbar);
virtual void deactivate (CSVWidget::SceneToolbar *toolbar);
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);

@ -0,0 +1,93 @@
#include "instanceselectionmode.hpp"
#include <QMenu>
#include <QAction>
#include "../../model/world/idtable.hpp"
#include "../../model/world/commands.hpp"
#include "worldspacewidget.hpp"
#include "object.hpp"
bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu)
{
if (menu)
{
menu->addAction (mSelectAll);
menu->addAction (mDeselectAll);
menu->addAction (mSelectSame);
menu->addAction (mDeleteSelection);
}
return true;
}
CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent,
WorldspaceWidget& worldspaceWidget)
: CSVWidget::SceneToolMode (parent, "Selection Mode"), mWorldspaceWidget (worldspaceWidget)
{
addButton (":placeholder", "cube-centre",
"Centred cube"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection cube outwards</li>"
"<li>The selection cube is aligned to the word space axis</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
addButton (":placeholder", "cube-corner",
"Cube corner to corner"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from one corner of the selection cube to the opposite corner</li>"
"<li>The selection cube is aligned to the word space axis</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
addButton (":placeholder", "sphere",
"Centred sphere"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection sphere outwards</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSelectAll = new QAction ("Select all instances", this);
mDeselectAll = new QAction ("Clear selection", this);
mDeleteSelection = new QAction ("Delete selected instances", this);
mSelectSame = new QAction ("Extend selection to instances with same object ID", this);
connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll()));
connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection()));
connect (mDeleteSelection, SIGNAL (triggered ()), this, SLOT (deleteSelection()));
connect (mSelectSame, SIGNAL (triggered ()), this, SLOT (selectSame()));
}
void CSVRender::InstanceSelectionMode::selectAll()
{
mWorldspaceWidget.selectAll (Mask_Reference);
}
void CSVRender::InstanceSelectionMode::clearSelection()
{
mWorldspaceWidget.clearSelection (Mask_Reference);
}
void CSVRender::InstanceSelectionMode::deleteSelection()
{
std::vector<osg::ref_ptr<TagBase> > selection =
mWorldspaceWidget.getSelection (Mask_Reference);
CSMWorld::IdTable& referencesTable =
dynamic_cast<CSMWorld::IdTable&> (*mWorldspaceWidget.getDocument().getData().
getTableModel (CSMWorld::UniversalId::Type_References));
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
iter!=selection.end(); ++iter)
{
CSMWorld::DeleteCommand *command = new CSMWorld::DeleteCommand (referencesTable,
static_cast<ObjectTag *> (iter->get())->mObject->getReferenceId());
mWorldspaceWidget.getDocument().getUndoStack().push (command);
}
}
void CSVRender::InstanceSelectionMode::selectSame()
{
mWorldspaceWidget.selectAllWithSameParentId (Mask_Reference);
}

@ -0,0 +1,46 @@
#ifndef CSV_RENDER_INSTANCE_SELECTION_MODE_H
#define CSV_RENDER_INSTANCE_SELECTION_MODE_H
#include "../widget/scenetoolmode.hpp"
class QAction;
namespace CSVRender
{
class WorldspaceWidget;
class InstanceSelectionMode : public CSVWidget::SceneToolMode
{
Q_OBJECT
WorldspaceWidget& mWorldspaceWidget;
QAction *mSelectAll;
QAction *mDeselectAll;
QAction *mDeleteSelection;
QAction *mSelectSame;
/// Add context menu items to \a menu.
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
public:
InstanceSelectionMode (CSVWidget::SceneToolbar *parent, WorldspaceWidget& worldspaceWidget);
private slots:
void selectAll();
void clearSelection();
void deleteSelection();
void selectSame();
};
}
#endif

@ -187,6 +187,7 @@ CSVRender::Object::~Object()
clear(); clear();
mParentNode->removeChild(mBaseNode); mParentNode->removeChild(mBaseNode);
mParentNode->removeChild(mOutline);
} }
void CSVRender::Object::setSelected(bool selected) void CSVRender::Object::setSelected(bool selected)
@ -284,3 +285,8 @@ std::string CSVRender::Object::getReferenceableId() const
{ {
return mReferenceableId; return mReferenceableId;
} }
osg::ref_ptr<CSVRender::TagBase> CSVRender::Object::getTag() const
{
return static_cast<CSVRender::TagBase *> (mBaseNode->getUserData());
}

@ -114,6 +114,8 @@ namespace CSVRender
std::string getReferenceId() const; std::string getReferenceId() const;
std::string getReferenceableId() const; std::string getReferenceableId() const;
osg::ref_ptr<TagBase> getTag() const;
}; };
} }

@ -509,6 +509,24 @@ void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask)
flagAsModified(); flagAsModified();
} }
void CSVRender::PagedWorldspaceWidget::selectAll (int elementMask)
{
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
iter->second->setSelection (elementMask, Cell::Selection_All);
flagAsModified();
}
void CSVRender::PagedWorldspaceWidget::selectAllWithSameParentId (int elementMask)
{
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
iter->second->selectAllWithSameParentId (elementMask);
flagAsModified();
}
std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const
{ {
const int cellSize = 8192; const int cellSize = 8192;
@ -520,6 +538,23 @@ std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point
return cellCoordinates.getId (mWorldspace); return cellCoordinates.getId (mWorldspace);
} }
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::PagedWorldspaceWidget::getSelection (
unsigned int elementMask) const
{
std::vector<osg::ref_ptr<CSVRender::TagBase> > result;
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
{
std::vector<osg::ref_ptr<CSVRender::TagBase> > cellResult =
iter->second->getSelection (elementMask);
result.insert (result.end(), cellResult.begin(), cellResult.end());
}
return result;
}
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector ( CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
CSVWidget::SceneToolbar *parent) CSVWidget::SceneToolbar *parent)
{ {

@ -98,8 +98,20 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation /// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask); virtual void clearSelection (int elementMask);
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask);
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask);
virtual std::string getCellId (const osg::Vec3f& point) const; virtual std::string getCellId (const osg::Vec3f& point) const;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const;
protected: protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);

@ -108,11 +108,29 @@ void CSVRender::UnpagedWorldspaceWidget::clearSelection (int elementMask)
flagAsModified(); flagAsModified();
} }
void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask)
{
mCell->setSelection (elementMask, Cell::Selection_All);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId (int elementMask)
{
mCell->selectAllWithSameParentId (elementMask);
flagAsModified();
}
std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const
{ {
return mCellId; return mCellId;
} }
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::UnpagedWorldspaceWidget::getSelection (
unsigned int elementMask) const
{
return mCell->getSelection (elementMask);
}
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight) const QModelIndex& bottomRight)
{ {

@ -46,8 +46,20 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation /// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask); virtual void clearSelection (int elementMask);
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask);
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask);
virtual std::string getCellId (const osg::Vec3f& point) const; virtual std::string getCellId (const osg::Vec3f& point) const;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const;
private: private:
virtual void referenceableDataChanged (const QModelIndex& topLeft, virtual void referenceableDataChanged (const QModelIndex& topLeft,

@ -33,8 +33,9 @@
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), : SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document),
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
mToolTipPos (-1, -1) mDragWheelFactor(0), mDragShiftFactor(0),
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
{ {
setAcceptDrops(true); setAcceptDrops(true);

@ -127,6 +127,15 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation /// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask) = 0; virtual void clearSelection (int elementMask) = 0;
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask) = 0;
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask) = 0;
/// Return the next intersection point with scene elements matched by /// Return the next intersection point with scene elements matched by
/// \a interactionMask based on \a localPos and the camera vector. /// \a interactionMask based on \a localPos and the camera vector.
/// If there is no such point, instead a point "in front" of \a localPos will be /// If there is no such point, instead a point "in front" of \a localPos will be
@ -140,6 +149,9 @@ namespace CSVRender
virtual std::string getCellId (const osg::Vec3f& point) const = 0; virtual std::string getCellId (const osg::Vec3f& point) const = 0;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const = 0;
protected: protected:
/// Visual elements in a scene /// Visual elements in a scene

@ -7,3 +7,8 @@ CSVWidget::ModeButton::ModeButton (const QIcon& icon, const QString& tooltip, QW
void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {} void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {}
void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {} void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {}
bool CSVWidget::ModeButton::createContextMenu (QMenu *menu)
{
return false;
}

@ -3,6 +3,8 @@
#include "pushbutton.hpp" #include "pushbutton.hpp"
class QMenu;
namespace CSVWidget namespace CSVWidget
{ {
class SceneToolbar; class SceneToolbar;
@ -22,6 +24,14 @@ namespace CSVWidget
/// Default-Implementation: do nothing /// Default-Implementation: do nothing
virtual void deactivate (SceneToolbar *toolbar); virtual void deactivate (SceneToolbar *toolbar);
/// Add context menu items to \a menu. Default-implementation: return false
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
}; };
} }

@ -3,10 +3,27 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QFrame> #include <QFrame>
#include <QSignalMapper> #include <QSignalMapper>
#include <QMenu>
#include <QContextMenuEvent>
#include "scenetoolbar.hpp" #include "scenetoolbar.hpp"
#include "modebutton.hpp" #include "modebutton.hpp"
void CSVWidget::SceneToolMode::contextMenuEvent (QContextMenuEvent *event)
{
QMenu menu (this);
if (createContextMenu (&menu))
menu.exec (event->globalPos());
}
bool CSVWidget::SceneToolMode::createContextMenu (QMenu *menu)
{
if (mCurrent)
return mCurrent->createContextMenu (menu);
return false;
}
void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
{ {
QString toolTip = mToolTip; QString toolTip = mToolTip;
@ -15,6 +32,9 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
toolTip += "<p>(left click to change mode)"; toolTip += "<p>(left click to change mode)";
if (createContextMenu (0))
toolTip += "<br>(right click to access context menu)";
setToolTip (toolTip); setToolTip (toolTip);
} }

@ -6,6 +6,7 @@
#include <map> #include <map>
class QHBoxLayout; class QHBoxLayout;
class QMenu;
namespace CSVWidget namespace CSVWidget
{ {
@ -29,6 +30,17 @@ namespace CSVWidget
void adjustToolTip (const ModeButton *activeMode); void adjustToolTip (const ModeButton *activeMode);
virtual void contextMenuEvent (QContextMenuEvent *event);
/// Add context menu items to \a menu. Default-implementation: Pass on request to
/// current mode button or return false, if there is no current mode button.
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
public: public:
SceneToolMode (SceneToolbar *parent, const QString& toolTip); SceneToolMode (SceneToolbar *parent, const QString& toolTip);

@ -122,7 +122,7 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp
CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar);
toolbar->addTool (runTool); toolbar->addTool (runTool);
toolbar->addTool (widget->makeEditModeSelector (toolbar)); toolbar->addTool (widget->makeEditModeSelector (toolbar), runTool);
return toolbar; return toolbar;
} }

@ -38,20 +38,20 @@ bool CSVWorld::ScriptEdit::event (QEvent *event)
return QPlainTextEdit::event (event); return QPlainTextEdit::event (event);
} }
CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, CSVWorld::ScriptEdit::ScriptEdit(
QWidget* parent) const CSMDoc::Document& document,
: QPlainTextEdit (parent), ScriptHighlighter::Mode mode,
mChangeLocked (0), QWidget* parent
) : QPlainTextEdit(parent),
mChangeLocked(0),
mShowLineNum(false), mShowLineNum(false),
mLineNumberArea(0), mLineNumberArea(0),
mDefaultFont(font()), mDefaultFont(font()),
mMonoFont(QFont("Monospace")), mMonoFont(QFont("Monospace")),
mDocument (document), mDocument(document),
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive)
{ {
// setAcceptRichText (false); wrapLines(false);
setLineWrapMode (QPlainTextEdit::NoWrap);
setTabStopWidth (4); setTabStopWidth (4);
setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead
@ -194,14 +194,37 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
return !(string.contains(mWhiteListQoutes)); return !(string.contains(mWhiteListQoutes));
} }
void CSVWorld::ScriptEdit::settingChanged (const CSMPrefs::Setting *setting) void CSVWorld::ScriptEdit::wrapLines(bool wrap)
{
if (wrap)
{
setLineWrapMode(QPlainTextEdit::WidgetWidth);
}
else
{
setLineWrapMode(QPlainTextEdit::NoWrap);
}
}
void CSVWorld::ScriptEdit::settingChanged(const CSMPrefs::Setting *setting)
{ {
if (mHighlighter->settingChanged (setting)) // Determine which setting was changed.
if (mHighlighter->settingChanged(setting))
{
updateHighlighting(); updateHighlighting();
else if (*setting=="Scripts/mono-font") }
setFont (setting->isTrue() ? mMonoFont : mDefaultFont); else if (*setting == "Scripts/mono-font")
else if (*setting=="Scripts/show-linenum") {
showLineNum (setting->isTrue()); setFont(setting->isTrue() ? mMonoFont : mDefaultFont);
}
else if (*setting == "Scripts/show-linenum")
{
showLineNum(setting->isTrue());
}
else if (*setting == "Scripts/wrap-lines")
{
wrapLines(setting->isTrue());
}
} }
void CSVWorld::ScriptEdit::idListChanged() void CSVWorld::ScriptEdit::idListChanged()

@ -22,6 +22,7 @@ namespace CSVWorld
{ {
class LineNumberArea; class LineNumberArea;
/// \brief Editor for scripts.
class ScriptEdit : public QPlainTextEdit class ScriptEdit : public QPlainTextEdit
{ {
Q_OBJECT Q_OBJECT
@ -77,6 +78,7 @@ namespace CSVWorld
virtual void resizeEvent(QResizeEvent *e); virtual void resizeEvent(QResizeEvent *e);
private: private:
QVector<CSMWorld::UniversalId::Type> mAllowedTypes; QVector<CSMWorld::UniversalId::Type> mAllowedTypes;
const CSMDoc::Document& mDocument; const CSMDoc::Document& mDocument;
const QRegExp mWhiteListQoutes; const QRegExp mWhiteListQoutes;
@ -89,9 +91,15 @@ namespace CSVWorld
bool stringNeedsQuote(const std::string& id) const; bool stringNeedsQuote(const std::string& id) const;
/// \brief Turn line wrapping in script editor on or off.
/// \param wrap Whether or not to wrap lines.
void wrapLines(bool wrap);
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting); /// \brief Update editor when related setting is changed.
/// \param setting Setting that was changed.
void settingChanged(const CSMPrefs::Setting *setting);
void idListChanged(); void idListChanged();

@ -1,20 +1,118 @@
#include "startscriptcreator.hpp" #include "startscriptcreator.hpp"
CSVWorld::StartScriptCreator::StartScriptCreator(CSMWorld::Data &data, QUndoStack &undoStack, const CSMWorld::UniversalId &id, bool relaxedIdRules): #include <QLabel>
GenericCreator (data, undoStack, id, true)
{} #include "../../model/doc/document.hpp"
#include "../../model/world/columns.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/idcompletionmanager.hpp"
#include "../../model/world/idtable.hpp"
#include "../widget/droplineedit.hpp"
std::string CSVWorld::StartScriptCreator::getId() const
{
return mScript->text().toUtf8().constData();
}
CSMWorld::IdTable& CSVWorld::StartScriptCreator::getStartScriptsTable() const
{
return dynamic_cast<CSMWorld::IdTable&> (
*getData().getTableModel(getCollectionId())
);
}
void CSVWorld::StartScriptCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const
{
CSMWorld::IdTable& table = getStartScriptsTable();
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_Id);
// Set script ID to be added to start scripts table.
command.addValue(column, mScript->text());
}
CSVWorld::StartScriptCreator::StartScriptCreator(
CSMWorld::Data &data,
QUndoStack &undoStack,
const CSMWorld::UniversalId &id,
CSMWorld::IdCompletionManager& completionManager
) : GenericCreator(data, undoStack, id, true)
{
setManualEditing(false);
// Add script ID input label.
QLabel *label = new QLabel("Script ID", this);
insertBeforeButtons(label, false);
// Add script ID input with auto-completion.
CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Script;
mScript = new CSVWidget::DropLineEdit(displayType, this);
mScript->setCompleter(completionManager.getCompleter(displayType).get());
insertBeforeButtons(mScript, true);
connect(mScript, SIGNAL (textChanged(const QString&)), this, SLOT (scriptChanged()));
}
void CSVWorld::StartScriptCreator::cloneMode(
const std::string& originId,
const CSMWorld::UniversalId::Type type)
{
CSVWorld::GenericCreator::cloneMode(originId, type);
// Look up cloned record in start scripts table and set script ID text.
CSMWorld::IdTable& table = getStartScriptsTable();
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_Id);
mScript->setText(table.data(table.getModelIndex(originId, column)).toString());
}
std::string CSVWorld::StartScriptCreator::getErrors() const std::string CSVWorld::StartScriptCreator::getErrors() const
{ {
std::string errors; std::string scriptId = getId();
errors = getIdValidatorResult(); // Check user input for any errors.
if (errors.length() > 0) std::string errors;
return errors; if (scriptId.empty())
else if (getData().getScripts().searchId(getId()) == -1) {
errors = "No Script ID entered";
}
else if (getData().getScripts().searchId(scriptId) == -1)
{
errors = "Script ID not found"; errors = "Script ID not found";
else if (getData().getStartScripts().searchId(getId()) > -1 ) }
else if (getData().getStartScripts().searchId(scriptId) > -1)
{
errors = "Script with this ID already registered as Start Script"; errors = "Script with this ID already registered as Start Script";
}
return errors; return errors;
} }
void CSVWorld::StartScriptCreator::focus()
{
mScript->setFocus();
}
void CSVWorld::StartScriptCreator::reset()
{
CSVWorld::GenericCreator::reset();
mScript->setText("");
}
void CSVWorld::StartScriptCreator::scriptChanged()
{
update();
}
CSVWorld::Creator *CSVWorld::StartScriptCreatorFactory::makeCreator(
CSMDoc::Document& document,
const CSMWorld::UniversalId& id) const
{
return new StartScriptCreator(
document.getData(),
document.getUndoStack(),
id,
document.getIdCompletionManager()
);
}

@ -3,23 +3,77 @@
#include "genericcreator.hpp" #include "genericcreator.hpp"
namespace CSVWorld { namespace CSMWorld
{
class IdCompletionManager;
class IdTable;
}
namespace CSVWidget
{
class DropLineEdit;
}
namespace CSVWorld
{
/// \brief Record creator for start scripts.
class StartScriptCreator : public GenericCreator class StartScriptCreator : public GenericCreator
{ {
Q_OBJECT Q_OBJECT
CSVWidget::DropLineEdit *mScript;
private:
/// \return script ID entered by user.
virtual std::string getId() const;
/// \return reference to table containing start scripts.
CSMWorld::IdTable& getStartScriptsTable() const;
/// \brief Add user input to command for creating start script.
/// \param command Creation command to configure.
virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const;
public: public:
StartScriptCreator(CSMWorld::Data& data, QUndoStack& undoStack,
const CSMWorld::UniversalId& id, bool relaxedIdRules = false);
StartScriptCreator(
CSMWorld::Data& data,
QUndoStack& undoStack,
const CSMWorld::UniversalId& id,
CSMWorld::IdCompletionManager& completionManager);
/// \brief Set script ID input widget to ID of record to be cloned.
/// \param originId Script ID to be cloned.
/// \param type Type of record to be cloned.
virtual void cloneMode(
const std::string& originId,
const CSMWorld::UniversalId::Type type);
/// \return Error description for current user input.
virtual std::string getErrors() const; virtual std::string getErrors() const;
///< Return formatted error descriptions for the current state of the creator. if an empty
/// string is returned, there is no error.
};
} /// \brief Set focus to script ID input widget.
virtual void focus();
/// \brief Clear script ID input widget.
virtual void reset();
private slots:
/// \brief Check user input for any errors.
void scriptChanged();
};
/// \brief Creator factory for start script record creator.
class StartScriptCreatorFactory : public CreatorFactoryBase
{
public:
virtual Creator *makeCreator(
CSMDoc::Document& document,
const CSMWorld::UniversalId& id) const;
};
}
#endif // STARTSCRIPTCREATOR_HPP #endif // STARTSCRIPTCREATOR_HPP

@ -52,7 +52,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<GenericCreator> >); new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<GenericCreator> >);
manager.add (CSMWorld::UniversalId::Type_StartScripts, manager.add (CSMWorld::UniversalId::Type_StartScripts,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<StartScriptCreator> >); new CSVDoc::SubViewFactoryWithCreator<TableSubView, StartScriptCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Cells, manager.add (CSMWorld::UniversalId::Type_Cells,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<CellCreator> >); new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<CellCreator> >);
@ -136,8 +136,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
CreatorFactory<GenericCreator> > (false)); CreatorFactory<GenericCreator> > (false));
manager.add (CSMWorld::UniversalId::Type_StartScript, manager.add (CSMWorld::UniversalId::Type_StartScript,
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, StartScriptCreatorFactory>(false));
CreatorFactory<StartScriptCreator> > (false));
manager.add (CSMWorld::UniversalId::Type_Skill, manager.add (CSMWorld::UniversalId::Type_Skill,
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, NullCreatorFactory > (false)); new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, NullCreatorFactory > (false));
@ -177,7 +176,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_MetaData, manager.add (CSMWorld::UniversalId::Type_MetaData,
new CSVDoc::SubViewFactory<SimpleDialogueSubView >); new CSVDoc::SubViewFactory<SimpleDialogueSubView >);
//preview //preview
manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>); manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>);
} }

@ -2,7 +2,6 @@
#include <QHeaderView> #include <QHeaderView>
#include <QAction> #include <QAction>
#include <QApplication>
#include <QMenu> #include <QMenu>
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include <QString> #include <QString>
@ -12,7 +11,6 @@
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/infotableproxymodel.hpp" #include "../../model/world/infotableproxymodel.hpp"
#include "../../model/world/idtableproxymodel.hpp" #include "../../model/world/idtableproxymodel.hpp"
@ -20,13 +18,10 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp" #include "../../model/world/record.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "recordstatusdelegate.hpp"
#include "tableeditidaction.hpp" #include "tableeditidaction.hpp"
#include "util.hpp" #include "util.hpp"
@ -231,7 +226,7 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event)
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
bool createAndDelete, bool sorting, CSMDoc::Document& document) bool createAndDelete, bool sorting, CSMDoc::Document& document)
: DragRecordTable(document), mCreateAction (0), : DragRecordTable(document), mCreateAction (0),
mCloneAction(0),mRecordStatusDisplay (0) mCloneAction(0), mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
{ {
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
@ -339,8 +334,6 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (tableSizeUpdate())); this, SLOT (tableSizeUpdate()));
//connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
// this, SLOT (rowsInsertedEvent(const QModelIndex&, int, int)));
connect (mProxyModel, SIGNAL (rowAdded (const std::string &)), connect (mProxyModel, SIGNAL (rowAdded (const std::string &)),
this, SLOT (rowAdded (const std::string &))); this, SLOT (rowAdded (const std::string &)));

@ -11,7 +11,6 @@
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "dragrecordtable.hpp" #include "dragrecordtable.hpp"
class QUndoStack;
class QAction; class QAction;
namespace CSMDoc namespace CSMDoc
@ -21,7 +20,6 @@ namespace CSMDoc
namespace CSMWorld namespace CSMWorld
{ {
class Data;
class IdTableProxyModel; class IdTableProxyModel;
class IdTableBase; class IdTableBase;
class CommandDispatcher; class CommandDispatcher;

@ -76,7 +76,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto
CSMDoc::Document& document, CSMDoc::Document& document,
const CSMWorld::UniversalId& id, const CSMWorld::UniversalId& id,
QWidget *parent) QWidget *parent)
: QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None), mHasPosition(false) : QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None), mHasPosition(false), mRow(0), mColumn(0)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
mStatusCount[i] = 0; mStatusCount[i] = 0;

@ -24,7 +24,7 @@
#ifndef PR_SET_PTRACER #ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61 #define PR_SET_PTRACER 0x59616d61
#endif #endif
#elif defined (__APPLE__) #elif defined (__APPLE__) || defined (__FreeBSD__)
#include <signal.h> #include <signal.h>
#endif #endif

@ -1556,7 +1556,7 @@ namespace MWMechanics
(target == getPlayer() && (target == getPlayer() &&
MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf")))
{ {
const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search("iWerewolfFightMod"); const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iWerewolfFightMod");
fight += iWerewolfFightMod->getInt(); fight += iWerewolfFightMod->getInt();
} }
} }

@ -44,7 +44,7 @@ namespace MWMechanics
{ {
if (mSpells.find (spell)==mSpells.end()) if (mSpells.find (spell)==mSpells.end())
{ {
std::map<const int, float> random; std::map<int, float> random;
// Determine the random magnitudes (unless this is a castable spell, in which case // Determine the random magnitudes (unless this is a castable spell, in which case
// they will be determined when the spell is cast) // they will be determined when the spell is cast)

@ -33,7 +33,7 @@ namespace MWMechanics
typedef const ESM::Spell* SpellKey; typedef const ESM::Spell* SpellKey;
typedef std::map<SpellKey, std::map<const int, float> > TContainer; // ID, <effect index, normalised random magnitude> typedef std::map<SpellKey, std::map<int, float> > TContainer; // ID, <effect index, normalised random magnitude>
typedef TContainer::const_iterator TIterator; typedef TContainer::const_iterator TIterator;
struct CorprusStats struct CorprusStats

@ -42,6 +42,7 @@
#include "camera.hpp" #include "camera.hpp"
#include "water.hpp" #include "water.hpp"
#include "terrainstorage.hpp" #include "terrainstorage.hpp"
#include "util.hpp"
namespace MWRender namespace MWRender
{ {
@ -504,15 +505,6 @@ namespace MWRender
mutable bool mDone; mutable bool mDone;
}; };
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
}
};
void RenderingManager::screenshot(osg::Image *image, int w, int h) void RenderingManager::screenshot(osg::Image *image, int w, int h)
{ {
osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera); osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera);

@ -17,6 +17,7 @@
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <osg/BlendFunc> #include <osg/BlendFunc>
#include <osg/AlphaFunc> #include <osg/AlphaFunc>
#include <osg/observer_ptr>
#include <osgParticle/ParticleSystem> #include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater> #include <osgParticle/ParticleSystemUpdater>
@ -374,8 +375,13 @@ public:
} }
else if (mMeshType == 2) else if (mMeshType == 2)
{ {
osg::Vec4Array* origColors = static_cast<osg::Vec4Array*>(geom->getColorArray()); if (geom->getColorArray())
alpha = ((*origColors)[i].x() == 1.f) ? 1.f : 0.f; {
osg::Vec4Array* origColors = static_cast<osg::Vec4Array*>(geom->getColorArray());
alpha = ((*origColors)[i].x() == 1.f) ? 1.f : 0.f;
}
else
alpha = 1.f;
} }
(*colors)[i] = osg::Vec4f(0.f, 0.f, 0.f, alpha); (*colors)[i] = osg::Vec4f(0.f, 0.f, 0.f, alpha);

@ -1,6 +1,7 @@
#ifndef OPENMW_MWRENDER_UTIL_H #ifndef OPENMW_MWRENDER_UTIL_H
#define OPENMW_MWRENDER_UTIL_H #define OPENMW_MWRENDER_UTIL_H
#include <osg/NodeCallback>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <string> #include <string>
@ -16,9 +17,17 @@ namespace Resource
namespace MWRender namespace MWRender
{ {
void overrideTexture(const std::string& texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node); void overrideTexture(const std::string& texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
// Node callback to entirely skip the traversal.
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// no traverse()
}
};
} }
#endif #endif

@ -41,6 +41,7 @@
#include "vismask.hpp" #include "vismask.hpp"
#include "ripplesimulation.hpp" #include "ripplesimulation.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -210,16 +211,6 @@ private:
osg::Plane mPlane; osg::Plane mPlane;
}; };
// Node callback to entirely skip the traversal.
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// no traverse()
}
};
/// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis. /// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis.
/// The offset works around graphics artifacts that occured with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least). /// The offset works around graphics artifacts that occured with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least).
/// Must be added as a Cull callback. /// Must be added as a Cull callback.

@ -447,5 +447,7 @@ op 0x20002fe: RemoveFromLevItem
op 0x20002ff: SetFactionReaction op 0x20002ff: SetFactionReaction
op 0x2000300: EnableLevelupMenu op 0x2000300: EnableLevelupMenu
op 0x2000301: ToggleScripts op 0x2000301: ToggleScripts
op 0x2000302: Fixme
op 0x2000303: Fixme, explicit
opcodes 0x2000302-0x3ffffff unused opcodes 0x2000304-0x3ffffff unused

@ -734,6 +734,18 @@ namespace MWScript
} }
}; };
template <class R>
class OpFixme : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWBase::Environment::get().getWorld()->fixPosition(ptr);
}
};
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5(Compiler::Transformation::opcodeSetScale,new OpSetScale<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetScale,new OpSetScale<ImplicitRef>);
@ -774,6 +786,8 @@ namespace MWScript
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors); interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors);
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme<ImplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeFixmeExplicit, new OpFixme<ExplicitRef>);
} }
} }
} }

@ -5,6 +5,7 @@
#include "../mwscript/locals.hpp" #include "../mwscript/locals.hpp"
#include <string>
#include <osg/Vec3f> #include <osg/Vec3f>
namespace SceneUtil namespace SceneUtil

@ -108,7 +108,11 @@ namespace MWWorld
} }
private: private:
#ifdef HAVE_UNORDERED_MAP
typedef std::unordered_map<std::string, ContentLoader*> LoadersContainer;
#else
typedef std::tr1::unordered_map<std::string, ContentLoader*> LoadersContainer; typedef std::tr1::unordered_map<std::string, ContentLoader*> LoadersContainer;
#endif
LoadersContainer mLoaders; LoadersContainer mLoaders;
}; };
@ -433,7 +437,7 @@ namespace MWWorld
// Werewolf (BM) // Werewolf (BM)
gmst["fWereWolfRunMult"] = ESM::Variant(1.f); gmst["fWereWolfRunMult"] = ESM::Variant(1.f);
gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f); gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f);
gmst["iWerewolfFightMod"] = ESM::Variant(1);
std::map<std::string, ESM::Variant> globals; std::map<std::string, ESM::Variant> globals;
// vanilla Morrowind does not define dayspassed. // vanilla Morrowind does not define dayspassed.
@ -1311,7 +1315,8 @@ namespace MWWorld
actor.getRefData().setPosition(pos); actor.getRefData().setPosition(pos);
osg::Vec3f traced = mPhysics->traceDown(actor, dist*1.1f); osg::Vec3f traced = mPhysics->traceDown(actor, dist*1.1f);
moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z()); if (traced != pos.asVec3())
moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z());
} }
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
@ -1744,6 +1749,8 @@ namespace MWWorld
{ {
cellid.mWorldspace = ref.mRef.getDestCell(); cellid.mWorldspace = ref.mRef.getDestCell();
cellid.mPaged = false; cellid.mPaged = false;
cellid.mIndex.mX = 0;
cellid.mIndex.mY = 0;
} }
else else
{ {

@ -541,6 +541,7 @@ namespace Compiler
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit); extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit); extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
extensions.registerInstruction("resetactors","",opcodeResetActors); extensions.registerInstruction("resetactors","",opcodeResetActors);
extensions.registerInstruction("fixme","",opcodeFixme, opcodeFixmeExplicit);
extensions.registerInstruction("ra","",opcodeResetActors); extensions.registerInstruction("ra","",opcodeResetActors);
} }
} }

@ -498,6 +498,8 @@ namespace Compiler
const int opcodeMoveWorld = 0x2000208; const int opcodeMoveWorld = 0x2000208;
const int opcodeMoveWorldExplicit = 0x2000209; const int opcodeMoveWorldExplicit = 0x2000209;
const int opcodeResetActors = 0x20002f4; const int opcodeResetActors = 0x20002f4;
const int opcodeFixme = 0x2000302;
const int opcodeFixmeExplicit = 0x2000303;
} }
namespace User namespace User

@ -12,7 +12,7 @@ namespace ESM
{ {
std::string id = esm.getHString(); std::string id = esm.getHString();
std::map<const int, float> random; std::map<int, float> random;
while (esm.isNextSub("INDX")) while (esm.isNextSub("INDX"))
{ {
int index; int index;
@ -73,8 +73,8 @@ namespace ESM
{ {
esm.writeHNString("SPEL", it->first); esm.writeHNString("SPEL", it->first);
const std::map<const int, float>& random = it->second; const std::map<int, float>& random = it->second;
for (std::map<const int, float>::const_iterator rIt = random.begin(); rIt != random.end(); ++rIt) for (std::map<int, float>::const_iterator rIt = random.begin(); rIt != random.end(); ++rIt)
{ {
esm.writeHNT("INDX", rIt->first); esm.writeHNT("INDX", rIt->first);
esm.writeHNT("RAND", rIt->second); esm.writeHNT("RAND", rIt->second);

@ -28,7 +28,7 @@ namespace ESM
float mMagnitude; float mMagnitude;
}; };
typedef std::map<std::string, std::map<const int, float> > TContainer; typedef std::map<std::string, std::map<int, float> > TContainer;
TContainer mSpells; TContainer mSpells;
std::map<std::string, std::vector<PermanentSpellEffectInfo> > mPermanentSpellEffects; std::map<std::string, std::vector<PermanentSpellEffectInfo> > mPermanentSpellEffects;

@ -1,6 +1,7 @@
#include "bulletshape.hpp" #include "bulletshape.hpp"
#include <stdexcept> #include <stdexcept>
#include <string>
#include <BulletCollision/CollisionShapes/btBoxShape.h> #include <BulletCollision/CollisionShapes/btBoxShape.h>
#include <BulletCollision/CollisionShapes/btTriangleMesh.h> #include <BulletCollision/CollisionShapes/btTriangleMesh.h>

@ -201,10 +201,22 @@ namespace Resource
} }
catch (std::exception& e) catch (std::exception& e)
{ {
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error.nif instead" << std::endl; static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2" };
Files::IStreamPtr file = mVFS->get("meshes/marker_error.nif");
normalized = "meshes/marker_error.nif"; for (unsigned int i=0; i<sizeof(sMeshTypes)/sizeof(sMeshTypes[0]); ++i)
loaded = load(file, normalized, mTextureManager, mNifFileManager); {
normalized = "meshes/marker_error." + std::string(sMeshTypes[i]);
if (mVFS->exists(normalized))
{
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error." << sMeshTypes[i] << " instead" << std::endl;
Files::IStreamPtr file = mVFS->get(normalized);
loaded = load(file, normalized, mTextureManager, mNifFileManager);
break;
}
}
if (!loaded)
throw;
} }
osgDB::Registry::instance()->getOrCreateSharedStateManager()->share(loaded.get()); osgDB::Registry::instance()->getOrCreateSharedStateManager()->share(loaded.get());

@ -5,6 +5,7 @@
#include <osg/Group> #include <osg/Group>
#include <osg/NodeVisitor> #include <osg/NodeVisitor>
#include <osg/observer_ptr>
namespace SceneUtil namespace SceneUtil
{ {

@ -14,7 +14,7 @@
[Camera] [Camera]
# Near clipping plane (>0.0, e.g. 0.01 to 18.0). # Near clipping plane (>0.0, e.g. 0.01 to 18.0).
near clip = 5.0 near clip = 1
# Cull objects smaller than one pixel. # Cull objects smaller than one pixel.
small feature culling = true small feature culling = true

Loading…
Cancel
Save