forked from Mirrors/openclonk
234 lines
6.2 KiB
C++
234 lines
6.2 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2013, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
|
|
/* Proplist table view */
|
|
|
|
#include "C4Include.h"
|
|
#include "script/C4Value.h"
|
|
#include "object/C4Def.h"
|
|
#include "object/C4Object.h"
|
|
#include "object/C4GameObjects.h"
|
|
#include "editor/C4ConsoleQtObjectListViewer.h"
|
|
#include "editor/C4Console.h"
|
|
#include "editor/C4EditCursor.h"
|
|
#include "script/C4Effect.h"
|
|
#include "object/C4GameObjects.h"
|
|
|
|
|
|
C4ConsoleQtObjectListModel::C4ConsoleQtObjectListModel() : last_row_count(0)
|
|
{
|
|
// default font colors
|
|
clr_deleted.setColor(QApplication::palette().color(QPalette::Mid));
|
|
clr_effect.setColor(QApplication::palette().color(QPalette::Dark));
|
|
// install self for callbacks from ObjectListDlg
|
|
::Console.ObjectListDlg.SetModel(this);
|
|
}
|
|
|
|
C4ConsoleQtObjectListModel::~C4ConsoleQtObjectListModel()
|
|
{
|
|
::Console.ObjectListDlg.SetModel(nullptr);
|
|
}
|
|
|
|
void C4ConsoleQtObjectListModel::Invalidate()
|
|
{
|
|
// Kill any dead object pointers and force redraw
|
|
emit layoutAboutToBeChanged();
|
|
QModelIndexList list = this->persistentIndexList();
|
|
for (auto idx : list)
|
|
{
|
|
if (idx.internalPointer())
|
|
{
|
|
QModelIndex new_index = GetModelIndexByItem(static_cast<C4PropList *>(idx.internalPointer()));
|
|
this->changePersistentIndex(idx, new_index);
|
|
}
|
|
}
|
|
QModelIndex topLeft = index(0, 0, QModelIndex());
|
|
QModelIndex bottomRight = index(last_row_count, columnCount() - 1, QModelIndex());
|
|
emit dataChanged(topLeft, bottomRight);
|
|
emit layoutChanged();
|
|
}
|
|
|
|
int C4ConsoleQtObjectListModel::rowCount(const QModelIndex & parent) const
|
|
{
|
|
int result = 0;
|
|
if (parent.isValid())
|
|
{
|
|
// Child row count of object
|
|
C4PropList *parent_item = GetItemByModelIndex(parent);
|
|
if (!parent_item) return result;
|
|
C4Object *obj = parent_item->GetObject();
|
|
if (!obj || !obj->Status) return result;
|
|
// Contained objects
|
|
for (C4Object *contents : obj->Contents)
|
|
if (contents && contents->Status)
|
|
++result;
|
|
}
|
|
else
|
|
{
|
|
// Static lists
|
|
result = IDX_Objects;
|
|
// Main object count
|
|
for (C4Object *obj : ::Objects)
|
|
if (obj && obj->Status && !obj->Contained)
|
|
++result;
|
|
last_row_count = result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int C4ConsoleQtObjectListModel::columnCount(const QModelIndex & parent) const
|
|
{
|
|
return 1; // Name only
|
|
}
|
|
|
|
QVariant C4ConsoleQtObjectListModel::data(const QModelIndex & index, int role) const
|
|
{
|
|
// Object list lookup is done in index(). Here we just use the pointer.
|
|
C4PropList *data = GetItemByModelIndex(index);
|
|
if (role == Qt::DisplayRole)
|
|
{
|
|
// Deleted proplist?
|
|
if (!data) return QString("<deleted>");
|
|
// Prefer own name
|
|
const char *name = data->GetName();
|
|
if (name && *name) return QString(name);
|
|
// If no name is set, fall back to definition name for objects
|
|
C4Object *obj = data->GetObject();
|
|
if (obj) return QString(obj->Def->id.ToString());
|
|
}
|
|
else if (role == Qt::ForegroundRole)
|
|
{
|
|
// Deleted proplist?
|
|
if (!data) return QVariant(clr_deleted);
|
|
// Object?
|
|
C4Object *obj = data->GetObject();
|
|
if (obj) return QVariant(); // default
|
|
// Effect
|
|
return QVariant(clr_effect);
|
|
}
|
|
// Nothing to show
|
|
return QVariant();
|
|
}
|
|
|
|
QModelIndex C4ConsoleQtObjectListModel::index(int row, int column, const QModelIndex &parent) const
|
|
{
|
|
// Current index out of range?
|
|
if (row < 0 || column != 0) return QModelIndex();
|
|
int index = row;
|
|
// Child element or main list?
|
|
if (parent.isValid())
|
|
{
|
|
// Child of valid object?
|
|
C4PropList *pobj = GetItemByModelIndex(parent);
|
|
C4Object *container = pobj->GetObject();
|
|
if (container)
|
|
{
|
|
for (C4Object *contents : container->Contents)
|
|
{
|
|
if (contents && contents->Status)
|
|
{
|
|
if (!index--)
|
|
{
|
|
return createIndex(row, column, static_cast<C4PropList *>(contents));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Static entries
|
|
if (index == IDX_Global)
|
|
{
|
|
return createIndex(row, column, static_cast<C4PropList *>(&::ScriptEngine));
|
|
}
|
|
else if (index == IDX_Scenario)
|
|
{
|
|
// This may create a null pointer entry. That's OK; it's only for the disabled display before the scenario is loaded
|
|
return createIndex(row, column, static_cast<C4PropList *>(::GameScript.ScenPropList.getPropList()));
|
|
}
|
|
else
|
|
{
|
|
// Main object list
|
|
for (C4Object *obj : ::Objects)
|
|
{
|
|
if (obj && obj->Status && !obj->Contained)
|
|
{
|
|
if (!index--)
|
|
{
|
|
return createIndex(row, column, static_cast<C4PropList *>(obj));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return QModelIndex(); // out of range
|
|
}
|
|
|
|
QModelIndex C4ConsoleQtObjectListModel::parent(const QModelIndex &index) const
|
|
{
|
|
// Find parent of object
|
|
if (!index.isValid()) return QModelIndex();
|
|
C4PropList *data = GetItemByModelIndex(index);
|
|
if (!data) return QModelIndex();
|
|
C4Object *obj = data->GetObject();
|
|
if (obj) return GetModelIndexByItem(obj->Contained);
|
|
// Root item
|
|
return QModelIndex();
|
|
}
|
|
|
|
QModelIndex C4ConsoleQtObjectListModel::GetModelIndexByItem(C4PropList *item) const
|
|
{
|
|
// Deduce position in model list from item pointer
|
|
// No position for invalid items
|
|
if (!item) return QModelIndex();
|
|
C4Object *obj = item->GetObject();
|
|
if (obj && !obj->Status) return QModelIndex();
|
|
// Default position for Global and Scenario object
|
|
int row;
|
|
if (item == &::ScriptEngine)
|
|
{
|
|
row = IDX_Global;
|
|
}
|
|
else if (item == ::GameScript.ScenPropList.getPropList())
|
|
{
|
|
row = IDX_Scenario;
|
|
}
|
|
else if (obj)
|
|
{
|
|
// Positions for object items
|
|
row = IDX_Objects;
|
|
const C4ObjectList *list = &::Objects;
|
|
if (obj->Contained) list = &(obj->Contained->Contents);
|
|
for (C4Object *cobj : *list)
|
|
{
|
|
if (cobj == obj) break;
|
|
if (cobj && cobj->Status) ++row;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return QModelIndex();
|
|
}
|
|
return createIndex(row, 0, static_cast<C4PropList *>(item));
|
|
}
|
|
|
|
C4PropList *C4ConsoleQtObjectListModel::GetItemByModelIndex(const QModelIndex &index) const
|
|
{
|
|
// Get proplist from model index
|
|
if (!index.isValid()) return nullptr;
|
|
return static_cast<C4PropList *>(index.internalPointer());
|
|
} |