PropertyModel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <cfloat>
00028 #endif
00029
00030 #include "PropertyModel.h"
00031 #include "PropertyItem.h"
00032
00033 using namespace Gui::PropertyEditor;
00034
00035
00036
00037
00038 PropertyModel::PropertyModel(QObject* parent)
00039 : QAbstractItemModel(parent)
00040 {
00041 rootItem = static_cast<PropertyItem*>(PropertyItem::create());
00042 }
00043
00044 PropertyModel::~PropertyModel()
00045 {
00046 delete rootItem;
00047 }
00048
00049 QModelIndex PropertyModel::buddy ( const QModelIndex & index ) const
00050 {
00051 if (index.column() == 1)
00052 return index;
00053 return index.sibling(index.row(), 1);
00054 }
00055
00056 int PropertyModel::columnCount ( const QModelIndex & parent ) const
00057 {
00058
00059 if (parent.isValid())
00060 return static_cast<PropertyItem*>(parent.internalPointer())->columnCount();
00061 else
00062 return rootItem->columnCount();
00063 }
00064
00065 QVariant PropertyModel::data ( const QModelIndex & index, int role ) const
00066 {
00067 if (!index.isValid())
00068 return QVariant();
00069
00070 PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
00071 return item->data(index.column(), role);
00072 }
00073
00074 bool PropertyModel::setData(const QModelIndex& index, const QVariant & value, int role)
00075 {
00076 if (!index.isValid())
00077 return false;
00078
00079
00080 if (role == Qt::EditRole) {
00081 PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
00082 QVariant data = item->data(index.column(), role);
00083 if (data.type() == QVariant::Double && value.type() == QVariant::Double) {
00084
00085
00086 double d = data.toDouble();
00087 double v = value.toDouble();
00088 if (fabs(d-v) > FLT_EPSILON)
00089 return item->setData(value);
00090 }
00091 else if (data != value)
00092 return item->setData(value);
00093 }
00094
00095 return true;
00096 }
00097
00098 Qt::ItemFlags PropertyModel::flags(const QModelIndex &index) const
00099 {
00100 PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
00101 return item->flags(index.column());
00102 }
00103
00104 QModelIndex PropertyModel::index ( int row, int column, const QModelIndex & parent ) const
00105 {
00106 PropertyItem *parentItem;
00107
00108 if (!parent.isValid())
00109 parentItem = rootItem;
00110 else
00111 parentItem = static_cast<PropertyItem*>(parent.internalPointer());
00112
00113 PropertyItem *childItem = parentItem->child(row);
00114 if (childItem)
00115 return createIndex(row, column, childItem);
00116 else
00117 return QModelIndex();
00118 }
00119
00120 QModelIndex PropertyModel::parent ( const QModelIndex & index ) const
00121 {
00122 if (!index.isValid())
00123 return QModelIndex();
00124
00125 PropertyItem *childItem = static_cast<PropertyItem*>(index.internalPointer());
00126 PropertyItem *parentItem = childItem->parent();
00127
00128 if (parentItem == rootItem)
00129 return QModelIndex();
00130
00131 return createIndex(parentItem->row(), 0, parentItem);
00132 }
00133
00134 int PropertyModel::rowCount ( const QModelIndex & parent ) const
00135 {
00136 PropertyItem *parentItem;
00137
00138 if (!parent.isValid())
00139 parentItem = rootItem;
00140 else
00141 parentItem = static_cast<PropertyItem*>(parent.internalPointer());
00142
00143 return parentItem->childCount();
00144 }
00145
00146 QVariant PropertyModel::headerData (int section, Qt::Orientation orientation, int role) const
00147 {
00148 if (orientation == Qt::Horizontal) {
00149 if (role != Qt::DisplayRole)
00150 return QVariant();
00151 if (section == 0)
00152 return tr("Property");
00153 if (section == 1)
00154 return tr("Value");
00155 }
00156
00157 return QVariant();
00158 }
00159
00160 bool PropertyModel::setHeaderData (int, Qt::Orientation, const QVariant &, int)
00161 {
00162 return false;
00163 }
00164
00165 QStringList PropertyModel::propertyPathFromIndex(const QModelIndex& index) const
00166 {
00167 QStringList path;
00168 if (index.isValid()) {
00169 PropertyItem* item = static_cast<PropertyItem*>(index.internalPointer());
00170 if (!item->isSeparator()) {
00171 do {
00172 path.push_front(item->propertyName());
00173 item = item->parent();
00174 }
00175 while (item != this->rootItem && item != 0);
00176 }
00177 }
00178
00179 return path;
00180 }
00181
00182 QModelIndex PropertyModel::propertyIndexFromPath(const QStringList& path) const
00183 {
00184 QModelIndex parent;
00185 for (QStringList::const_iterator it = path.begin(); it != path.end(); ++it) {
00186 int rows = this->rowCount(parent);
00187 for (int i=0; i<rows; i++) {
00188 QModelIndex index = this->index(i, 0, parent);
00189 if (index.isValid()) {
00190 PropertyItem* item = static_cast<PropertyItem*>(index.internalPointer());
00191 if (item->propertyName() == *it) {
00192 parent = index;
00193 break;
00194 }
00195 }
00196 }
00197 }
00198 return parent;
00199 }
00200
00201 void PropertyModel::buildUp(const std::map<std::string, std::vector<App::Property*> >& props)
00202 {
00203
00204 rootItem->reset();
00205
00206
00207 std::map<std::string, std::vector<std::vector<App::Property*> > > propGroup;
00208 std::map<std::string, std::vector<App::Property*> >
00209 ::const_iterator jt;
00210 for (jt = props.begin(); jt != props.end(); ++jt) {
00211 App::Property* prop = jt->second.front();
00212 const char* group = prop->getGroup();
00213 std::string grp = group ? group : "Base";
00214 propGroup[grp].push_back(jt->second);
00215 }
00216
00217 std::map<std::string, std::vector<std::vector<App::Property*> > >
00218 ::const_iterator kt;
00219 for (kt = propGroup.begin(); kt != propGroup.end(); ++kt) {
00220
00221 PropertyItem* group = static_cast<PropertyItem*>(PropertySeparatorItem::create());
00222 group->setParent(rootItem);
00223 rootItem->appendChild(group);
00224 group->setPropertyName(QString::fromAscii(kt->first.c_str()));
00225
00226
00227 std::vector<std::vector<App::Property*> >::const_iterator it;
00228 for (it = kt->second.begin(); it != kt->second.end(); ++it) {
00229 App::Property* prop = it->front();
00230 QString editor = QString::fromAscii(prop->getEditorName());
00231 if (!editor.isEmpty()) {
00232 Base::BaseClass* item = 0;
00233 try {
00234 item = static_cast<Base::BaseClass*>(Base::Type::
00235 createInstanceByName(prop->getEditorName(),true));
00236 }
00237 catch (...) {
00238 }
00239 if (!item) {
00240 qWarning("No property item for type %s found\n", prop->getEditorName());
00241 continue;
00242 }
00243 if (item->getTypeId().isDerivedFrom(PropertyItem::getClassTypeId())) {
00244 PropertyItem* child = (PropertyItem*)item;
00245 child->setParent(rootItem);
00246 rootItem->appendChild(child);
00247 child->setPropertyName(QString::fromAscii(prop->getName()));
00248 child->setPropertyData(*it);
00249 }
00250 }
00251 }
00252 }
00253
00254 reset();
00255 }
00256
00257 #include "moc_PropertyModel.cpp"