OpenClonk
C4ConsoleQtObjectListViewer.cpp
Go to the documentation of this file.
1 /*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5 * Copyright (c) 2013, The OpenClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16 
17 /* Proplist table view */
18 
19 #include "C4Include.h"
20 #include "script/C4Value.h"
21 #include "object/C4Def.h"
22 #include "object/C4Object.h"
23 #include "object/C4GameObjects.h"
25 #include "editor/C4Console.h"
26 #include "editor/C4EditCursor.h"
27 #include "script/C4Effect.h"
28 #include "object/C4GameObjects.h"
29 
30 
31 C4ConsoleQtObjectListModel::C4ConsoleQtObjectListModel()
32 {
33  // default font colors
34  clr_deleted.setColor(QApplication::palette().color(QPalette::Mid));
35  clr_effect.setColor(QApplication::palette().color(QPalette::Dark));
36  // install self for callbacks from ObjectListDlg
37  ::Console.ObjectListDlg.SetModel(this);
38 }
39 
40 C4ConsoleQtObjectListModel::~C4ConsoleQtObjectListModel()
41 {
42  ::Console.ObjectListDlg.SetModel(nullptr);
43 }
44 
45 void C4ConsoleQtObjectListModel::Invalidate()
46 {
47  // Kill any dead object pointers and force redraw
48  emit layoutAboutToBeChanged();
49  QModelIndexList list = this->persistentIndexList();
50  for (auto idx : list)
51  {
52  if (idx.internalPointer())
53  {
54  QModelIndex new_index = GetModelIndexByItem(static_cast<C4PropList *>(idx.internalPointer()));
55  this->changePersistentIndex(idx, new_index);
56  }
57  }
58  QModelIndex topLeft = index(0, 0, QModelIndex());
59  QModelIndex bottomRight = index(last_row_count, columnCount() - 1, QModelIndex());
60  emit dataChanged(topLeft, bottomRight);
61  emit layoutChanged();
62 }
63 
64 int C4ConsoleQtObjectListModel::rowCount(const QModelIndex & parent) const
65 {
66  int result = 0;
67  if (parent.isValid())
68  {
69  // Child row count of object
70  C4PropList *parent_item = GetItemByModelIndex(parent);
71  if (!parent_item) return result;
72  C4Object *obj = parent_item->GetObject();
73  if (!obj || !obj->Status) return result;
74  // Contained objects
75  for (C4Object *contents : obj->Contents)
76  if (contents && contents->Status)
77  ++result;
78  }
79  else
80  {
81  // Static lists
82  result = IDX_Objects;
83  // Main object count
84  for (C4Object *obj : ::Objects)
85  if (obj && obj->Status && !obj->Contained)
86  ++result;
87  last_row_count = result;
88  }
89  return result;
90 }
91 
92 int C4ConsoleQtObjectListModel::columnCount(const QModelIndex & parent) const
93 {
94  return 1; // Name only
95 }
96 
97 QVariant C4ConsoleQtObjectListModel::data(const QModelIndex & index, int role) const
98 {
99  // Object list lookup is done in index(). Here we just use the pointer.
100  C4PropList *data = GetItemByModelIndex(index);
101  if (role == Qt::DisplayRole)
102  {
103  // Deleted proplist?
104  if (!data) return QString("<deleted>");
105  // Prefer own name
106  const char *name = data->GetName();
107  if (name && *name) return QString(name);
108  // If no name is set, fall back to definition name for objects
109  C4Object *obj = data->GetObject();
110  if (obj) return QString(obj->Def->id.ToString());
111  }
112  else if (role == Qt::ForegroundRole)
113  {
114  // Deleted proplist?
115  if (!data) return QVariant(clr_deleted);
116  // Object?
117  C4Object *obj = data->GetObject();
118  if (obj) return QVariant(); // default
119  // Effect
120  return QVariant(clr_effect);
121  }
122  // Nothing to show
123  return QVariant();
124 }
125 
126 QModelIndex C4ConsoleQtObjectListModel::index(int row, int column, const QModelIndex &parent) const
127 {
128  // Current index out of range?
129  if (row < 0 || column != 0) return QModelIndex();
130  int index = row;
131  // Child element or main list?
132  if (parent.isValid())
133  {
134  // Child of valid object?
135  C4PropList *pobj = GetItemByModelIndex(parent);
136  C4Object *container = pobj->GetObject();
137  if (container)
138  {
139  for (C4Object *contents : container->Contents)
140  {
141  if (contents && contents->Status)
142  {
143  if (!index--)
144  {
145  return createIndex(row, column, static_cast<C4PropList *>(contents));
146  }
147  }
148  }
149  }
150  }
151  else
152  {
153  // Static entries
154  if (index == IDX_Global)
155  {
156  return createIndex(row, column, static_cast<C4PropList *>(&::ScriptEngine));
157  }
158  else if (index == IDX_Scenario)
159  {
160  // This may create a null pointer entry. That's OK; it's only for the disabled display before the scenario is loaded
161  return createIndex(row, column, static_cast<C4PropList *>(::GameScript.ScenPropList.getPropList()));
162  }
163  else
164  {
165  // Main object list
166  for (C4Object *obj : ::Objects)
167  {
168  if (obj && obj->Status && !obj->Contained)
169  {
170  if (!index--)
171  {
172  return createIndex(row, column, static_cast<C4PropList *>(obj));
173  }
174  }
175  }
176  }
177  }
178  return QModelIndex(); // out of range
179 }
180 
181 QModelIndex C4ConsoleQtObjectListModel::parent(const QModelIndex &index) const
182 {
183  // Find parent of object
184  if (!index.isValid()) return QModelIndex();
185  C4PropList *data = GetItemByModelIndex(index);
186  if (!data) return QModelIndex();
187  C4Object *obj = data->GetObject();
188  if (obj) return GetModelIndexByItem(obj->Contained);
189  // Root item
190  return QModelIndex();
191 }
192 
193 QModelIndex C4ConsoleQtObjectListModel::GetModelIndexByItem(C4PropList *item) const
194 {
195  // Deduce position in model list from item pointer
196  // No position for invalid items
197  if (!item) return QModelIndex();
198  C4Object *obj = item->GetObject();
199  if (obj && !obj->Status) return QModelIndex();
200  // Default position for Global and Scenario object
201  int row;
202  if (item == &::ScriptEngine)
203  {
204  row = IDX_Global;
205  }
206  else if (item == ::GameScript.ScenPropList.getPropList())
207  {
208  row = IDX_Scenario;
209  }
210  else if (obj)
211  {
212  // Positions for object items
213  row = IDX_Objects;
214  const C4ObjectList *list = &::Objects;
215  if (obj->Contained) list = &(obj->Contained->Contents);
216  for (C4Object *cobj : *list)
217  {
218  if (cobj == obj) break;
219  if (cobj && cobj->Status) ++row;
220  }
221  }
222  else
223  {
224  return QModelIndex();
225  }
226  return createIndex(row, 0, static_cast<C4PropList *>(item));
227 }
228 
229 C4PropList *C4ConsoleQtObjectListModel::GetItemByModelIndex(const QModelIndex &index) const
230 {
231  // Get proplist from model index
232  if (!index.isValid()) return nullptr;
233  return static_cast<C4PropList *>(index.internalPointer());
234 }
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
C4Console Console
Definition: C4Globals.cpp:45
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4GameScriptHost GameScript
C4ObjectListDlg ObjectListDlg
Definition: C4Console.h:89
C4ID id
Definition: C4Def.h:101
C4Value ScenPropList
Definition: C4ScriptHost.h:164
const char * ToString() const
Definition: C4Id.h:56
C4NotifyingObjectList Contents
Definition: C4Object.h:151
C4ObjectPtr Contained
Definition: C4Object.h:142
C4Def * Def
Definition: C4Object.h:141
virtual C4Object * GetObject()
Definition: C4PropList.cpp:636
virtual const char * GetName() const
Definition: C4PropList.cpp:618
int32_t Status
Definition: C4PropList.h:173
C4PropList * getPropList() const
Definition: C4Value.h:116