|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Designer of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "promotionmodel_p.h" |
|
43 #include "widgetdatabase_p.h" |
|
44 |
|
45 #include <QtDesigner/QDesignerWidgetDataBaseInterface> |
|
46 #include <QtDesigner/QDesignerPromotionInterface> |
|
47 #include <QtDesigner/QDesignerFormEditorInterface> |
|
48 |
|
49 #include <QtGui/QStandardItem> |
|
50 #include <QtCore/QCoreApplication> |
|
51 |
|
52 QT_BEGIN_NAMESPACE |
|
53 |
|
54 namespace { |
|
55 typedef QList<QStandardItem *> StandardItemList; |
|
56 |
|
57 // Model columns. |
|
58 enum { ClassNameColumn, IncludeFileColumn, IncludeTypeColumn, ReferencedColumn, NumColumns }; |
|
59 |
|
60 // Create a model row. |
|
61 StandardItemList modelRow() { |
|
62 StandardItemList rc; |
|
63 for (int i = 0; i < NumColumns; i++) { |
|
64 rc.push_back(new QStandardItem()); |
|
65 } |
|
66 return rc; |
|
67 } |
|
68 |
|
69 // Create a model row for a base class (read-only, cannot be selected). |
|
70 StandardItemList baseModelRow(const QDesignerWidgetDataBaseItemInterface *dbItem) { |
|
71 StandardItemList rc = modelRow(); |
|
72 |
|
73 rc[ClassNameColumn]->setText(dbItem->name()); |
|
74 for (int i = 0; i < NumColumns; i++) { |
|
75 rc[i]->setFlags(Qt::ItemIsEnabled); |
|
76 } |
|
77 return rc; |
|
78 } |
|
79 |
|
80 // Create an editable model row for a promoted class. |
|
81 StandardItemList promotedModelRow(const QDesignerWidgetDataBaseInterface *widgetDataBase, |
|
82 QDesignerWidgetDataBaseItemInterface *dbItem, |
|
83 bool referenced = false) { |
|
84 |
|
85 const int index = widgetDataBase->indexOf(dbItem); |
|
86 |
|
87 // Associate user data: database index and enabled flag |
|
88 QVariantList userDataList; |
|
89 userDataList.push_back(QVariant(index)); |
|
90 userDataList.push_back(QVariant(referenced)); |
|
91 const QVariant userData(userDataList); |
|
92 |
|
93 StandardItemList rc = modelRow(); |
|
94 // name |
|
95 rc[ClassNameColumn]->setText(dbItem->name()); |
|
96 rc[ClassNameColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable); |
|
97 rc[ClassNameColumn]->setData(userData); |
|
98 // header |
|
99 const qdesigner_internal::IncludeSpecification spec = qdesigner_internal::includeSpecification(dbItem->includeFile()); |
|
100 rc[IncludeFileColumn]->setText(spec.first); |
|
101 rc[IncludeFileColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable); |
|
102 rc[IncludeFileColumn]->setData(userData); |
|
103 // global include |
|
104 rc[IncludeTypeColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsUserCheckable); |
|
105 rc[IncludeTypeColumn]->setData(userData); |
|
106 rc[IncludeTypeColumn]->setCheckState(spec.second == qdesigner_internal::IncludeGlobal ? Qt::Checked : Qt::Unchecked); |
|
107 // referenced |
|
108 rc[ReferencedColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); |
|
109 rc[ClassNameColumn]->setData(userData); |
|
110 if (!referenced) { |
|
111 //: Usage of promoted widgets |
|
112 static const QString notUsed = QCoreApplication::translate("PromotionModel", "Not used"); |
|
113 rc[ReferencedColumn]->setText(notUsed); |
|
114 } |
|
115 return rc; |
|
116 } |
|
117 } |
|
118 |
|
119 namespace qdesigner_internal { |
|
120 |
|
121 PromotionModel::PromotionModel(QDesignerFormEditorInterface *core) : |
|
122 m_core(core) |
|
123 { |
|
124 connect(this, SIGNAL(itemChanged(QStandardItem *)), this, SLOT(slotItemChanged(QStandardItem *))); |
|
125 } |
|
126 |
|
127 void PromotionModel::initializeHeaders() { |
|
128 setColumnCount(NumColumns); |
|
129 QStringList horizontalLabels(tr("Name")); |
|
130 horizontalLabels += tr("Header file"); |
|
131 horizontalLabels += tr("Global include"); |
|
132 horizontalLabels += tr("Usage"); |
|
133 setHorizontalHeaderLabels (horizontalLabels); |
|
134 } |
|
135 |
|
136 void PromotionModel::updateFromWidgetDatabase() { |
|
137 typedef QDesignerPromotionInterface::PromotedClasses PromotedClasses; |
|
138 |
|
139 clear(); |
|
140 initializeHeaders(); |
|
141 |
|
142 // retrieve list of pairs from DB and convert into a tree structure. |
|
143 // Set the item index as user data on the item. |
|
144 const PromotedClasses promotedClasses = m_core->promotion()->promotedClasses(); |
|
145 |
|
146 if (promotedClasses.empty()) |
|
147 return; |
|
148 |
|
149 const QSet<QString> usedPromotedClasses = m_core->promotion()->referencedPromotedClassNames(); |
|
150 |
|
151 QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase(); |
|
152 QDesignerWidgetDataBaseItemInterface *baseClass = 0; |
|
153 QStandardItem *baseItem = 0; |
|
154 |
|
155 const PromotedClasses::const_iterator bcend = promotedClasses.constEnd(); |
|
156 for (PromotedClasses::const_iterator it = promotedClasses.constBegin(); it != bcend; ++it) { |
|
157 // Start a new base class? |
|
158 if (baseClass != it->baseItem) { |
|
159 baseClass = it->baseItem; |
|
160 const StandardItemList baseRow = baseModelRow(it->baseItem); |
|
161 baseItem = baseRow.front(); |
|
162 appendRow(baseRow); |
|
163 } |
|
164 Q_ASSERT(baseItem); |
|
165 // Append derived |
|
166 baseItem->appendRow(promotedModelRow(widgetDataBase, it->promotedItem, usedPromotedClasses.contains(it->promotedItem->name()))); |
|
167 } |
|
168 } |
|
169 |
|
170 void PromotionModel::slotItemChanged(QStandardItem * changedItem) { |
|
171 // Retrieve DB item |
|
172 bool referenced; |
|
173 QDesignerWidgetDataBaseItemInterface *dbItem = databaseItem(changedItem, &referenced); |
|
174 Q_ASSERT(dbItem); |
|
175 // Change header or type |
|
176 switch (changedItem->column()) { |
|
177 case ClassNameColumn: |
|
178 emit classNameChanged(dbItem, changedItem->text()); |
|
179 break; |
|
180 case IncludeTypeColumn: |
|
181 case IncludeFileColumn: { |
|
182 // Get both file and type items via parent. |
|
183 const QStandardItem *baseClassItem = changedItem->parent(); |
|
184 const QStandardItem *fileItem = baseClassItem->child(changedItem->row(), IncludeFileColumn); |
|
185 const QStandardItem *typeItem = baseClassItem->child(changedItem->row(), IncludeTypeColumn); |
|
186 emit includeFileChanged(dbItem, buildIncludeFile(fileItem->text(), typeItem->checkState() == Qt::Checked ? IncludeGlobal : IncludeLocal)); |
|
187 } |
|
188 break; |
|
189 } |
|
190 } |
|
191 |
|
192 QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItemAt(const QModelIndex &index, bool *referenced) const { |
|
193 if (const QStandardItem *item = itemFromIndex (index)) |
|
194 return databaseItem(item, referenced); |
|
195 |
|
196 *referenced = false; |
|
197 return 0; |
|
198 } |
|
199 |
|
200 QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItem(const QStandardItem * item, bool *referenced) const { |
|
201 // Decode user data associated with item. |
|
202 const QVariant data = item->data(); |
|
203 if (data.type() != QVariant::List) { |
|
204 *referenced = false; |
|
205 return 0; |
|
206 } |
|
207 |
|
208 const QVariantList dataList = data.toList(); |
|
209 const int index = dataList[0].toInt(); |
|
210 *referenced = dataList[1].toBool(); |
|
211 return m_core->widgetDataBase()->item(index); |
|
212 } |
|
213 |
|
214 QModelIndex PromotionModel::indexOfClass(const QString &className) const { |
|
215 const StandardItemList matches = findItems (className, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive); |
|
216 return matches.empty() ? QModelIndex() : indexFromItem (matches.front()); |
|
217 } |
|
218 } // namespace qdesigner_internal |
|
219 |
|
220 QT_END_NAMESPACE |