1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3     SPDX-FileCopyrightText: 2016-2020 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
4 */
5 
6 #include "objectsmodel.h"
7 
8 // app includes
9 #include "attribute.h"
10 #include "classifier.h"
11 #include "folder.h"
12 #include "operation.h"
13 #include "uml.h"
14 #include "umldoc.h"
15 
16 #include "umlobjectprivate.h"
17 
18 // kde includes
19 #include <KLocalizedString>
20 
21 // qt includes
22 #include <QtDebug>
23 
24 Q_DECLARE_METATYPE(UMLObject*);
25 
ObjectsModel()26 ObjectsModel::ObjectsModel()
27 {
28 }
29 
add(UMLObject * o)30 bool ObjectsModel::add(UMLObject *o)
31 {
32     if (m_allObjects.contains(o))
33         return false;
34     int index = m_allObjects.size();
35     beginInsertRows(QModelIndex(), index, index);
36     m_allObjects.append(o);
37     endInsertRows();
38     return true;
39 }
40 
remove(UMLObject * o)41 bool ObjectsModel::remove(UMLObject *o)
42 {
43     int index = m_allObjects.indexOf(o);
44     if (index == -1)
45         return false;
46     beginRemoveRows(QModelIndex(), index, index);
47     m_allObjects.removeAll(o);
48     endRemoveRows();
49     return true;
50 }
51 
rowCount(const QModelIndex & parent) const52 int ObjectsModel::rowCount(const QModelIndex &parent) const
53 {
54     Q_UNUSED(parent);
55 
56     int count = m_allObjects.size();
57     return count;
58 }
59 
columnCount(const QModelIndex & parent) const60 int ObjectsModel::columnCount(const QModelIndex &parent) const
61 {
62     Q_UNUSED(parent);
63 
64     return 7;
65 }
66 
headerData(int section,Qt::Orientation orientation,int role) const67 QVariant ObjectsModel::headerData(int section, Qt::Orientation orientation, int role) const
68 {
69     if (section < 0)
70         return QVariant();
71 
72     if (role != Qt::DisplayRole)
73         return QVariant();
74 
75     if (orientation == Qt::Vertical)
76         return section + 1;
77     if (section == 0)
78         return QVariant(i18n("Name"));
79     else if (section == 1)
80         return QVariant(i18n("Type"));
81     else if (section == 2)
82         return QVariant(i18n("Folder"));
83     else if (section == 3)
84         return QVariant(i18n("ID"));
85     else if (section == 4)
86         return QVariant(i18n("Saved"));
87     else if (section == 5)
88         return QVariant(i18n("Parent"));
89     else if (section == 6)
90         return QVariant(i18n("Pointer"));
91     else return QVariant();
92 }
93 
data(const QModelIndex & index,int role) const94 QVariant ObjectsModel::data(const QModelIndex & index, int role) const
95 {
96     if (role == Qt::UserRole && index.column() == 0) {
97         QVariant v;
98         v.setValue(m_allObjects.at(index.row()).data());
99         return v;
100     }
101     else if (role != Qt::DisplayRole)
102         return QVariant();
103 
104     int cCount = columnCount(index);
105     if (index.column() >= cCount)
106         return QVariant();
107 
108     UMLObject *o  = m_allObjects.at(index.row());
109 
110     // each case needs to return
111     switch (index.column()) {
112     case 0:
113         return o->name();
114     case 1:
115         return o->baseTypeStr();
116     case 2:
117         if (o->umlPackage())
118             return o->umlPackage()->name();
119         else if (o->parent()) {
120             UMLObject *p = dynamic_cast<UMLObject*>(o->parent());
121             if (p)
122                 return p->name();
123         }
124         return QVariant();
125    case 3:
126         return Uml::ID::toString(o->id());
127    case 4:
128         return o->m_d->isSaved;
129    case 5:
130         if (o->umlPackage()) {
131             UMLFolder *f = o->umlPackage()->asUMLFolder();
132             if (f) {
133                 UMLObjectList content = f->containedObjects();
134                 if (content.contains(o))
135                     return QLatin1String("package +");
136                 content = f->subordinates();
137                 if (content.contains(o))
138                     return QLatin1String("list +");
139             }
140             else
141                 return QLatin1String("package -");
142         } else if (o->umlParent()) {
143             if (o->isUMLAttribute()) {
144                 UMLOperation *op = o->umlParent()->asUMLOperation();
145                 if (op && op->getParmList().contains(o->asUMLAttribute()))
146                     return QLatin1String("parent +");
147                 else
148                     return QLatin1String("parent -");
149             } else if (o->isUMLOperation()) {
150                 UMLClassifier *c = o->umlParent()->asUMLClassifier();
151                 if (c && c->getOpList().contains(o->asUMLOperation()))
152                     return QLatin1String("parent +");
153                 else
154                     return QLatin1String("parent -");
155             }
156             return QLatin1String("not implemented");
157         } else
158             return QLatin1String("no parent");
159         return QVariant();
160     case 6:
161         return QString::number((quintptr)o, 16);
162     default:
163         return QVariant();
164     }
165 }
166 
emitDataChanged(const QModelIndex & index)167 void ObjectsModel::emitDataChanged(const QModelIndex &index)
168 {
169     emit dataChanged(index, index);
170 }
171 
emitDataChanged(int index)172 void ObjectsModel::emitDataChanged(int index)
173 {
174     QModelIndex mi = createIndex(index,0);
175     emit dataChanged(mi, mi);
176 }
177 
emitDataChanged(UMLObject * o)178 void ObjectsModel::emitDataChanged(UMLObject *o)
179 {
180 #if QT_VERSION < 0x050000
181     emit layoutAboutToBeChanged();
182 #endif
183     int index  = m_allObjects.indexOf(o);
184     emitDataChanged(index);
185 #if QT_VERSION < 0x050000
186     emit layoutChanged();
187 #endif
188 }
189